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']; }* ** *?>*
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']; }
?>
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.eduwrote:
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/ ]