PHP и Jquery Создание нескольких динамических списков выбора с вероятным условным поведением

Название немного многовато, поэтому позвольте мне разобрать его. То, что я пытаюсь выполнить здесь, - это выбрать вариант из выбора 1 (onChange), чтобы получить предварительно созданный выбор для выбора 2 из внешнего скрипта php. То же самое для 2 -> 3 и 3 -> 4. Я знаю, как это сделать, возможно, неэффективно, но я могу это сделать.

Проблема, с которой я столкнулся, заключалась в том, что третий выбор не всегда возможен. Это проблема, потому что 4-й выбор - это конечный результат, который мне нужен. Второй выбор в этом случае даст мне идентификатор для создания выбора 4. Есть смысл?

HTML:

<td>
    <select name = "collectionID" id = "bpCollection" class = "form-control">
        <option value = "">Select Collection</option>
            <?PHP echo optionsFromDatabase();?>
    </select>
</td>
<td><select name = "bpClass"id = "bpClass" class = "form-control"></select></td>
<td><select name = "bpFaction"id = "bpFaction" class = "form-control"></select></td>
<td><select name = "bpID"id = "bpID" class = "form-control"></select></td>

ДЖКЕРИ:

<script>

    $("#bpCollection").change(function() {
        $("#bpClass").load("inc/api/auto.php?type=class&choice = " + $("#bpCollection").val());
    });

    $("#bpClass").change(function() {
        $("#bpFaction").load("inc/api/auto.php?type=faction&choice = " + $("#bpClass").val());
    });

    $("#bpFaction").change(function() {
        $("#bpID").load("inc/api/auto.php?type=blueprint&choice = " + $("#bpFaction").val());
    });


</script>

Как уже говорилось ранее, это работает отлично.

Auto.php

$group = $db->escape($_GET['type']);
$choice = $db->escape($_GET['choice']);

$list = ''; 

switch ($group) { 

    case 'blueprint':

        $db->where('marketGroupID',$choice);
        $db->orderBy('typeName','ASC');
        $map = $db->get('invTypes');

        foreach ( $map as $val ) { 

            $list .= '<option value = "'.$val['typeID'].'">'.$val['typeName'].'</option>';

        }

        break;

    default:

        $db->where('parentGroupID',$choice);
        $db->orderBy('marketGroupName','ASC');
        $map = $db->get('invmarketgroups');

        foreach ( $map as $val ) { 

            $list .= '<option value = "'.$val['marketGroupID'].'">'.$val['marketGroupName'].'</option>';

        }



}

echo $list;

Это отлично работает, за исключением. #bpFaction не всегда является вариантом, в котором он не может быть заполнен, поскольку #bpClass содержит параметры идентификатора для #bpID. Я могу выбрать опцию выбора #bpClass, и мне нужно будет сразу перейти к #bpID. Я думаю, что большая часть моей проблемы заключается в том, что я не представляю код, необходимый на обоих концах, чтобы все работало должным образом. Мне нужно, чтобы jquery делал это, мне нужно изменить auto.php или и то, и другое?

Есть ли у вас какие-нибудь мысли, как это лучше сделать?

Как определить, что вариант 3 вам не нужен? Это когда у вас нет результатов из БД или только один?

Michel 08.09.2018 10:07

Я бы использовал запросы Ajax вместо использования функции jQuery load. Таким образом, вы можете либо получить следующие параметры поля выбора, либо получить результат, в котором указано, что вы достигли конца, и обработать это в JS (Ajax может обрабатывать ответы JSON вместо простого HTML, что позволяет вам более эффективно передавать состояния и информацию для таких вещей) . Обновлено: я построил ту же самую установку, но более сложную около месяца назад.

Skylord123 08.09.2018 10:14

@Michel, это совершенно верно. Когда запускается #bpClass, у auto.php не будет ссылок на базу данных с этим идентификатором. Так мы узнаем, что #bpFaction нет, есть только #bpID.

CLHardman 08.09.2018 15:53

@ Skylord123 Я знаю об Ajax гораздо меньше, чем следовало бы. Могу я попросить вас привести пример кода для справки?

CLHardman 08.09.2018 15:54

