Аналитический паралич при переборе данных JSON для заполнения поля выбора разделами optgroup

У меня есть Аналитический паралич, и мне нужен ввод. Я могу изменить SQL-запрос, JavaScript, И / или контроллер CFML (весь код размещен ниже).

Все, что я хочу сделать, это заполнить поле выбора параметрами и оптгруппами. Optgroup - это то, что меня сбивает с толку.

Sql довольно прост и выглядит так:

SELECT
    g.groupID,
    g.groupLabel,
    u.unitLabel,
    u.unitID
  FROM
    group g
    LEFT JOIN unit u ON g.groupID = u.groupID

И цикл (ы) CFML выглядит следующим образом (я считаю, что здесь также необходимо выполнить настройку с некоторой логикой, например, если thisGroupLabel соответствует preGroupLabel, оставайтесь в цикле и продолжайте добавлять unitLabel и unitID), но есть ли более эффективный способ ?:

local.data.unitLabels = [];
    for(local.row in local.__unitLabels){
        local.unit = {};
        local.unit.groupLabel = local.row.groupLabel;
        local.unit.unitLabel = local.row.unitLabel;
        local.unit.unitID = local.row.unitID;
        //  loop over the array so that we can identify which one needs to be preselected
        for(local.dataValue in local.data.unitDetails){
            if (local.unit.unitID eq local.dataValue.unitID) {
                local.unit.selected = 'selected';
            } else {
                local.unit.selected = '';
            }
        }
    arrayAppend(local.data.unitLabels, local.unit);
}

Данные JSON выглядят так, но у меня есть доступ к запросу, поэтому при необходимости я могу его переформатировать:

{
    "data": {
        "selectDataOptions": [{
            "groupLabel": "COMPLETION",
            "selected": "",
            "unitID": 1,
            "unitLabel": "Completion"
        }, {
            "groupLabel": "DISTANCE",
            "selected": "",
            "unitID": 2,
            "unitLabel": "Meters"
        }, {
            "groupLabel": "DISTANCE",
            "selected": "",
            "unitID": 3,
            "unitLabel": "Miles"
        }, {
            "groupLabel": "DISTANCE",
            "selected": "",
            "unitID": 4,
            "unitLabel": "Yards"
        }, {
            "groupLabel": "TIME",
            "selected": "",
            "unitID": 5,
            "unitLabel": "Hours"
        }, {
            "groupLabel": "TIME",
            "selected": "",
            "unitID": 5,
            "unitLabel": "minutes"
        }, {
            "groupLabel": "TIME",
            "selected": "",
            "unitID": 5,
            "unitLabel": "Seconds"
        }]
    }
}

В нынешнем виде мое поле выбора выглядит примерно так:

<select>
    <optgroup>COMPLETION</optgroup>
    <option>Complettion</option>
    <optgroup>DISTANCE</OPTGROUP>
    <option>Meters</option>
    <optgroup>DISTANCE</optgroup>
    <option>Miles</option>
    <optgtroup>DISTANCE</optgroup>
    <option>Yards</option>
    <optgtroup>TIME</optgroup>
    <option>Hours</option>
    <optgtroup>TIME</optgroup>
    <option>Minutes</option>
</select>

Обратите внимание, что повторяются optgroup Distance и TIME. Желаемый результат будет выглядеть так:

<select>
    <optgroup>COMPLETION</optgroup>
    <option>Complettion</option>
    <optgroup>DISTANCE</OPTGROUP>
    <option>Meters</option>
    <option>Miles</option>
    <option>Yards</option>
    <optgroup>TIME</optgroup>
    <option>Hours</option>
    <option>Mintues</option>
</select>

Таким образом, трудность заключается в том, как лучше всего создать JSON, представляющий параметры списка, ИЛИ как использовать, который JSON во внешнем интерфейсе заполняет списки? Кроме того, я не уверен, что слежу за тем, как вы определяете, какие параметры следует выбрать заранее. Откуда взялся local.dataValue.unitID? Я вижу это только один раз в коде ..

SOS 23.09.2018 22:54

