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.
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?
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.
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,
);
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/ ]