Drupal → Пишем простейший калькулятор на AJAX для Drupal 7

17.07.2010

Реализация простейшего калькулятора на AJAX который выводит результат сложения двух чисел:

/**
 * Implements hook_menu().
 */
function simplecalc_menu() {
  $items['calc'] = array(
    'title' => 'Simple calc',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('simplecalc_form'),
    'access callback' => true,
  );
  return $items;
}

/**
 * Form builder.
 */
function simplecalc_form($form, &$form_state) {
  $form['number1'] = array(
    '#type' => 'textfield',
    '#title' => 'Number 1',
  );

  $form['number2'] = array(
    '#type' => 'textfield',
    '#title' => 'Number 2',
  );

  if (isset($form_state['values'])) {
    $result = $form_state['values']['number1'] + $form_state['values']['number2'];
  }
  else {
    $result = '...';
  }

  $form['result'] = array(
    '#markup' => '<div id="result">Result: ' . $result . '</div>',
  );

  $form['calculate'] = array(
    '#type' => 'button',
    '#value' => 'Calculate',
    '#ajax' => array(
      'callback' => 'simplecalc_form_ajax_callback',
      'wrapper' => 'result',
    ),
  );

  return $form;
}

/**
 * Ajax callback.
 */
function simplecalc_form_ajax_callback($form, &$form_state) {
  return $form['result'];
}

Калькулятор будет работать даже с выключенным js.

Ссылки по теме:

AJAX Forms in Drupal 7
Drupal 7 AJAX Forms
Набор модулей-примеров
Рабочие примеры AJAX форм
Видео уроки по работе с Javascript в Drupal 7

Написанное актуально для
Drupal 7
Похожие записи

Комментарии

Vydrin_AP
10.05.2011, 13:57

Добрый день! Отличный пример.
Скажите пожалуйста, как можно очищать поля после ajax-сабмита?

Vydrin_AP
10.05.2011, 14:27

Точно! Как-то сразу не догадался )
Спасибо!

Webtoucher
17.10.2011, 09:11

А можно ошибки выводить каким-нить простым способом?? Или по умолчанию это не предусмотрено для AJAX-запросов и вставлять блок так же вручную командой??

Гость
06.12.2011, 11:47

http://api.drupal.org/api/drupal/developer--topics--forms_api_reference…
#ajax['method']

Description: Modify the behavior of the returned HTML from an AJAX request when inserting into the #ajax['wrapper']. If not set, the returned HTML will replace the contents of the wrapper element, but it's also possible to use any of the available jQuery operations for DOM manipulation.

Values: String. Possible values: 'replace' (default), 'after', 'append', 'before', 'prepend'.

ScentTiger
02.10.2012, 03:00

Привет! Хороший пример, думаю на его основе можно сделать калькулятор услуг, но.. модуль сам скачал включил, он не где не появился, должно было что-то произойти после его включения? У вас на сайте регистрация отключена, жаль.

Евгений
26.02.2013, 23:49

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

Гость
31.05.2013, 12:12

Подскажите пожалуйста. как сделать что бы расчет выводился виде бокса и с дополнительными водами значениями для решения? Ну или хотя бы в каком направлении надо смотреть.

Игорь
04.10.2014, 13:16

Позволю себе переписать пример, так как считаю использовать метод ajax_command_invoke($selector, $method, array $arguments = array()) более правильно, из-за его офигительной универсальности!

/**
 * Описание формы
 */
function simplecalc_form($form, &$form_state) {
  // другие элементы формы. Как в примере выше.
  // ....
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => 'Посчитать',
    '#ajax' => array(
      'callback' => 'simplecalc_callback',
    ),
  );
  return $form;
}
 
/**
 * AJAX callback
 */
function simplecalc_callback($form, $form_state) {
  $commands = array();
  // Можно использовать Сколько угодно методов jQuery!!! 
  // И изменять любое!!! содержимое страницы!
  $commands[] = ajax_command_invoke('#answer', 'html', array( 
    strval($form_state['values']['number1'] + $form_state['values']['number2']) ));
  return array('#type' => 'ajax', '#commands' => $commands);
}
Гость
08.03.2015, 19:01

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

погуглите как создавать страницы и блоки

Игорь
08.03.2015, 19:18

Чувак, так как ты не представился, ты совсем не понимаешь программирование на drupal - задавая такой вопрос!
видишь - hook_menu - получится страница - calc от корня сайта (установки drupal) - на ней и выведется. Обычно это site.ru/calc
Это в примере, а если нужно вывести на какой-то случайной странице - то можно блоком (php код) или программно создать блок и его выводить.

Гость
08.03.2015, 19:51

