jquery dropdownlist hide value if selected in second dropdown - javascript

Okay so I have two drop downs I want the selected item in dropdown one to be hidden in dropdown two and vice versa.
I have done the following so far can't seem to figure out the final step was hoping for a hand.
What I have currently is I have two lists that append to the dropdowns from and to, these list are looped over and append values to the dropdownlists, I then check for change event and when this occurs I remove values from a dropdown based on its index.
I am currently removing on selectedIndex, I want to remove on selectedValue rather then index but could not grasp that either.
<script type="text/javascript">
var fromCurrencies = {
FRO : 'Convert this currency',
AUD : 'AUD, Australian Dollar',
NZD : 'NZD, New Zealand Dollar',
EUR : 'EUR, Euro',
USD : 'USD, United States Dollar',
};
var toCurrencies = {
TOC : 'To this currency',
AUD : 'AUD, Australian Dollar',
NZD : 'NZD, New Zealand Dollar',
EUR : 'EUR, Euro',
USD : 'USD, United States Dollar',
};
$(document).ready(function () {
var ddFrom = $(".ddConvertFrom");
$.each(fromCurrencies, function (val, text) {
ddFrom.append(
$('<option></option>').val(val).html(text)
);
}); /*End ddFrom loop*/
var ddTo = $(".ddConvertTo");
$.each(toCurrencies, function (val, text) {
ddTo.append(
$('<option></option>').val(val).html(text)
);
}); /*End ddTo loop*/
}); /*End document.ready function*/
function doAction(){
if ($('.ddConvertFrom').val == "" || $('.ddConvertFrom').get(0).selectedIndex == 0) {
//Do nothing or hide...?
} else {
/*Hide selected value from other dropdown*/
var index = $('.ddConvertFrom').get(0).selectedIndex;
$('.ddConvertTo option:eq(' + index + ')').remove();
}
}
</script>
The html:
<div class="selectstyler">
<asp:DropDownList ID="ddConvertFrom" OnChange="doAction()" CssClass="ddConvertFrom" runat="server"></asp:DropDownList>
</div>
<div class="selectstyler">
<asp:DropDownList ID="ddConvertTo" CssClass="ddConvertTo" runat="server"></asp:DropDownList>
</div>

