Математическая функция.

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

Аватар пользователя ady1503 ady1503 6 октября 2022 в 9:08

Добрый день всем.

Если этот код в hook form alter:

<?php
// fields for math operations
if (isset($form["field_numero1"]) && isset($form["field_numero2"]) && isset($form["field_resultado"])) {
  
  
$form['field_numero1']['widget'][0]['value']['#ajax'] = [
    
'callback' => 'buangh_test_ajax_math_callback',
    
'event' => 'blur',
    
'disable-refocus' => TRUE,
    
'wrapper' => 'number-id',
    
'progress' => [
      
'type' => 'throbber',
      
'message' => t('Adding up...'),
    ],
  ];
    
  
$form['field_numero2']['widget'][0]['value']['#ajax'] = [
    
'callback' => 'buangh_test_ajax_math_callback',
    
'event' => 'blur',
    
'disable-refocus' => TRUE,
    
'wrapper' => 'number-id',
    
'progress' => [
      
'type' => 'throbber',
      
'message' => t('Adding up...'),
      ],
    ];
    
  
$form["field_resultado"]["#prefix"] = "<div id='number-id'>";
  
$form["field_resultado"]["#suffix"] = "</div";
    
  
$num1 $form_state->getValue('field_numero1')[0]['value'];
  
$num2 $form_state->getValue('field_numero2')[0]['value'];
    
  
$res $num1 $num2;
    
  
$form['field_resultado']['widget'][0]['value']['#value'] = $res;
  
$form['field_resultado']['widget'][0]['value']['#attributes']['readonly'] = TRUE;  
  
$form['field_resultado']['widget'][0]['value']['#attributes']['tabindex'] = '-1';
}
// fin fields for math operations
?>

И сам callback:

<?php
function buangh_test_ajax_math_callback (&$formFormStateInterface $form_state){

  return 

$form['field_resultado'];
}
?>

Вопрос в том что когда нужно менять уже сохранённые данные, edit node, это поле <?php$form['field_resultado']?>, имеет 0 вместо суммы при сохранение, save node.

Это простая сумма двух полей с результатом в третьем поле. Нечего сложного.

Помогите пожалуйста понять в чём дело?

Где моя ошибка.

Спасибо большое.

Лучший ответ

Аватар пользователя ady1503 ady1503 8 октября 2022 в 10:29
1

Привет.

Вот решение задачи:

Вместо :$form['field_resultado']['widget'][0]['value']['#value'] = $res;

Ставим:
$values = $form_state->getUserInput();
$values['field_resultado']['0']['value'] = $res;
$form_state->setUserInput($values)->setRebuild();

Как говорят в drupal ducumentation, надо быть осторожным что введёт пользователь и использовать эти функции с осторожностью.

У меня номерные поля так что не волнует.

Спасибо за помощь.

Комментарии

Аватар пользователя ady1503 ady1503 6 октября 2022 в 20:49

Простая.

Сумма двух полей и их результат через ajax, о как говорят on the fly. Чтобы был виден сразу результат, а не при сохранение формы.

Всё работает, кроме того что при изменение уже сохренненой формы результат не тот что надо, а именно сумма двух полей а ноль.

Спасибо.

Аватар пользователя ivnish ivnish 6 октября 2022 в 20:54

Вангую, что при изменении формы снова срабатывает ваш hook_form_alter, он не находит значений в полях field_numero1 и field_numero2, и дальше судя по коду складывает 0+0 и получает 0 и записывает его в поле field_resultado

Аватар пользователя ady1503 ady1503 6 октября 2022 в 21:34

Нет.

Первое и второе поле емеет тo что я вводил при новой форме и сохранил. И результат тоже точный. Но при изменение формы не загружается результат, а именно ноль. Что странно, потому что поле результат не емеет никакое значение в конфигурации поля.
Спасибо.

Аватар пользователя ady1503 ady1503 6 октября 2022 в 23:38

Я нашёл что не работает.

Ajax response делает сумму двух номеров, и это видно в форме. Но в $form_state->getValue, поля результат получает ноль 0, после результата ajax суммы.

Но в поле результат в навигатор видно сумма номеров.

Есть идеей?

Спасибо.

Аватар пользователя ady1503 ady1503 7 октября 2022 в 0:30

Вот и ответ:

In case someone comes by and wants to know the difference between ["#value"] and ["#default_value"] :

["#default_value"] will set the value when you create the form, if you edit the title your changes are retained.

["#value"] will reset the value any time it's executed. since hook_form_alter is fired at save and when editing your node your changes will be overwritten.

И как с этим быть?

Спасибо.

Аватар пользователя gun_dose gun_dose 7 октября 2022 в 10:27

По-моему, тут вообще не нужен аякс. Проще приаттачить к форме маленький скрипт, который будет всё складывать.

Аватар пользователя ady1503 ady1503 7 октября 2022 в 10:57

Я вас понял.

Но, мне нравится искать решение всегда.

Понять суть проблемы и её решить.

Это простая сумма двух номеров, но этот же принцип можно и в другом случае использовать.

Хочу понять: the difference between ["#value"] and ["#default_value"]

И как их использовать.

Спасибо.

P. S. Очень нравится примеры, я учусь всегда на примеры. Если кто-то может скинуть ссылки или сам код.

Аватар пользователя Andruxa Andruxa 7 октября 2022 в 11:32

ady1503 wrote: Хочу понять: the difference between ["#value"] and ["#default_value"]

["#value"] - останется в $form_state->getValues() независимо от того, что ввел пользователь.
["#default_value"] - элемент формы будет предзаполнен этим значением, но пользователь сможет его изменить и после сабмита в $form_state->getValues() будет значение, введенное пользователем.

Аватар пользователя ady1503 ady1503 7 октября 2022 в 12:22

Спасибо за ответ.

Тогда вопрос почему мой код не работает с ["#default_value"]? А работает с ["#value"]?

Только при загрузки изменить форму не загружает результат.

Много двойной и непонятной информации.

И это проблема только в простой функции суммы двух номеров. А если логика кода больше сложная что делать.

Спасибо большое.

Аватар пользователя gun_dose gun_dose 7 октября 2022 в 15:45
2

ady1503 wrote: Тогда вопрос почему мой код не работает с ["#default_value"]? А работает с ["#value"]?

"#default_value" работает только в том случае, если в форму ещё ничего не вводили. Попробуйте через $form_state->setUserInput($input);

Аватар пользователя OldWarrior OldWarrior 7 октября 2022 в 18:17

+1 к ::setUserInput()/::getUserInput()
Однако, при сабмите нужно быть осторожным - убедиться, что в $form_state->getValues() действительно падают нужные значения. Или тогда и на сабмите опять же читать ::getUserInput()

Аватар пользователя ady1503 ady1503 8 октября 2022 в 10:29
1

Привет.

Вот решение задачи:

Вместо :$form['field_resultado']['widget'][0]['value']['#value'] = $res;

Ставим:
$values = $form_state->getUserInput();
$values['field_resultado']['0']['value'] = $res;
$form_state->setUserInput($values)->setRebuild();

Как говорят в drupal ducumentation, надо быть осторожным что введёт пользователь и использовать эти функции с осторожностью.

У меня номерные поля так что не волнует.

Спасибо за помощь.