Как из hook_form вызвать callback-функцию?

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

Аватар пользователя Lord of Cats Lord of Cats 13 апреля 2018 в 10:18

Добрый день.

Подскажите, пожалуйста, можно ли вызвать callback-функцию из произвольного места в hook_form()?

Пример:

<?php
/**
 * Callback-функция
 */
function my_callback($form, &$form_state) {
    
$commands[] = ajax_command_alert('RUN CALLBACK');
    return array(
'#type' => 'ajax''#commands' => $commands);
}
?>
<?php
/**
 * Реализация hook_form()
 */
function my_form($form, &$form_state) {
    
$form['submit'] = array(
        
'#type' => 'submit',
        
'#value' => 'Submit',
    );
    
// my_callback(); // Можно ли осуществить вызов функции?
    
return $form;
}
?>

Лучший ответ

Аватар пользователя bumble bumble 13 апреля 2018 в 15:56

Посмотрите Examples, там есть примеры навешивания AJAX-обработчиков на селект.
Вероятно, это то что Вам нужно.

Комментарии

Аватар пользователя jsv jsv 13 апреля 2018 в 10:20

Непонятно что мешает. И непонятно зачем передавать в функцию переменные из формы - тут поэтому если раскомментировать вызов будет ошибка

Аватар пользователя Lord of Cats Lord of Cats 13 апреля 2018 в 11:03

У меня ошибки нет, но и результата выполнения функции my_callback нет. Сомневаюсь, что вообще так можно вызывать. Вы не знаете?

Аватар пользователя bumble bumble 13 апреля 2018 в 14:16

1. Попробуйте подключить AJAX-библиотеку:

<?php
drupal_add_library
('system''drupal.ajax');
?>

2. Вам нужно возвращать или форму, или AJAX-команды. Сейчас, у Вас в my_form возвращается форма, а my_callback - просто, безрезультатно выполняется. Нужно что-то вроде этого:

<?php
function my_form($form, &$form_state) {
    
$form['submit'] = array(
        
'#type' => 'submit',
        
'#value' => 'Submit',
        
'#ajax'   => array(
            
'callback' => 'my_callback',
        ),
    );
 
    return 
$form;
}
 
function 
my_callback($form$form_state) {
    
$commands[] = ajax_command_alert('RUN CALLBACK');
  
    return array(
'#type' => 'ajax''#commands' => $commands);
}
?>
Аватар пользователя Lord of Cats Lord of Cats 13 апреля 2018 в 14:27

Да, такое будет работать. Даже без AJAX-библиотеки. Но это сработает, насколько я понимаю, когда будет клик по кнопке Submit. Мне надо бы выполнить набор Ajax-команд без нажатия по этой кнопке.

Аватар пользователя bumble bumble 13 апреля 2018 в 14:30

Напишите лучше, чего Вы пытаетесь добиться. Вывод 2х элементов (формы и команд) - не получится сделать из 1го коллбека.

Аватар пользователя bumble bumble 13 апреля 2018 в 14:34

Хотя, можно попробовать так:

<?php
function my_form($form, &$form_state) {
    
$form['commands'] = array(
        
'#type' => 'ajax',
        
'#commands' => my_callback($form$form_state),
    );
 
    
$form['submit'] = array(
        
'#type' => 'submit',
        
'#value' => 'Submit',
    );
 
    return 
$form;
}
  
function 
my_callback($form$form_state) {
    
$commands = [];
    
$commands[] = ajax_command_alert('RUN CALLBACK');
  
    return 
$commands;
}
?>

Не готов ручаться за результат.

Аватар пользователя gun_dose gun_dose 13 апреля 2018 в 14:44

Lord of Cats wrote:

Мне надо бы выполнить набор Ajax-команд без нажатия по этой кнопке.

Мой опыт подсказывает, что при такой постановке задачи, саму задачу нужно переосмыслить. Можете объяснить, что конкретно вам нужно?

Аватар пользователя Lord of Cats Lord of Cats 13 апреля 2018 в 15:20

Думаю вы правы.
Смотрите. Мне нужно при изменении текстового поля (textfield) установить атрибут selected к элементу выпадающего поля со списком (select), но не отправлять саму форму. Элементы select'а наполняются в соответствии с введенным значением в текстовом поле. Сначала я пытался добиться такого результата при помощи опции #default_value. Этот вариант мне не подходит, т.к. данные с формы уже были отправлены и #default_value в таком случае не работает. Я написал на JS функцию которая устанавливает атрибут selected в выпадающем поле со списком. Но теперь мне надо её как то вызвать после того как изменилось значение в текстовом поле.

Аватар пользователя gun_dose gun_dose 13 апреля 2018 в 17:36

Если у вас автокомплит, то нужно отслеживать не изменение текстфилда, а обновление автокомплита. И делается это чисто в js вообще без модулей.

Аватар пользователя Lord of Cats Lord of Cats 13 апреля 2018 в 15:37

Примерно так:

jQuery('input[name="test_input"]').live('change', function () {
       var elements = [];
       var selector = 'select[name="test_select"]';
       jQuery(selector + ' option').each(function () {
            var elem = jQuery(this).val();
            elements.push(elem);
       });
       var max = Math.max.apply(Math, elements);
       jQuery(selector).val(max);
});