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. - add_more_question_categories, category count = 1 - questionnaire_my_form, category count = 2 - questionnaire_category_callback, category count = 2 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".****
Please see link http://www.netcloudsystems.com/?q=questionnaire/form/manage****
****
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/ ]