JQuery не работает из внешнего пакета Symfony - PullRequest
0 голосов
/ 05 апреля 2019

Здравствуйте, я пытаюсь реализовать это Symfony 3.4 RatingBundle

https://github.com/blackknight467/StarRatingBundle

я получил этот результат

pic one

CSS работает идеальноно звезды не кликабельны, так что проблема в том, что между js и звездами нет связи

это мой код #update: я поместил код js на страницу ветки, чтобы сделать код более понятным.

html.twig

   {%  extends 'base.html.twig' %}

{% block body %}

    <h1>Lists of Posts !</h1>

    <div class="album py-5 bg-light">
        <div class="container">

            <h2>Search A Post !!</h2>

            <div class="sidebar-search">

                <div class="input-group custom-search-form">

                    <input type="text" id="search" class="form-control" placeholder="Search here">
                </div>
                <!-- /input-group -->
            </div>
            <ul class="nav" id="side-menu">
                <li>
                    <a href="#"> resultats de recherche<span class="fa arrow"></span></a>
                    <ul class="nav nav-second-level" id="entitiesNav">
                    </ul>
                </li>
            </ul><br><br><br><br>

            <script type="text/javascript" src="{{ asset('assets/js/jquery-2.2.3.min.js') }}"></script>

            <script type="text/javascript">



                $(function(){

                    // $( '.rating' ).click(function() {
                    //     alert(parseInt($(this).find('input').val()));
                    // });


                    var labelWasClicked = function labelWasClicked(){

                        var input = $(this).siblings().filter('input');
                        if (input.attr('disabled')) {
                            return;
                        }
                        input.val($(this).attr('data-value'));

                    }

                    var turnToStar = function turnToStar(){
                        if ($(this).find('input').attr('disabled')) {
                            return;
                        }
                        var labels = $(this).find('div');
                        labels.removeClass();
                        labels.addClass('star');
                    }

                    var turnStarBack = function turnStarBack(){
                        var rating = parseInt($(this).find('input').val());

                        if (rating > 0) {
                            var selectedStar = $(this).children().filter('#rating_star_'+rating)
                            var prevLabels = $(selectedStar).nextAll();
                            prevLabels.removeClass();
                            prevLabels.addClass('star-full');
                            selectedStar.removeClass();
                            selectedStar.addClass('star-full');
                        }
                    }

                    $('.star, .rating-well').click(labelWasClicked);
                    $('.rating-well').each(turnStarBack);
                    $('.rating-well').hover(turnToStar,turnStarBack);

                });
                jQuery(document).ready(function() {
                    var searchRequest = null;
                    $("#search").keyup(function() {
                        var minlength = 1;
                        var that = this;
                        var value = $(this).val();
                        var entitySelector = $("#entitiesNav").html('');
                        if (value.length >= minlength ) {
                            if (searchRequest != null)
                                searchRequest.abort();
                            searchRequest = $.ajax({
                                type: "GET",
                                url: "{{ path('ajax_search') }}",
                                data: {
                                    'q' : value
                                },
                                dataType: "text",
                                success: function(msg){
                                    //we need to check if the value is the same
                                    if (value===$(that).val()) {
                                        var result = JSON.parse(msg);
                                        $.each(result, function(key, arr) {
                                            $.each(arr, function(id, value) {
                                                if (key === 'posts') {
                                                    if (id !== 'error') {
                                                        console.log(value[1]);
                                                        entitySelector.append('<li><b>'+value[1]+'</b><a href="/pidev_symfony-officiel/web/app_dev.php/livre/detailedlivre/'+id+'">'+'<img src="/pidev_symfony-officiel/web/livimages/'+value[0]+'" style="width: 50px; height: 70px"/>'+'</a></li>');
                                                    } else {
                                                        entitySelector.append('<li class="errorLi">'+value+'</li>');
                                                    }
                                                }
                                            });
                                        });
                                    }
                                }
                            });
                        }
                    });
                });
            </script>
            <div class="post-container">
                <div class="row">


                    <section class="featured section-padding">
                        <div class="container">
                            <div class="row">
                                <div class="col-12 text-center">
                                    <div class="heading">
                                        <h1 class="section-title">Livres</h1>
                                        <br>
                                    </div>
                                </div>

                                {% for livre in livres %}

                                    <div class="col-xs-6 col-sm-6 col-md-6 col-lg-4">
                                        <div class="featured-box">
                                            <figure>
                                                  {#<img class="img-fluid" src="{{ asset('livimages/' ~ livre.image) }}" style="width: 270px;height: 350px">#}
                                                <a href="{{ path('detailed_livre',{'id': livre.idLivre}) }}"><img class="img-fluid" src="{{ asset('livimages/' ~ livre.image) }}" style="width: 50px; height: 70px" alt=""></a>
                                            </figure>
                                            <div class="content-wrapper">
                                                <div class="feature-content">
                                                    <h4>{{ livre.libelle }}</a></h4>
                                                    <p class="listing-tagline">{{ livre.description|trim }}</p>

                                                    <p class="rating">{{ '4'|rating }}</p>


                                                </div>

                                            </div>
                                        </div>
                                    </div>
                                {% endfor %}

                            </div>
                        </div>

                    </section>



                </div>

            </div>
        </div>
    </div>
{% endblock %}

{% block javascripts %}


{% endblock %}


php:

<?php

namespace Esprit\LoisirBundle\Form;

use blackknight467\StarRatingBundle\Form\RatingType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class LivreType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('libelle')
            ->add('description' ,TextareaType::class)
            ->add('file')
            ->add('auteur')
            ->add('url')
            ->add('type', ChoiceType::class, array('label' => 'Type',
                'choices' => array(' PDF' => 'pdf',
                    'Audio' => 'audio'),
                'required' => true,))
            ->add('categorie', ChoiceType::class, array('label' => 'Categorie',
                'choices' => array(
                    ' Historique' => 'historique',
                    ' Biographique' => 'biographique',
                    ' Politique' => 'politique',
                    ' Voyages' => 'Voyages',
                    'Jeunesse' => 'Jeunesse'),
                    'required' => true,))
        ->add('rating', RatingType::class, [
        'label' => 'Rating'
    ]);

    }/**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Esprit\LoisirBundle\Entity\Livre'
        ));
    }

    /**
     * {@inheritdoc}
     */
    public function getBlockPrefix()
    {
        return 'esprit_loisirbundle_livre';
    }


}

