Привет, я пытаюсь реализовать этот Symfony 3.4 RatingBundle
https://github.com/blackknight467/StarRatingBundle
я получил этот результат

css работает отлично, но звезды не кликабельны, поэтому проблема в том, что между js и звездами нет связи
это мой код #обновление: я поместил код 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.info(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';
}
}
контроллер.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);
тест в new.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 %}
как я могу вызвать код js на звездах с правильным именем класса

Пример на Github пишет: {{someInteger|рейтинг}} Ты пишешь {{ someInteger|рейтинг() }}
это не проблема звезды даже не меняются я пробовал их обе
Вам нужно поместить «рейтинг» в шаблон ветки из symfony что-то вроде
<?php
// ...
$builder->add('rating', RatingType::class, [
//...
'stars' => 4,
//...
]);
// ...
Я уже сделал это, проблема в том, что html я неправильно вызываю скрипт js!
Затем, пожалуйста, обновите свой вопрос, чтобы показать свой код. rating() - это то, как вы вызываете функцию в js, поэтому функция каким-то образом отсутствует на странице.
вызов функции в js с именем класса, которое вы здесь не понимаете.
что именно вы хотите увидеть?
PHP-код, который вы написали для импорта php в пакете, на который вы ссылаетесь.
Вам все еще нужно импортировать пакет из php, js и css недостаточно.
я обновил страницу ветки, чтобы вы могли меня понять
используйте blackknight467\StarRatingBundle\Form\RatingType;
хорошо, теперь я все вижу. Попробуйте использовать 4, а не '4' в {{ '4'|рейтинг }} :)
это же ничего не изменит, проблема в классе под названием js, звездочки некликабельны
Если я правильно понимаю, как работает библиотека, то я думаю, что фильтр ветки rating используется только для отображения рейтинга.
Чтобы действительно оценить, вам нужно поместить RatingType в форму (как вы это сделали), отобразить форму, а затем отправить ее и сохранить результаты.
В предоставленном вами файле ветки вы, кажется, перебираете набор Livre (я полагаю) объектов, и в этом контексте вы можете просматривать только рейтинг livre. На данный момент я вижу, что у вас есть жестко запрограммированный 4 в {{ '4'|rating }}, но я думаю, что в какой-то момент он должен стать {{ livre.rating|rating }} (при условии, что вы сохраните рейтинг в объекте Livre под столбцом rating), чтобы отразить фактический рейтинг.
Код javascript, который вы добавили в файл ветки, неуместен. Как я уже упоминал, вы, кажется, находитесь в контексте «просмотра». Чтобы на самом деле использовать этот скрипт для оценки, вам нужно находиться на странице, где отображается форма LivreType (поскольку это та, которая содержит поле RatingType внутри). Пожалуйста, вставьте файл ветки, содержащий форму LivreType, если можете.
Код javascript также не нужен, так как вы должны иметь возможность использовать функцию asset twig для импорта скрипта из самого пакета (который вы вставили в файл twig). Это должно, согласно файл 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 для звездочек добавляются в порядке убывания.
спасибо за ваши заметки, прежде чем я поместил js на веб-страницу, я уже протестировал ее с импортом с активом, также основная проблема в том, что js даже не работает (звезды не движутся), я не в части сущности, и я вставлю свой livre тип сек
К вашему сведению, вы снова вставили класс формы LivreType. Можете ли вы вставить контроллер, который отображает представленный файл ветки?
Да, из того, что я вижу, файл ветки, который вставлен сверху, на самом деле является либо index.html.twig, либо list.html.twig, что означает, что вы показываете только рейтинг каждого сохраненного объекта Livre (с помощью фильтра |rating), поэтому звезды не двигаются. Бьюсь об заклад, однако, что когда вы перейдете к new.html.twig или edit.html.twig, которые отображают форму LivreType, и добавите туда актив скрипта, вы сможете фактически оценить данный Livre, и звезды будут двигаться. Пожалуйста, поправьте меня, если я ошибаюсь.
дай мне минутку я попробую
я ввел рейтинг в new.html.twig, как вы предложили, я попытался с этим {{ '2'|rating }}, но я не изменил контроллер, к сожалению, звезды все еще не движутся
Можете ли вы затем вставить содержимое new.html.twig?
добавлен новый.html.twig
Итак, часть {{ '2'|rating }} в new.html.twig не нужна. Как я уже писал - этот используется только для отображения рейтинга, статично, без каких-либо движений. Именно form_widget(form) должен отображать звезды при рендеринге rating части LivreType. Когда вы просматриваете new.html.twig в браузере, какой тип элемента вы видите для поля ratingform? Это просто поле ввода? Или там звезды на месте?
рейтинг в LivreType представляет собой закомментированный код, подобный этому /* ->add('rating', RatingType::class, ['label' => 'Rating']);*/ потому что, когда я добавляю его, я получаю исключение, потому что я ddint еще добавил атрибут рейтинга к объекту (я хотел проверить звезды перед изменением объекта), вот скриншот для элемента проверки prntscr.com/n8dmmo
Вам действительно нужно добавить параметр rating к сущности Livre и раскомментировать часть ->add('rating' .... Если вы это сделаете, то увидите интерактивные звезды на отрендеренной странице new.html.twig. Пожалуйста, попробуйте это и дайте мне знать, если вы действительно видите интерактивные звезды.
оно работает !! после добавления публичного $рейтинга; в сущности, я думаю, документация была плохой!, это будет работать в list.html.twig?
Если вы действительно хотите поставить рейтинг с помощью этих интерактивных звездочек, находясь на list.html.twig, вам следует передать тип формы, созданный вами самостоятельно, который будет содержать элемент RatingType (как и ваш LivreType). Это означало бы, что вам пришлось бы создавать эту форму для каждого Livre в listlivreAction() и отображать эти формы вместо отображения статического рейтинга. Однако в этом случае вам также потребуется написать пользовательский JavaScript, который будет запрашивать отправку индивидуальной рейтинговой формы, по которой щелкнули, и сохранить результаты в базе данных. Хотя слишком много, чтобы писать здесь.
у меня есть detail_livre.twig, который отображает 1 объект с использованием идентификатора, это будет работать? если да, что я должен настроить, кроме обновления таблицы базы данных и объекта
Давайте продолжить обсуждение в чате.
Вы спрашиваете, как запустить код js для элемента с заданным классом? Этот вопрос довольно расплывчатый, не могли бы вы обновить его?