HTML/JS/Django Hiding incompatible options from two picklists - javascript

I'm running a filter for my object on a django-run website.
I have two select fields, with dropdowns based on related models to my model that i'd like to sort.
The problem is that some options are incompatible with each another and i'd like to hide the options of the second picklist based on what the user has selected on the first one.
I feel like i am going to use some JS but i've never used it before.
1st picklist: tasks <option value = task_id>
2nd picklist: crafts <option value = craft_id>
I have prepared a dictionnary that holds all the compatible values of any option selected on the first picklist, if that can help !
useful_dictionnary = {
first_task_id = [list_of_compatible_craft_ids]
...
last_task_id = [list_of_compatible_craft_ids]
}
How can i get JS to look at the task_id selected on the first picklist, and hide the options from the second picklist that are not in this list ?
Would be great! Thanks !
Here is my picklists code, if that helps
<div class="form-group col-sm-4 col-md-3">
<label for="id_tasks">Tasks:</label>
<select class="form-control" id="id_tasks" name="task">
<option value="">---------</option>
<option value="1" selected="selected">Tie-job: Front-tie Marker</option>
<option value="2">Tie-job: Scrapmachine support trackman</option>
<option value="3">Tie-job: Plate Thrower</option>
<option value="4">Tie-job: New-tie Marker</option>
</select>
</div>
<div class="form-group col-sm-4 col-md-3">
<label for="id_craft">Craft:</label>
<select class="form-control" id="id_craft" name="craft">
<option value="" selected="selected">---------</option>
<option value="1">Senior Engineer</option>
<option value="2">Roadmaster</option>
<option value="3">Foreman</option>
<option value="4">Assistant Foreman</option>
<option value="5">Electrical Welder EA</option>
<option value="6">Oxygen Welder OA</option>
<option value="7">Railway Machine Operator (RMO)</option>
<option value="8">Truck Driver (Type A, B or C)</option>
</select>
</div>