controller.php

<?php

namespace Esprit\LoisirBundle\Controller;

use Esprit\LoisirBundle\Entity\Livre;
use Esprit\LoisirBundle\Entity\Utilisateur;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

/**
 * Livre controller.
 *
 */
class LivreController extends Controller
{
    /**
     * Lists all livre entities.
     *
     */
    public function indexAction()
    {
        $em = $this->getDoctrine()->getManager();

        //$livres = $em->getRepository('EspritLoisirBundle:Livre')->findAll();
        $livres = $em->getRepository('EspritLoisirBundle:Livre')->findBy([], ['idLivre' => 'DESC']);

        return $this->render('livre/index.html.twig', array('livres' => $livres));
    }

    /**
     * Creates a new livre entity.
     *
     */
    public function newAction(Request $request)
    {
        /* ====== sesssion try */

        $user = $this->container->get('security.token_storage')->getToken()->getUser();
        $user1=new Utilisateur();
        $user1= $this->getDoctrine()->getRepository(Utilisateur::class) ->find($user->getId());

        /* ====== sesssion try */

        $livre = new Livre();
        $form = $this->createForm('Esprit\LoisirBundle\Form\LivreType', $livre);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            /* ===== session */
            $livre->setIdUtilisateur($user1);
            /* ===== session */

            $em = $this->getDoctrine()->getManager();
            /* =====Image Up====== */
            $livre -> uploadPicture();
            /* =====Image Up====== */
            $em->persist($livre);
            $em->flush();

            return $this->redirectToRoute('livre_show', array('idLivre' => $livre->getIdlivre()));
        }

        return $this->render('livre/new.html.twig', array(
            'livre' => $livre,
            'form' => $form->createView(),
        ));
    }

    /**
     * Finds and displays a livre entity.
     *
     */
    public function showAction(Livre $livre)
    {
        $deleteForm = $this->createDeleteForm($livre);

        return $this->render('livre/show.html.twig', array(
            'livre' => $livre,
            'delete_form' => $deleteForm->createView(),
        ));
    }

    /**
     * Displays a form to edit an existing livre entity.
     *
     */
    public function editAction(Request $request, Livre $livre)
    {
        $deleteForm = $this->createDeleteForm($livre);
        $editForm = $this->createForm('Esprit\LoisirBundle\Form\LivreType', $livre);
        $editForm->handleRequest($request);

        if ($editForm->isSubmitted() && $editForm->isValid()) {
            $this->getDoctrine()->getManager()->flush();

            return $this->redirectToRoute('livre_edit', array('idLivre' => $livre->getIdlivre()));
        }

        return $this->render('livre/edit.html.twig', array(
            'livre' => $livre,
            'edit_form' => $editForm->createView(),
            'delete_form' => $deleteForm->createView(),
        ));
    }

    /**
     * Deletes a livre entity.
     *
     */
    public function deleteAction(Request $request, Livre $livre)
    {
        $form = $this->createDeleteForm($livre);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->remove($livre);
            $em->flush();
        }

        return $this->redirectToRoute('livre_index');
    }

    /**
     * Creates a form to delete a livre entity.
     *
     * @param Livre $livre The livre entity
     *
     * @return \Symfony\Component\Form\Form The form
     */
    private function createDeleteForm(Livre $livre)
    {
        return $this->createFormBuilder()
            ->setAction($this->generateUrl('livre_delete', array('idLivre' => $livre->getIdlivre())))
            ->setMethod('DELETE')
            ->getForm()
        ;
    }

    public function showdetailedAction($id)
    {
        $em= $this->getDoctrine()->getManager();
        $liv=$em->getRepository('EspritLoisirBundle:Livre')->find($id);
        return $this->render('@EspritLoisir/Livre/detailedpost.html.twig', array(
            'libelle'=>$liv->getLibelle(),
            'description'=>$liv->getDescription(),
            'image'=>$liv->getImage(),
            'auteur'=>$liv->getAuteur(),
            'url'=>$liv->getUrl(),
            'type'=>$liv->getType(),
            'categorie'=>$liv->getCategorie(),
            //'posts'=>$liv,
            'comments'=>$liv,
            'idLivre'=>$liv->getIdLivre()
        ));
    }


    public function listlivreAction(Request $request)
    {
        $em=$this->getDoctrine()->getManager();
        $livres=$em->getRepository('EspritLoisirBundle:Livre')->findAll();
        return $this->render('livre/list.html.twig', array(
            "livres" =>$livres
        ));
    }

    public function searchAction(Request $request)
    {
        $em = $this->getDoctrine()->getManager();
        $requestString = $request->get('q');
        $livres =  $em->getRepository('EspritLoisirBundle:Livre')->findEntitiesByString($requestString);
        if(!$livres) {
            $result['posts']['error'] = "0 books given ";
        } else {
            $result['posts'] = $this->getRealEntities($livres);
        }
        return new Response(json_encode($result));
    }
    public function getRealEntities($livres){
        foreach ($livres as $livres){
            $realEntities[$livres->getIdLivre()] = [$livres->getImage(),$livres->getLibelle()];
        }
        return $realEntities;
    }
}