Ба, время редактирования истекло. Возможно, такая установка, как $('#bpCollection, #bpClass, #bpFaction').change(function() { , для просмотра всех выбранных параметров и выполнения моих вызовов auto.php путем захвата document.getElementById("#bpWhatever").value; в одной единственной функции?

CLHardman 08.09.2018 16:11
Поведение ключевого слова "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) для оценки ваших знаний,...
0
5
45
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

$list= myswitch($db, $group, $choice);

function myswitch($db, $group, $choice){
   $list='';
   switch ($group) { 
      case 'blueprint':
      ...
      break;

     default:
        $db->where('parentGroupID',$choice);
        $db->orderBy('marketGroupName','ASC');
        $map = $db->get('invmarketgroups');

       //*** CONDITION HERE ***
       //IF condition met: set new variables
       if ($choice === ... && $map === ...)){
          $group = "xxx";
          $choice = "yyy";

          //call the function again with new values
          $list = myswitch($db, $group, $choice);
          }
      //ELSE create normal list
      else{
          foreach ( $map as $val ) { 
             $list.= ....
             }
          }
   return list;
 }

Конечно, я думал об этом. Тогда с моим jQuery впереди, как я могу сказать #bpClass пропустить #faction?

CLHardman 08.09.2018 15:50
Ответ принят как подходящий

Я рекомендовал использовать Ajax с JSON выше. Здесь я более подробно расскажу, как это сделать. Я буду писать этот образец, используя Штаты, Города и Юрисдикции в качестве типов поля выбора.

Мы будем использовать один контроллер в PHP для всех полей выбора (точно так же, как ваш выше), за исключением того, что мы будем переписывать его, чтобы вместо этого возвращать JSON. Я не знаю, какой фреймворк вы используете, поэтому я просто написал образец того, как он будет выглядеть:

    // if no state passed in, return list
    if (!$stateId = $request->get('state')) {
        $loadedStatesFromDb = ...; // states loaded from DB

        // if your $loadedCitiesFromDb is an array of classes we need to format it into a flat array for JSON
        $states = [];
        foreach($loadedStatesFromDb as $state) {
            $states[$state->getId()] = $state->getName();
        }

        // your framework may require a different method of passing json data
        return json_encode([
            'result' => 'ok', // we pass this so the Ajax jquery call can check it returned successfully
            'states' => $states
        ]);
    }

    // if no city passed in, load cities for the selected state
    if (!$cityId = $request->get('city')) {
        $loadedCitiesFromDb = ...; // cities loaded from DB for $stateId

        // if your $loadedCitiesFromDb is an array of classes we need to format it into a flat array for JSON
        $cities = [];
        foreach($loadedCitiesFromDb as $city) {
            $cities[$city->getId()] = $city->getName();
        }

        // your framework may require a different method of passing json data
        return json_encode([
            'result' => 'ok', // we pass this so the Ajax jquery call can check it returned successfully
            'cities' => $cities
        ]);
    }

    // if no jurisdiction selected, load list
    if (!$jurisdictionId = $request->get('jurisdiction')) {
        $loadedJurisdictionsFromDb = ...; // jurisdictions loaded from DB for $cityId

        // if your $loadedCitiesFromDb is an array of classes we need to format it into a flat array for JSON
        $jurisdictions = [];
        foreach($loadedJurisdictionsFromDb as $jurisdiction) {
            $jurisdictions[$jurisdiction->getId()] = $jurisdiction->getName();
        }

        // your framework may require a different method of passing json data
        return json_encode([
            'result' => 'ok', // we pass this so the Ajax jquery call can check it returned successfully
            'jurisdictions' => $jurisdictions
        ]);
    }

И вот как бы выглядело ваше представление (непроверено, но в целом, как вы это сделаете):

    <select name = "state" id = "state-select"></select>
    <select name = "city" id = "city-select"></select>
    <select name = "jurisdiction" id = "jurisdiction-select"></select>


    <script type = "text/javascript">
        function _load_select_boxes(e) {
            if (
                $("#state-select").val() && $("#city-select").val() && $("jurisdiction-select").val() && // if we have an item selected in all select boxes
                typeof e !== 'undefined' && e.target.id == 'jurisdiction-select' // if the select box that triggered the event is the last one
            ) {
                _select_box_completed('jurisdiction', $("jurisdiction-select").val());
            }

            $.ajax({
                url: '/where/you/load/select/boxes',
                type: 'POST',
                data: $("#state-select, #city-select, #jurisdiction-select").serialize(),
                dataType: 'json', // what server will return
                success: function (data) {
                    if (data.result === 'ok') {
                        if (typeof data.states !== 'undefined') {
                            // no need to reset options for the first select (unless we will be re-loading it without selecting a value)

                            // set select box options using the array of cities
                            for(var stateId in data.states) {
                                var stateName = data.states[stateId];
                                $("#city-select").append('<option value = "' + stateId + '">' + stateName + '</option>')
                            }
                        } else if (typeof data.cities !== 'undefined') {
                            // reset select box
                            $('#city-select').find('option').remove();

                            // set select box options using the array of cities
                            for(var cityId in data.cities) {
                                var cityName = data.cities[cityId];
                                $("#city-select").append('<option value = "' + cityId + '">' + cityName + '</option>')
                            }
                        } else if (typeof data.jurisdictions !== 'undefined') {
                            if (!data.jurisdictions.length) {
                                // no jurisdictions returned so we reached end
                                _select_box_completed('city', $("#city-select").val());
                            } else {
                                // reset select box
                                $('#jurisdiction-select').find('option').remove();

                                // set select box options using the array of jurisdictions
                                for(var jurisdictionId in data.jurisdictions) {
                                    var jurisdictionName = data.jurisdictions[jurisdictionId];
                                    $("#jurisdiction-select").append('<option value = "' + jurisdictionId + '">' + jurisdictionName + '</option>')
                                }
                            }
                        }
                    } else {
                        // handle error for app
                    }
                },
                error: function (jqXHR, textStatus, errorThrown) {
                    // handle error for app
                }
            });
        }

        function _select_box_completed(type, id) {
            // fired when we have selected as far as we can go
        }

        $(function(){
            // this runs when page finishes loading, so we can load in the defaults and set events on the select boxes
            $("#state-select, #city-select, #jurisdiction-select").on('change', function(e){
                _load_select_boxes(e);
            });

            _load_select_boxes();
        });
    </script>

Спасибо, это поможет мне двигаться вперед. Я ценю помощь.

CLHardman 11.09.2018 01:29

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