Голосование в модальном окне

InstantCMS 2.X

Компонент Рейтинг

#1 1 июня 2026 в 15:07

Доброго дня!

Господа, подскажите как заставить работать голосование в модальном окне..

Вывожу запись ТК в окне со страницы списка таким образом: 

  1. <a class="ajax-modal" href="<?php echo href_to($ctype['name'], $item['slug'].'.html'); ?>">

Голосование в окне отображается, но не активно (невозможно проголосовать). 

Как можно «подтянуть» этот функционал в модальное окно?

#2 1 июня 2026 в 15:37
Доброго дня! Господа, подскажите как заставить работать голосование в модальном окне… Вывожу запись ТК в окне со страницы списка таким образом:  <a class=«ajax-modal» href="<?
denmois

попробуйте «ajax-modal ajax-modal-ready»

#3 2 июня 2026 в 09:17
попробуйте «ajax-modal ajax-modal-ready»
TOPg

К сожалению не сработало (

#4 2 июня 2026 в 14:30

 denmois, надо отследить открытие страницы в модальном окне. И перезапустить рейтинг.

Отследить с помощью этого github.com/instantsoft/icms2/blob/44f3a9d04a3207c82cdc756599cbdf084a02858f/templates/modern/js/modal.js#L174

А перезапустить рейтинг так github.com/instantsoft/icms2/blob/44f3a9d04a3207c82cdc756599cbdf084a02858f/templates/modern/js/rating.js#L13

Готового кода нет. Но вы пробуйте и пишите сюда ваши попытки.

#5 2 июня 2026 в 22:08

 Zau4man, спасибо, но боюсь мне ваша подсказка не поможет, т.к в js вообще ни чего не понимаю..

Что нужно отследить… и.т.д..

Вот переменные в этой точке

Изображение

Но что с ними делать я не понимаю..

Добавлено спустя 7 минут

 Zau4man, может возьметесь за платную доработку данного функционала?

Я все равно даже с пол литра не разберусь)

#6 3 июня 2026 в 09:00

templates/modern/main.tpl.php, заменить

  1. $this->addMainTplJSName(['core', 'modal']);

на

  1. $this->addMainTplJSName(['core', 'modal', 'rating']);

templates/modern/js/modal.js, после строк в методе showContent

  1. if(title){
  2. $(modal_el).find('.modal-title').show().html(title);
  3. } else {
  4. $(modal_el).find('.modal-title').hide();
  5. }
  6. $(modal_el).addClass('in');

добавить

  1. icms.events.run('icms_modal_content');

