David,
Thanks a lot for your kind answer.
I had read about 'storage', I hope it was mentioned it is used in D6. In D7 it may work, probably they were discouraging to use it.
 
I have managed to do it using _SESSION stuff. Though it is working to some extent, still I beleive I am missing certian things here. Request to experts kindly review below code and guide me if I am correct.
 
For reference kindly see http://www.netcloudsystems.com/?q=questionnaire/form/manage link.
Corresponding code is as below.  Please let me know, if below code is correct, or it can be optimized for faster operation. I have two major concerns,
 
1.   It looks to me the whole form is rebuilt when I click the "Add More Caregories" button, hence it takes more time to add a question category. I know it is happeing because I have a line of code  $form_state['rebuild'] = TRUE; in add_more_categories function.
 
2. Next the sequence of calling of functions looks strange to me.
First time page loads, it calls questionnaire_my_form.
On clicking "Add More Categories" button, functions are called in below sequence.
 
My understanding is that with AJAX, we should be able to modify the portion of a form, not the whole form.
I am not able to acheive it.
 
Kindly somebody help me to understand D7 AJAX stuff better.

<?php
function questionnaire_menu() {
    $items = array();
    $items['questionnaire/form/manage'] = array(
        'title' => t('Manage questions'),
        'page callback' => 'questionnaire_form',
        'access arguments' => array('question manage'),
        'type' => MENU_SUGGESTED_ITEM,
    );
    return $items;
}
function questionnaire_permission()
{
    return array(
        'question manage' => array(
        'title' => t('Question management'),
        'description' => t('Provides question management capability'),
    ),
    );          
}
function questionnaire_form()
{
    unset( $_SESSION['questionnaire']['all_categories'] );
    $_SESSION['questionnaire']['all_categories'] = 1;
    return drupal_get_form('questionnaire_my_form');
}
function questionnaire_my_form($form, &$form_state)

    $form_state['cache'] = TRUE;
   
   
    /////////////  Start question category ////////////
   
    $form['category_fieldset'] = array(   
        '#tree' => TRUE,
        '#title' => t("Questions Categories"),   
        '#prefix' => '<div id="category-div">',   
        '#suffix' => '</div>',   
        '#type' => 'fieldset',   
        //'#description' => t('Please enter the question categories'),
       '#collapsible' => TRUE,
       '#collapsed' => FALSE,
    );
    for ($i=1; $i <= $_SESSION['questionnaire']['all_categories'] ; $i++)
    {   
        if(isset($_SESSION['questionnaire'][$i-1]['catg']))
        {
            $form['category_fieldset'][$i]['catg'] = array(     
                '#type' => 'textfield',     
                '#title' => "Question Category $i",
                '#value' => $_SESSION['questionnaire'][$i-1]['catg'],
            ); 
           
            unset($_SESSION['questionnaire'][$i-1]['catg']);
            $form['category_fieldset'][$i]['remove'] = array(     
                '#type' => 'checkbox',     
                '#title' => 'Remove',
            ); 
        }
        else
        {
            $form['category_fieldset'][$i]['catg'] = array(     
                '#type' => 'textfield',     
                '#title' => "Question Category $i", 
            ); 
            $form['category_fieldset'][$i]['remove'] = array(     
                '#type' => 'checkbox',     
                '#title' => 'Remove',
            ); 
        }
       
    } 
    $form['category_fieldset']['add_more_categories'] = array(   
        '#type' => 'submit',
        '#value' => t('Add More Categories'),
        '#submit' => array('add_more_question_categories'),
        '#ajax' => array(     
        'callback' => 'questionnaire_category_callback',     
        'wrapper' => 'category-div',     
        'method' => 'replace',     
        'effect' => 'fade',   
    ),
    );
    /////////////  End question category ////////////

  $form['line_break1'] = array(
  '#markup' => '<br>',
  );   
    $form['submit'] = array(   
        '#type' => 'submit',   
        '#value' => t('Save Questions & Categories'), 
    ); 
    return $form;
}  
function questionnaire_category_callback($form, $form_state)

    return $form['category_fieldset'];
}
function add_more_question_categories($form, &$form_state)
{
    //Here, loop through all the category elements, if any remove checkbox is enabled, delete the corresponding row.
    $removed_categories = 0;
    $i = 0;
    $j = 0;
    while ($i < $_SESSION['questionnaire']['all_categories'])
    {
        if($form_state['values']['category_fieldset'][($i + 1)]['remove'] == 1)
        {
            $removed_categories++;
        }
        else
        {
            $_SESSION['questionnaire'][$j]['catg'] = $form_state['values']['category_fieldset'][($i + 1)]['catg'];
            $j++;
        }
       
        $i++;
    }
   
    if($removed_categories > 0)
    {
        $_SESSION['questionnaire']['all_categories'] = $_SESSION['questionnaire']['all_categories'] - $removed_categories;
    }
    else
    {
        $_SESSION['questionnaire']['all_categories'] = $_SESSION['questionnaire']['all_categories'] + 1;
    }
    $form_state['rebuild'] = TRUE;
}
function questionnaire_submit($form, &$form_state)
{
    drupal_set_message('Save functionality not implemented yet.');
    $form['#redirect'] = FALSE;
}
?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 


 
On Mon, Sep 10, 2012 at 9:01 PM, Metzler, David <metzlerd@evergreen.edu> wrote:

