7.x-1.x ajax_example_graceful_degradation.inc ajax_example_add_more($form, &$form_state, $no_js_use = FALSE)

Form with 'add more' and 'remove' buttons.

This example shows a button to "add more" - add another textfield, and the corresponding "remove" button.

It works equivalently with javascript or not, and does the same basic steps either way.

The basic idea is that we build the form based on the setting of $form_state['num_names']. The custom submit functions for the "add-one" and "remove-one" buttons increment and decrement $form_state['num_names'] and then force a rebuild of the form.

The $no_js_use argument is simply for demonstration: When set, it prevents '#ajax' from being set, thus making the example behave as if javascript were disabled in the browser.

Related topics

1 string reference to 'ajax_example_add_more'
ajax_example_menu in ajax_example/ajax_example.module
Implements hook_menu().


ajax_example/ajax_example_graceful_degradation.inc, line 550
Demonstrations of AJAX with graceful degradation.


function ajax_example_add_more($form, &$form_state, $no_js_use = FALSE) {
  $form['description'] = array(
    '#markup' => '<div>' . t('This example shows an add-more and a remove-last button. The <a href="!ajax">AJAX version</a> does it without page reloads; the <a href="!multistep">non-js version</a> is the same code but simulates a non-javascript environment, showing it with page reloads.', array(
      '!ajax' => url('examples/ajax_example/add_more'),
      '!multistep' => url('examples/ajax_example/add_more_no_js'),
    )) . '</div>',

  // Because we have many fields with the same values, we have to set
  // #tree to be able to access them.
  $form['#tree'] = TRUE;
  $form['names_fieldset'] = array(
    '#type' => 'fieldset',
    '#title' => t('People coming to the picnic'),
    // Set up the wrapper so that AJAX will be able to replace the fieldset.
    '#prefix' => '<div id="names-fieldset-wrapper">',
    '#suffix' => '</div>',

  // Build the fieldset with the proper number of names. We'll use
  // $form_state['num_names'] to determine the number of textfields to build.
  if (empty($form_state['num_names'])) {
    $form_state['num_names'] = 1;
  for ($i = 0; $i < $form_state['num_names']; $i++) {
    $form['names_fieldset']['name'][$i] = array(
      '#type' => 'textfield',
      '#title' => t('Name'),
  $form['names_fieldset']['add_name'] = array(
    '#type' => 'submit',
    '#value' => t('Add one more'),
    '#submit' => array(
    // See the examples in ajax_example.module for more details on the
    // properties of #ajax.
    '#ajax' => array(
      'callback' => 'ajax_example_add_more_callback',
      'wrapper' => 'names-fieldset-wrapper',
  if ($form_state['num_names'] > 1) {
    $form['names_fieldset']['remove_name'] = array(
      '#type' => 'submit',
      '#value' => t('Remove one'),
      '#submit' => array(
      '#ajax' => array(
        'callback' => 'ajax_example_add_more_callback',
        'wrapper' => 'names-fieldset-wrapper',
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Submit'),

  // This simply allows us to demonstrate no-javascript use without
  // actually turning off javascript in the browser. Removing the #ajax
  // element turns off AJAX behaviors on that element and as a result
  // ajax.js doesn't get loaded.
  // For demonstration only! You don't need this.
  if ($no_js_use) {

    // Remove the #ajax from the above, so ajax.js won't be loaded.
    if (!empty($form['names_fieldset']['remove_name']['#ajax'])) {
  return $form;


nabajit’s picture

I tried the add more functionality in theme setting form but it is throughing the following error

An AJAX HTTP request terminated abnormally.
Debugging information follows.
Path: /orange/system/ajax
StatusText: n/a
Fatal error: Call to undefined function ajax_example_add_more_add_one() in C:\xampp\htdocs\orange\includes\form.inc on line 1520
ReadyState: undefined

Any help is greatly appreciable.

roald.umandal’s picture

"Fatal error: Call to undefined function ajax_example_add_more_add_one() in" ----> because the function is not defined, you have to add it, check this one https://api.drupal.org/api/examples/ajax_example!ajax_example_graceful_d...

wuxiaogu’s picture

Hi, I think this is really a cool job. but how to store the values?

Frederic wbase’s picture

You can always use return system_settings_form to autostore the values in a variable.

El Alemaño’s picture

Using this code works great, but the form errors are just being shown if no item is added, does anyone know how can I fix this?


Max_Headroom’s picture

In form validate:

if ($form_state['clicked_button']['#value'] == 'Add one more' || $form_state['clicked_button']['#value'] == 'Remove one') {
myhemant’s picture

I am using this code. really this great code for add more fields in our custom form.

omrmankar’s picture

An AJAX HTTP error occurred.
HTTP Result Code: 500
Debugging information follows.
Path: /demo/system/ajax
StatusText: Service unavailable (with message)
ResponseText: Error: Call to undefined function ajax_example_add_more_add_one() in form_execute_handlers() (line 1520 of /opt/lampp/htdocs/demo/includes/form.inc).