Як зробити так, щоб кнопки форми викликали лише JavaScript?


9

Я експериментую з формами JavaScript та Drupal. В даний час я намагаюся створити кнопку у формі адміністрування модуля, який використовуватиме JavaScript для додавання параметрів до списку вибору. Проблема, з якою я стикаюся, полягає в тому, що коли я натискаю кнопку, мій JavaScript викликається, але вся форма оновляється. Я переглянув посилання API Forms, думаючи, що є якийсь атрибут, який я можу встановити на кнопці, щоб зупинити його, але нічого не знайшов. Чи є якийсь спосіб я зупинити кнопку оновлення сторінки або це глухий кут?

$form['#attached']['js'] = array(
  drupal_get_path('module', 'test').'/js/test.js',
);

$form['list'] = array(
  '#type' => 'select',
  '#options' => array(),
  '#attributes' => array(
    'name' => 'sellist',
  ),
  '#size' => 4,
);

$form['add_button'] = array(
  '#type' => 'button',
  '#value' => 'Add',
  '#attributes' => array(
    'onclick' => "add_to_list(this.form.sellist, 'Append' + this.form.sellist.length);",
  ),
);

//JavaScript
function add_to_list(list, text) {
  try {
    list.add(new Option(text, list.length), null) //add new option to end of "sample"
  }
  catch(e) {
    list.add(new Option(text, list.length));
  }
}

Мій кінцевий код:

<?php
function jstest_menu() {
  $items['admin/config/content/jstest'] = array(
    'title' => 'JavaScript Test',
      'description' => 'Configuration for Administration Test',
      'page callback' => 'drupal_get_form',
      'page arguments' => array('_jstest_form'),
      'access arguments' => array('access administration pages'),
      'type' => MENU_NORMAL_ITEM,
  );

  return $items;
}

function _jstest_form($form, &$form_state) {
  $form['list'] = array(
    '#type' => 'select',
    '#options' => array(),
    '#size' => 4,
  );

  $form['text'] = array(
    '#type' => 'textfield',
  );

  $form['add_button'] = array (
    '#type' => 'button',
    '#value' => t("Add"),
    '#after_build' => array('_jstest_after_build'),
  );
  return $form;
}

function _jstest_after_build($form, &$form_state) {
  drupal_add_js(drupal_get_path('module', 'jstest').'/js/jstest.js');
  return $form;
}

JavaScript
(function ($) {
  Drupal.behaviors.snmpModule = {
    attach: function (context, settings) {
      $('#edit-add-button', context).click(function () {
        var list = document.getElementById('edit-list');
        var text = document.getElementById('edit-text');

        if (text.value != '')
        {
          try {
            list.add(new Option(text.value, list.length), null);
          }
          catch(e) {
            list.add(new Option(text.value, list.length));
          }

          text.value = '';
        }

        return false;
      });
      $('#edit-list', context).click(function () {
        var list = document.getElementById('edit-list');

        if (list.selectedIndex != -1)
          list.remove(list.selectedIndex);

        return false;
      });
    }
  };
}(jQuery));

Відповіді:


4

Найпростіший спосіб досягти цього - просто повернути помилку у коді JavaScript:

function add_to_list(list, text) {
  try {
    list.add(new Option(text, list.length), null);
    return false;
  } catch(e) {
    list.add(new Option(text, list.length));   
    return false;
  }
}

або кращим способом є використання поведінки:

Drupal.behaviors.some_action = function(context) {
  $('#id-button:not(.button-processed)',context)
  .addClass('button-processed').each(function() {

    //whatever you want here
    return false;
  });
}

1
Дякую за те, що вказували мені на поведінку, я зараз читаю це фактично. І чомусь повернення неправди не працює для мене; сторінка все ще оновлюється = /. Для подальшого запитання, як слід обробляти користувачів, які блокують / відключають JavaScript?
Сатхаріел

Якщо ви поставите кнопку назовні до тегу <form> </form>, це не буде подано, але це не рекомендується, більш звичайний спосіб зробити це за допомогою JavaScript. Якщо ви все ще оновлюєте форму, перевірте, чи є ще якийсь javascript, відображається помилка чи щось подібне.
Gnuget

Куди поставити код Drupal.Behaviors? у файлі javascript?

Так, подивіться на це: amazeelabs.com/en/blog/drupal-behaviors-quick-how
Gnuget

7

визначення кнопки форми нижче для мене працює, #after_build корисний для завантаження у javascript, який може приєднати обробник кліків.

$form['add_button'] = array (
  '#type' => 'button',
  '#attributes' => array('onclick' => 'return (false);'),
  '#value' => t("Add"),
);

$form['#after_build'] = array('[module_name]_after_build');

Тоді мій JavaScript, який завантажується в окремий файл функцією after build, виглядає приблизно так:

Drupal.behaviors.[module_name] = function(context) {
  $('#edit-add-button').click(function() {
   ...Do something here
  });
};

After_build не працює для мене. Це приносить мені фатальну помилку: виклик до невизначеної функції [module_name] _after_build (). Якщо я визначу метод [ім'я_модуля] _after_build () з порожнім тілом, форма не відображатиметься. Чи можете ви уточнити трохи більше, як ним користуватися?
sumanchalki

Вибачте, я не бачив цього питання ... Я припускаю, що ви замінюєте [ім'я_модуля] фактичним іменем вашого модуля?
Малкс

$ form ['# after_build'] призначений для додавання функції сервера (PHP) - це не для вказівки JavaScript після створення збірки. api.drupal.org/api/drupal/…
Крістіан

3

Ви можете просто додати return falseоператор після виклику функції у рядку атрибутів елемента форми кнопки:

'#attributes' => array(
   'onclick' => "add_to_list(this.form.sellist, 'Append' + this.form.sellist.length); return false",
),

Я думаю, що кращим варіантом є додавання зовнішнього слухача подій, а не розміщення все це в Inline onclick події.
Крістіан

0

В ідеалі - прочитати власні здібності AJAX (або AHAH) Drupal. Дійсно базовий вступ тут http://drupal.org/node/752056

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

Чи потрібен javascript, щоб повернути помилкове, як, наприклад, посилання робить це, щоб зупинити його стрибок назад вгору сторінки?


Насправді я намагався уникати використання AJAX, оскільки те, що я намагаюся зробити, це в основному на клієнтському кінці. Лише до того, як буде подано форму, сервер потребує даних. Що стосується повернення речей у JavaScript, я намагався повернути true, false та null без різниці.
Sathariel
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.