This snippet should do the trick. Change compatibleIds to map the options for the second select based on the first one.
$(document).ready(function(){
$("#id_craft option:not([value=0])").hide();
});
$("#id_tasks").change(function(){
$("#id_craft").val("0");
$("#id_craft option:not([value=0])").hide();
var compIds = { 1: [ 1,2,3,4,5], 3 : [ 4,2,3,8,7], 4 : [ 7,9,1,5], 2 :[5,3,1,8]};
for(var i = 0; i < compIds[$("#id_tasks").val()].length; i++){
$("#id_craft option[value=" + compIds[$("#id_tasks").val()][i] + "]").show();
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="form-group col-sm-4 col-md-3">
<label for="id_tasks">Tasks:</label>
<select class="form-control" id="id_tasks" name="task">
<option value="0" selected="selected">---------</option>
<option value="1">Tie-job: Front-tie Marker</option>
<option value="2">Tie-job: Scrapmachine support trackman</option>
<option value="3">Tie-job: Plate Thrower</option>
<option value="4">Tie-job: New-tie Marker</option>
</select>
</div>
<div class="form-group col-sm-4 col-md-3">
<label for="id_craft">Craft:</label>
<select class="form-control" id="id_craft" name="craft">
<option value="0" selected="selected">---------</option>
<option value="1">Senior Engineer</option>
<option value="2">Roadmaster</option>
<option value="3">Foreman</option>
<option value="4">Assistant Foreman</option>
<option value="5">Electrical Welder EA</option>
<option value="6">Oxygen Welder OA</option>
<option value="7">Railway Machine Operator (RMO)</option>
<option value="8">Truck Driver (Type A, B or C)</option>
</select>
</div>
Small add-on as the original question was about a django dictionary object:
To use a django list or dictionnary in the javascript, it is pretty straightforward as the {{ django_variable }} works fine inside the script tags.
So the final JS for this django template page is:
$(document).ready(function(){
$("#id_craft option:not([value=0])").hide();
});
$("#id_tasks").change(function(){
$("#id_craft").val("0");
$("#id_craft option:not([value=0])").hide();
var compatibleIds = {{ my_python_dictionary }};
for(var i = 0; i < compatibleIds[$("#id_tasks").val()].length; i++){
$("#id_craft option[value=" + compatibleIds[$("#id_tasks").val()][i] + "]").show();
}
});

Related

How to get option tag custom data value using pure JS?

function calculateDeliveryCharge()
{
var CA=document.getElementById("pickup");
var c=CA.options[CA.selectedIndex].getAttribute('data-area');
alert(c);
}
<div class="container">
<div class="row">
<div class="col-12">
<select id="pickup" placeholder="পিকআপ এলাকা নির্বাচন করুন">
<option value="">পিকআপ এলাকা.....</option>
<option value="300 Feet"data-area="1">৩০০ ফিট (300 Feet)</option>
<option value="Adabor" data-area="1">আদাবর(Adabor)</option>
<option value="Adarsha Nagar(Badda)"data-area="1">আদর্শ নগর(বাড্ডা)- Adarsha Nagar(Badda)</option>
<option value="Aftab Nagar"data-area="1">আফতাব নগর(Aftab Nagar)</option>
<option value="Aga Nagar"data-area="1">আগা নগর(Aga Nagar)</option>
<option value="Agargaon"data-area="1">আগারগাঁও(Agargaon)</option>
<option value="Ahalia-Uttara"data-area="1">আহালিয়া-উত্তরা(Ahalia-Uttara)</option>
<option value="Ahmed Nagar"data-area="1">আহমেদ নগর(Ahmed Nagar)</option>
<option value="Ainusbag"data-area="1">আইনুসবাগ(Ainusbag)</option>
<option value="Ainusbag-Dakshinkhan"data-area="1">আইনুসবাগ-দক্ষিণখান(Ainusbag-Dakshinkhan)</option>
<option value="Ajiz Market"data-area="1">আজিজ মার্কেট(Ajiz Market)</option>
<option value="Alatunnessa School Road"data-area="1">আলাতুন্নেছা স্কুল রোড(Alatunnessa School Road)</option>
<option value="Alubazar"data-area="1">আলুবাজার(Alubazar)</option>
<option value="Amin bazar"data-area="1">আমিন বাজার(Amin bazar)</option>
<option value="Apollo"data-area="1">অ্যাপোলো(Apollo)</option>
</select>
</div>
</div>
<button class="border-1 p-2 bg-danger text-white"onclick="calculateDeliveryCharge()">ডেলিভারি চার্জ দেখুন</button>
</div>
I want to get the custom data attribute "data-area" value, 1 expected is here but I am getting null every time. What is the problem in my code and what is the solution?
This is a bit easier.
document.querySelector('#pickup option:checked').dataset.area
If we use #pickup, we selecting by ID as you have above. But by also specifying option:checked, we're looking for the currently selected option. (:checked is a bit weird here, but it's consistent with how other input elements work, such as checkboes.) Next, if you want the area data option, we can access it on the dataset property directly.
If nothing is selected, or the option does not contain the data-area property, your result will be not as expected.
It is generally not a good idea to use inline event handlers.
Here's a snippet using event delegation.
// => onclick="calculateDeliveryCharge()" becomes
document.addEventListener(`click`, handle);
function handle(evt) {
if (evt.target.nodeName === `BUTTON`) {
const selectr = document.querySelector("#pickup option:checked");
// find the selected option using a css selector ^^^
// this statement returns the option element when something
// is selected, null if nothing is selected
console.clear();
if (selectr &&
selectr.dataset.area) {
// ^ a data attribute value can be found using the elements' "dataset"
return console.log(`Area: ${selectr.dataset.area}`);
}
console.log(`No area or nothing selected yet`);
}
}
<div class="row">
<div class="col-12">
<select id="pickup" placeholder="পিকআপ এলাকা নির্বাচন করুন">
<option value="">পিকআপ এলাকা.....</option>
<option value="300 Feet" data-area="1">৩০০ ফিট (300 Feet)</option>
<option value="Adabor" data-area="1">আদাবর(Adabor)</option>
<option value="Adarsha Nagar(Badda)" data-area="1">আদর্শ নগর(বাড্ডা)- Adarsha Nagar(Badda)</option>
<option value="Aftab Nagar" data-area="1">আফতাব নগর(Aftab Nagar)</option>
<option value="Aga Nagar" data-area="1">আগা নগর(Aga Nagar)</option>
<option value="Agargaon" data-area="1">আগারগাঁও(Agargaon)</option>
<option value="Ahalia-Uttara" data-area="1">আহালিয়া-উত্তরা(Ahalia-Uttara)</option>
<option value="Ahmed Nagar" data-area="1">আহমেদ নগর(Ahmed Nagar)</option>
<option value="Ainusbag" data-area="1">আইনুসবাগ(Ainusbag)</option>
<option value="Ainusbag-Dakshinkhan" data-area="1">আইনুসবাগ-দক্ষিণখান(Ainusbag-Dakshinkhan)</option>
<option value="Ajiz Market" data-area="1">আজিজ মার্কেট(Ajiz Market)</option>
<option value="Alatunnessa School Road" data-area="1">আলাতুন্নেছা স্কুল রোড(Alatunnessa School Road)</option>
<option value="Alubazar" data-area="1">আলুবাজার(Alubazar)</option>
<option value="Amin bazar" data-area="1">আমিন বাজার(Amin bazar)</option>
<option value="Apollo" data-area="1">অ্যাপোলো(Apollo)</option>
</select>
</div>
</div>
<button class="border-1 p-2 bg-danger text-white">ডেলিভারি চার্জ দেখুন</button>
</div>

HTML Form Select Dropdown Options and Hidden Form Fields Not showing in PHP Form using JS Script

Recently i set up a script in JS with help from Stack to show a Form Row labled "other" when i select an option called "Other" from a dropdown option above. Example is below. This works well for one dropdown. But as soon as I add another dropdown Menu and "other" form row the JS code breaks and neither the 1st or 2nd Form Dropdown Options get posted to the Database and the form row "other" does not show. I hope i have explained the issue correctly. I essentially want one JS script to repeat for all dropdown forms so when "other" option value is selected i want the form row "other" to display below so custom data can be typed in. Using Bootstrap 4.3.1 with all JS querir plugins working. The datbase is connected with no issues posting data when its just a text field. So i was hoping someone might have work around and i will have a lot of dropdowns with the "Other" form row posting different form data in to the database. Many thanks.
<script>
function handleSelect() {
document.getElementById("other").value = document.getElementById("mySelect").value;
var selected = document.getElementById("mySelect").value;
var details = document.getElementById("other-details");
if (selected === "") {
details.classList.remove("d-none");
details.classList.add("d-block");
} else {
details.classList.remove("d-block");
details.classList.add("d-none");
}
}
</script>
<div class="form-row">
<div class="form-group col-md-6 offset-md-3 mx-auto">
<label class="control-label custom_label col-xs-12">Cemetery</label>
<select name="cemetery" class="form-control" id="mySelect" onchange="handleSelect();">
<option value="select" selected="selected">Select Cemetery</option>
<option value="Akatarawa">Akatarawa</option>
<option value="Taita">Taita</option>
<option value="Wainuiomata">Wainuiomata</option>
<option value="Whenua Tapu">Whenua Tapu</option>
<option value="Makara">Makara</option>
<option value="Karori">Karori</option>
<option value="St Johns">St Johns</option>
<option value="Awa Tapu">Awa Tapu</option>
<option value="Paraparaumu">Paraparaumu</option>
<option value="">Other</option>
</select>
</div>
</div>
<div class="form-row d-none" id="other-details">
<div class="form-group col-md-6 offset-md-3 mx-auto">
<input type="text" id="other" class="form-control" name="cemetery" />
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6 offset-md-3 mx-auto">
<label class="control-label custom_label col-xs-12">Headstone - Stone Color</label>
<select name="headstone_color" class="form-control" id="mySelect" onchange="handleSelect();">
<option value="headstone_color" selected="selected">Select Headstone - Stone Color</option>
<option value="Black">Black</option>
<option value="African Grey">African Grey</option>
<option value="Platinum Blue">Platinum Blue</option>
<option value="Blue Pearl">Blue Pearl</option>
<option value="Emerald Pearl">Emerald Pearl</option>
<option value="White Pearl">White Pearl</option>
<option value="Imperial Red">Imperial Red</option>
<option value="Balmoral Red">Balmoral Red</option>
<option value="G603-Chinese White/Grey">G603-Chinese White/Grey</option>
<option value="">Other</option>
</select>
</div>
</div>
<div class="form-row d-none" id="other-details">
<div class="form-group col-md-6 offset-md-3 mx-auto">
<input type="text" id="other" class="form-control" name="headstone_color" />
</div>
</div>
Please check the select id. both of the select has the same id as myselect. The id must be unique. So please make your code generic and use some unique ids.
Thanks
Something like this?
<script>
function handleSelect() {
document.getElementById("other1").value = document.getElementById("mySelect1").value;
var selected = document.getElementById("mySelect1").value;
var details = document.getElementById("other-details1");
document.getElementById("other2").value = document.getElementById("mySelect2").value;
var selected = document.getElementById("mySelect2").value;
var details = document.getElementById("other-details2");
if (selected === "") {
details.classList.remove("d-none");
details.classList.add("d-block");
} else {
details.classList.remove("d-block");
details.classList.add("d-none");
}
}
</script>
and so on ??

angularjs ng-repeat cascading Dropdown not updating

I have this issue using Angularjs
i am creating cascade drop down like below
<div class="col-sm-2 pr10">
<select class="PropertyType" ng-controller="LOV" ng-init="InitLov(140)" ng-model="PropertyType" ng-change="update(PropertyType)" >
<option value="" selected="selected" disabled="disabled"> {{type ? type: 'Property Type'}} </option>
<!-- <option value="">-- Select Type --</option>-->
<option ng-repeat="Lov in LovList" value="{{Lov.Value}}" >{{Lov['Lable'+Lang]}} </option>
</select>
</div>
<div class="col-sm-2 pr10">
<select class="PropertySubType" ng-controller="LOV" ng-model="PropertySubType" >
<option value="" selected="selected"disabled="disabled" >{{subType ? subType: 'Property Sub Type'}}</option>
<!-- <option value="">-- Select Sub Type --</option> -->
<option ng-repeat="Sub in SubType" value="{{Sub.Value}}" >{{Sub['Lable'+Lang]}} </option>
</select>
</div>
and the Angular file:
$scope.update = function (id) {
$http.post("API/WebsiteService.asmx/getSubPropertyLov", { type: id }).success(function (data) {
debugger;
var rr = eval('(' + data.d + ')');
$scope.SubType = rr.result;
});
}
the API returns data, and the SubType scope gets it, but it doesn't change the dropdown data (PropertySubType),
*the function is inside LOV controller.
Don't duplicated ng-controller="LOV" on each select, this way they both get different scopes. Put both selects in the scope of the same controller.
Also don't use ngRepeat, use ngOptions:
<div ng-controller="LOV">
<div class="col-sm-2 pr10">
<select class="PropertyType"
ng-init="InitLov(140)"
ng-model="PropertyType"
ng-change="update(PropertyType)"
ng-options="Lov.Value as Lov['Lable' + Lang] for Lov in LovList">
<option value="" selected="selected" disabled="disabled"> {{type || 'Property Type'}} </option>
</select>
</div>
<div class="col-sm-2 pr10">
<select class="PropertySubType"
ng-options="Sub.Value as Sub['Lable' + Lang] for Sub in SubType"
ng-model="PropertySubType">
<option value="" selected="selected" disabled="disabled">{{subType || 'Property Sub Type'}}</option>
</select>
</div>
</div>

JQuery Variables for Arithmetic being treated as strings [duplicate]

This question already has answers here:
How to ensure javascript addition instead of string concatenation (Not always adding integers)
(4 answers)
Closed 7 years ago.
I am trying to get the month that is 3 months from a selected month using a html select box and jquery in the below code. The code is not adding two variables together instead its treating them as two strings. Could anyone assist me to get this right?
<body>
<form role="form" class="form-inline">
<div class="form-group">
<label class="control-label" for="Q1Month">
Quarter 1 Month
</label>
<select class="form-control" id="Q1Month">
<option selected value=''>--Select Month--</option>
<option value='1'>January</option>
<option value='2'>February</option>
<option value='3'>March</option>
<option value='4'>April</option>
<option value='5'>May</option>
<option value='6'>June</option>
<option value='7'>July</option>
<option value='8'>August</option>
<option value='9'>September</option>
<option value='10'>October</option>
<option value='11'>November</option>
<option value='12'>December</option>
</select>
</div>
</form>
<script src="js/jquery.js"></script>
<script>
$(function() {
$('#Q1Month').change(function() {
var month = $(this).val();
$('#Q2Month').val(month);
var advanceby = 3;
var newmonth = month + advanceby;
window.alert(newmonth);
});
});
</script>
</body>
When any value is read from the DOM, it is string. To convert it to the Number you can use unary + operator.
Add + in front of the value
var month = +$(this).val();
+ is also the concatenation operator in Javascript, so when any one of the operand is string + is used for string concatenation.
$(function() {
$('#Q1Month').change(
function() {
var month = $(this).val();
$('#Q2Month').val(month);
var advanceby = 3;
var newmonth = month + advanceby;
window.alert(newmonth);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<form role="form" class="form-inline">
<div class="form-group">
<label class="control-label" for="Q1Month">
Quarter 1 Month
</label>
<select class="form-control" id="Q1Month">
<option selected value=''>--Select Month--</option>
<option value='1'>January</option>
<option value='2'>February</option>
<option value='3'>March</option>
<option value='4'>April</option>
<option value='5'>May</option>
<option value='6'>June</option>
<option value='7'>July</option>
<option value='8'>August</option>
<option value='9'>September</option>
<option value='10'>October</option>
<option value='11'>November</option>
<option value='12'>December</option>
</select>
</div>
</form>
Because the value that you have fetched is a string!
What You need is the option index and the actual value, so try accessing the current selected options index instead of value and then add 3 and reset your required element.
Hope I helped
val() always returns string, so use parseInt() to convert string to integer before adding
$(function() {
$('#Q1Month').change(
function() {
var month = parseInt($(this).val(),10);
$('#Q2Month').val(month);
var advanceby = 3;
var newmonth = month + advanceby;
window.alert(newmonth);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<form role="form" class="form-inline">
<div class="form-group">
<label class="control-label" for="Q1Month">
Quarter 1 Month
</label>
<select class="form-control" id="Q1Month">
<option selected value=''>--Select Month--</option>
<option value='1'>January</option>
<option value='2'>February</option>
<option value='3'>March</option>
<option value='4'>April</option>
<option value='5'>May</option>
<option value='6'>June</option>
<option value='7'>July</option>
<option value='8'>August</option>
<option value='9'>September</option>
<option value='10'>October</option>
<option value='11'>November</option>
<option value='12'>December</option>
</select>
</div>
</form>

Already-selected items of dropdown/combo box should reflect as selected on click over Label

I am using label for attribute for input elements in my website that will help blind users. I have Combobox/Drop down in
my code to enter Date (Month/Day) format. Currently if there is only single drop down , for example Select Country, then on click on Label,
already selected country is reflecting as selected, that is okay. I have used this code of Jquery:
$(function () {
$('label').click(function () {
var id = $(this).attr('for');
$('#' + id).select();
});
});
But in Case of Date format as there are Child 'Label for' under Parent 'Label for' that is used for "ExpiryDate". So in this case
my upper written Jquery is not working.
That Jquery is working fine for Single Dropdown and for Teaxt boxes. But I want to select First child i.e. Month's already selected month should be
selected. Please assist me so that I can implement it. I want to handle that when user click over Label then TextBox, Single Dropdown and Combobox/Multiple related dropdown's already entered/selected items should
be shown as selected.
My HTML Code is here:
<div class="editor-label">
<label for="ExpiryDate">*Expiration Date</label>
</div>
<div class="editor-field">
<label class="accessibleText" for="ExpirationMonth">
<label for="ExpiryDate">*Expiration Date</label>
</label>
<select id="ExpirationMonth" name="ExpirationMonth" tabindex="0"><option value="">Month</option>
<option selected="selected" value="1">Jan</option>
<option value="2">Feb</option>
<option value="3">Mar</option>
<option value="4">Apr</option>
<option value="5">May</option>
<option value="6">Jun</option>
<option value="7">Jul</option>
<option value="8">Aug</option>
<option value="9">Sep</option>
<option value="10">Oct</option>
<option value="11">Nov</option>
<option value="12">Dec</option>
</select>
<label class="accessibleText" for="ExpirationDay">
<label for="ExpiryDate">*Expiration Date</label>
</label>
<select id="ExpirationDay" name="ExpirationDay" tabindex="0"><option value="">Day</option>
<option selected="selected" value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
</select>
</div>
I want to select only first child's already select items to shown as selected.
if you change your label for to point related select attribute like below for month and day it will select when you click label.
<label for="ExpirationMonth">*Expiration Date</label>
<select id="ExpirationMonth" name="ExpirationMonth" tabindex="0">

Categories