Виконання Javascript, коли доданий віджет у програму Backend


20

У мене є віджети, до яких додані керування javascript.

Якщо віджет присутній під час завантаження сторінки адміністратора віджетів, елементи керування працюють правильно.

Коли я додаю новий віджет, вони не працюють належним чином, я отримую розмітку, але жодні події JavaScript не набувають чинності.

Якщо я збережу новий віджет, коли форма перезавантажується, елементи керування створюються правильно і зараз працюють.

Оновлення сторінки також виправляє проблему, але лише для існуючих віджетів. Нові віджети все ще мають цю проблему.

Зокрема, у цих точках я вибираю selectize на вибраних входах:

  • документ готовий
  • Ajaxcomplete

Я перевірив, що мій код працює за кожною подією за бажанням, але результати не такі, як очікувалося.

Ось тестовий плагін, який демонструє проблему:

https://gist.github.com/Tarendai/8466299

Ви побачите, що у мене є лічильник, який збільшується з кожним елементом вибору, який він виявить, що він може конвертувати.

Примітки:

  • Коли сторінка віджета завантажується, я бачу, як лічильник збільшується на консолі JS, як очікувалося
  • Коли я додаю новий віджет, код запускається, однак він не зможе знайти жодних виділених елементів, на яких він може працювати, як показано found.length, що дорівнює 0. Це не повинно бути так, як повинен бути кожен новий віджет цього типу мають елемент вибору
  • елементи вибору мають клас для їх ідентифікації, цей клас видаляється після застосування бібліотеки selectize для запобігання дублювання та повторної обробки на існуючих віджетах.
  • До використання selectize я використовував Select2, який мав ту саму проблему
  • Коментуючи код AJAX, я б очікував, що нові віджети матимуть стандартне введення. Вони не. Я не знаю, чому це так

Тож як зробити так, щоб керувати селектизацією роботу, не кажучи користувачеві оновити / натиснути зберегти до внесення змін?


Це питання делегування заходу. Вам потрібно буде вивчити, використовуючи .on()метод jQuerys . Що вимагає прив’язання події до документа. Однак яка подія буде доречною, я зараз не впевнений. Зрештою, це тому, що ваші оригінальні прив’язки являють собою початкову версію DOM, коли сторінка була завантажена, і здебільшого сліпі за новими елементами (вміст віджетів), які додаються через ajax. Сподіваюсь, це покаже вас у правильному напрямку, якщо ні, я можу відповісти краще, коли я на роботі.

Це я очікував, і чому я додав jQuery( document ).ajaxStop( function() {частину, щоб я міг ініціалізувати елементи керування у нещодавно завантажених віджетах. Однак якщо я видалюю цей рядок, я б очікував, що нові віджети матимуть стандартні HTML-вхідні дані, але вони не мають = s
Tom J Nowell

Як прокоментував @ aaron-holbrook, його підхід є найбільш чітким, використовуючи події widget-updatedта widget-addedподії. Також я хочу підкреслити, що в коді @michaeljames використовується ідентифікатор елемента #widgets-right. Обов’язково використовуйте його для націлювання на активні елементи віджетів всередині вашого JS-коду, інакше ви можете отримати повторювані елементи, оскільки ваш код також може вибрати приховані неактивні елементи віджетів у лівій частині екрана (і ті клонуються, коли додається віджет).
Жульєн

Відповіді:


12

Відмінна новина,

Я це виправив.

Вибачте за те, що ви пропустили свою суть у моєму первинному коментарі та давши вам відповідь, яку ви вже реалізували. Це навчить мене відповідати по телефону на час поїзда!

Використання ajaxstop правильне. Пекло JS здебільшого працює коректно, ви могли бачити стилі css, які ініціалізуються та зміни в DOM.

Фактично проблема полягає у вашому виборі.

Це відбувається тому, що вміст віджетів не завантажується через ajax, насправді він клонує його з лівої колонки, де він схований, а потім запускає виклик ajax, щоб зберегти позицію віджета в стовпці правої руки. Це пояснює, чому ajaxstop працює частуванням, навіть думка про зміст клонується. Однак, оскільки в лівій колонці є прихована версія віджета, ваш JS інстанціює про це. Коли ви перетягуєте його до правої колонки, ви отримуєте зграбний клон прихованого віджета.

Таким чином, вам потрібно вибрати ліворуч. Нижче виправлений код:

<script>
jQuery( document ).ready( function( $ ) {
    function runSelect() {
        var found = $( '#widgets-right select.testselectize' );
        found.each( function( index, value ) {

            $( value ).selectize();
                .removeClass( 'testselectize' )
                .addClass( 'run-' + window.counter );

            console.log( $val );
            window.counter++;
        } );
    }

    window.counter = 1;

    runSelect();

    $( document ).ajaxStop( function() {
        runSelect();
    } );
} );
</script>

Святий молі, мені потрібно пройти перевірку цього <3
Том Дж. Ноуелл

Дуже елегантне рішення головного болю!
bosco

3
Я б радив не працювати на кожному події "ajaxStop", а замість цього запропонував би використовувати події "додано віджети", а також "події, оновлені віджетом".
Тирун

16

Як @aaron-holbrook прокоментував більш чистий підхід:

jQuery(document).on('widget-updated widget-added', function(){
    // your code to run
});

У багатьох випадках вам також захочеться запустити JS при завантаженні сторінки, а також при оновленні віджетів. Ви можете зробити так, як це.

function handle_widget_loading(){
   // your code to run
}
jQuery(document).ready( handle_widget_loading );
jQuery(document).on('widget-updated widget-added', handle_widget_loading );

Тільки вставляючи сюди для довідки, оскільки відповіді набагато простіше знайти ці коментарі


2
ймовірно, слід використовувати jQuery замість $
Марк Каплун
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.