parent от parent в fieldList

ЗАКРЫТО InstantCMS 2.X

Подгрузка данных ajax от зависимого поля

#1 24 октября 2022 в 12:31

Всем здравствуйте.

Пишу одну поделку для своего сайта. Коротко о назначении — есть своя метеостанция (китайская, но всё-же), она передаёт на сайт кучу показаний, в первом приближении компонент был уже реализован и на сайте установлен, таким образом прием показаний осуществляется успешно.

Так как некоторые данные приходят на сайт так, как заложено передающим устройством, т.е. например, направление ветра измеряется и делится на 16 румбов, которые передаются как интернациональные наименования: N,S,E,W,N и т.д.

Изображение

Как следствие наличия таких данных — их неудобно и не правильно отображать пользователю на сайте, не покажешь же надпись «Ветер NE 3.2 м/с», хотелось бы «Ветер северо-восточный 3.2 м/с», поэтому необходимо преобразование данных, но не на этапе приема, а на этапе отображения.

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

А теперь к описанию проблемы, есть форма добавления правила преобразования данных, которая включает в себя:

Выбор действия (на данном этапе мы будем рассматривать только замену значения)

  1. new fieldList('handler_type',[
  2. 'title' => LANG_GATEWAYS_HANDLER_TYPE,
  3. 'items' => [
  4. 'none' => LANG_GATEWAYS_NONE,
  5. gatewaysHandlers::RULE_REPLACE => LANG_GATEWAYS_HANDLER_RULE_REPLACE
  6. ],
  7. 'rules' => [['required']]
  8. ]),

Выбор справочника, установленного обработчиком в зависимости от правила:

  1. new fieldList('dictionary',[
  2. 'title' => LANG_GATEWAYS_DICTIONARY,
  3. 'visible_depend' => ['handler_type' => ['show' => [gatewaysHandlers::RULE_REPLACE]]],
  4. 'parent' => [
  5. 'list' => 'handler_type',
  6. 'url' => href_to($this->controller->root_url, 'handler',[
  7. $handler_name,
  8. $this->controller::ACTION_AJAX,
  9. 'dictionaries'
  10. ])
  11. ],
  12. ]),

Список справочников получается нормально, так как нужно.

Следующим этапом нужно подгрузить 2 поля, в зависимости от того, какой справочник выбран, т.е. надо дать выбор поля «где искать значение» и «на что заменить значение».

Но, если своять конструкцию аналогичную с директивой parent, ajax запроса после изменения набора данных dictionary не выполняется, для примера пробовал и так:

  1. new fieldList('options:from',[
  2. 'title' => LANG_GATEWAYS_FROM_FIELD,
  3. 'visible_depend' => ['handler_type' => ['show' => [gatewaysHandlers::RULE_REPLACE]]],
  4. 'parent' => [
  5. 'list' => 'dictionary',
  6. 'url' => href_to($this->controller->root_url, 'handler',[
  7. $handler_name,
  8. $this->controller::ACTION_AJAX,
  9. 'from'
  10. ])
  11. ],
  12. ]),

и иначе, через директивы dynamic_list...

Теперь к вопросу сабжа, можно ли обрабатывать поля с директивой parent в зависимости от другого поля с директивой parent. Если нет, можете ли вы предложить какую-то идею по реализации, судя по всему — у меня творческий кризис.

ICMS 2.15.2 PHP 7.4

Заранее спасибо за помощь и идеи.

Добавлено спустя 8 минут

Дополню, пробовал делать render_child от значения, подгруженного через parent, не сработало. Так-же пробовал делать generator => function ($item, $request), но $request не в виджетах у меня почему-то не срабатывает.

#2 24 октября 2022 в 20:31

метеостанция (китайская, но всё-же)

savenkoffcom

А можно ссылку на эту метеостанцию станцию ?

#3 25 октября 2022 в 04:51

 Игорь ФИН, офтоп, но всё-же вот. Брал комплект датчиков, снимал с него сигнал, расшифровывал, писал приемник на Ардуино с передачей сигнала через Wi-Fi на сайт. Несколько устаревший вариант прошивки есть на форуме AlexGyver, мы там с ребятам разбирали прошивку. 

