web-dev-qa-db-ja.com

「郵便番号」を入力すると、「市」フィールドが自動的に入力されます

私は何度も議論されてきたがまだ解決策が書かれていない問題に遭遇しました。これはDrupal 7.についてです。

私のノード追加フォームには、「アドレス」フィールドがあります。 「郵便番号」フィールド、「市区町村」フィールド、その他のフィールドで構成されるフィールドコレクションアイテム。すべての住所はドイツの住所であり、ドイツでは5桁の郵便番号が一意にによって都市を決定します。つまり、同じ郵便番号を持つ2つの都市はありません。ノード追加フォームを操作して、郵便番号を入力すると、都市フィールドが自動的に入力されるようにします。

http://www.zippopotam.us は、これを次のように実現できるAPIを提供しています。 (ノード追加フォームの郵便番号フィールドのIDはであることに注意してください)edit-field-address-und-0-field-postal-code-und-0-valueと市フィールドのIDはedit-field-address-und-0-field-city-und-0-valueです。)

1)次のコードを含むカスタムモジュールを追加しました。

_function custom_form_alter(&$form, &$form_state, $form_id) {
  $form['#after_build'][] = 'custom_afterbuildfunction';
}

function custom_afterbuildfunction($form_element, &$form_state) {
  drupal_add_js('http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js', 'external');
  drupal_add_js('sites/all/modules/custom/custom.js', 'file');

  return $form_element;
}
_

2)次に、モジュールのディレクトリに、次のコードを含むcustom.jsファイルを追加します。

_$(function() {  
  // Disable City and State on Load
  $(document).ready( function() {           
    $('#edit-field-address-und-0-field-city-und-0-value').attr('readonly','readonly');
  });

  // OnKeyDown Function
  $("#edit-field-address-und-0-field-postal-code-und-0-value").keyup(function() {
    var Zip_in = $(this);
    var Zip_box = $('#field-address-und-0-field-postal-code-add-more-wrapper');

    if (Zip_in.val().length<5) {
      Zip_box.removeClass('error success');
    }
    else if (Zip_in.val().length>5) {
      Zip_box.addClass('error').removeClass('success');
    }
else if ((Zip_in.val().length == 5)) {      
      // Make HTTP Request
      $.ajax({
        url: "http://api.zippopotam.us/de/" + Zip_in.val(),
        cache: false,
        dataType: "json",
        type: "GET",
        data: "de/" + Zip_in.val(),
        success: function(result, success) {
          // German Post Code Records Officially Map to only 1 Primary Location
          places = result['places'][0];
          $("#edit-field-address-und-0-field-city-und-0-value").val(places['place name']);
          Zip_box.addClass('success').removeClass('error');
        },
        error: function(result, success) {
          Zip_box.removeClass('success').addClass('error');
        }
      });
    }
  });
});
_

ただし、私は本当にジッポポタマスから独立したいと思います。 「郵便番号」と呼ばれるすべての郵便番号と対応する都市のテーブルをデータベースにインポートしました。 「Zip」という列と「city」という列があります。このテーブルには、ロケーションモジュールが付属しています。 ownデータベースからdb_query("select city from {zipcodes} where Zip = :Zip limit 1", array(":Zip" => '$Zip_in'))->fetchField();を介して郵便番号に対応する都市を取得し、[City]フィールドに入力します。

***編集***

残念ながら動作しない次の変更されたコードを試してみました。

1)カスタムモジュール:

_/**
 * Implementation of hook_menu()
 */

function product_menu() {
$items = array();

$items['get_city'] = array(
        'page callback' => 'custom_get_city',
        'access arguments' => TRUE,
        'type' => MENU_CALLBACK,
);

return $items;
}

/**
 * Implementation of hook_form_alter()
 */

function custom_form_alter(&$form, &$form_state, $form_id) {

if ($form_id == 'job_offer_node_form') {

    $form['#after_build'][] = 'custom_validate_and_populate';

}
}

/**
 * Implementation of #after_build custom function hook_validate_and_populate()
 */

function custom_validate_and_populate($form_element, &$form_state) {

drupal_add_js('sites/all/modules/custom/custom.js', 'file');
return $form_element;

}