templates/modern/js/rating.js, заменить

  1. this.onDocumentReady = function(){
  2. $('.rating_widget').each(function(){
  3. self.bindWidget($(this));
  4. });
  5. };
  6.  
  7. this.bindWidget = function(widget){

на

  1. this.onDocumentReady = function(){
  2. $('.rating_widget').each(function(){
  3. self.bindWidget($(this));
  4. });
  5. icms.events.on('icms_modal_content', function(){
  6. self.onModalContent();
  7. });
  8. };
  9.  
  10. this.onModalContent = function(){
  11. if (!self.options.url) {
  12. let $first = $('#icms_modal .modal-body .rating_widget').first();
  13. if ($first.data('vote-url')) {
  14. self.setOptions({url: $first.data('vote-url')});
  15. }
  16. }
  17. $('#icms_modal .modal-body .rating_widget').each(function(){
  18. self.bindWidget($(this));
  19. });
  20. };
  21.  
  22. this.bindWidget = function(widget){

templates/modern/js/rating.js, заменить

  1. $('a.vote-up', widget).on('click', function(){
  2. return self.vote('up', controller, subject, id);
  3. });
  4.  
  5. $('a.vote-down', widget).on('click', function(){
  6. return self.vote('down', controller, subject, id);
  7. });
  8.  
  9. $('.vote-clear', widget).on('click', function(){
  10. return self.vote('clear', controller, subject, id);
  11. });

на

  1. $('a.vote-up', widget).off('click').on('click', function(){
  2. return self.vote('up', controller, subject, id, widget);
  3. });
  4.  
  5. $('a.vote-down', widget).off('click').on('click', function(){
  6. return self.vote('down', controller, subject, id, widget);
  7. });
  8.  
  9. $('.vote-clear', widget).off('click').on('click', function(){
  10. return self.vote('clear', controller, subject, id, widget);
  11. });

templates/modern/js/rating.js, заменить

  1. this.vote = function(direction, controller, subject, id){
  2.  
  3. let widget_id = 'rating-' + subject + '-' + id;
  4. let widget = $('#'+widget_id);

на

  1. this.vote = function(direction, controller, subject, id, widget){
  2.  
  3. if (!widget || !widget.length) {
  4. widget = $('#icms_modal .modal-body .rating_widget[data-target-subject="' + subject + '"][data-target-id="' + id + '"]');
  5. if (!widget.length) {
  6. widget = $('#rating-' + subject + '-' + id).last();
  7. }
  8. }

templates/modern/controllers/rating/widget.tpl.php, заменить

  1. data-target-id="<?php echo $target_id; ?>"
  2. data-info-url="<?php echo $this->href_to('info'); ?>"
  3. <?php } ?>

на

  1. data-target-id="<?php echo $target_id; ?>"
  2. data-info-url="<?php echo $this->href_to('info'); ?>"
  3. data-vote-url="<?php echo $this->href_to('vote'); ?>"
  4. <?php } ?>

templates/modern/controllers/rating/widget.tpl.php, заменить

  1. icms.rating.setOptions({
  2. url: '<?php echo $this->href_to('vote'); ?>'
  3. });

на

  1. if (typeof icms.rating !== 'undefined') {
  2. icms.rating.setOptions({
  3. url: '<?php echo $this->href_to('vote'); ?>'
  4. });
  5. }
#7 3 июня 2026 в 09:49

 ideasdigger, ой ей. Как же это все потом поддерживать и обновлять :)

а можно в том файле шаблона списка, в котором добавляли класс ajax-modal добавить небольшой код в конце. И будет так

Изображение

Рассмотрим на примере демо-контента новости. Откроем файл templates\modern\content\default_list_featured.tpl.php и сперва добавим класс ajax-modal

Для этого заменим

  1. <a href="<?php echo href_to($ctype['name'], $item['slug'].'.html'); ?>">

на

  1. <a class="ajax-modal" href="<?php echo href_to($ctype['name'], $item['slug'].'.html'); ?>">

и затем в конце файла, после пагинации добавим

  1. <?php
  2. $this->addTplJSName('rating');
  3. ob_start(); ?>
  4. <script>
  5. icms.modal.setCallback('open', function() {
  6.  
  7. let checkContentInterval = setInterval(function() {
  8. var $modalBody = $('.modal').find('.modal-body');
  9.  
  10. if ($modalBody.length > 0 && $modalBody.text().trim().length > 0) {
  11. clearInterval(checkContentInterval);
  12.  
  13. $('.modal').find('.rating_widget').each(function() {
  14. icms.rating.bindWidget($(this));
  15. });
  16. }
  17. }, 100);
  18. });
  19. </script>
  20. <?php $this->addBottom(ob_get_clean()); ?>

Я изначально думал, что код будет проще, но коллбэк срабатывает раньше, чем появится содержимое модалки. Поэтому в код добавлен интервал.

Обратите внимание, что для типа контента, который открывается в модалке, также должны быть отключены комментарии. Иначе в консоли будут ошибки js и код не сработает. Починить комментарии в модалке — это отдельная история, которая возможно не решаема без правок типа выше.

#8 3 июня 2026 в 12:34

@Zau4man да согласен, для поддержки и обновление предложенный вариант удобнее, намного удобнее, но с учётом ситуации если необходимо подключить в нескольких типах списка_list.tpl, я бы вынес логику в templates/modern/assets/ui

у openAjax есть правильная точка callback когда html уже вставлен, обычный ajax-modal, callback не использует и не позволяет передать, но можно обойтись и без setInterval, а через свой класс, да и раз класс всё равно прописывать)

