Come fare in modo che i pulsanti dei moduli chiamino solo javascript?


9

Sto sperimentando moduli JavaScript e Drupal. Attualmente sto provando a creare un pulsante nel modulo di amministrazione di un modulo che utilizzerà JavaScript per aggiungere opzioni a un elenco selezionato. Il problema in cui mi imbatto è che quando faccio clic sul pulsante, viene chiamato il mio JavaScript ma l'intero modulo si aggiorna. Ho esaminato il riferimento all'API Forms pensando che ci fosse una sorta di attributo che posso impostare sul pulsante per impedirlo, ma non ho trovato nulla. Esiste un modo per impedire al pulsante di aggiornare la pagina o è un vicolo cieco?

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

Il mio codice finale:

<?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));

Risposte:


4

Il modo più semplice per farlo è semplicemente restituire false nel tuo codice 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;
  }
}

o un modo migliore è usare comportamenti:

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

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

1
Grazie per avermi indicato i comportamenti, sto leggendo proprio ora in realtà. E per qualche motivo il ritorno di false non funziona per me; la pagina è ancora rinfrescante = /. Per una domanda di follow-up, come dovresti gestire gli utenti che bloccano / disabilitano javascript?
Sathariel,

Se si mette il pulsante all'esterno di un tag <form> </form>, questo non verrà inviato, ma ciò non è raccomandato, il modo più convenzionale di farlo è con javascript. Se il modulo è ancora in fase di aggiornamento, verificare se è presente un altro javascript che visualizza un errore o qualcosa del genere.
Gnuget,

Dove mettere il codice Drupal.Behaviors? nel file javascript?


7

la definizione del pulsante modulo qui sotto funziona per me, #after_build è utile per il caricamento in javascript che può allegare il gestore di clic.

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

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

Quindi il mio javascript che viene caricato in un file separato dalla funzione after build, assomiglia a:

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

After_build non funziona per me. Mi genera un errore irreversibile: chiamata alla funzione indefinita [nome_modulo] _after_build (). Se definisco il metodo [nome_modulo] _after_build () con corpo vuoto, il modulo non viene visualizzato. Puoi chiarire un po 'di più come usarlo?
Sumanchalki,

Spiacente, non ho visto questa domanda ... Suppongo che stai sostituendo [nome_modulo] con il nome effettivo del tuo modulo?
Malks,

$ form ['# after_build'] serve per aggiungere una funzione lato server (PHP), non per specificare javascript post build. api.drupal.org/api/drupal/…
Christian

3

Puoi semplicemente aggiungere l' return falseistruzione dopo la chiamata della funzione, all'interno della riga dell'attributo dell'elemento modulo pulsante:

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

Penso che un'opzione migliore sia quella di aggiungere un listener di eventi esterno piuttosto che metterlo tutto nell'evento onclick in linea.
Christian

0

Idealmente, leggi le abilità della forma AJAX (o AHAH) di Drupal. Introduzione davvero di base qui http://drupal.org/node/752056

Altrimenti, sono sorpreso che stia aggiornando la pagina in quanto è solo un 'pulsante' non un invio o altro.

È necessario il javascript per restituire false, come su un collegamento per impedirlo di tornare all'inizio della pagina?


In realtà stavo cercando di evitare di usare AJAX poiché quello che sto cercando di fare è principalmente sul lato client. Solo quando viene inviato il modulo il server ha bisogno dei dati. Per quanto riguarda la restituzione di cose in JavaScript, ho provato a restituire true, false e null senza alcuna differenza.
Sathariel,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.