css:

https://github.com/blackknight467/StarRatingBundle/blob/master/Resources/public/css/rating.css

js:

https://github.com/blackknight467/StarRatingBundle/blob/master/Resources/public/js/rating.js

Моя основная проблема заключается в том, как вызвать это в html-странице

$('.star, .rating-well').click(labelWasClicked);
    $('.rating-well').each(turnStarBack);
    $('.rating-well').hover(turnToStar,turnStarBack);

в новом тесте.html.twig по запросу:

{% extends 'base.html.twig' %}
{% form_theme form 'bootstrap_4_layout.html.twig' %}

{% block body %}
    <link rel="stylesheet" type="text/css" href="{{ asset('assets/public/css/rating.css') }}" />
    <script src="{{ asset('assets/public/js/rating.js') }}"></script>
    <h1>Livre creation</h1>

    {{ form_start(form) }}
        {{ form_widget(form) }}
        <input type="submit" value="Create" class="btn btn-primary" />
    {{ form_end(form) }}
    {{ '2'|rating }}

    <ul>
        <li>
            <a href="{{ path('livre_index') }}">Back to the list</a>
        </li>
    </ul>
{% endblock %}


Ответы [ 3 ]

1 голос
/ 06 апреля 2019

Если я понимаю, как библиотека работает правильно, то я думаю, что фильтр rating используется только для отображения рейтинга.

Чтобы реально оценить, вам нужно поместить RatingType в форму (как вы это сделали), отобразить форму, а затем отправить ее и сохранить результаты.

В предоставленном вами файле ветки вы, кажется, зацикливаетесь на коллекции Livre (я полагаю) сущностей, и в этом контексте вы можете просматривать только рейтинг ливры. Пока я вижу, что у вас есть жестко закодированный 4 в {{ '4'|rating }}, но я думаю, что в какой-то момент он должен стать {{ livre.rating|rating }} (при условии, что вы сохраните рейтинг в сущности Livre в столбце rating), чтобы отражать фактическую оценку рейтинга.

Код javascript, который вы добавили в файл ветки, неуместен. Как я уже упоминал, вы, кажется, находитесь в «просмотре» контекста. Чтобы на самом деле использовать этот скрипт для оценки, вы должны быть на странице, где отображается форма LivreType (так как она содержит поле RatingType внутри). Пожалуйста, вставьте файл ветки, который содержит форму LivreType, если можете.

Код javascript также не нужен, так как вы можете использовать функцию ветки asset для импорта сценария из самого пакета (это то, что вы вставили в файл ветки). В соответствии с файлом readme он должен выглядеть так:

<script src="{{ asset('bundles/starrating/js/rating.js') }}"></script>

Если вы хотите иметь возможность оценивать рейтинг при просмотре коллекции Livre сущностей, я боюсь, что вам нужно изменить весь подход, есть много способов, которыми вы можете достичь этого, например, отображение формы RatingType вместо только оценки рейтинга.

Еще одно замечание - я не уверен, что используемая вами библиотека работает так, как задумано. Я не пробовал себя, но из , что я вижу , похоже, что действительное значение рейтинга неверно. В случае 5-звездочной системы (так по умолчанию) и при нажатии 4-й звезды код, который я связал, даст значение 2, потому что в data-value="{{ stars - star + 1 }}" значение stars равно 5 и star 4.

На самом деле код там верный, просто элементы div для звезд добавляются в порядке убывания.

0 голосов
/ 05 апреля 2019

Вам нужно поставить 'rating' в шаблон веточки от Symfony, например

<?php
    // ...
    $builder->add('rating', RatingType::class, [
        //...
        'stars' => 4,
        //...
    ]);
    // ...
0 голосов
/ 05 апреля 2019

Пример на Github пишет: {{someInteger | rating}} Вы пишете {{someInteger | rating ()}}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...