Comment faire pour que les boutons du formulaire appellent uniquement le javascript?

9

J'expérimente avec des formulaires JavaScript et Drupal. Actuellement, j'essaie de créer un bouton dans le formulaire d'administration d'un module qui utilisera JavaScript pour ajouter des options à une liste de sélection. Le problème que je rencontre est que lorsque je clique sur le bouton, mon JavaScript est appelé mais l'ensemble du formulaire est actualisé. J'ai regardé la référence de l'API Forms en pensant qu'il y avait une sorte d'attribut que je peux définir sur le bouton pour l'arrêter, mais je n'ai rien trouvé. Existe-t-il un moyen d'empêcher le bouton de rafraîchir la page ou s'agit-il d'une impasse?

$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));
  }
}

Mon code final:

<?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));
Sathariel
la source

Réponses:

4

Le moyen le plus simple d'y parvenir est de renvoyer false dans votre code 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;
  }
}

ou mieux utilise des comportements:

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

    //whatever you want here
    return false;
  });
}
Gnuget
la source
1
Merci de m'avoir signalé des comportements, je le lis en ce moment en fait. Et pour une raison quelconque, retourner faux ne fonctionne pas pour moi; la page est toujours rafraîchissante = /. Pour une question de suivi, comment devez-vous gérer les utilisateurs qui bloquent / désactivent le javascript?
Sathariel
Si vous placez le bouton à l'extérieur dans une balise <form> </form>, cela ne sera pas soumis mais ce n'est pas recommandé, la manière la plus conventionnelle de le faire est avec javascript. Si votre formulaire est encore rafraîchissant, vérifiez s'il existe un autre javascript qui affiche une erreur ou quelque chose comme ça.
Gnuget
Où mettre le code Drupal.Behaviors? dans le fichier javascript?
Oui, jetez un œil à ceci: amazeelabs.com/en/blog/drupal-behaviors-quick-how
Gnuget
7

la définition du bouton de formulaire ci-dessous fonctionne pour moi, le #after_build est utile pour le chargement en javascript qui peut attacher le gestionnaire de clics.

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

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

Ensuite, mon javascript qui est chargé dans un fichier séparé par la fonction after build, ressemble à quelque chose comme:

Drupal.behaviors.[module_name] = function(context) {
  $('#edit-add-button').click(function() {
   ...Do something here
  });
};
Malks
la source
After_build ne fonctionne pas pour moi. Cela me renvoie une erreur fatale: appel à la fonction non définie [nom_module] _after_build (). Si je définis la méthode [nom_module] _after_build () avec un corps vide, le formulaire ne s'affiche pas. Pouvez-vous clarifier un peu comment l'utiliser?
sumanchalki
Désolé, je n'ai pas vu cette question ... Je suppose que vous remplacez [nom_module] par le nom réel de votre module?
Malks
$ form ['# after_build'] sert à ajouter une fonction côté serveur (PHP) - ce n'est pas pour spécifier le javascript post-construction. api.drupal.org/api/drupal/…
Christian
3

Vous pouvez simplement ajouter l' return falseinstruction après votre appel de fonction, à l'intérieur de la ligne d'attribut de l'élément de formulaire bouton:

'#attributes' => array(
   'onclick' => "add_to_list(this.form.sellist, 'Append' + this.form.sellist.length); return false",
),
Sandokan
la source
Je pense qu'une meilleure option consiste à ajouter un écouteur d'événement externe plutôt que de tout mettre dans l'événement onclick en ligne.
Christian
0

Idéalement, lisez les propres capacités de forme AJAX (ou AHAH) de Drupal. Intro vraiment basique ici http://drupal.org/node/752056

Sinon, je suis surpris qu'il rafraîchisse la page car ce n'est qu'un «bouton» et non une soumission ou quoi que ce soit.

A-t-il besoin du javascript pour renvoyer false, comme sur un lien pour l'empêcher de revenir en haut de la page?

joevallender
la source
En fait, j'essayais d'éviter d'utiliser AJAX car ce que j'essaie de faire est principalement du côté client. Ce n'est que lorsque le formulaire est soumis que le serveur a besoin des données. En ce qui concerne le retour des choses dans le JavaScript, j'ai essayé de retourner true, false et null sans différence.
Sathariel