0

I have the following form built with Form API. Its method is GET. I try to validate or submit, but it does not work. I have checked the method names, etc., and are correct, in fact I see an "attempt" of validation in some cases. I guess that there is something weird for the way I use the select autofilling field. It is a "car models" select whose values are filled by selection of "car brand" select, and I think that the code somehow interferes with the normal use of Form API.

function mymodule_search_form(){
    $brands = get_brands();
    $brand = get_default_brand();

    $form['product'] = array(
      '#type' => 'textfield',
      '#title' => t('Product'),
      '#autocomplete_path' => 'product-busq/productos/all',
      '#attributes' => array("placeholder" => t('Product'), ) // 'class' => array('auto_submit')
     );

     $form['brand'] = array(
       '#type' => 'select',
       '#title' => t('Brand'),
       '#options' => $brands,
       '#default_value' => $brand,
       '#ajax' => array(
           'callback' => 'mymodule_models_update',
           'wrapper' => 'models_wrapper',
           'progress' => array(
           'message' => '',
           'type' => 'throbber',
          ),
         ),
        );

    $form['model'] = array(

      '#type' => "select",
      '#title' => t('Model'),
      '#required' => FALSE,
      '#multiple' => YES,
      '#attributes' => array("placeholder" => t('Model'), ), // 'class' => array('auto_submit')

       '#prefix' => '<div id="models_wrapper">',
       '#suffix' => '</div>',
       '#disabled' => TRUE,
      );

  $form['submit'] = array(
     '#type' => 'submit',
     '#value' => t('Submit'),
      '#name' => ""
 );

   $form["#action"] = $base_url . "/" . $language->language . "/" .   drupal_get_path_alias("node/3");
  $form["#method"] = "get";

  return $form;
} // function

And now the autofilling function which may be causing the problems, especially the last sentence. The code is copied from a tutorial somewhere:

function mymodule_models_update($form, &$form_state) {
   unset($form_state['input']['model'], $form_state['values']['model']);
   $brand = $form_state['values']['brand'];
   $brand_desc = "";
   $results = db_query("SELECT description FROM {taxonomy_term_data} tax WHERE tax.tid = :tid", array(":tid" => $brand));
    foreach($results as $row) $brand_desc = $row->description;

    if($brand_desc != "") $form['model']['#options'] =      _hook_list_models($brand_desc);
    unset($form['model']["#attributes"]['disabled']);
   $form['model']['#disabled'] = FALSE;
   $form["model"]["#attributes"]["id"] = "edit-model";
   return form_builder($form['#id'], $form['model'], $form_state);
 } // function
10
  • Please do not define any function with hook_ prefix. It is reserved for implementing hook API.
    – Jimmy Ko
    Commented Aug 11, 2016 at 9:18
  • You should use $form_state['rebuild'] = TRUE; instead of calling form_builder() to rebuild the form. In the ajax callback, you should only return the dynamic part only. In your case, it is return $form['model'];
    – Jimmy Ko
    Commented Aug 11, 2016 at 9:21
  • In fact it is the name of the module, maybe I had better used mymodule_ to make it clear.
    – Cesar
    Commented Aug 11, 2016 at 9:22
  • hook_models is the module name? It is not a good idea. LOL
    – Jimmy Ko
    Commented Aug 11, 2016 at 9:28
  • Sorry for my poor English, but I don't catch the funny thing of it, though I suspect something. Uhm... BTW, your solution works, but only if the method is POST instead of GET. Strange.
    – Cesar
    Commented Aug 11, 2016 at 9:35

1 Answer 1

1

According to the Drupal official documentation on drupal_build_form.

method: The HTTP form method to use for finding the input for this form. May be 'post' or 'get'. Defaults to 'post'. Note that 'get' method forms do not use form ids so are always considered to be submitted, which can have unexpected effects. The 'get' method should only be used on forms that do not change data, as that is exclusively the domain of 'post.'

I would recommend you using POST method rather then GET method, so please remove the line $form["#method"] = "get";

Also, you should rewrite your ajax callback.

function hook_models_update($form, &$form_state) {
   unset($form_state['input']['model'], $form_state['values']['model']);
   $brand = $form_state['values']['brand'];
   $brand_desc = "";
   $results = db_query("SELECT description FROM {taxonomy_term_data} tax WHERE tax.tid = :tid", array(":tid" => $brand));
    foreach($results as $row) $brand_desc = $row->description;

    if($brand_desc != "") $form['model']['#options'] =      _hook_list_models($brand_desc);
    unset($form['model']["#attributes"]['disabled']);
   $form['model']['#disabled'] = FALSE;
   $form["model"]["#attributes"]["id"] = "edit-model";

   $form_state['rebuild'] = TRUE;
   return $form['model'];
}

IMPORTANT NOTE:

If you can, I would suggest you rename your function or module name to avoid using hook_ prefix. It would cause unexpected function name conflict in future, because hook_ prefix is reserved for building hook API in Drupal.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.