Monday, July 21, 2014

Drupal 7 ajax without jquery using use-ajax

Using "use-ajax" attribute, we can achieve ajax in Drupal.
Follow below steps to do it.

Steps :
1) hook_menu entry
2) function definition to declare ajax element (Hyperlink)
3) Ajax definition

1) hook_menu entry.
function yourModuleName_menu() {
  $items = array();
  $items['Mymodule/ajax'] = array(
    'page callback' => 'Mymodule_ajax_test',
    'access callback' => TRUE,
    'type' => MENU_CALLBACK,
  );
  $items['Mymodule/ajax/%/%'] = array(
    'page callback' => 'Mymodule_ajax_callback',
    'page arguments' => array(2, 3),
    'access callback' => TRUE,
    'type' => MENU_CALLBACK,
  );
  return $items;
}

2) function definition to declare ajax element (Hyperlink).
function Mymodule_ajax_test() {
  drupal_add_library('system', 'drupal.ajax');
  drupal_add_library('system', 'jquery.form');
  $arg = 'arg';
  $output = l(t('AJAX'), 'pm/ajax/nojs/' . $arg, array('attributes' => array('class' => array('use-ajax'))));
  $output .='<div id="some-wrapper"></div>'; // udadate result here.
  return $output;
}
// Another method.
function Mymodule_ajax_test() {
  drupal_add_library('system', 'drupal.ajax');
  drupal_add_library('system', 'jquery.form');
  $some_argument = 'arg';
  $output = l(t('AJAX'), 'Mymodule/ajax/nojs/' . $arg, array('attributes' => array('class' => array('use-ajax'), 'id' => array('some-wrapper')))); // overwrite result here.
  return $output;
}

3)  Ajax definition.
function Mymodule_ajax_callback($type = 'ajax', $arg) {

 if ($type == 'ajax') {
    $commands[] = ajax_command_replace('#some-wrapper', 'Ajax result '  );
    $page = array('#type' => 'ajax', '#commands' => $commands);
    ajax_deliver($page);
  }
  else {
    $output = t("Ajax fail or page load contents.");
    return $output;
  }
}

Friday, July 18, 2014

Drupal 7 ajax form validation and submit - Ajax framework commands

Ajax is one of the best interactive way to validate and submit Drupal custom form.
Using below steps, we can achieve ajax form validation and submit.

Steps :
1) Declare form elements
2) Call back definitions.

1) Declare form elements.
$form['submit'] = array(
  '#type' => 'submit',
  '#value' => t('SUBMIT'),
  '#validate' => array('validate_callback'), // custom form validate.
  '#ajax' => array(
    'callback' => 'submit_callback',
    'effect' => 'fade',
    'wrapper' => 'specific-wrapper',
    'event' => 'click',
    'progress' => array('message' => '', 'type' => 'throbber'),
  ),
);

2) Call back definitions.
function submit_callback($form, $form_state) {
  if (form_get_errors()) {
    $form_state['rebuild'] = TRUE;
    return $form;
  }

  $response = my_form_submit($form, $form_state); // write your form submit logic here.
  return $response;
}
"validate_callback" is our normal hook_form_validate(). 

NOTE : Reach me through the contact form if you have any question.

Update:
Recently I have worked on "Ajax framework commands", this is also very useful Technic to achieve ajax form submit & validation.

1) Declare form elements to use ajax framework.
$form['submit'] = array(
  '#type' => 'submit',
  '#value' => t('SUBMIT'),
  '#ajax' => array(
    'callback' => 'ajax_command_callback',    
  ),
);

2) Call back definitions.
function ajax_command_callback($form, $form_state) {
  // Collect error.
  $error = form_get_errors();
  // Clear error for all the cases.
  drupal_get_messages();
 // Logic behind error.
if (!empty($error) && $error['title']) {
   $form_state['rebuild'] = TRUE;
    // Create place holder to display error(class name / ID).
    $selector = '.error_place_holder';
    // Java script function to process error.
    $commands[] = ajax_command_invoke(NULL, "error_javascript_call");
    $commands[] = ajax_command_replace($selector, '<div class="error_place_holder"><div class = "error-msgs">' .    $error['title'] . '</div></div>');
    return array('#type' => 'ajax', '#commands' => $commands);
  }
  else {
    // Same thing you can do it for success.
    // Passing dynamic value to java script.
    $commands[] = ajax_command_invoke(NULL, "success_javascript_call", array(array('url'=>url('some_url_to_redirect_on_success'))));
    return array('#type' => 'ajax', '#commands' => $commands);
  }
}


ajax_command_replace on error:
It contains $selector as a first argument & "error_place_holder" class name is the second argument.

Selector: <div class="error_place_holder"> </div>
Error result : <div class="error_place_holder"><div class = "error-msgs">' . $error['title'] . '</div></div>

In the final, your selector will be updated with error result. Means,
<div class="error_place_holder"> <div class="error_place_holder"><div class = "error-msgs">' . $error['title'] . '</div></div> </div>



ajax_command_invoke usage.
 // Redirect on success.
  $.fn.success_javascript_call= function(val){
    window.location.href = val.url;
  }
  // Hide or do something on error.
  $.fn.error_javascript_call= function(val){
    $('.class').removeClass().addClass('some-test');
  }