Форма поиска, получение данных и select

Главные вкладки

Аватар пользователя coder1coder coder1coder 25 марта 2015 в 23:28

Уважаемые,
принялся за разработку модуля и тем самым вышел на работу с формами. На данный момент застрял на следующем:

Имеем: друпаловская форма, на ней селект (данные подгружаются из бд), кнопка с прикрученным калбэком на аяксе.
Необходимо: вывести записи из бд в зависимости от выбранного итема в селекте.

  • Аякс запрос - не проблема
  • Не могу понять почему при onChange в селекте не меняется аттрибут "selected" у выбранного итема
  • Когда пытался сделать сделать через обычный сабмит - провалился с передачей данных в ту же форму по сабмиту
  1. На пыхе почти ничего не написал, это первый опыт такого масштаба.
  2. Читать мануалы к сожалению нет времени, поэтому и обращаюсь сюда.

Надеюсь на понимание и соответствующую помощь.

Листинг формы:

<?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;?>

Комментарии

Аватар пользователя coder1coder coder1coder 26 марта 2015 в 0:36

formatC'vt wrote:
в $form_state['values'] точно выбранных данных нет?

$form_state['values'] содержит значение выбранного итема в селекте. Однако дальнейшее OnChange селекта не меняет его значения.

Аватар пользователя t1mm1 t1mm1 26 марта 2015 в 2:46

а где описанный коллбек работы аякса? где код js onSelect?

вы для onSelect live используете? delegate?

где сабмит формы?

предполагаю, что в теме не выодится еще $message , где у вас будет сообщение о том, что ваша форма была изменеа после выполнения аякса и потому не может быть обработана (надеюсь, что не так).

Напишите полный код всей формы + js файл.

Аватар пользователя coder1coder coder1coder 26 марта 2015 в 7:14

"formatC'vt" wrote:
в выше приведенном примере нету кода OnChange который меняет значение, угадать сложно что с ним не так.

Для меня, как программиста c#, очень странно понимается, что выпадающий список надо принудить к onChange и дальнейшим присвоениям SelectedItem/Index/Value

"t1mm1" wrote:
предполагаю, что в теме не выодится еще $message , где у вас будет сообщение о том, что ваша форма была изменеа после выполнения аякса и потому не может быть обработана (надеюсь, что не так).

от нехватки опыта не понял что за $message. Да и врятли он есть, потому как в моей задаче стоит вывести результаты из таблицы бд в зависимости от указанного фильтра.

Будьте благосклонны ко мне, быть может есть ваше решение такой задачи?

Аватар пользователя coder1coder coder1coder 26 марта 2015 в 7:18

Листинг:

<?php

/** STUDENTS **/

function student_form($form$form_state$student null)
{
    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();

    

$options = array();
    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('Выполнено!'));
    }

    

drupal_goto('college/students');
}

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();

    

$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("Найти"), 
        '#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)
{
   
}

?>
Аватар пользователя t1mm1 t1mm1 26 марта 2015 в 11:56

По стилизации кода вижу, что с#. Знакомые стандарты.. ) Тем более приятно читать правильный код. Ну это такое.

По делу.
У вас форма вызывает обработчик по сабмиту и через аякс грузит (должна) данные в таблицу. Точнее должна пересоздать ее часть в соответствии с выбранным значением в селект.
Перезагрузка формы происходит потому, что не отрабатывает аякс + отсутствие обработки формы в случае не работающего js (да да, бывает и такое).

Рекомендую к ознакомлению
1. https://www.drupal.org/node/752056
Вы потратите час от силы, что бы вникнуть (судя по вашему опыту). И у вас будет левел ап. Дело в том, что в Друпале несколько отличатется идеология работы валидации формы при отработке аякс в рамках этой формы. С точки зрения даже проектирования вы все делаете правильно. С точки зрения друпала - не совсем. Что бы не было вопросов - лучше почитать по ссылке. Там не много. Но есть хороший пример.
2. Рекомендую еще вот это http://xandeadx.ru/. Много интересных мыслей и решений, да и подсказок. И ваш вопрос там тоже есть. А именно http://xandeadx.ru/search/node/form%20ajax

Прошу понять правильно. Я могу решить вашу задачу, но вы не получите никакого профита и в следующей такой проблеме снова будете искать помощь, потому как не разберетесь в первопричине.

П.с. прошу понять правильно )