Уважаемые,
принялся за разработку модуля и тем самым вышел на работу с формами. На данный момент застрял на следующем:
Имеем: друпаловская форма, на ней селект (данные подгружаются из бд), кнопка с прикрученным калбэком на аяксе.
Необходимо: вывести записи из бд в зависимости от выбранного итема в селекте.
- Аякс запрос - не проблема
- Не могу понять почему при onChange в селекте не меняется аттрибут "selected" у выбранного итема
- Когда пытался сделать сделать через обычный сабмит - провалился с передачей данных в ту же форму по сабмиту
- На пыхе почти ничего не написал, это первый опыт такого масштаба.
- Читать мануалы к сожалению нет времени, поэтому и обращаюсь сюда.
Надеюсь на понимание и соответствующую помощь.
Листинг формы:
<?php$form = array();
$query = db_select('college_lessons');
$query->fields('college_lessons', array('id', 'name',));
$query->orderBy('name', 'ASC');
$lessons = $query->execute()->fetchAll();
$options = array();
foreach ($lessons as $lesson) {
$options[$lesson->id] = $lesson->name;
}
$form['lesson_id'] = array(
'#type' => 'select',
'#options' => $options,
"#empty_option"=>t('- Select -'),
'#default_value' => 0,
'#prefix' => '<div class="container-inline">',
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Load content'),
'#ajax' => array(
'callback' => 'form_ajax_form_load_node_content',
'wrapper' => 'form-ajax-node-content',
'method' => 'replace',
'effect' => 'fade',
),
);
$rows = array();
$form['table'] = array(
'#theme' => 'table',
'#header' => array('Дата', 'Дисциплина', 'Оценка'),
'#rows' => $rows,
'#empty' => t('Нет результатов.'),
'#attributes' => array (
'id' => "form-ajax-node-content",
),
);
$form['id'] = array(
'#type' => 'value',
'#value' => $student['id']
);
return $form;?>
Комментарии
в $form_state['values'] точно выбранных данных нет?
$form_state['values'] содержит значение выбранного итема в селекте. Однако дальнейшее OnChange селекта не меняет его значения.
в выше приведенном примере нету кода OnChange который меняет значение, угадать сложно что с ним не так.
а где описанный коллбек работы аякса? где код js onSelect?
вы для onSelect live используете? delegate?
где сабмит формы?
предполагаю, что в теме не выодится еще $message , где у вас будет сообщение о том, что ваша форма была изменеа после выполнения аякса и потому не может быть обработана (надеюсь, что не так).
Напишите полный код всей формы + js файл.
Для меня, как программиста c#, очень странно понимается, что выпадающий список надо принудить к onChange и дальнейшим присвоениям SelectedItem/Index/Value
от нехватки опыта не понял что за $message. Да и врятли он есть, потому как в моей задаче стоит вывести результаты из таблицы бд в зависимости от указанного фильтра.
Будьте благосклонны ко мне, быть может есть ваше решение такой задачи?
Листинг:
<?php /** STUDENTS **/ function student_form($form, $form_state, $student = null)
$options = array();
drupal_goto('college/students');
$options = array();
{
if ($student)
{
drupal_set_title('Студент: редактирование');
}
else
{
drupal_set_title('Студент: создание');
}
$form = array();
$form['f_name'] = array(
'#title' => 'Фамилия',
'#type' => 'textfield',
'#default_value' => $student ? $student['f_name'] : '',
'#required' => true,
);
$form['i_name'] = array(
'#title' => 'Имя',
'#type' => 'textfield',
'#default_value' => $student ? $student['i_name'] : '',
'#required' => true,
);
$form['o_name'] = array(
'#title' => 'Отчество',
'#type' => 'textfield',
'#default_value' => $student ? $student['o_name'] : '',
'#required' => true,
);
$query = db_select('college_groups');
$query->fields('college_groups', array('id', 'name',));
$query->orderBy('name', 'ASC');
$results = $query->execute()->fetchAll();
foreach ($results as $result) {
$options[$result->id] = $result->name;
}
$form['group_id'] = array(
'#type' => 'select',
'#title' => t('Группа'),
'#options' => $options,
'#default_value' => $student ? $student['group_id'] : '',
'#required' => true,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => $student ? t('Сохранить изменения') : t('Добавить'),
);
if ($student) {
$form['id'] = array(
'#type' => 'value',
'#value' => $student['id'],
);
}
return $form;
}
function
student_form_validate($form, $form_state){
$f_name = $form_state['values']['f_name'];
$i_name = $form_state['values']['i_name'];
$o_name = $form_state['values']['o_name'];
$group_id = $form_state['values']['group_id'];
if (is_null($f_name) || $f_name === '')
{
form_set_error('f_name', t('Фамилия задана не верно'));
}
if (is_null($i_name) || $i_name === '')
{
form_set_error('i_name', t('Имя задано не верно'));
}
if (is_null($o_name) || $o_name === '')
{
form_set_error('o_name', t('Отчество задано не верно'));
}
}
function
student_form_submit($form, $form_state){
$student = array(
'f_name' => $form_state['values']['f_name'],
'i_name' => $form_state['values']['i_name'],
'o_name' => $form_state['values']['o_name'],
'group_id' => $form_state['values']['group_id'],
);
if (isset(
$form_state['values']['id'])) {$student['id'] = $form_state['values']['id'];
drupal_write_record('college_students', $student, 'id');
drupal_set_message(t('Выполнено!'));
}
else {
drupal_write_record('college_students', $student);
drupal_set_message(t('Выполнено!'));
}
}
function
student_marks($form, $form_state, $student = null){
drupal_set_title($student['f_name'].' '.$student['i_name'].' '.$student['o_name'].': оценки');
$form = array();
$query = db_select('college_lessons');
$query->fields('college_lessons', array('id', 'name',));
$query->orderBy('name', 'ASC');
$lessons = $query->execute()->fetchAll();
foreach ($lessons as $lesson) {
$options[$lesson->id] = $lesson->name;
}
$form['lesson_id'] = array(
'#type' => 'select',
'#options' => $options,
"#empty_option"=>t('- Select -'),
'#default_value' => 0,
'#prefix' => '<div class="container-inline">',
);
/*
$form['submit'] = array(
'#type' => 'submit',
'#value' => t("Найти"),
'#suffix' => '</div>',
);
*/
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Load content'),
'#ajax' => array(
'callback' => 'form_ajax_form_load_node_content',
'wrapper' => 'form-ajax-node-content',
'method' => 'replace',
'effect' => 'fade',
),
);
$marks = db_select('college_marks', 't')
->fields('t', array('id', 'student_id', 'lesson_id', 'date_set', 'mark'))
->condition('t.student_id',$student['id']);
if (isset($_REQUEST['lesson_id']) && $_REQUEST['lesson_id']!=0)
{
$marks = $marks->condition('t.lesson_id',$_REQUEST['lesson_id']);
}
$marks = $marks->execute()->fetchAll();
$rows = array();
if ($marks)
{
foreach ($marks as $mark) {
$rows [] = array(
array('data' => $mark->date_set),
array('data' => getLessonnameById($mark->lesson_id)),
array('data' => $mark->mark),
);
}
$form['table'] = array(}
'#theme' => 'table',
'#header' => array('Дата', 'Дисциплина', 'Оценка'),
'#rows' => $rows,
'#empty' => t('Нет результатов.'),
'#attributes' => array (
'id' => "form-ajax-node-content",
),
);
//$form['pager'] = array('#markup' => theme('pager'));
$form['id'] = array(
'#type' => 'value',
'#value' => $student['id']
);
return $form;
}
function
form_ajax_form_load_node_content($form, $form_state){
return $form['lesson_id']['#type'].']['.$form['lesson_id']['#value'].']['.$form_state['values']['lesson_id'];
}
function
student_marks_submit($form, $form_state){
} ?>
По стилизации кода вижу, что с#. Знакомые стандарты.. ) Тем более приятно читать правильный код. Ну это такое.
По делу.
У вас форма вызывает обработчик по сабмиту и через аякс грузит (должна) данные в таблицу. Точнее должна пересоздать ее часть в соответствии с выбранным значением в селект.
Перезагрузка формы происходит потому, что не отрабатывает аякс + отсутствие обработки формы в случае не работающего js (да да, бывает и такое).
Рекомендую к ознакомлению
1. https://www.drupal.org/node/752056
Вы потратите час от силы, что бы вникнуть (судя по вашему опыту). И у вас будет левел ап. Дело в том, что в Друпале несколько отличатется идеология работы валидации формы при отработке аякс в рамках этой формы. С точки зрения даже проектирования вы все делаете правильно. С точки зрения друпала - не совсем. Что бы не было вопросов - лучше почитать по ссылке. Там не много. Но есть хороший пример.
2. Рекомендую еще вот это http://xandeadx.ru/. Много интересных мыслей и решений, да и подсказок. И ваш вопрос там тоже есть. А именно http://xandeadx.ru/search/node/form%20ajax
Прошу понять правильно. Я могу решить вашу задачу, но вы не получите никакого профита и в следующей такой проблеме снова будете искать помощь, потому как не разберетесь в первопричине.
П.с. прошу понять правильно )
Совершенно прекрасно понял. Выражаю огромную благодарность и низкий поклон