/**
 * Implementation of hook_get_city()
 * This function ONLY introduces a new variable that carries the city name corresponding to the entered Zip code.
 * replacement of Zippopotamus API;
 * does NOT yet populate any fields; this happens in the corresponding javascript file
 */

function custom_get_city() {
$Zip = strtolower($_GET['Zip_in']);
$city = db_query("select city from {zipcodes} where Zip = :Zip limit 1", array(":Zip" => $Zip))->fetchField();

}
_

2)JavaScriptファイル:

_$(function() {

        // Set city to 'readonly' on load.
        $(document).ready( function() {

            $('#edit-field-address-und-0-field-city-und-0-value').attr('readonly','readonly');

        });

        // keyup function
        $("#edit-field-address-und-0-field-postal-code-und-0-value").keyup(function() {
            var Zip_in = $(this);
            var Zip_box = $('#field-address-und-0-field-postal-code-add-more-wrapper');

            if ((Zip_in.val().length == 5) ) 
            {

                // Make HTTP Request
                $.ajax({
                    url: "/get_city",
                    cache: false,
                    dataType: "json",
                    type: "GET",
                    data: "Zip_in=" + Zip_in.val(),
                    success: function(result, success) {
                        $("#edit-field-address-und-0-field-city-und-0-value").val('$city');
                        Zip_box.addClass('success').removeClass('error');
                    },
                    error: function(result, success) {
                        Zip_box.removeClass('success').addClass('error');
                    }
                });

            }
});
});
_
1
deinqwertz

おそらく次のようなものですか?私が取り組んでいる何かに基づいている以下のコードを試していません(参照: http://drupal.org/node/195669 ).. 'selectboxのオプションを自動入力しようとしています'。どちらが機能しています..そして、あなたはjavascriptに優れているので:)「フォームのEnterキー」を防ぐにはどうすればよいですか? :)(参照: http://drupal.org/node/370694

(編集:以下のコードをテストして動作します。検索ボックスに郵便番号を入力し、タブキーを押すと、CITYテキストフィールドにデータベースのデータが入力されます:))。残っている唯一の問題は、ユーザーが入力ボタンを押すとフォームが送信されることです。したがって、私の質問、フォーム送信を実行するEnterキーをどのように防ぐことができますか?

(編集2:リターンキーを押したときにフォームを送信しないようにする

$form['#attributes'] = array('onsubmit' => 'return false');

)上記はすべての送信をまとめて無効にします

シナリオ2(JavaScript):

  $('#edit-searchfield').keypress(function(event) {
   if (event.keyCode == '13') {
       event.preventDefault();
   }
});

<?php


function autofill_menu(){

    $items['test/cities'] = array(
        'title' => 'autofill from db',
        'page callback' => 'drupal_get_form',
        'page arguments' => array('autofill_cities'),
        'access callback' => TRUE,
        'weight' => 4,
        'type' => MENU_NORMAL_ITEM,
        );

    return $items;
    }

function autofill_cities($form, &$form_state) {

    $form['searchcity']['input'] = array(
        '#title' => t('Search database and fill select options'),
        '#type' => 'textfield',
        '#required' => TRUE,
        '#maxlength' => 115,
        '#size' => 55,
        '#weight' => 0,
        '#default_value' => 'look for it',
         "#executes_submit_callback" => FALSE,
        '#ajax' => array(
            'event' => 'change',
            'callback' => '_get_select',
            'wrapper' => 'replace_textfield_div',
            ),
    );


    $form['city'] = array(
        '#type' => 'textfield',
        '#title' => 'City',
        '#size' => 15,
        // The prefix/suffix provide the div that we're replacing, named by
        // #ajax['wrapper'] above.
        '#prefix' => '<div id="replace_textfield_div">',
        '#suffix' => '</div>',
    );


    if (!empty($form_state['values']['input'])) {
        $test =  $form_state['values']['input'];
        // dpm($test);
        $getrow = _get_cities($form_state['values']['input']);  
        $form['city']['#value'] = $getrow;  
        }

  return $form;
}

function _get_select($form, $form_state) {
  // The form has already been submitted and updated. We can return the replaced
  // item as it is. 
  return $form['city'];
}

function _get_cities($key) {

$query = db_select('zipcodes', 'ct')
        ->fields('ct')
        ->condition('Zip', array($key)  , '=')
        ->execute()
        ->fetchAssoc();

return($query['Product']);

}  
3
user1973842