Purely for completeness to add to an already working answer from undefined.
To address the vice versa and the extended issue of re-adding those values including auto-selecting the previous value if it exists see: DEMO
See below for the changes I made to your original scripts.
I'm sure the code below can be optimised on several levels but I only tried to get it working first. Making it pretty I leave to you :)
To start I re-factored your code so the values are attached in their respective methods.
The dropdowns are now fully cleared before the values are re-added.
First though we record the value of the currently selected option to ensure we can re-select it if it exists. Adds a more dynamic feel to it and saves the user form re-selecting manually.
See example of attaching values to the from-dropdown:
function attachFromValues() {
var ddFrom = $(".ddConvertFrom");
var selectedValue = ddFrom.val();
var selectedIndex = 0;
ddFrom.html("");
var index = 0;
$.each(fromCurrencies, function(val, text) {
ddFrom.append(
$('<option></option>').val(val).text(text));
if (selectedValue == val) {
selectedIndex = index;
}
index++;
}); /*End ddFrom loop*/
if (selectedIndex > 0) {
ddFrom.get(0).selectedIndex = selectedIndex;
}
};
I also re-factored the code which removes the value in the other dropdown calling the new re-factored methods to re-attach all values first before removing the specific value. That makes sure you do not end up with an empty dropdown after while.
See example of the change event of the to-dropdown:
(taken from undefined's answer, only added call to re-populate)
$('select.ddConvertTo').change(function() {
if ($('.ddConvertTo').val == "") {
//Do nothing or hide...?
} else { /*Hide selected value from other dropdown*/
attachFromValues();
var txt = $(this).val();
$('.ddConvertFrom option[value=' + txt + ']').remove();
}
})
For the complete code changes check the linked DEMO
Edit (25-Jun-2012)
Updated code as I noticed an inconsistency whereby the currencies did not re-set correctly if the default selection (index 0) was made. The latest version of this code now re-binds the currencies correctly.

try this and instead of using onChange attribute you can use change event handler.
$('select:first').change(function(){
/*remove selected value from other dropdown*/
var txt = $(this).val();
$('.ddConvertTo option[value=' + txt + ']').remove();
})
http://jsfiddle.net/ue4Cm/1/

Related

Show/hide multiple fields based on drop down selection

I am using SharePoint Calendar and we are using multiple columns and it is 25 columns, in each time when we want to add new record, we have to skip a lot of columns. So using a dropdown list by showing or hiding multiple columns based on my selection would be a good idea.
What I did after discovering below code, I create a dropdown named Selection and applied the script code below but however it does not work based on my selection. I will be grateful if you guys could help me on this issue.
Thank you
<script src="/SiteAssets/jquery-3.3.1.js"></script>
<script src="/SiteAssets/sputility.js "></script>
<script>
$(document).change(function() {
var ddlValue = SPUtility.GetSPField('Selection').GetValue();
if (ddlValue == 'Country') {
SPUtility.ShowSPField('Country');
SPUtility.ShowSPField('Colour');
SPUtility.HideSPField('Animal');
SPUtility.HideSPField('Fruit');
}
if (ddlValue == 'Fruit') {
SPUtility.ShowSPField('Fruit');
SPUtility.ShowSPField('Colour');
SPUtility.HideSPField('Country');
SPUtility.HideSPField('Animal');
}
if (ddlValue == 'Animal') {
SPUtility.ShowSPField('Animal');
SPUtility.HideSPField('Country');
SPUtility.HideSPField('Fruit');
SPUtility.HideSPField('Colour');
}
if (ddlValue == 'Colour') {
SPUtility.ShowSPField('Colour');
SPUtility.ShowSPField('Animal');
SPUtility.HideSPField('Country');
SPUtility.HideSPField('Fruit');
}
});
</script>
First thing you need to do is create a change() function linked to your dropdown so that the function triggers every time you change the values. You can do that by doing this:
$("your selector for your dropdownfield").change(function() {
//your actions here
});
The next thing you need to do is get the value of the dropdown field then perform the hiding of the fields based from its value. To do that, you need to do the following:
var ddlValue = SPUtility.GetSPField('Selection').GetValue();
if (ddlValue == 'Test Value 1') {
//hide fields for 'Test Value 1'
}
So if we combine the two together you will end up with:
$("your selector for your dropdownfield").change(function() {
var ddlValue = SPUtility.GetSPField('Selection').GetValue();
if (ddlValue == 'Test Value 1') {
//hide fields for 'Test Value 1'
}
});
You can just add more if conditions within the change() function and you should now be able to hide/show fields based on the value of the dropdown.
Let me know if it works!

JS issue with dropdown menu and state selection

Here's the fiddle: https://jsfiddle.net/6aevjxkx/38/
In the dropdown menu, if you select Nebraska, you'll see a school location from Washington state, which shouldn't appear.
The issue I believe is that the script is searching the ENTIRE td section for any matching state initial. In the case of the school from Washington, it has "NE" in the address, causing it to appear when you choose Nebraska from the dropdown.
With that said, how can the script be updated so it can only search for a matching state within the div that has a class "state"? Or if there's another solution, my ears are wide open.
Thanks ahead!
Code of the script
$('select#stateCollege').change( function(e) {
var letter = $(this).val();
if (letter === 'ALL') {
$ ('table.event tr').css('display','inline-block');
} else {
$('table.event tr').each( function(rowIdx,tr) {
$(this).hide().find('td').each( function(idx, td) {
if( idx === 0 || idx === 1) {
var check = $(this).text();
if (check && check.indexOf(letter) > 0) {
$(this).parent().css('display','inline-block');
}
}
});
});
}
});
Something like the following works:
$('table.event tr').each(function(rowIdx, tr) {
var row = $(this).hide();
var state = row.find('.state').text().trim();
if (state === letter)
row.css('display', 'inline-block');
});
Updated demo: https://jsfiddle.net/6aevjxkx/42/
That is, hide the current row, then find the .text() of its .state element, .trim() that, then rather than .indexOf() just use === to compare to the value in the rather confusingly named letter variable.
Note that there was no point to using .each() on your td elements given that there is only one td in each row.

jQuery - append string to input when changed

I have multiple select inputs on a page and I'd like to set all of them to have a particular option selected if a checkbox is checked
Once the form is submitted the inputs that have been updated will be looped through and sent to the database, so I have a function to append a string to the option value which is called on change of the select
This is all working great, however I'd like to append the updated string (to the value, not text) when the select option is changed by the checkbox being checked, but can't seem to get this to work
Fiddle https://jsfiddle.net/69zzr6xa/2/
I've tried looping through each select like so and then checking if the second option is already selected. If not, append the string, but it doesn't appear to work
$('select').each(function() {
if (!$(this).$('option').text == 'Two') {
var inputname = $(this).find(":selected")[0].value;
$(this).(":selected").val(inputname + "-updated");
}
});
I think this is what you are looking for.
function set_to_two() {
$('option:nth-child(2)').each(function(){
$(this).prop('selected', true);
if( $(this).val().indexOf('-updated') < 0 ){
$(this).val( $(this).val() + "-updated" );
}
});
set_updated();
}

Clear a form and populate jquery

I am trying to clear a form and then repopulate it with new data. I have a page that has a list of search histories, along with a "search again" button, when clicked, it takes that search history string, split it, then match those again all the various form items; checkbox, radio, etc. The form has basically every kind of form element in it and everything is populating like I want it to except the checkboxes. The first time I click the populate form button, it works fine, but after the first click all the checkboxes start going haywire...some items populating like they should, some not, in a strange random pattern. I have not included the html because I don't think it is necessary but if anyone needs more info, please let me know.
This resets the form. I have tested this independently and it works.
function form_reset(){
$('#hosp_search_form')[0].reset();
$('#hosp_search_form').find("input[type=text], textarea").val("");
$('input[type=checkbox]').each(function(){
$('input[type=checkbox]').removeAttr('checked');
});
$('input[type=number]').val('');
$('input[type=radio]').each(function(){
$(this).removeAttr('checked');
});
On click, first clear the form of previous values, then grab the other needed values and format them...this part gets a little ugly in sections but I have consoled out all the values and everything is how it should be.
$('.search_again_btn').on('click', function(){
form_reset();
$('#hosp_search_form').find('input[type=checkbox]').removeAttr('checked');
var id = $(this).data('id');
var searchstring = $('#searchstring_' + id).text();
var patientcode = $('#patientcode_' + id).text();
var mrn = $('#mrn_' + id).text();
var first_name = patientcode.substr(0,2);
var last_name = patientcode.substr(2,2);
var age = patientcode.substr(4,3);
var gender = patientcode.substr(6,2);
var age = age.replace(/\D+/g, '');
gender = gender.replace(/[0-9]/g, '');
Populates some of the form, works fine
//populate fields in search form
$('input[name=fn]').val(first_name);
$('input[name=ln]').val(last_name);
$('input[name=patientage]').val(age);
$('input[name=mrn]').val(mrn);
Populate another part of the form, also always works as needed
//populate gender fields
if(gender == 'F'){
$('.female').attr('checked', 'checked');
}
if(gender == 'M'){
$('.male').attr('checked', 'checked');
}
Here is where I suspect the issue is. splitsearch is a long string (a previous search history) with items separated by a . and they get split into separate items. I console logged this, it correctly breaking it into the smaller values like I need, then iterate through those and iterate through all the checkboxes which each have a data attr holding values that can be in the splitsearch. If a value matches, it should make it checked. This works every time the first time, for any combo of splitsearch/search string values, but after the first time, I don't know what it is doing. I expect that each click, the form is cleared and it does the value matching again as I described.
//populate checkboxes
var splitsearch = searchstring.split('. ');
$.each(splitsearch, function(key, value){
$('input[type=checkbox').each(function(keyb, checkbox){
item = $(checkbox).data('services');
if(item == value){
$(this).attr('checked', 'checked');
console.log($(this));
}
});
This is doing the same as the above but works every time...probably because there is never multiple combinations like with checkboxes.
$('input[name=payor]').each(function(k, radio){
if(value == $(radio).data('payors')){
$(this).attr('checked', 'checked');
//console.log($(this));
}
});
Also like the above and works.
$('input[name=bedtype]').each(function(keyc, radio){
bed = $(radio).data('bed');
if(bed == value){
$(this).attr('checked', 'checked');
}
});
This part below is quite ugly but is populating the form like I need every time.
//if searchstring contains Needs Transportation, returns true, else returns false
if(value.indexOf("Needs Transportation") > -1 === true){
$('.transyes').attr('checked', 'checked');
}
if(value.indexOf("Near hospital") > -1 != true){
$('input[name=desiredzip]').val(searchstring.substr(5,5));
}
if(value.indexOf("5 mile radius") > -1 === true){
$('.miles_5').attr('checked', 'checked');
}
if(value.indexOf("10 mile radius") > -1 === true){
$('.miles_10').attr('checked', 'checked');
}
if(value.indexOf("15 mile radius") > -1 === true){
$('.miles_15').attr('checked', 'checked');
}
if(value.indexOf("20 mile radius") > -1 === true){
$('.miles_20').attr('checked', 'checked');
}
});
Scrolls the window up to the populated search form and show it.
window.scrollTo(0,100);
$('#search_show').show();
});
Just a thought but, it might help you to restructure your code a bit to keep it DRY.
// used to Hold search data in local or global
var data;
function form_reset() {
// clear form
}
function get_search_data() {
// populate data with search results
}
function form_populate() {
// use data to populate form
}
$('.search_again_btn').on('click', function(){
get_search_data();
form_reset();
form_populate();
});
// Initial Load of form
get_search_data();
form_populate();
that way you use the same population function initially as you do when you refresh and it forces you to put your data into a variable that can be seen in both the clear and populate functions removing your reliance on this and $(this).
also you need to bear in mind that the value of this inside a click function is going to be in the context of the click event itself and not the JavaScript object that the rest of your code belongs to.

Modify function to filter by several data-attributes simultaneously

The function below allows users to filter products by data-attributes, and accommodates filtering by multiple values simultaneously. It does this by creating an array of the values selected, and when any of the values are clicked (in this case checked/unchecked) it hides all the items and then re-shows those that match the values in the updated array.
It works correctly when filtering for one data-attribute, but when combined to filter by more than one attribute it no longer shows all results matching any of the values and instead only shows results matching all the specified values.
I've posted a fiddle which demonstrates the problem here: http://jsfiddle.net/chayacooper/WZpMh/94/ All but one of the items have the values of both data-style="V-Neck" and data-color="Black" and they should therefore remain visible if either of the filters are selected, but if another value from a different data-attribute some of the items are hidden.
$(document).ready(function () {
var selected = [];
$('#attributes-Colors *').click(function () {
var attrColor = $(this).data('color');
var $this = $(this);
if ($this.parent().hasClass("active")) {
$this.parent().removeClass("active");
selected.splice(selected.indexOf(attrColor),1);
}
else {
$this.parent().addClass("active");
selected.push(attrColor);
}
$("#content").find("*").hide();
$.each(selected, function(index,item) {
$('#content').find('[data-color *="' + item + '"]').show();
});
return false;
});
$('#attributes-Silhouettes *').click(function () {
var attrStyle = $(this).data('style');
var $this = $(this);
if ($this.parent().hasClass("active")) {
$this.parent().removeClass("active");
selected.splice(selected.indexOf(attrStyle),1);
}
else {
$this.parent().addClass("active");
selected.push(attrStyle);
}
$("#content").find("*").hide();
$.each(selected, function(index,item) {
$('#content').find('[data-style *="' + item + '"]').show();
});
return false;
});
});
Both of your handlers are updating the selected array, but only one handler executes on a click. The first one if a color was (de)selected, the second if a style. Let's say you've clicked on "Black" and "Crew Neck". At that time your selected array would look like this: [ "Black", "Crew_Neck" ]. The next time you make a selection, let's say you click "Short Sleeves", the second (style) handler executes. Here's what is happening:
Short_Sleeves gets added to the selected array.
All of the items are hidden using $("#content").find("*").hide();
The selected array is iterated and items are shown again based on a dynamic selector.
Number 3 is the problem. In the above example, a style was clicked so the style handler is executing. Any items in the selected array that are colors will fail because, for example, no elements will be found with a selector such as $('#content').find('[data-style *="Black"]').show();.
I would suggest 2 things.
Keep 2 arrays of selections, one for color, one for style.
Combine your code to use only a single handler for both groups.
Here's a (mostly) working example.
Note that I added a data-type="color|style" to your .filterOptions containers to allow for combining to use a single handler and still know which group was changed.
Here's the full script:
$(document).ready(function () {
// use 2 arrays so the combined handler uses correct group
var selected = { color: [], style: [] };
// code was similar enough to combine to 1 handler for both groups
$('.filterOptions').on("click", "a", function (e) {
// figure out which group...
var type = $(e.delegateTarget).data("type");
var $this = $(this);
// ...and the value of the checkbox checked
var attrValue = $this.data(type);
// same as before but using 'type' to access the correct array
if ($this.parent().hasClass("active")) {
$this.parent().removeClass("active");
selected[type].splice(selected[type].indexOf(attrValue),1);
}
else {
$this.parent().addClass("active");
selected[type].push(attrValue);
}
// also showing all again if no more boxes are checked
if (attrValue == 'All' || $(".active", ".filterOptions").length == 0) {
$('#content').find('*').show();
}
else {
// hide 'em all
$("#content").find("*").hide();
// go through both style and color arrays
for (var key in selected) {
// and show any that have been checked
$.each(selected[key], function(index,item) {
$('#content').find('[data-' + key + ' *="' + item + '"]').show();
});
}
}
});
});
UPDATE: incorporating suggestions from comments
To make the handler work with checkboxes instead of links was a small change to the event binding code. It now uses the change method instead of click and listens for :checkbox elements instead of a:
$('.filterOptions').on("change", ":checkbox", function (e) {
// handler code
});
The "All" options "hiccup" was a little harder to fix than I thought it would be. Here's what I ended up with:
// get a jQuery object with all the options the user selected
var checked = $(":checked", ".filterOptions");
// show all of the available options if...
if (checked.length == 0 // ...no boxes are checked
|| // ...or...
checked.filter(".all").length > 0) // ...at least one "All" box is checked...
{
// remainder of code, including else block, unchanged
}
I also added an all class to the appropriate checkbox elements to simplify the above conditional.
Updated Fiddle

Categories