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.
Related
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;
}
});
I'm building a search form but have something strange going on with the selected="selected" option not being highlighted.
The form's pulling data from a database and duplicates are then being removed using javascript (seen below). The website is built using ExpressionEngine and the form is using Solspace Super Search.
The strange thing is that for option's that only display one result such as 'Andover', the dropdown selects 'Andover' but if more than one result is found (such as Bournemouth) then the dropdown reverts to the first option (All locations) rather than Bournemouth, even though the Bournemouth option features selected="selected".
Here's a sample of the code that's being output, any ideas what's going on here?
<select name="club_feed_town" id="locationList">
<option value="">All Locations</option>
<option value="Andover">Andover</option>
<option value="Bishops waltham">Bishops Waltham</option>
<option value="Blandford forum">Blandford Forum</option>
<option value="Boscombe">Boscombe</option>
<option selected="selected" value="Bournemouth">Bournemouth</option>
</select>
Here's the script that's removing duplicates if that helps:
$(document).ready(function() {
var optionValues = [];
var lastRemoved = null;
$('#locationList option').each(function(){
if($.inArray(this.value, optionValues) >-1){
$(this).remove();
// remember the very last removed one
lastRemoved = $(this);
}else{
optionValues.push(this.value);
}
});
// after removing duplicates, add the very last removed one back to the list
$('#locationList').append(lastRemoved);
});
As always, any thoughts or suggestions are welcome.
Thanks in advance,
Tom
I just made some add in your js code to make it work. Just give it a look.
$(document).ready(function() {
var optionValues = [];
var lastRemoved = null;
$('#locationList option').each(function(i){
if($.inArray(this.value, optionValues) >-1){
//////////////////////add in code///////////////////////////////
if($(this).prop('selected')){
$(this).removeAttr("selected");
}
$('#locationList').prop('selectedIndex',i-1);
//////////////////////end of my code//////////////////////////////
// remember the very last removed one
$(this).remove();
lastRemoved = $(this);
}else{
optionValues.push(this.value);
}
});
// after removing duplicates, add the very last removed one back to the list
$('#locationList').append(lastRemoved);
});
I would like to do a select option dependent of another select, i saw there's a way using array with fixed values, but my array is reloaded every time we add a new form field on the form. I would like something like when i select op1, then it just show op1 options on second select.
<select id="id1" name="optionshere">
<option relone="op1">opt one</option>
<option relone="op2">opt two</option>
</select>
<select id="id2" name="resulthere">
<option relone="op1">ans 1 op1</option>
<option relone="op1">ans 2 op2</option>
<option relone="op2">ans 1 op2</option>
</select>
Any idea?
thanks all
Here's a method without jQuery:
When you select an option in the first selectbox, it will hide everything that doesn't match its relone.
var id1 = document.getElementById("id1");
var id2 = document.getElementById("id2");
id1.addEventListener("change", change);
function change() {
for (var i = 0; i < id2.options.length; i++)
id2.options[i].style.display = id2.options[i].getAttribute("relone") == id1.options[id1.selectedIndex].getAttribute("relone") ? "block" : "none";
id2.value = "";
}
change();
<select id="id1" name="optionshere">
<option relone="op1">opt one</option>
<option relone="op2">opt two</option>
</select>
<select id="id2" name="resulthere">
<option relone="op1">ans 1 op1</option>
<option relone="op1">ans 2 op1</option>
<option relone="op2">ans 1 op2</option>
</select>
If Jquery is an option you may go with something like this:
<script type='text/javascript'>
$(function() {
$('#id1').change(function() {
var x = $(this).val();
$('option[relone!=x]').each(function() {
$(this).hide();
});
$('option[relone=x]').each(function() {
$(this).show();
});
});
});
</script>
Then to expand:
There really are many ways in which you can solve this predicament, depending on how variable your pool of answers is going to be.
If you're only interested in using vanilla javascript then let's start with the basics. You're going to want to look into the "onchange" event for your html, so as such:
<select onchange="myFunction()">
Coming right out of the w3schools website, on the Html onchange event attribute:
The onchange attribute fires the moment when the value of the element
is changed.
This will allow you to make a decision based on this element's value. Then inside your js may branch out from here:
You may use Ajax and pass to it that value as a get variable to obtain those options from a separate file.
You may get all options from the second div through a combination of .getElementbyId("id2") and .getElementsByTagName("option") then check for their individual "relone" attribute inside an each loop, and hide those that don't match, and show those that do.
Really, it's all up to what you want to do from there, but I personally would just go for the Jquery approach
I have an issue with the data which is sent from a drop down menu, the selector only returns a single value, even when multiple values are selected. I have searched online for a solution to this, but they all use PHP, JQuery or some method outside the scope of the course I am taking; to capture multiple selected items. I have tried .value of the individual options, but that returns all of the options rather than just the ones which are selected. Is there some kind of trick to sending multiple values?
Here is my code for the menu. For example If I select JAVA PROGRAMMING, NETWORKS and VIDEO GAMES, only JAVA PROGRAMMING is sent.
<select multiple id="CK_Expertise">
<option id="CK_Exp1" value="Java programming">JAVA PROGRAMMING</option>
<option id="CK_Exp2" value="Networks">NETWORKS</option>
<option id="CK_Exp3" value="Video game programming">VIDEO GAMES</option>
<option id="CK_Exp4" value="Accounter">ACCOUNTER</option>
<option id="CK_Exp5" value="Help Desk">HELPDESK</option>
<option id="CK_Exp6" value="C++ programming">C++</option>
<option id="CK_Exp7" value="Programming">PROGRAMMING</option>
</select>
I have also tried using the Select Object in the DOM, http://www.w3schools.com/jsref/dom_obj_select.asp
which has a few methods for accessing the options in the dropdown menu. One method in particular called selectedIndex, seemed to be what I am looking for, however it only returns the the index of the first selected option, instead of all of the selected options.
Is there a simple solution to this using just Javascript and the DOM?
Thanks
- Chris
Get the options, iterate and check if they are selected, and add the values to an array
var select = document.getElementById('CK_Expertise'),
options = select.getElementsByTagName('option'),
values = [];
for (var i=options.length; i--;) {
if (options[i].selected) values.push(options[i].value)
}
console.log(values)
FIDDLE
or being a little more fancy
var select = document.getElementById('CK_Expertise'),
values = Array.prototype.filter.call(select.options, function(el) {
return el.selected;
}).map(function(el) {
return el.value;
});
console.log(values)
FIDDLE
You could use the select.selectedOptions property:
select.onchange = function() {
var values = [].map.call(this.selectedOptions, function(opt){
return opt.value;
});
};
document.getElementById('CK_Expertise').onchange = function() {
document.querySelector('pre').textContent = JSON.stringify([].map.call(
this.selectedOptions, function(opt){ return opt.value; }
));
}
<select multiple id="CK_Expertise">
<option id="CK_Exp1" value="Java programming">JAVA PROGRAMMING</option>
<option id="CK_Exp2" value="Networks">NETWORKS</option>
<option id="CK_Exp3" value="Video game programming">VIDEO GAMES</option>
<option id="CK_Exp4" value="Accounter">ACCOUNTER</option>
<option id="CK_Exp5" value="Help Desk">HELPDESK</option>
<option id="CK_Exp6" value="C++ programming">C++</option>
<option id="CK_Exp7" value="Programming">PROGRAMMING</option>
</select>
<pre></pre>
If you can use jQuery, this will give you all the values
$(document).ready(function(){
$('#CK_Expertise').change(function(e){
var values = $('#CK_Expertise').val()
alert(values);
});
});
HTH,
-Ted
You could iterate storing select.selectedIndex in an array and unselecting the corresponding option to get the next one:
select.onchange = function() {
var i, indices=[], values = [];
while((i=this.selectedIndex) > -1) {
indices.push(i);
values.push(this.value);
this.options[i].selected = false;
}
while((i=indices.pop()) > -1)
this.options[i].selected = true;
console.log(values);
}
Demo
This way you avoid iterating over all options, but you must iterate twice over the selected ones (first to unselect them, them to select them again).
Why not using an indexed variable in the SELECT command?
<SELECT MULTIPLE id="stuff" name="stuff[]">
<OPTION value=1>First stuff</option>
<OPTION value=2>Second stuff</option>
<OPTION value=3>Third stuff</option>
</SELECT>
In that case it's easy to read the array:
$out=$_REQUEST['stuff'];
foreach($out AS $thing) {
echo '<br />'.$thing;
}
Sorry for the poor indentation, but I just wanted to show the way I use for solving this case!
var select = document.getElementById('CK_Expertise'),
options = select.selectedOptions,
values = [];
for(let i=0;i<options.length;i++)
{
values.push(options[i].value);
}
console.log(values);
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