#4 27 октября 2022 в 07:38

Изображение

Добавлено спустя Только что

А теперь очень жду советов по реализации.

#5 27 октября 2022 в 14:24

А насколько велик объём данных, которые нужно будет менять? Может легче составить массив этих данных и производить подмену на стороне клиента? Если вывод на одной странице, думаю jquery или vue.js с этим отлично справятся.

#6 27 октября 2022 в 18:06

Или написать свой обработчик полей, поставить слушатель к полям и делать аякс запрос.

Мало информации по полям и по данных которые передается, поэтому сложно чем то помочь

#7 28 октября 2022 в 18:00

А насколько велик объём данных, которые нужно будет менять? Может легче составить массив этих данных и производить подмену на стороне клиента? Если вывод на одной странице, думаю jquery или vue.js с этим отлично справятся.

Lora

Вы немножко не поняли суть вопроса, задача с отображением — это второстепенная задача. Первичная из сабжа — это формирования формы настройки правила замены. Мне нужно как-то максимально дистрибутивно сделать форму, в которой от поля, подгружаемого по ajax через parent будет срабатывать ещё n-e количество полей по значению выше.

Или написать свой обработчик полей, поставить слушатель к полям и делать аякс запрос.

My-InstantCMS.Ru

Можете мне дать ссылку на какой-нибудь пример реализации подобного функционала, себе такого не писал ни разу — пока не понимаю, с какой стороны подойти к данной реализации.

Мало информации по полям и по данных которые передается, поэтому сложно чем то помочь

My-InstantCMS.Ru

Мне кажется для озвученной задачи информации вполне достаточно. Давайте дам информации по полям, поля — катомные, настраиваются аналогично типам контентов, в т.ч. размерность. Настроенный перечень полей:

  • Время (Дата)
  • Температура (Число)
  • Влажность (Число)
  • Направление ветра (Строковое поле)
  • Скорость ветра (Число)
  • Порывы ветра (Число)
  • Осадки (Число)
  • Атмосферное давление (Число)
  • Low Battery (Флаг)

Поле «Направление ветра (Строковое поле)» как раз то, что требуется заменять по настроенному в админке правилу, форму настройки которого я пытаюсь сделать.

#8 28 октября 2022 в 18:19

 savenkoffcom, я имел в виду поля, при изменении которых меняется данные других полей.

пока не понимаю, с какой стороны подойти к данной реализации

savenkoffcom

Если коротко.

У нас есть поле Страна, Область, город

Список стран заранее подгружен. Нам надо при изменении поле Страна, подгружались области и при изменении области, подгружались города.

  1. $('#ID_ПОЛЕ_СТРАНА').on('change', function(){
  2. $.post("ССЫЛКА_НА_СТРАНЦУ_ОБЛАСТИ", { country_id: $(this).val()}, function(result){
  3. $.each( result, function( index, value ) {
  4. $('#ID_ПОЛЕ_ОБЛАСТЬ').append('<option value="' + index + '"''>' + value + '</option>');
  5. });
  6. $('#ID_ПОЛЕ_ОБЛАСТЬ').trigger('chosen:updated');
  7. }, 'json');
  8. });
  9. $('#ID_ПОЛЕ_ОБЛАСТЬ').on('change', function(){
  10. $.post("ССЫЛКА_НА_СТРАНЦУ_ГОРОДОВ", { region_id: $(this).val()}, function(result){
  11. $.each( result, function( index, value ) {
  12. $('#ID_ПОЛЕ_ГОРОД').append('<option value="' + index + '"''>' + value + '</option>');
  13. });
  14. $('#ID_ПОЛЕ_ГОРОД').trigger('chosen:updated');
  15. }, 'json');
  16. });
#9 28 октября 2022 в 18:22

 My-InstantCMS.Ru, прошу прощения, не правильно понял. Понял, это компонент geo. Пойду посмотрю на него ещё разок. Спасибо за наводку.

#10 31 октября 2022 в 23:40

 My-InstantCMS.Ru, прошу прощения, не правильно понял. Понял, это компонент geo. Пойду посмотрю на него ещё разок. Спасибо за наводку.

