Название немного многовато, поэтому позвольте мне разобрать его. То, что я пытаюсь выполнить здесь, - это выбрать вариант из выбора 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 или и то, и другое?
Есть ли у вас какие-нибудь мысли, как это лучше сделать?
Я бы использовал запросы Ajax вместо использования функции jQuery load. Таким образом, вы можете либо получить следующие параметры поля выбора, либо получить результат, в котором указано, что вы достигли конца, и обработать это в JS (Ajax может обрабатывать ответы JSON вместо простого HTML, что позволяет вам более эффективно передавать состояния и информацию для таких вещей) . Обновлено: я построил ту же самую установку, но более сложную около месяца назад.
@Michel, это совершенно верно. Когда запускается #bpClass, у auto.php не будет ссылок на базу данных с этим идентификатором. Так мы узнаем, что #bpFaction нет, есть только #bpID.
@ Skylord123 Я знаю об Ajax гораздо меньше, чем следовало бы. Могу я попросить вас привести пример кода для справки?
Ба, время редактирования истекло. Возможно, такая установка, как $('#bpCollection, #bpClass, #bpFaction').change(function() { , для просмотра всех выбранных параметров и выполнения моих вызовов auto.php путем захвата document.getElementById("#bpWhatever").value; в одной единственной функции?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Самый простой способ сделать это, не меняя большого количества кода, - сделать ваш переключатель функцией, создать условие и вызвать его снова с измененными параметрами, если это условие выполнено.
$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?
Я рекомендовал использовать 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>
Спасибо, это поможет мне двигаться вперед. Я ценю помощь.
Как определить, что вариант 3 вам не нужен? Это когда у вас нет результатов из БД или только один?