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

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

Добрый день.

Подскажите, пожалуйста, можно ли вызвать 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;
}
?>

Комментарии

Аватар пользователя jsv jsv 0

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

13 апреля 2018 в 10:20

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

13 апреля 2018 в 11:03

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);
}
?>
13 апреля 2018 в 14:16

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

13 апреля 2018 в 14:27

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

13 апреля 2018 в 14:30

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

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

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

13 апреля 2018 в 14:34

Lord of Cats wrote:

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

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

13 апреля 2018 в 14:44

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

13 апреля 2018 в 15:20

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

13 апреля 2018 в 17:36

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

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);
});
13 апреля 2018 в 15:37