The task is to make two select for the search panel; When choosing a device and sending the form, it turns out that the second one does not match the selected value. In the browser, the following is obtained:

<div class="search-panel" style="font-size: 24px;" > <form id="search-box" method="Post" action="/phone/get_table"> <div class="search-box"> Выберете устройство : <select id="select1" name="model"> <option id="opt" value="1" onClick="showhide(1)">Apple</option> <option id="opt" value="3" onClick="showhide(3)">Nokia</option> <option id="opt" value="4" onClick="showhide(4)">HTC</option> <option id="opt" value="8" onClick="showhide(8)">Alcatel</option> <option id="opt" value="10" onClick="showhide(10)">LG</option> <option id="opt" value="11" onClick="showhide(11)">Meizu</option> <option id="opt" value="13" onClick="showhide(13)">Philips</option> <option id="opt" value="16" onClick="showhide(16)">ZTE</option> </select> <div id="1" style="display: none;" > <select name="device"> <option value="1">iPhone 6</option> <option value="3">iPhone 5s</option> <option value="7">iPhone 6s</option> <option value="10">IPhone 4</option> <option value="12">IPhone 6 plus</option> </select> </div> <div id="3" style="display: none;" > <select name="device"> <option value="0">[--все--]</option> </select> </div> <div id="4" style="display: none;" > <select name="device"> <option value="4">HTC One M8</option> <option value="13">Другие</option> </select> </div> <!--.....--> <div id="8" style="display: none;" > <select name="device"> <option value="0">[--все--]</option> </select> </div> <input type="hidden" name="brand" value ="1"> <button class="btn" href="#">Найти</button> </div> </form> </div> <!--javascript--> <script type="application/javascript"> var divState = {}; function showhide(id) { if (document.getElementById) { var divid = document.getElementById(id); divState[id] = (divState[id]) ? false : true; //close others for (var div in divState){ if (divState[div] && div != id){ document.getElementById(div).style.display = 'none'; divState[div] = false; } } divid.style.display = (divid.style.display == 'inline-block' ? 'none' : 'inline-block'); } } </script> 

on php it looks like this:

 <div class="search-panel" style="font-size: 24px;" > <form id="search-box" method="Post" action="/{{$url}}/get_table"> <div class="search-box"> Выберете устройство : <select id="select1" name="model"> @foreach($model as $dev) <option id="opt" value="{{ $dev->id }}" onClick="showhide({{ $dev->id }})">{{ $dev->title }}</option> @endforeach </select> @foreach($model as $dev) <?php $devicemodel =\App\DeviceModel::checkDM($brand->id,$dev->id);?> <div id="{{$dev->id}}" style="display: none;" > @if($devicemodel) <select name="device"> @foreach($devicemodel as $dev) @if($dev) <?php $name =\App\DeviceModel::returnName($dev->device_id)?> <option value="{{$dev->device_id}}">{{$name->title}}</option> @endif @endforeach </select> @else <select name="device"> <option value="0">[--все--]</option> </select> @endif </div> @endforeach <input type="hidden" name="brand" value ="{{ $brand->id }}"> <input type="hidden" name="_token" value="{{ csrf_token() }}"> <button class="btn" href="#">Найти</button> </div> </form> </div> 

Perhaps the fact is that the select heap named device and you output what we need by changing the display: none property, but if I change the name to for example device _ {{$ dev-> device_id}} how do I get this in POST? Thank you in advance .

    1 answer 1

    Excuse me, but your code is no good.

    First, let's take a look at how you handle the select event in the first model. in this case, onclick is not only inconvenient to use (for each option, you need to add the corresponding function call in the onclick attribute) and ugly, but absolutely wrong! After all, the choice is made not only by clicking the mouse. I, for example, on duty, respect the keyboard more and prefer to navigate through the forms using TAB and select the selection in the selection, often with arrows, followed by pressing enter. Your form will not understand me and will not show the second field.

    Much more correctly, from all sides, is to use the change event that fires on the select element at the moment of selection. No descendants of attributes, just one event listener in js code.

    Further: as you rightly noted, the thing is that you have in the form of a bunch of elements with the same name . When sending a form, the browser, roughly speaking, collects an array, where it adds under the keys - name - field values. If there are several fields with the same name , each next one will overwrite the value of the previous one (new values ​​are added to the array under the same key over and over again) and as a result only the last value will remain.

    No need to create a bunch of selektov with the same name You need to create only one and in it, when choosing the first select, regenerate the option list. Or, nevertheless, you can create a bunch of ready-made selects, but with an empty name and add it to the desired select along with its display, removing the name from everyone else. But nevertheless, the first option is closer to me. It is cleaner and more transparent, in my opinion.

    Now I invite you to familiarize yourself with the simplified code, in which I will try to demonstrate to you how to accomplish your task:

     //в js на загрузке страницы создадим объект, в котором под id производителя разложим списки устройств var devicesByModel = { //здесь "1" - id производителя, в данном случае - "Apple" 1: { //здесь "1" - будущее value для option, "iPhone 6" - его текст 1: "iPhone 6", 3: "iPhone 5s", 7: "iPhone 6s", 10: "IPhone 4" }, 3: { 1: "3310", 2: "8110", 3: "8310", 4: "6310" }, 4: { 1: "ONE M7", 2: "ONE M8", 3: "ONE M9", 4: "TWO" } }; //выбираем селект по его id и вешаем слушателя события change document.getElementById('modelSelect').addEventListener('change', function(){ var value = this.value, devicesList = devicesByModel[value], deviceSelect = document.getElementById('deviceSelect'); //если в нашем массиве есть девайсы по выбранному производителю if(devicesList){ var options = ""; //идем по списку девайсов и на каждом создаем очередной option с соответствующими значениями for(var deviceId in devicesList){ options += '<option value="'+deviceId+'">'+devicesList[deviceId]+'</option>'; } //заменяем список option внутри device-select'а на только что сгенереный deviceSelect.innerHTML = options; deviceSelect.style.display = 'block'; } else { //эта часть нужна только в случае, если у model-selecta можно снять выбор deviceSelect.style.display = 'none'; } }); 
     <select id="modelSelect" name="model"> <option id="opt" value="">Выберите производителя...</option> <option id="opt" value="1">Apple</option> <option id="opt" value="3">Nokia</option> <option id="opt" value="4">HTC</option> </select> <select id="deviceSelect" name="device" style="display:none"> <!--пока пусто. сгенерируем список options после выбора в селекте name=model--> </select> 

    • Thanks, got it. I haven't really dealt with js. I'll try to figure it out. - Konstantin Maslov
    • @KonstantinMaslov if the answer helped you and is correct - confirm this by pressing the button to the left of the answer. Also, you can express gratitude to the author by putting the answer +1. - Ivan Pshenitsyn