jQuery to update a div depending on the selection from dropdowns - javascript

We have two dropdowns that according to your selection it changes part of the string in some div containers. The purpose of this is to return URLs to give to clients.
This is a sample of the code
<select name="lstLanguage" id="lstLanguage">
<OPTION VALUE="">-- Generic default ---</OPTION>
<OPTION ID="Arabic" VALUE="AR">Arabic</OPTION>
<OPTION ID="German" VALUE="D">German</OPTION>
</select>
<select name="lstTemplate" id="lstTemplate">
<OPTION VALUE="">-- Generic default ---</OPTION>
<OPTION VALUE="1">Member</OPTION>
<OPTION VALUE="2">NonMember</OPTION>
</select>
<div id='Ind_URL'>http://example.com/Registration.asp?Language_Code=?Role=</div>
<div id='Ind_W_URL'>http://example.com/Registration.asp?Language_Code=?Role=</div>
<div id='Login_URL'>http://example.com/?Language_Code=</div>
And this is the jQuery we currently have, which was provided by irama.
$(function(){
divIDs = [
'Ind_URL',
'Ind_W_URL',
'Login_URL',
];
$('#lstTemplate').bind('change', function(){
role = $(this).find('option:selected').val();
updateURLDivs(langCode=null, role);
});
$('#lstLanguage').bind('change', function(){
langCode = $(this).find('option:selected').val();
updateURLDivs(langCode, role=null);
});
updateURLDivs = function (langCode, role) {
for (i in divIDs) {
currentDiv = $('#'+divIDs[i]);
if (langCode !== null) {
currentDiv.data('Language_Code', langCode);
}
if (role !== null) {
currentDiv.data('role', role);
}
// Cache original div contents, so that the select menu can be changed more than once.
if (typeof currentDiv.data('contents') == 'undefined') {
divContents = currentDiv .html();
currentDiv .data('contents', divContents);
} else {
divContents = currentDiv .data('contents');
}
currentDiv.empty().append(
divContents
.replace('role=','role='+currentDiv.data('role'))
.replace('Language_Code=','Language_Code='+currentDiv.data('Language_Code'))
);
}
}
});
This is working fine, but this morning we found a few issues
It is currently updating both parameters, no matter if you change one or both. We need it to update if you change the template, just the template and if you change the language just the language.
If nothing is selected we need it to replace it with a blank not with undefined as it is currently doing
If we change the Template it also needs to replace Registration.asp to PersonImport.asp from the URLs
This is how it should work
The div containers need to have the default URLs in them
If I change the language (lstLanguage) it should just change the Language_Code on the DIV containers. Then if I select the language option with no value ("Generic default") the Language_Code should be blank ''
If I change the template (lstTemplate) it should change the Role on the DIV containers. Also should change Registration.asp to PersonImport.asp. Then if I select the template option with no value ("Generic Default) the Role should be blank '' and PersonImport.asp should go back to Registration.asp.
I'm not a good coder on this, but it would be great if any of you can give me a hand with this.
Thanks in advance
Federico

I have create a fiddle with a lot of improvement in your code. Take a look.
Working demo

Related

Auto pre-select dropdown value from URL address

I'm using the dropdown select menu which redirects users to selected cities. I have searched for this topic everywhere and tried many solutions found on stackoverflow but each of them did not work. In many cases it even disabled the redirection of my dropdown. So I am posting a new question. Hopefully that someone could solve my problem.
Problem: When I visit URL I see select delivery city - non value option. It should show the selected city based on URL address.
My URL looks like this /kategoria-produktu/CITY U SELECT (/kategoria-produktu/cadca/)
To sum up: When u visit url /kategoria-produktu/cadca the dropdown should be preselect on current url and display Čadca.
Any ideas how could I solve this?
Thank you very much!
CODE
JS
if(location.href.indexOf(localStorage.country) == -1){
location.href = localStorage.country
}
function formChanged(form) {
var val = form.options[form.selectedIndex].value;
if (val !== 'non-value') {
if (localStorage) {
localStorage.country = val;
}
if (!location.href.indexOf(val)) {
location = val;
}
}
}
HTML
<form name="form1">
<select id="saleTerm" onchange="formChanged(this); location =
this.options[this.selectedIndex].value;" NAME="country" SIZE="1">
<OPTION VALUE="non-value">Select delivery city</option>
<OPTION VALUE="/kategoria-produktu/cadca/">Čadca</option>
<OPTION VALUE="/kategoria-produktu/brno/">Brno</option>
<OPTION id="bratislava" VALUE="/kategoria-produktu/bratislava/">Bratislava</option>
</select>
</form>
So a bunch of little things need to change here for you to get what you want. I'll try to write them all down:
You should access localStorage using getItem and setItem like in the localStorage MDN documentation
Use an event listener instead of the inline onchange attribute, it's much cleaner.
You probably want to use includes instead of indexOf since you are looking for a substring (country) in a string (href), indexOf won't do this for you.
I used location.pathname since you really only care about the path, there are better ways to get the exact path parameter you want.
No need to use a <form/> as far as I can see from the code you shared.
I removed /kategoria-produktu/ from the option's value attribute since its repetitive and just placed it once in the js
You should change the value of the select to the city you want as the default selected. You can do this by parsing out the city from the path and setting it as the value attribute on the select
I think that's it, here is an example using those points above.
const PREFIX = "kategoria-produktu";
window.addEventListener('load', function() {
let countryInStorage = localStorage.getItem("country");
if (countryInStorage && !location.pathname.includes(countryInStorage)) {
location.href = `/${PREFIX}/${countryInStorage}`;
}
document.getElementById("saleTerm").addEventListener("change", formChanged);
setDefaultOption();
})
function setDefaultOption() {
let countryPath = location.pathname.split("/")[2];
if (countryPath) {
document.getElementById("saleTerm").value = countryPath;
}
}
function formChanged() {
let selectedCountry = this.value;
if (selectedCountry !== "non-value") {
if (localStorage) {
localStorage.setItem("country", selectedCountry);
}
if (!location.pathname.includes(selectedCountry)) {
location.href = `/${PREFIX}/${selectedCountry}`;
}
}
}
<select id="saleTerm" name="country">
<option value="non-value">Select delivery city</option>
<option value="cadca">Čadca</option>
<option value="brno">Brno</option>
<option value="bratislava">Bratislava</option>
</select>
If I understand it correctly, you are looking onto showing the proper option from the select element based on the URL.
Look at the example below. It basically runs a process on page load and when the DOM is ready (hence DOMContentLoaded) to check if an option based on URL exists in the select options and picks that. You may have to update your logic depending on the URL structure. The example below assumes your URL is always formatted like http://your.domain.com/kategoria-produktu/<city>/.
document.addEventListener("DOMContentLoaded", function() {
// find the option based on the URL.
let option = document.querySelector("#saleTerm > option[value='" + location.pathname + "']");
// assign the option value to the select element if such exists.
if (option) {
document.querySelector("#saleTerm").value = option.value;
}
});

How can I hide some elements from a select list?

I am new to programming and I would like to know how to hide some options from a select control I have...
I am going to explain the thing: So, i have two select controls.. according to the option from the select number 1, I want to hide some items from the second select, but I don't know how to do it, I was trying with some jQuery .hide but it is not working... Hope you can help me...
Thank you
Hope this gives you an idea, since you didn't post any code.
HTML
<select id="selectA">
<option value="">Select Fruit or Veg</option>
<option value="fruit">Fruit</option>
<option value="vegetable">Vegetable</option>
</select>
<select id="selectB">
<option value="">All</option>
<option value="apple" data-type="fruit">apple</option>
<option value="orange" data-type="fruit">orange</option>
<option value="carrot" data-type="vegetable">carrot</option>
<option value="tomato" data-type="vegetable">tomato</option>
</select>
JS
var selectA = document.querySelector('#selectA')
var selectB = document.querySelector('#selectB')
selectA.addEventListener('change', event => {
var type = event.target.value;
[].slice.call(selectB.querySelectorAll('option'))
.forEach(el => {
el.style.display = (el.dataset.type === type ? 'block' : 'none')
})
})
JSFiddle Demo: https://jsfiddle.net/hw76aLqv/1/
Try this.
if($("#APU").val("1")) {
$("#celda option[value = 'raven']").wrap('<span>')
}
To show again, just find that option(not span) and
$("#celda option[value = 'raven']").unwrap()
I hope this helps . Although the jQuery function is pretty lengthy but This way you will be able to get what is actually happening . After selecting an option from first select element , do a check whether id is 'selectA' or not .
Take the selected option as an object in the variable OPTIONS.
and then go to the next select Element using .next() function .
There use a loop which will go through all the child elements of select element .
after that I am doing a check . If the data-type of the child element is not equal to options.val() hide the child element using .hide()
Here is the code
$(document).ready(function(){
$('select').on('change',function(){
if($(this).attr('id')=='selectFirst'){
var options = $(this).find('option:selected');
var nextSelect = $('select').next();
nextSelect.children().each(function(){
child = $(this);
if(child.attr('data-type') != options.val()){
child.hide();
}
});
}
});

Display option fields (child) based on parent option condition - JS solutions needed?

I am looking for a simple .js solution. I have two dropdown buttons - code:
<select name="parent_dropdown" id="parent">
<option value="option_01">parent_option_01</option>
<option value="option_02">parent_option_02</option>
</select>
<br />
<select name="child_dropdown" id="child">
<option value="opt01">child_option_01</option>
<option value="opt02">child_option_02</option>
<option value="opt03">child_option_03</option>
<option value="opt04">child_option_04</option>
</select>
Now I need to accomplish this:
When option_01 in #parent is chosen ---> make available only child_option_01 and child_option_02 in #child dropdown
When option_02 in #parent is chosen ---> make available only child_option_03 and child_option_04 in #child dropdown
I tried some solutions I found online but so far no luck. I have a very basic .js knowledge.
Link to FIddle: http://jsfiddle.net/q5kKz/343/
Help will be appreciated.
Taking the next step with your fiddle, this will do (almost) what you want:
$('#parent').change(function() {
$("option[value='opt01']")[$(this).val() == "option_01" ? 'show' : 'hide']("fast");
}).change();
Notice the attribute selector: "option[value='opt01']" - that says "any options with value of opt01".
You should probably expand that selector to be "#child option[value='opt01']"
Using a "basic" programming method, you could do this for multiple options:
$('#parent').change(function() {
$("option[value='opt01']")[$(this).val() == "option_01" ? 'show' : 'hide']("fast");
$("option[value='opt02']")[$(this).val() == "option_01" ? 'show' : 'hide']("fast");
// Adding multiple options here. This is a bad method for maintainability
}).change();
A better way to go would be to assign some sort of other attributes to the options that should show depending on which parent is selected. One example is using a class that matches the parent value desired - which would require modifying your child list like so:
<select name="child_dropdown" id="child">
<option value="opt01" class="option_01">child_option_01</option>
<option value="opt02" class="option_01">child_option_02</option>
<option value="opt03" class="option_02">child_option_03</option>
<!-- The below option would show whenever the parent is on option 2 OR 3 -->
<option value="opt04" class="option_02 option_03">child_option_04</option>
</select>
But then your script could be much more usefully constructed like so, and wouldn't need to be changed if you added / changed options:
$('#parent').change(function() {
var val = $(this).val();
$("#child option")[$(this).hasClass(val) ? 'show' : 'hide']("fast");
}).change();
This still leaves the problem of the list option hiding, and the select can still be set to a "hidden" value. This would need to be addressed somehow. Something like the below:
$('#parent').change(function() {
var val = $(this).val();
$("#child option")[$(this).hasClass(val) ? 'show' : 'hide']("fast");
var child_val = $('#child').val();
// If the selected option is not visible...
if ($('#child').find(":selected").not(":visible")) {
// Set it to the first option that has the proper parent class
$("#child").val($("#child option." + val + ":first").val());
};
}).change();
With newer versions of jQuery you could do something like:
var group1 = $("#child").find("option[value='opt01'], option[value='opt02']");
var group2 = $("#child").find("option[value='opt03'], option[value='opt04']");
$('#parent').change(function() {
var selected = $("#parent").find(":selected").text();
if (selected == "parent_option_01") {
group1.prop("disabled", false);
group2.prop("disabled", true);
} else {
group1.prop("disabled", true);
group2.prop("disabled", false);
}
}).change();
The other people may have it right. But when you want to make changes you have to change a bunch of JS code. I think this is a better approach. In our child HTML we add a data attribute to show what values of parent will make this child option show. This way if we ever need to add more elements or change what ones make the children appear we can just change the HTML and it leaves our javascript a lot cleaner.
http://jsfiddle.net/q5kKz/348/
var parent = $("#parent");
var child = $("#child");
var val;
$('#parent').change(function() {
//Get value of parent
val = $("#parent").val();
//cycle through children and find which data show matches the parent
child.children().each(function(){
var c = $(this);
//Jquery's .data wasn't working for some reason
if(c.attr("data-show") === val){
c.show()
}else{
c.hide()
}
})
}).change();
In the HTML
<select name="parent_dropdown" id="parent">
<option value="option_01">parent_option_01</option>
<option value="option_02">parent_option_02</option>
</select>
<br />
<select name="child_dropdown" id="child">
<option value="opt01" data-show="option_01">child_option_01</option>
<option value="opt02" data-show="option_01">child_option_02</option>
<option value="opt03" data-show="option_02">child_option_03</option>
<option value="opt04" data-show="option_02">child_option_04</option>
</select>

Allowing for multiple selectors within one function in jquery

I have a drop down box in which allows for a "category" to be selected, if it is changed it loads the new category as shown in the code below. I have since introduced a "Sub-Category" system and am in need of modifying this code slightly. I found the following information to be very helpful:
How to attach different events on multiple selectors through .on function in jquery?.
However, it doesn't quite solve my problem... I could use that to run two separate events for each selector within the same function but I need to run both simultaneously in the event both a "category" and "sub-category" are selected. Though they need to also be capable of running separate, in the event only one is selected. I'm fairly new to js/jquery so the more info you can provide the better! Thank you very much!
<script type='text/javascript'>
$(document).ready(function()
{
$('select#selectCategory').change(function()
{
var cat = $('select#selectCategory').val();
var subcat
if(cat > 0)
{
var param = '&category_id=' + cat;
}else{
var param = '';
}
var href = './videoroom.php?action=video_gallery'+ param +'&page=1';
window.location.href = href;
});
});
</script>
Here is the HTML section related to the already written jquery code:
<select style="min-weight:100px;" name="filter_by_cat" id="selectCategory">
<option value="0">All</option>
<option value="9">Wizard101</option>
<option value="10">Pirate101</option>
<option value="11">Pet Derby</option>
<option value="14">Misc/Fun</option>
</select>
And here is the new bit I added for the newly created Sub-Category:
<select style="min-weight:100px;" name="filter_by_subcat" id="selectSubCategory">
<option value="0">All</option>
<option value="21">General PvP</option>
<option value="22">PvPC Matches</option>
<option value="23">PvP Guides</option>
<option value="24">Miscellaneous</option>
</select>
Add the event listener to both dropdowns and check both of them when either is changed:
jsFiddle
$('#selectCategory, #selectSubCategory').change(function() {
var cat = $('#selectCategory').val();
var subcat = $('#selectSubCategory').val();
var params = [
'action=video_gallery',
'page=1'
];
if (cat > 0) {
params.push('category_id='+ cat);
if (subcat > 0) {
params.push('subcategory_id='+ subcat);
}
}
var href = './videoroom.php?'+ params.join('&');
window.location.href = href;
});
I'm assuming you only want the subcategory choice to be taken into account when the main category is selected. If that's not the case, move the second if-statement outside the first one.
I also refactored your code a little to make it more easily extensible and (IMO) cleaner. I'm adding all the params to an array and them just joining them at the end. If you need to add any more params, just put them in the array as well.

Removing and adding options from a group of select menus with jQuery

This is a little more complicated than the title makes it out to be, but here are the essential business rules:
There are three select menus on the
page, each filled with the same
options and values.
There will always be three select
menus.
There will always be the same number
of options/values in each select
menu.
Selecting a question in any of the
menus will remove that question as an option from
the other two menus.
Re-selecting a different question
from any of the menus will bring
back the question that was
previously removed from the other
two menus at the index it was at previously.
I've tried this a few different ways, and the thing that is killing me is number 5. I know that it wouldn't be inserted at the exact index because some questions may have already been removed, which would reorder the index. It basically needs an insertBefore or insertAfter that puts it in the same "slot".
Even if you don't post any code, some thoughts on how you might approach this would be extremely helpful. The select menus and jQuery look something like this, but I've had numerous tries at it in different variations:
jQuery:
$(function() {
$(".questions").change(function() {
var t = this;
var s = $(t).find(":selected");
// Remove, but no "insert previously selected" yet...
$(".questions").each(function(i) {
if (t != this) {
$(this).find("option[value=" + s.val() + "]").remove();
}
});
});
});
HTML:
<select name="select1" class="questions">
<option value="1">Please select an option...</option>
<option value="2">What is your favorite color?</option>
<option value="3">What is your pet's name?</option>
<option value="4">How old are you?</option>
</select>
<select name="select2" class="questions">
<option value="1">Please select an option...</option>
<option value="2">What is your favorite color?</option>
<option value="3">What is your pet's name?</option>
<option value="4">How old are you?</option>
</select>
<select name="select3" class="questions">
<option value="1">Please select an option...</option>
<option value="2">What is your favorite color?</option>
<option value="3">What is your pet's name?</option>
<option value="4">How old are you?</option>
</select>
Don't remove the elements, hide them. With removing, you are causing you a lot more problems than necessary. This works for me:
$(function() {
$('select.questions').change(function() {
var hidden = [];
// Get the values that should be hidden
$('select.questions').each(function() {
var val = $(this).find('option:selected').val();
if(val > 0) {
hidden.push($(this).find('option:selected').val());
}
});
// Show all options...
$('select.questions option').show().removeAttr('disabled');
// ...and hide those that should be invisible
for(var i in hidden) {
// Note the not(':selected'); we don't want to hide the option from where
// it's active. The hidden option should also be disabled to prevent it
// from submitting accidentally (just in case).
$('select.questions option[value='+hidden[i]+']')
.not(':selected')
.hide()
.attr('disabled', 'disabled');
}
});
});
I made a small change to your HTML also, I denoted an option that should always be visible with a value of 0. So the valid options go from 1 to 3.
Here's a working example, tell me if I misunderstood you:
http://www.ulmanen.fi/stuff/selecthide.php
I was working on a solution of this recently and modified this code to remove rather than disable/hide. For my solution it was required (I'm also using UI to style the select elements). Here's how I did it:
// Copy an existing select element
var cloned = $('select[name="select1"]').clone();
// Each time someone changes a select
$('select.questions').live('change',function() {
// Get the current values, then reset the selects to their original state
var hidden[];
$('select.questions').each(function() {
hidden.push($(this).val());
$(this).html(cloned.html());
});
// Look through the selects
for (var i in hidden) {
$('select.questions').each(function() {
// If this is not the current select
if ((parseInt(i)) != $(this).parent().index()) {
// Remove the ones that were selected elsewhere
$(this).find('option[value="'+hidden[i]+'"]').not('option[value="0"]').remove();
} else {
// Otherwise, just select the right one
$(this).find('option[value="'+hidden[i]+'"]').not('option[value="0"]').attr('selected','selected');
}
});
}
});

Categories

Resources