I have not used form values in this way before and am unsure if they will work this way.  Typically $form_state[‘storage’] is where you might place these values that are part the form that may be modified by ajax callback handlers.  Have you tried using $form_state[‘storage’] instead of $form_state[‘values’] for your $all_categories data?  

 

 

 


From: support-bounces@drupal.org [mailto:support-bounces@drupal.org] On Behalf Of Kamal Palei
Sent: Sunday, September 09, 2012 8:44 PM
To: support@drupal.org
Subject: [support] Drupal 7 AHAH/AJAX issue

 

Hi List

I am trying to learn ajax stuff in Drupal 7.

 

I want to have a simple questionnaire form. Where I will have a single textfield.

In that text field one will type a question category, and if he wants to type more question categories, user need to click a  button "Add More Categories".

 

The whole source code is at the end of this email.  When ajax callback fires, I want to remember how many textfields I need to add, so that when a section of form is updated in _form() hook, I can according add those many textfields.

 

I am trying to manage that using a variable "$all_categories" and form element $form['all_categories']  (of type value).

 

I tried many options, always I find $all_categories value is 1.   So I am unable to add more textfields. 

My observation is whatever I set in ajax callback, in _form hook api, I find value is lost.

 

Kindly guide me what I am missing.

 

Best Regards

Kamal

NECS, Bangalore

 

 

<?php

function questionnaire_menu() {
 $items = array();
 
 $items['questionnaire/form/manage'] = array(
 'title' => t('Manage questions'),
 'page callback' => 'questionnaire_form',
 'access arguments' => array('question manage'),
 'type' => MENU_SUGGESTED_ITEM,
 );

  return $items;
}

function questionnaire_permission()
{
  return array(
   'question manage' => array(
   'title' => t('Question management'),
   'description' => t('Provides question management capability'),
   ),
  );          
}

 

 

function questionnaire_form()
{
 return drupal_get_form('questionnaire_my_form');
}

 

 

function questionnaire_my_form($form, &$form_state)

  $form_state['cache'] = TRUE;
 
  $all_categories = !empty($form_state['values']['all_categories']) ? $form_state['values']['all_categories'] : 1; 

 

  $form['all_categories'] = array(
   '#type' => 'value',
   '#default_value' => $all_categories,
   '#value' => $all_categories);

 

   // The prefix/suffix provide the div that we're replacing, named by   
   // #ajax['wrapper'] above.   
   $form['category_fieldset'] = array(   
        '#title' => t("Questions Categories"),   
        '#prefix' => '<div id="category-div">',   
        '#suffix' => '</div>',   
        '#type' => 'fieldset',   
        '#description' => t('Please enter the question categories'),
   );


   for ($i=1; $i<= $all_categories ; $i++)
   {  
      $key = 'ctg' . $i;
      $form['category_fieldset']['category'][$key] = array(     
         '#type' => 'textfield',     
         '#title' => "Question category $i",   
         ); 
    } 

   $form['category_fieldset']['add_more_category'] = array(   
        '#type' => 'submit',
        '#value' => t('Add More Categories'),
        '#ajax' => array(     
          'callback' => 'questionnaire_category_callback',
          'wrapper' => 'category-div',     
          'method' => 'replace',     
          'effect' => 'fade',   
          ),
     );
   
    $form['submit'] = array(   
        '#type' => 'submit',   
        '#value' => t('Submit'), 
        ); 
       
    return $form;
}  

 

function questionnaire_category_callback($form, &$form_state)
{
  $form_state['values']['all_categories'] = $form_state['values']['all_categories'] + 1;
  return $form['category_fieldset'];
}

 

?>

 

Best Regards
Kamal
NECS, Bangalore
 
--
[ Drupal support list | http://lists.drupal.org/ ]