savenkoffcom

А вот этот компонент не смотрел instantcms.ru/addons/meteo2.html там если смотреть с сайта есть все данные.

#11 1 ноября 2022 в 12:00

 Игорь ФИН, задача — отдавать показания онлайн со своих приборов, иметь возможность строить графики и хранить показания а архиве n-e кол-во времени. Параллельно — брать показания с открытых датчиков сервиса Народный Мониторинг по району. А указанное Вами дополнение не отвечает моим требованиям.

Добавлено спустя 24 минуты

 My-InstantCMS.Ru, не, снова какой-то тупик. Второй запрос на обновление в любом случае не выполняется.

Форма php:

  1. class formGatewaysRemake extends cmsForm {
  2. public function init($do, $handler_name, $allowed_rules, $dictionaries)
  3. {
  4. return [
  5. 'options' => [
  6. 'type' => 'fieldset',
  7. 'title' => LANG_OPTIONS,
  8. 'childs' => [
  9. new fieldString('name', [
  10. 'title' => LANG_SYSTEM_NAME,
  11. 'rules' => [
  12. ['required'],
  13. ['sysname'],
  14. ['max_length', 32]
  15. ]
  16. ]),
  17. new fieldString('title', [
  18. 'title' => LANG_TITLE,
  19. 'rules' => [
  20. ['required'],
  21. ['max_length', 128]
  22. ]
  23. ]),
  24. new fieldList('handler_type',[
  25. 'title' => LANG_GATEWAYS_HANDLER_TYPE,
  26. 'items' => [
  27. 'none' => LANG_GATEWAYS_NONE,
  28. gatewaysHandlers::RULE_REPLACE => LANG_GATEWAYS_HANDLER_RULE_REPLACE
  29. ],
  30. 'rules' => [['required']]
  31. ]),
  32. ],
  33. ],
  34. 'settings' => [
  35. 'type' => 'fieldset',
  36. 'title' => LANG_GATEWAYS_HANDLER_OPTIONS,
  37. 'childs' => [
  38. new fieldList('dictionary', [
  39. 'title' => LANG_GATEWAYS_DICTIONARY,
  40. 'rules' => [['required']],
  41. 'visible_depend' => ['handler_type' => ['show' => [gatewaysHandlers::RULE_REPLACE]]],
  42. 'parent' => [
  43. 'list' => 'handler_type',
  44. 'url' => href_to($this->controller->root_url, 'handler',[
  45. $handler_name,
  46. $this->controller::ACTION_AJAX,
  47. 'dictionaries'
  48. ])
  49. ],
  50. 'generator' => function($item, $request) {
  51. $list = ['none' => LANG_GATEWAYS_NONE];
  52. $handler_type = is_array($item) ? array_value_recursive('handler_type', $item) : false;
  53. if (!$handler_type && $request) {
  54. $handler_type = $request->get('handler_type', 0);
  55. }
  56. if (!$handler_type) {
  57. return $list;
  58. }
  59. return ['0' => '0'];
  60. }
  61. ]),
  62. new fieldList('options:from', [
  63. 'title' => LANG_FROM,
  64. 'rules' => [['required']],
  65. 'parent' => [
  66. 'list' => 'dictionary',
  67. 'url' => href_to($this->controller->root_url, 'handler',[
  68. $handler_name,
  69. $this->controller::ACTION_AJAX,
  70. 'from'
  71. ])
  72. ],
  73. 'visible_depend' => ['handler_type' => ['show' => [gatewaysHandlers::RULE_REPLACE]]],
  74. 'generator' => function($item, $request) {
  75. $list = ['none' => LANG_GATEWAYS_NONE];
  76. $handler_type = is_array($item) ? array_value_recursive('dictionary', $item) : false;
  77. if (!$handler_type && $request) {
  78. $handler_type = $request->get('dictionary', 0);
  79. }
  80. if (!$handler_type) {
  81. return $list;
  82. }
  83. return ['0' => '0'];
  84. }
  85. ]),
  86. ]
  87. ],
  88. ];
  89. }
  90. }

