内部に多数のオプションを含むHTMLフォームがあり、以前のユーザーの選択に基づいてこれらのオプション内の値を変更したいと思います。次のようなものがあるとします。
<select name="fruit">
<option value="Apple">Apple</option>
<option value="banana">Banana</option>
<option value="Peach">Peach</option>
</select>
ユーザーがそこで選択したものに基づいて、別の値を表示する別のドロップダウンリストを表示します。ユーザーが最初のドロップダウンリストで「Apple」を選択した場合、次のようになります。
<select name="price">
<option value="3">Apple 1kg 3€</option>
<option value="5">Apple 2kg 5€</option>
<option value="7">Apple 3kg 7€</option>
</select>
「バナナ」を選択すると、次のようになります。
<select name="price">
<option value="4">Banana 1kg 4€</option>
<option value="7">Banana 2kg 7€</option>
<option value="10">Banana 3kg 10€</option>
</select>
バナナはリンゴなどと価格が異なるため、最初のドロップダウンリストに基づいて値とテキストを変更する必要があります。私はそれについていくつかのスレッドを読みましたが、これを実現するために必要なことを本当に理解することができませんでした。これまで読んだこととここから読むことができることから、私はajaxに触れたことはありません: 別のドロップダウンリストの値に基づいてドロップリストの値を変更する 私はそれについていくつかの基本的なものが必要です。 JavaScriptを使用してそれを行うことは可能ですか?
これを実現するには、オブジェクトを使用して値とそれに関連付けられたドロップダウンの説明を保持します。これを行うには、最初にeventListener
をドロップダウンに追加して、新しい果物を選んだときに変更が検出されるようにする必要があります。このイベントリスナーを使用すると、_this.value
_を使用して選択されたオプションの値を取得できます。
選択したオプションのvalue
を使用すると、prices
というオブジェクトから関連するドロップダウン値を取得できます(これにより配列が返されます)。この配列を取得したら、ループして、.reduce()
を使用してHTMLの文字列を「構築」し、price
選択タグのオプションとして配置できます。この文字列を作成したら、_.innerHTML
_を使用してselectタグ内に追加し、HTML文字列をDOMオブジェクト(単なるテキストではなく実際の要素)に「変換」します。
_let prices = {"Apple":[{value:3,desc:"Apple 1kg 3€"},{value:5,desc:"Apple 2kg 5€"},{value:7,desc:"Apple 3kg 7€"}],
"banana":[{value:3,desc:"Banana 2kg 3.5€"},{value:5,desc:"Banana 4kg 7€"},{value:7,desc:"Banana 5kg 11€"}],
"Peach":[{value:3,desc:"Peach 1.5kg 3€"},{value:5,desc:"Peach 3kg 6€"},{value:7,desc:"Peach 4kg 7€"}]}
document.getElementsByName('fruit')[0].addEventListener('change', function(e) {
document.getElementsByName('price')[0].innerHTML = prices[this.value].reduce((acc, elem) => `${acc}<option value="${elem.value}">${elem.desc}</option>`, "");
});
_
_<select name="fruit">
<option value="Apple">Apple</option>
<option value="banana">Banana</option>
<option value="Peach">Peach</option>
</select>
<br />
<select name="price">
<option value="3">Apple 1kg 3€</option>
<option value="5">Apple 2kg 5€</option>
<option value="7">Apple 3kg 7€</option>
</select>
_
.reduce()
を使いたくない場合は、代わりに通常のforループを使用できます。
_document.getElementsByName('fruit')[0].addEventListener('change', function(e) {
let options = "";
for(obj of prices[this.value]) {
options += '<option value="' +obj.value +'">' +obj.desc +'</option>';
}
document.getElementsByName('price')[0].innerHTML = options;
});
_
これは、JQueryで要素の作成とonchangeイベントを使用する添付ソリューションです
// First we initialize a variable with the fruits and their prices per kg
fruitPrices = {'Apple':[3, 5, 6], 'banana':[4, 7, 10]}
// Listen to changes in selected fruit
$('#fruit-selector').on('change', function(element) {
// Clearing the price selector and getting the selected fruit
$('#price-selector').empty()
chosenFruit = this.value;
// For each price in the fruitPrices for this fruit
for (fruitIndex in fruitPrices[chosenFruit]) {
// Get the price and create an option element for it
price = fruitPrices[chosenFruit][fruitIndex];
price_option = '<option>{0} {1}kg {2}$<option>'.replace('{0}', chosenFruit).replace('{1}', fruitIndex + 1).replace('{2}', price);
// Add the option to the price selector
$('#price-selector').append(price_option)
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id='fruit-selector' name="fruit">
<option value="Apple">Apple</option>
<option value="banana">Banana</option>
<option value="Peach">Peach</option>
</select>
<select id='price-selector' name="price">
</select>
console.clear();
(function() {
var fruitsField = document.querySelector('[name=fruits]')
var amountField = document.querySelector('[name=amount]')
var json = {};
onReady(loadJson);
fruitsField.addEventListener('change', populateAmount)
function onReady(callback) {
if (
document.readyState === "complete" ||
(document.readyState !== "loading" && !document.documentElement.doScroll)
) {
callback();
} else {
document.addEventListener("DOMContentLoaded", callback);
}
}
function getSelectedFruit() {
return fruitsField.value;
}
function populateFruits() {
clearOptions(fruitsField)
fruits = json.fruits
for (var i in fruits) {
addOption(fruitsField, i, fruits[i])
}
}
function populateAmount() {
clearOptions(amountField)
var fruit = getSelectedFruit()
fruits = json.fruits
prices = json.prices[fruit]
for (var i in prices) {
addOption(amountField, i, fruits[fruit] + " " + i + "kg " + prices[i] + "€")
}
}
// Load a json resource and start the fruit process
function loadJson() {
fetch('//api.jsonbin.io/b/5bf5645b746e9b593ec0e8b5')
.then(function(response) {
return response.json()
})
.then(function(response) {
json = response
populateFruits()
})
.catch(function(err) {
console.error(err);
})
}
// function loadJson() {
// var j = '{"fruits":{"Apple":"Apples","banana":"Bananas","Peach":"Peaches"},"prices":{"Apple":{"1":3,"2":5,"3":7},"banana":{"1":4,"2":7,"3":10},"Peach":{"1":5,"2":9,"3":13}}}'
// json = JSON.parse(j)
// populateFruits()
// }
function addOption(select, value, text) {
var option = document.createElement('option')
option.setAttribute('value', value)
option.textContent = text
select.appendChild(option)
}
function clearOptions(select) {
var children = select.children
var childrenToRemove = [];
for (var i = 1; i < children.length; i++) {
childrenToRemove.Push(children[i])
}
for (var i = 0; i < childrenToRemove.length; i++) {
select.removeChild(childrenToRemove[i])
}
}
}())
<form>
<select name="fruits" size="4">
<option value="0">Select Fruit</option>
</select>
<select name="amount" size="4">
<option value="0" >Select Amount</option>
</select>
</form>