Комментарий / вопрос о сложности правильный. Чтобы ответить на другие вопросы, данные будут заполнять плагин jQuery, Select2, так что параметры будут предварительно выбраны для пользователя. UnitID войдет в <option value=unitID>...</option>, но я оставил это, чтобы код был более лаконичным. Надеюсь, это не запутало меня больше.

HPWD 23.09.2018 23:00

Я только что вспомнил о проблеме определения объема при использовании FOR LOOPS с ColdFusion, поэтому мне, вероятно, придется заменить ее на INDEX LOOP.

HPWD 23.09.2018 23:05

Другими словами, проблема заключается в том, как создать строку JSON, которую может понять Select2? Я собирался предложить вложенный массив дочерних элементов, как описано в разделе «Сгруппированные данные» select2.org/data-sources/formats

SOS 23.09.2018 23:35

Какую версию CF вы используете? IIRC, CF11 + поддерживают "группу" cfloop, что значительно упростит задачу ...

SOS 23.09.2018 23:42

Предполагая, что данные сначала отсортированы по groupLabel, вот пример (игнорируйте различия меток) trycf.com/gist/9b0de6c843fbe3549128b1691fbafc27/…

SOS 23.09.2018 23:59

Прошу прощения за задержку с возвращением, вышел на обед. Элемент, содержащий поле выбора, загружается после рендеринга DOM, поэтому Select2 должен применяться постфактум. Все, что мне нужно сделать, это создать поле выбора и применить плагин select2. Технически говоря, я использую Lucee 5.x, и он тоже поддерживает cfloop с группировкой.

HPWD 24.09.2018 00:05

Рассматривая суть ...

HPWD 24.09.2018 00:37

Позвольте нам продолжить обсуждение в чате.

SOS 24.09.2018 01:16

созданная вами суть очень помогла. Все, что мне нужно сделать сейчас, это изменить мой JS, и я золотой. Команда cfloop / group была идеальным решением.

HPWD 24.09.2018 01:29

Если вы переместите свой GIST к ответу, я отмечу его как правильный. Деталь, которую я переработал, была data = []; cfloop(query = "qDemo", group = "groupLabel") { children = []; cfloop() { arrayAppend(children, {"id": qDemo.unitID, "text": qDemo.unitLabel}); } group = {"text" : qDemo.GroupLabel, "children" : children }; arrayAppend(data, group); }.

HPWD 24.09.2018 01:49

Отлично, рад, что помог!

SOS 24.09.2018 02:41
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
12
57
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема в том, как создать строку JSON, которую может понять Select2? Я бы предложил создать вложенный массив дочерних элементов для каждого GroupLabel, как описано в документации в разделе Сгруппированные данные.

CF11 + и Lucee 4.5+ поддерживают cfloop "группа", что значительно упростит задачу. Просто выполните цикл по запросу и сгруппируйте его по "groupLabel". (NB: не забудьте изменить SQL-запрос и ORDER BY g.groupLabel, чтобы группировка работала должным образом.)

Пример TryCF.com

Код:

data= [];
cfloop(query = "qDemo", group = "groupLabel") {

   children = [];
   cfloop() {
      arrayAppend(children, {"id": qDemo.unitID, "text": qDemo.unitLabel});
   }

   arrayAppend(data, {"text" : qDemo.GroupLabel, "children" : children });
}

writeDump(serializeJSON(data));

Результат:

[
  {
    "text": "COMPLETION",
    "children": [
      {
        "text": "Completion",
        "id": 1
      }
    ]
  },
  {
    "text": "DISTANCE",
    "children": [
      {
        "text": "Meters",
        "id": 2
      },
      {
        "text": "Miles",
        "id": 3
      },
      {
        "text": "Yards",
        "id": 4
      }
    ]
  },
  {
    "text": "TIME",
    "children": [
      {
        "text": "Hours",
        "id": 5
      },
      {
        "text": "minutes",
        "id": 5
      },
      {
        "text": "Seconds",
        "id": 5
      }
    ]
  }
]

Другие вопросы по теме