в templates/modern/content/default_list_featured.tpl.php вместо ajax-modal указать класс ajax-modal-content:

  1. <a class="ajax-modal-content" href="<?php echo href_to($ctype['name'], $item['slug'].'.html'); ?>">
  2. <?php html($item[$field['name']]); ?>
  3. </a>

а в конце файла ниже пагинации добавить:

  1. <?php $this->renderAsset('ui/ajax-modal-content'); ?>

сам asset создать в templates/modern/assets/ui/ajax-modal-content.tpl.php

  1. <?php
  2. $this->addTplJSName(['rating', 'jquery-scroll', 'comments']);
  3. ob_start(); ?>
  4. <script>
  5. $(function() {
  6. if (typeof icms === 'undefined' || !icms.modal) {
  7. return;
  8. }
  9.  
  10. function initModalContent() {
  11. if (icms.rating) {
  12. $('#icms_modal .modal-body .rating_widget').each(function() {
  13. icms.rating.bindWidget($(this));
  14. });
  15. }
  16.  
  17. if (icms.comments && $('#icms_modal .modal-body #comments_widget').length) {
  18. icms.comments.onDocumentReady();
  19. }
  20. }
  21.  
  22. $('a.ajax-modal-content').off('click').on('click', function() {
  23. var $link = $(this);
  24. var title = $link.attr('title') || $link.data('original-title');
  25.  
  26. icms.modal.openAjax($link.attr('href'), $link.data('params'), initModalContent, title, $link.data('style'));
  27.  
  28. return false;
  29. });
  30. });
  31. </script>
  32. <?php $this->addBottom(ob_get_clean()); ?>

если комментария не используются, вариант без них:

  1. <?php
  2. $this->addTplJSName('rating');
  3. ob_start(); ?>
  4. <script>
  5. $(function() {
  6. if (typeof icms === 'undefined' || !icms.modal) {
  7. return;
  8. }
  9.  
  10. function initModalContent() {
  11. if (icms.rating) {
  12. $('#icms_modal .modal-body .rating_widget').each(function() {
  13. icms.rating.bindWidget($(this));
  14. });
  15. }
  16.  
  17. }
  18.  
  19. $('a.ajax-modal-content').off('click').on('click', function() {
  20. var $link = $(this);
  21. var title = $link.attr('title') || $link.data('original-title');
  22.  
  23. icms.modal.openAjax($link.attr('href'), $link.data('params'), initModalContent, title, $link.data('style'));
  24.  
  25. return false;
  26. });
  27. });
  28. </script>
  29. <?php $this->addBottom(ob_get_clean()); ?>
  30.  


такой вариант удобнее для внедрения, особенно в случае нескольких списков, не тянет rating.js везде даже там где он не нужен, весь код остаётся на уровне asset что удобнее для поддержки, без лишних правок к modal.js, rating.js, не цепляет глобальный таймер к всем модальным окнам, а рейтинг и комментарии инициализируются только там, где они реально ожидаются

комментария добавляются, редактируются, но явно что то может ещё не хватать, как минимум скроллит тело страницы при добавлении нового

#9 3 июня 2026 в 23:07

 Zau4man,  ideasdigger, спасибо большое за ваше участие, помощь! Вечером буду у компьютера, опробую оба варианта 

Добавлено спустя 6 минут
@такой вариант удобнее для внедрения, особенно в случае нескольких списков, не тянет rating.js везде даже там где он не нужен, весь код остаётся на уровне asset что удобнее для поддержки, без лишних правок к modal.js, rating.js, не цепляет глобальный таймер к всем модальным окнам, а рейтинг и комментарии инициализируются только там, где они реально ожидаются
ideasdigger

Блин, читая такое понимаешь какая пропость  между разработчиками и обычными пользователями 🙈)

Добавлено спустя 6 часов

Опробовал, оба способа рабочие!

 ideasdiggerZau4man, еще раз благодарю

Вы не можете отвечать в этой теме.
Войдите или зарегистрируйтесь, чтобы писать на форуме.

Похожее в блогах

🍪Мы используем файлы cookie для работы сайта. Читать подробнее.