При этом генерируется java-script:

  1. <script>
  2. $('#handler_type').chosen({no_results_text: 'Нет элементов для отображения', placeholder_text_single: 'Выбрать', placeholder_text_multiple: 'Выбрать несколько', disable_search_threshold: 8, width: '100%', allow_single_deselect: true, search_placeholder: 'Начните вводить или выберите из списка', search_contains: true, hide_results_on_select: false});
  3. </script>
  4.  
  5. <script>
  6. $('#handler_type').on('change', function(){
  7. icms.forms.updateChildList('dictionary', '/admin/controllers/edit/gateways/handler/wind/x/dictionaries', $(this).val(), "", $(this).attr('name'));
  8. });
  9. $('#dictionary').chosen({no_results_text: 'Нет элементов для отображения', placeholder_text_single: 'Выбрать', placeholder_text_multiple: 'Выбрать несколько', disable_search_threshold: 8, width: '100%', allow_single_deselect: true, search_placeholder: 'Начните вводить или выберите из списка', search_contains: true, hide_results_on_select: false});
  10. </script>
  11.  
  12. <script>
  13. $('#dictionary').on('change', function(){
  14. icms.forms.updateChildList('options_from', '/admin/controllers/edit/gateways/handler/wind/x/from', $(this).val(), "", $(this).attr('name'));
  15. });
  16. $('#options_from').chosen({no_results_text: 'Нет элементов для отображения', placeholder_text_single: 'Выбрать', placeholder_text_multiple: 'Выбрать несколько', disable_search_threshold: 8, width: '100%', allow_single_deselect: true, search_placeholder: 'Начните вводить или выберите из списка', search_contains: true, hide_results_on_select: false});
  17. </script>
  18.  
  19. <script>
  20. initMultyTabs('.field_tabbed');
  21. icms.forms.addVisibleDepend('e87c66e64e5ed0a7556fa7473916eee6', 'dictionary', {"handler_type":{"show":["replace"]}});
  22. icms.forms.addVisibleDepend('e87c66e64e5ed0a7556fa7473916eee6', 'options:from', {"handler_type":{"show":["replace"]}});
  23. icms.forms.VDReInit();
  24. </script>

Но запроса на изменение поля dictioaries не выполняется:

Изображение

Как добиться, чтобы выполнялось обновление поля options:from в зависимости от поля dictionaries? Собственно, повторяю сабж.

Добавлено спустя 58 минут

generator по-моему вообще лишний, не заметил, что что-то отрабатывает...

#12 1 ноября 2022 в 18:31

generator по-моему вообще лишний

savenkoffcom

parent тоже лишний или js код с onchange 

Вы либо используйте системный parent либо то что я подсказал, через on change  наблюдать изменения и подгрузить данные.

И смотрите вкладку Сеть, там при аякс запросе показывает куда ушел запрос, что передано и что вернули.

Изображение

#13 28 ноября 2022 в 11:36

Прошу прощения за отсутствие, работал на другом проекте. 

My-InstantCMS.Ru, я использую максимально имеющиеся возможности дистрибутива, в генерацию JS стараюсь вообще не лезть, так как это не мое (временно). Вот как раз вкладка консоль прекрасно отображает что отправилось и что вернулось. В окне сеть, чуть больше информации, но по нему так же видно, что второй (необходимый) запрос не выполняется:

Изображение

Похоже, пойду я, уже пройденным ранее методом, через сессионное хранение параметров запроса. А то уже слишком зациклился я с этой выборкой. 

Добавлено спустя 1 час

Говорят, со свежей головой и работается лучше. Нашел решение. Весь представленный код выше корректен, не корректно было возвращать список значений (в моем случае Справочников) одним значением, которое сразу устанавливается в поле формы. Если вернуть хотя бы 2 значения, одно из которых сделать none => Не выбрано, то при смене значения второй запрос Ajax выполняется. 

Вообщем не баг, а фича.

Изображение

Тему закрываю, всем спасибо за участие. 

Используя этот сайт, вы соглашаетесь с тем, что мы используем файлы cookie.