Forms API - несколько кнопок submit.

Прислано: CynicusAE

пн, 15/03/2010 - 06:12

Доброго времени суток.

Делаю форму вида
[набор полей]
  [набор полей 1]
    [поле-1-1]
    [поле-1-2]
    [сабмит-1]
  [набор полей 2]
    [поле-2-1]
    [поле-2-2]
    [сабмит-2]

Функция построения формы (без "лишних" полей, чтобы не было избыточности информации):

function list_of_vacancies(){
 
// Создаем набор полей - обертку, чтобы держать информацию свернутой
 
    $form['vacancies_list'] = array (
        '#title' => t('List of vacancies'),
        '#type' => 'fieldset',
        '#collapsible' => TRUE,
        '#collapsed' => TRUE,
        '#tree' => TRUE,
    );
    $result = db_query ("SELECT * FROM {vacancy} WHERE companyid = %d", arg(1));
 
//Здесь начинаем строить наборы полей с содержимым и кнопками
 
    while ($item = db_fetch_object($result)){
        $form['vacancies_list'][$item->fcid] = array (
            '#type' => 'fieldset',
            '#collapsible' => FALSE,
        );
        $form['vacancies_list'][$item->fcid]['vacancy'] = array (
            '#type' => 'textfield',
            '#default_value' => $item->vacancyname,
            '#size' => 20,
        );
        $form['vacancies_list'][$item->fcid]['salary'] = array (
            '#type' => 'textfield',
            '#default_value' => $item->salary,
            '#size' => 6,
        );
        $form['vacancies_list'][$item->fcid]['update'] = array (
            '#type' => 'submit',
            '#value' => t('Update'),
            '#validate' => array ('list_of_vacancy_update_validate'),
            '#submit' => array ('list_of_vacancy_update_submit'),
        );
        $form['vacancies_list'][$item->fcid]['delete'] = array (
            '#type' => 'submit',
            '#value' => t('Delete'),
            '#submit' => array ('list_of_vacancy_delete_submit'),
        );
    }
 
// Общие для всех форм кнопки обработки.
 
    $form['vacancies_list']['update_all'] = array (
        '#type' => 'submit',
        '#value' => t('Update all')
    );
    $form['vacancies_list']['delete_all'] = array (
        '#type' => 'submit',
        '#value' => t('Delete all')
    );
    return $form;
};

В итоге получается, что на каждый набор полей вызывается одна и та же функция и обрабатывает все одноименные поля сразу. Как сообщить функциям валидации и отправки, какая именно кнопка была нажата?

Или есть иной способ получить требуемый результат? Только от подобной структуры наборов полей отказываться не хочется, потому что таких групп на одной странице может быть несколько.

Комментарии


Настройки просмотра комментариев

Выберите нужный метод показа комментариев и нажмите "Применить"
Опубликовано Nikit в пн, 15/03/2010 - 06:39.

http://drupal.org/node/144132#buttons


Опубликовано CynicusAE в пн, 15/03/2010 - 07:35.

Nikit написал(а):

http://drupal.org/node/144132#buttons

Не то. Более того, оное мной благополучно используется в этом же коде. Сложность в том, что количество наборов полей переменное и зависит от числа записей в базе - одно, пять, двадцать...

Выводятся они через цикл и в данном случае и '#value' => t('something') у них будут одинаковыми, и функция обработки одна и та же. Различия только в ID - ибо ['vacancies_list'][$item->fcid]['update'] (ну и удалением аналогично).

Так что вопрос остается - как сообщить функциям валидации и отправки, какая из кнопок нажата? Выбор не между update и delete, это легко решаемо, а между разными update и разными delete.


Опубликовано graker в пн, 15/03/2010 - 07:44.

Решал аналогичную задачу. Надо в кнопке сохранять какой-нибудь id, а потом при сабмите проверять. Точно не помню где он будет доступен, что-то вроде $form_state['submit'].

На орге об этом есть информация, поищите. Если не найдете, могу примерно после 15:00 посмотреть свой код.


Опубликовано Nikit в пн, 15/03/2010 - 08:23.

проще было бы одну кнопку с условиями на селектах или радиобаттонах.
попробуй принтануть form_state


Опубликовано RxB в пн, 15/03/2010 - 08:25.

hook_forms()? Не?


Опубликовано graker в пн, 15/03/2010 - 08:41.

RxB написал(а):

hook_forms()? Не?

Да не, он же вроде одну форму генерирует, а не несколько форм с одним набором обработчиков.

Там не нужны никакие дополнительные поля, селекты и баттоны, надо id набора полей сохранять в массиве-описании соответствующей кнопки, он будет передан в форм-стейт, надо только вспомнить, куда именно :)


Опубликовано graker в пн, 15/03/2010 - 08:45.

Во, нашел.

Цитата:

form_state['clicked_button']
A full copy of the button element that was clicked to submit the form. This is more reliable than the old $form_values['op'] name, and also carries any additional information that was placed in the button element's form definition.

Это с той же страницы, что Nikit в начале привел. По-моему так оно и делается. После обеда проверю.


Опубликовано RxB в пн, 15/03/2010 - 08:48.

"graker" написал(а):

form_state['clicked_button']

Тогда надо не забыть каждой кнопки свой ID назначать, да так чтоб потом различить


Опубликовано graker в пн, 15/03/2010 - 08:58.

Ага, я так и написал: надо id набора полей сохранять в массиве-описании соответствующей кнопки. $item->fcid из приведенного кода, вероятно, подойдет.

Но, кстати, у использования hook_forms() и генерации множества одинаковых форм есть свои плюсы. Например, легко потом повесить аякс на сабмит каждой формы. Ну и движку не нужно будет тащить в form_state значения всех групп полей при сабмите только одной группы.


Опубликовано RxB в пн, 15/03/2010 - 09:09.

Да вот мне тоже вариант с hook_forms() больше нравится, гибче


Опубликовано Обухов Никита в пн, 15/03/2010 - 12:05.

Обычно это делается так:

<?php  $form['buttons'] = array();
  
$form['buttons']['submit'] = array(
    
'#type' => 'submit',
    
'#value' => t('Save'),
    
'#weight' => 5,
    
'#validate' => array('validate_func_1'),
    
'#submit' => array('submit_func_1'),
  );
  
$form['buttons']['delete'] = array(
    
'#type' => 'submit',
    
'#value' => t('Delete'),
    
'#weight' => 15,
    
'#validate' => array('validate_func_2'),
    
'#submit' => array('submit_func_2'),
  );
?>

Ну можно конечно навесить ID и обойтись 2-мя функциями, но имхо лучше разделять.


Опубликовано graker в пн, 15/03/2010 - 12:30.

Тут вроде речь про случаи с неизвестным/переменным числом кнопок.


Опубликовано CynicusAE в пн, 15/03/2010 - 13:21.

Спасибо ответившим.
Пока реализовал с помощью '#name' -> $item->fcid,в свойствах кнопки и проверки $form_state['clicked_button']['#name']в функциях.

На hook_forms() посмотрю. Похоже, это действительно будет более правильным и удобным решением.


Опубликовано aRpi в пт, 11/11/2011 - 18:51.

Кликнутая кнопка в *_submit доступна через:
$sta['clicked_button']

<?php
function *_submit($frm, &$sta) {
  
drupal_set_message($sta['clicked_button']['#value']);
}
?>

 ]http://naveensnayak.wordpress.com/2010/03/09/drupal-multiple-submit-buttons/[/man


Новое на сайте

Ссылки партнёров