フォームボタンでJavaScriptのみを呼び出す方法は?


9

私はJavaScriptとDrupalのフォームを実験しています。現在、JavaScriptを使用して選択リストにオプションを追加するモジュールの管理フォームにボタンを作成しようとしています。私が実行している問題は、ボタンをクリックすると、JavaScriptが呼び出されてもフォーム全体が更新されることです。Forms APIリファレンスを見て、ボタンを停止するためにボタンに設定できる何らかの属性があると考えましたが、何も見つかりませんでした。ボタンによるページの更新を停止する方法はありますか?これは行き止まりですか?

$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コードでfalseを返すだけです。

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
私に行動を教えてくれてありがとう、私は実際にそれを今読んでいます。そして、何らかの理由でfalseを返すことは私にとってはうまくいきません。ページはまだ更新中です= /。補足質問として、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は、次のようになります。

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

After_buildが機能しません。致命的なエラーが発生します。未定義の関数[module_name] _after_build()を呼び出します。空のボディでメソッド[module_name] _after_build()を定義すると、フォームがレンダリングされません。使い方をもう少し明確にしていただけませんか?
sumanchalki 2013

この質問は表示されませんでした... [module_name]を実際のモジュール名に置き換えていると思いますか?
マルクス2013

$ 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",
),

インラインのonclickイベントにすべてを置くのではなく、外部イベントリスナーを追加する方が良いオプションだと思います。
クリスチャン

0

理想的には、Drupal独自のAJAX(またはAHAH)フォーム機能を読み取ってください。ここで本当に基本的なイントロ http://drupal.org/node/752056

それ以外の場合は、ページを更新するだけでびっくりします。送信ボタンなどではなく、単なる「ボタン」です​​。

ページの上部に戻るリンクを停止するのと同じように、falseを返すにはJavaScriptが必要ですか?


実際、私がしようとしているのは主にクライアント側にあるため、AJAXの使用を避けようとしていました。フォームが送信されるまで、サーバーはデータを必要としません。JavaScriptで物事を返す限り、私は違いなしでtrue、false、nullを返すことを試みました。
ササリエル
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.