[英]Javascript not reading the keys and values of a dictionary in django template
[英]Set dynamic values from a dictionary for select values inside a Django template using Javascript or other method
我有三個連續的 select 選項,它們的值根據前面的 select 而變化。目的是使用這些 select 選項對產品進行分類。 第一個選項是根據產品的usage
或model
值對產品進行分類。 如果選擇usage
作為第一個select
選項,則顯示填充有usage
列表的第二個select
,該列表是Usage
model 的所有對象,如果選擇model
,則填充 MainModel 885736168 的所有對象的MainModel
是顯示,另一個select
標簽被visually-hidden
class 隱藏。
至此,我的代碼如下:
意見.py:
def get_common_queryset():
usage_queryset = Usage.objects.all()
main_model_queryset = MainModel.objects.all()
sub_usage_queryset = SubUsage.objects.all()
pump_type_queryset = PumpType.objects.all()
queryset_dictionary = {
"usage_queryset": usage_queryset,
"main_model_queryset": main_model_queryset,
"sub_usage_queryset": sub_usage_queryset,
"pump_type_queryset": pump_type_queryset,
}
return queryset_dictionary
def solution_main(request):
context = get_common_queryset()
return render(request, "solutions/solution_main.html", context)
我的模板:
<div class="col-md-3 mx-md-5">
<h2 class="h5 nm-text-color fw-bold mb-4">Choose usage or model:</h2>
<select required aria-label="Select usage or model"
id="usage_model_select" class="form-select" onchange="set_usage_or_model_dic()">
<option>----</option>
<option value="usage">Usage</option>
<option value="model">Model</option>
</select>
</div>
{# usage or model select div #}
<div class="col-md-3 mx-md-5">
{# usage select div #}
<div class="usage visually-hidden" id="usage_div">
<h2 class="h5 nm-text-color fw-bold mb-4">Select usage:</h2>
<select required aria-label="Select usage" class="form-select"
name="usage_select" onchange="set_sub_usage_list()" id="usage_select_id">
<option selected>----</option>
{% for usage in usage_queryset %}
<option value="{{ usage.id }}">{{ usage.usage_name_fa }}</option>
{% endfor %}
</select>
</div>
{# model select div #}
<div class="model visually-hidden" id="model_div">
<h2 class="h5 nm-text-color fw-bold mb-4">Select model:</h2>
<select required aria-label="Select model" class="form-select"
name="model_select" onchange="set_pump_type_list()" id="model_select_id">
<option selected>----</option>
{% for model in main_model_queryset %}
<option value="{{ model.id }}">{{ model.model_name_fa }}</option>
{% endfor %}
</select>
</div>
</div>
{# select sub_usage or pump_type div #}
<div class="col-md-3 mx-md-5">
{# sub_usage select div #}
<div class="sub_usage visually-hidden" id="sub_usage_div">
<h2 class="h5 nm-text-color fw-bold mb-4">Select sub-usage:</h2>
<select required aria-label="Select sub_usage" class="form-select" name="sub_usage_select">
<option selected>All sub-usages from this usage</option>
{% for sub_usage in sub_usage_queryset %}
<option value="{{ sub_usage.id }}">{{ sub_usage.sub_usage_name_fa }}</option>
{% endfor %}
</select>
</div>
{# model select div #}
<div class="pump-type visually-hidden" id="pump_type_div">
<h2 class="h5 nm-text-color fw-bold mb-4">Select pump type:</h2>
<select aria-label="Select pump_type" class="form-select" name="pump_type_select">
<option selected>All pump types of this model</option>
{% for pump_type in pump_type_queryset %}
<option value="{{ pump_type.id }}">{{ pump_type.type_name }}</option>
{% endfor %}
</select>
</div>
</div>
<div>
<input type="submit" value="Next" id="submit" class="btn btn-primary">
</div>
(我使用 JS 來顯示/隱藏特定的 div,刪除/添加visually-hidden
類)
但是,我不想使用sub_usage_queryset = SubUsage.obects.all()
,我想看看在前一階段選擇了哪個usage
(或model
)並根據這個選擇填充下一個select
。
我想到的解決方案是,由於usage
s 和main_model
s 很少,我可以為每個創建一個字典,其中包含不同的usage
s 或main_model
s 作為鍵,並將它們的sub_usage
s 或pump_type
s 作為它們的值的列表. 作為usage
示例:
sub_usage_list = {}
for usage in Usage.objects.all():
usage_sub_usage_list = SubUsage.objects.filter(usage=usage)
sub_usage_list[usage] = usage_sub_usage_list
因此sub_usage_list
將包含每個usage
作為鍵,並且該usage
的sub_usage
s 作為該鍵值的列表。
我不知道這種方法是否正確,即使正確,我也不知道如何根據相關select
選項中的選定值使用該詞典中的特定 sub_usage 列表。 我對 JS 不是很熟悉,所以非常感謝您的幫助和提示。
注意:如您所見,我正在使用服務器端渲染,所以我不知道如何在不刷新頁面的情況下執行此操作。
要在不刷新頁面的情況下實現您想要的效果,有必要使用 AJAX。
從您的模板開始。 由於您將根據選擇動態填充,因此沒有必要為每個 QuerySet 設置一個框。 您可以使用 JS 清除並重新填充它們。
模板.html:
<body>
<div class="col-md-3 mx-md-5">
<h2 class="h5 nm-text-color fw-bold mb-4">Choose usage or model:</h2>
<select required aria-label="Select usage or model"
id="usage_model_select" class="form-select" onchange="populate_lists()">
<option value="" selected>----</option>
<option value="usage">Usage</option>
<option value="model">Model</option>
</select>
</div>
{# usage or model select div #}
<div class="col-md-3 mx-md-5">
{# usage select div #}
<div class="usage visually-hidden" id="usage_div">
<h2 class="h5 nm-text-color fw-bold mb-4">Select options:</h2>
<select required aria-label="Select usage" class="form-select"
name="usage_select" onchange="populate_lists()" id="select_options">
<option value="" selected>----</option>
</select>
</div>
</div>
{# select sub_usage or pump_type div #}
<div class="col-md-3 mx-md-5">
{# sub_usage select div #}
<div class="sub_usage visually-hidden" id="sub_usage_div">
<h2 class="h5 nm-text-color fw-bold mb-4">Sub selection:</h2>
<select required aria-label="Select sub_usage" class="form-select" id="sub_usage_select" name="sub_usage_select">
<option selected>All sub-selections</option>
</select>
</div>
</div>
<div>
<input type="submit" value="Next" id="submit" class="btn btn-primary">
</div>
</body>
templates.html <script>
: ( CSRF with AJAX | Get Select element | Populate Select element | Clear Select element )
<script>
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
// Clear SelectionBoxes
function removeOptions(selectElement, initial) {
var i, L = selectElement.options.length - 1;
for(i = L; i >= 0; i--) {
selectElement.remove(i);
}
var opt = document.createElement('option');
opt.value = "";
opt.innerHTML = initial;
selectElement.appendChild(opt);
}
function populate_lists() {
const url = '/solution/ajax/';
const csrftoken = getCookie('csrftoken');
var e = document.getElementById("usage_model_select");
var selectedOption = e.value;
if (selectedOption == "" ) {
removeOptions(document.getElementById("select_options"), "----");
removeOptions(document.getElementById("sub_usage_select"), "All sub-usages from this usage");
return
}
var e = document.getElementById("select_options");
var option = e.value;
if (option == "" ) {
option = null
}
// Send AJAX Request
fetch(url, {
method: 'POST',
headers: {
'X-CSRFToken': csrftoken,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"select": selectedOption,
"option": option,
}),
})
.then((response) => response.json())
.then((data) => {
var select = document.getElementById("select_options");
removeOptions(select, "----");
var selected_usage_name = null
for (var i = 0; i<=data.select.length-1; i++){
var opt = document.createElement('option');
opt.value = data.select[i]['id'];
opt.innerHTML = data.select[i]['name'];
if (data.select[i]['id'] == data.selected_option) {
selected_usage_name = data.select[i]['name'];
opt.selected = true
}
select.appendChild(opt);
}
if (data.sub_select != null) {
var select = document.getElementById("sub_usage_select");
removeOptions(select, `All sub-usages from ${selectedOption} ${selected_usage_name}`);
for (var i = 0; i<=data.sub_select.length-1; i++){
var opt = document.createElement('option');
opt.value = data.sub_select[i]['id'];
opt.innerHTML = data.sub_select[i]['name'];
select.appendChild(opt);
}
console.log(data.sub_select)
}
})
.catch((error) => {
console.error('Error:', error);
});
}
</script>
意見.py:
def solution_ajax(request):
data = json.loads(request.body)
sub_select = None
if data['select'] == 'usage':
select = list(Usage.objects.all().values())
if data['option'] is not None:
sub_select = list(SubUsage.objects.filter(usage__id=data['option']).values())
elif data['select'] == 'model':
select = list(MainModel.objects.all().values())
if data['option'] is not None:
sub_select = list(PumpType.objects.filter(model__id=data['option']).values())
return JsonResponse({
'select': select,
'selected_option': data['option'],
'sub_select': sub_select,
})
def solution_main(request):
return render(request, "solutions/solution_main.html")
請注意,我做了一些額外的功能,例如清除選擇選項,但不是針對所有事件。
聖誕快樂。
django中有使用django-select2的方法。 請參閱這篇文章的解決方案: How to populate a select list in a Django Template dynamically using Javascript?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.