Wie kann man dafür sorgen, dass Formularschaltflächen nur Javascript aufrufen?

9

Ich experimentiere mit JavaScript- und Drupal-Formularen. Derzeit versuche ich, eine Schaltfläche im Verwaltungsformular eines Moduls zu erstellen, das JavaScript verwendet, um Optionen an eine Auswahlliste anzuhängen. Das Problem, auf das ich stoße, ist, dass beim Klicken auf die Schaltfläche mein JavaScript aufgerufen wird, aber das gesamte Formular aktualisiert wird. Ich habe mir die Forms-API-Referenz angesehen und gedacht, dass es eine Art Attribut gibt, das ich für die Schaltfläche festlegen kann, um sie zu stoppen, aber nichts gefunden habe. Kann ich auf irgendeine Weise verhindern, dass die Schaltfläche die Seite aktualisiert, oder ist dies eine Sackgasse?

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

Mein letzter Code:

<?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
quelle

Antworten:

4

Der einfachste Weg, dies zu erreichen, ist die Rückgabe von false in Ihrem Javascript-Code:

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

oder ein besserer Weg ist die Verwendung von Verhaltensweisen:

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

    //whatever you want here
    return false;
  });
}
Gnuget
quelle
1
Vielen Dank, dass Sie mich auf Verhaltensweisen hingewiesen haben. Ich lese gerade darüber. Und aus irgendeinem Grund funktioniert die Rückgabe von false bei mir nicht. Die Seite wird immer noch aktualisiert = /. Wie sollten Sie bei einer Folgefrage mit Benutzern umgehen, die Javascript blockieren / deaktivieren?
Sathariel
Wenn Sie die Schaltfläche außerhalb eines <form> </ form> -Tags platzieren, wird dies nicht gesendet, dies wird jedoch nicht empfohlen. Die konventionellere Methode ist Javascript. Wenn Ihr Formular noch aktualisiert wird, überprüfen Sie, ob in einem anderen Javascript ein Fehler oder ähnliches angezeigt wird.
Gnuget
Wo soll Drupal.Behaviors Code abgelegt werden? in der Javascript-Datei?
Ja, sehen Sie sich das an: amazeelabs.com/en/blog/drupal-behaviors-quick-how
Gnuget
7

Die unten stehende Definition der Formularschaltfläche funktioniert für mich. Das #after_build ist nützlich zum Laden in Javascript, das den Klick-Handler anhängen kann.

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

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

Dann sieht mein Javascript, das von der After-Build-Funktion in eine separate Datei geladen wird, ungefähr so ​​aus:

Drupal.behaviors.[module_name] = function(context) {
  $('#edit-add-button').click(function() {
   ...Do something here
  });
};
Malks
quelle
After_build funktioniert bei mir nicht. Es wird ein schwerwiegender Fehler ausgegeben: Aufruf der undefinierten Funktion [Modulname] _after_build (). Wenn ich die Methode [Modulname] _after_build () mit leerem Körper definiere, wird das Formular nicht gerendert. Können Sie etwas näher erläutern, wie man es benutzt?
Sumanchalki
Entschuldigung, ich habe diese Frage nicht gesehen ... Ich nehme an, Sie ersetzen [Modulname] durch den tatsächlichen Namen Ihres Moduls?
Malks
$ form ['# after_build'] dient zum Hinzufügen einer serverseitigen (PHP) Funktion - nicht zum Angeben von Javascript nach dem Erstellen. api.drupal.org/api/drupal/…
Christian
3

Sie können die return falseAnweisung einfach nach Ihrem Funktionsaufruf in der Attributzeile des Schaltflächenformularelements hinzufügen :

'#attributes' => array(
   'onclick' => "add_to_list(this.form.sellist, 'Append' + this.form.sellist.length); return false",
),
Sandokan
quelle
Ich denke, eine bessere Option ist es, einen externen Ereignis-Listener hinzuzufügen, anstatt alles in das Inline-Onclick-Ereignis einzufügen.
Christian
0

Lesen Sie im Idealfall Drupals eigene AJAX- (oder AHAH-) Formfähigkeiten durch. Wirklich einfaches Intro hier http://drupal.org/node/752056

Ansonsten bin ich überrascht, dass die Seite aktualisiert wird, da es sich nur um eine Schaltfläche handelt, nicht um eine Übermittlung oder etwas anderes.

Benötigt es das Javascript, um false zurückzugeben, wie es bei einem Link der Fall ist, um zu verhindern, dass es wieder an den Anfang der Seite zurückspringt?

Joevallender
quelle
Eigentlich habe ich versucht, AJAX zu vermeiden, da ich hauptsächlich auf Client-Seite versuche, dies zu tun. Erst wenn das Formular gesendet wird, benötigt der Server die Daten. Was die Rückgabe von Dingen in JavaScript angeht, habe ich versucht, true, false und null ohne Unterschied zurückzugeben.
Sathariel