xandeadx
Ясно, это не совсем модуль, а просто фрагмент. В названии тогда лучше указывать данный аспект, а то не совсем понятно поначалу. ScentTiger, Втр 02/10/2012 - 03:00 прокомментировал, что скачал модуль. Начал искать, откуда скачать, нигде не нашёл )
Проверки получается, что нет на то, когда вводятся буквы, к примеру, а не цифры?

Игорь
Чувак, так ты не назвал свою фамилию и не указал адрес места жительства. По умолчанию в поле Ваше имя "Гость" подставляется.

Игорь
08.03.2015, 19:57

Лучше бы признался, что чайник, а не огрызался ... разве я тебе не помог?

Игорь
08.03.2015, 19:58

По умолчанию надо идти джумлу мучать ;-)

Игорь
08.03.2015, 20:21

simplecalc - это модуль конечно же, но то что надо добавить голову и дописать ещё код необходимый для того или иного - это само-собой разумеется. Автор старается приводить минимум кода для понимании идеи. В данном случае взаимодействия с AJAX.
Готовые модули, которые можно скачать, установить и мучать(модифицировать) - https://www.drupal.org/project/examples - удобная штука для любой версии drupal!

scenttiger
09.03.2015, 10:12

Собственно давно написал свой калькулятор услуг на JS и повесил на сайт через shadowbox

Игорь
09.03.2015, 11:52

Собственно давно написал свой калькулятор услуг на JS и повесил на сайт через shadowbox

Поделился бы ссылкой?!
Вот мой калькулятор стоимости ремонта квартиры. Можно составить смету ремонта онлайн, но оказалась сложная штука для простого юзверя. Тоже давно писал, ещё на 6-ке.

Здравствуйте.
Спасибо за статью, все очень наглядно. Но я пытаюсь вывести тоже самое, но не на странице, а в блоке. И никак не могу сообразить как это правильно сделать.
Я заменил функцию simplecalc_menu, на функции:

function simplecalc_block_info() {
  $blocks['calculator'] = array(
    'info' => t('Caclulator'),
    'cache' => DRUPAL_NO_CACHE,
  );
   return $blocks;
}
 
function simplecalc_block_view($delta = '') {
  $block = array();
   switch ($delta) {
    case 'calculator':
      $block['subject'] = t('Calculator');
      $block['content'] = simplecalc_form();
      break;
  }
  return $block;
}

Но естественно это не работает как надо. Не обновляется ajax'ом и выдается ошибка что не переданы аргументы в функцию simplecalc_form().
Что нужно передать в $block['content']? Нужно дописать какую-то промежуточную функцию?

формы в друпале надо выводить через drupal_get_form()

Нашел ответ.
$block['content'] = drupal_get_form('simplecalc_form');

P.S. Вечно так нахожу ответ либо пока пишу вопрос, либо сразу после этого. Хотя перед этим долго гуглю.

Здравствуйте.
Сделал по вашему примеру довольно сложный калькулятор. И добавил валидатор. Изначально задал default_value для полей формы, чтобы не заполнять поля каждый раз.
Теперь убрал умолчания и форма работает некорректно. Сразу выдает ошибки
Notice: Undefined index: values в функции calculator_form_formula() на каждое поле формы.
Т.е. форма сабмитится сразу при открытии страницы.
Если нажать сабмит то все происходит как надо - срабатывает мой валидатор и показывает ошибку прописанную в нем.

Пока писал, понял сам часть проблемы.
Результат работы формы показывается сразу при открытии, потому что в теле формы стоит:
$result = $current_number1_value + $current_number2_value;
Только у меня $result = функции с формулами.

Куда засунуть этот $result чтобы он не срабатывал сразу при открытии формы?
Я пробовал засунуть его как есть внутрь валидатора
function calculator_form_validate($form, &$form_state)
Теперь вызывается если валидация проходит успешно
Ошибки как и ожидалось исчезли, но и результат не показывается.

проверяйте наличие данных в $form_state['values']

Спасибо за подсказку. Я вижу здесь в примере вы тоже дописали эту проверку.
Я уж было засунул $result в calculator_form_ajax_callback, работало, но это явно кривое решение.

Кирилл
25.02.2019, 11:29

Хотел как-то попробовать создать калькулятор по статье, не не тут то было. Оказалось намного сложней чем я думал :( В итоге вот такую штуку ucalc.pro/help/integration/drupal установил у себя.

Вадик
07.08.2019, 13:44

Еще в 2012 по статье делал себе калькулятор)) Сейчас уже не до кода, формы расчета через stepform.io наклепал себе и времени сэкономил.

Добавить комментарий