0

Here is the code for the custom form with a field(field_B) that calls an function through ajax.

The issue is that I want the function (MY_MODULE_XYZ_function()) to be executed only once, when the page loads for the first time. But the function(MY_MODULE_XYZ_function()) is being executed for each ajax call through field_B because the whole form is being regenerated.

How can I prevent whole form regeneration(so that the function won't be called more than once) for each ajax call? Thanks in advance.

function MY_MODULE_menu(){
    $items['abcd/xyz'] = array(
        'title' => 'ABCD',
        'page callback' => 'drupal_get_form',
        'page arguments' => array('xyz_custom_form'),
        'access arguments' => array('access content'),
        'type' => MENU_CALLBACK,
    );
    return $items;
}

function xyz_custom_form($form, &$form_state){

    MY_MODULE_XYZ_function($arg1, $arg2);

    $form['field_A'] = array(  .... );

    $form['field_B'] = array(
        '#type' => 'radios',
        '#options' => array("a"=>"A", "b"=>"B", "c"=>"C"),
        '#prefix' => "<div id='customDiv'>",
        '#suffix' => "</div>",
        '#ajax' => array(
        'callback' => 'MY_MODULE_custom_ajax_callback',
            'wrapper' => 'customDiv',
            'progress' => array( 'type' => 'throbber', 'message' => NULL),
            'effect' => 'fade',
        ),
    );
}

function MY_MODULE_XYZ_function($arg1, $arg2){
    //Some Query Execution
}

function MY_MODULE_custom_ajax_callback($form, &$form_state){
    //Some Callback code
}
  • What is MY_MODULE_XYZ_function() doing? – Jaypan Apr 19 at 3:38
  • Its creating a node programmatically. – Drupal User Apr 19 at 3:42
  • In that case, you're going about this in a non-Drupally way. You should create the node, and pass it into your form to be used, rather than creating it from within the form. I'll write up an example for you. – Jaypan Apr 19 at 4:04
  • Actually its a different kind of node that I want to store data in whenever the form loads. Anyways I may want to do other stuff also in the function. The main issue is I want the function to be called only once. – Drupal User Apr 19 at 4:09
  • "Actually its a different kind of node that I want to store data in whenever the form loads." <--- the example I give covers this. – Jaypan Apr 19 at 4:27
0

If you need a entity (which could be a node) to be created whenever the form is loaded, can create the enitiy, and pass it to your form, rather than creating it within your form. Then you can also use the same form for editing the entity.

For example, in a module called nodeform:

function nodeform_menu() {
  $menu['nodeform/add'] = [
    'title' => 'Nodeform add',
    'page callback' => 'nodeform_add_page',
    'access arguments' => ['some_create_permission'],
  ];

  // Note: using %node will call node_load(), passing it
  // the value given in that index of the path. If no node
  // is loaded, or the user does not have access, a page
  // not found error is returned (or maybe access denied)
  $menu['nodeform/%node'] = [
    'title' => 'Nodeform add',
    'page callback' => 'nodeform_edit_page',
    // The page argument is the 1st index of the path
    // which is %node. So the page argument will be a
    // node object.
    'page arguments' => [1],
    'access arguments' => ['some_edit_permission'],
  ];

  return $menu;
}

function nodeform_add_page() {
  global $user;

  $node = (object) array(
    'uid' => $user->uid,
    'name' => isset($user->name) ? $user->name : '',
    'title' => t('Default title'),
    'type' => 'some_node_type',
    'language' => LANGUAGE_NONE,
  );

  return [
    '#prefix' => '<div id="nodeform_add_form_page">',
    '#suffix' => '</div>',
    'form' => drupal_get_form('nodeform_default_form', $node),
  ];
}

// The edit page receives a loaded node as its argument:
function nodeform_edit_page(array $node) {
  return [
    '#prefix' => '<div id="nodeform_edit_form_page">',
    '#suffix' => '</div>',
    'form' => drupal_get_form('nodeform_default_form', $node),
  ];
}

// The form then receives a node:
function nodeform_default_form($form, $form_state, $node) {
  // Get the node from the form state if it exists, or use
  // the node passed to the form if it does not.
  $node = isset($form_state['nodeform_node']) ? $form_state['nodeform_node'] : $node;
  // Save the nodeform to the node
  $form_state['nodeform_node'] = $node;

  // Add your form elements:
  $form['title'] = [
    '#title' => t('Title'),
    '#type' => 'textfield',
    '#default_value' => $node->title,
  ];

  return $form;
}

function nodeform_default_form_submit($form, $form_state) {
  $node = &$form_state['nodeform_node'];
  $node->title = $form_state['values']['title'];
  node_save($node);
}

You may not need all of the above example, but if you look at the nodeform/add menu path, it shows how you can always create a node when the form is called, and it will only happen once, rather than every time the form is built. If you don't need to use it in the form, then call node_save() on the node in node_add_page().

0

Simply create a key inside $form_state that will keep track if ajax has ran.

function xyz_custom_form($form, &$form_state){

  if (empty($form_state['ajax_ran']) { 
    $form_state['ajax_ran'] = FALSE;
  }

  $form['field_B'] = array(
    '#type' => 'radios',
    '#options' => array("a"=>"A", "b"=>"B", "c"=>"C"),
    '#prefix' => "<div id='customDiv'>",
    '#suffix' => "</div>",
    '#ajax' => array(
      'callback' => 'MY_MODULE_custom_ajax_callback',
        'wrapper' => 'customDiv',
        'progress' => array( 'type' => 'throbber', 'message' => NULL),
        'effect' => 'fade',
      ),

  if ($form_state['ajax_ran']) { // if TRUE
    unset($form['field_B']['#ajax']): // remove ajax
  }

}

function MY_MODULE_custom_ajax_callback($form, &$form_state){
    $form_state['ajax_ran'] = TRUE;
    // Some Callback code
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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