I've looked through stackoverflow for an answer and am almost there but need some help.
I have multiple drop down lists with the same options in them. For example three identical lists with the following:
<label for='distlist_1'>Distribution List 1</label>
<select name='distlist_1'>
<option value=''>Please Select:</option>
<option value='1'>All</option>
<option value='2'>All Managers</option>
<option value='3'>Leavers</option>
</select>
The only difference being the name eg, distlist_1, 2, 3 etc. I can add ids if necessary.
When a user selects an option in the first drop down list I need it to be removed from all other drops downs. I found a script that did this.
$('option').click(function(){
$('option:contains(' + $(this).html() +')').not(this).remove();
});
But I need it so that if the user then decides, 'wait I don't need that option in drop down list 1 after all', she picks something else and the option reappears in the other drop downs. The code above removes the options then there is no way of retrieving them until if you click enough they all disappear.
This actually does what you want... This is based on jquery 1.7 and the on() event binder
$(document).ready(function (){
$('select').on('focus', function() {
// on focus save the current selected element so you
// can place it back with all the other dropdowns
var current_value = $(this).val();
// bind the change event, with removes and adds elements
// to the dropdown lists
$(this).one('change.tmp', { v : current_value }, function(e)
{
if ($(this).val() != '')
{ // do not remove the Please select options
$('option[value="' + $(this).val() + '"]')
.not($('option[value="' + $(this).val() + '"]', $(this)))
.remove();
}
if (e.data.v != '')
{ // do not add the Please select options
$('select').not($(this)).append($('option[value="' + e.data.v + '"]', $(this)).clone());
}
});
// on blur remove all the eventhandlers again, this is needed
// else you don't know what the previously selected item was.
$(this).on('blur.tmp', { v : current_value}, function (e)
{
$(this).off('blur.tmp');
$(this).off('change.tmp');
});
});
});
The only thing it doesn't do is ordering everything in the right order. You will have to think of your own way of doing that at the .append function.
I ended up using this as it was concise...
jQuery(document).ready(function() {
var selects = $('.mapping')
selects.change(function() {
var vals = {};
selects.each(function() {
vals[this.value] = true;
}).get();
selects.not(this).children().not(':selected').not(':first-child').each(function() {
this.disabled = vals[this.value];
});
});
});
Related
I have a .php page with about two hundred select form elements on it. The element values are being populated by a .txt file in the same directory using PHP:
<?php
$schoolselected = 'schools.txt';
$eachlines1 = file($schoolselected, FILE_IGNORE_NEW_LINES);
?>
and
<select name="schoolselected001">
<option value="" disabled selected>Select School...</option>
<option value=" " <?php if(isset($_POST['schoolselected001'])) echo "selected"; ?>></option>
<?php foreach($eachlines1 as $lines1){
echo "<option value='".$lines1."'>$lines1</option>";
}?>
</select>
Each select form element have the same name but with 001 through 200.
I'm using this jQuery function to disable an option when selected to prevent doubling up:
<script>
$(document).ready(function(){
$('select[name*=schoolselected]').on('click', function() {
$('option').prop('disabled', false);
$('select[name*=schoolselected]').each(function() {
var val = this.value;
$('select[name*=schoolselected]').not(this).find('option').filter(function() {
return this.value === val;
}).prop('disabled', true);
});
}).change();
});
</script>
Everything works perfectly and there was no delay when I tested with ten values but now with two hundred values, there is a 10-12 second delay each time I click any of the select form elements.
Are there any tweaks I can do to the existing code to remove the delay? Or maybe I'm taking the wrong approach? I looked into caching the data but had no luck finding a solution. If I disable the jQuery function there is zero delay. Any help or suggestions would be appreciated.
So many questions to what you are trying to achieve
Why 200 select dropdowns?
Why did you use 'on click' on a select? you want 'on change' event right?
your code is slow because you are iterating twice over your 200 selects
here is the working code
<script>
$(document).ready(function(){
var lastSelectedValue = {};
$('select[name*=schoolselected]').on('change', function() {
var currentSelect = this.attributes.name.value;
var oldValue = lastSelectedValue[currentSelect];
lastSelectedValue[currentSelect] = this.value;
$('select[name*=schoolselected]').not(this).each(function() {
if(oldValue){
$(this).find("option[value='"+oldValue+"']").prop('disabled', false);
}
$(this).find("option[value='"+lastSelectedValue[currentSelect]+"']").prop('disabled', true);
});
});
});
</script>
Am using the following code to perform a livesearch via a SQL query. The Jquery code is shown below:
$(document).ready(function() {
$('#holdername').on('keydown', function() {
var searchKeyword = $(this).val();
if (searchKeyword.length >= 3) {
$.post('holdersearch.php', { keywords: searchKeyword }, function(data) {
$('ul#liveSearchList').empty()
$.each(data, function() {
$('ul#liveSearchList').append('<span class="searchResultItem">' + this.holder + '</span></br>');
});
}, "json").fail($('ul#liveSearchList').empty());
} else {
$('ul#liveSearchList').empty()
};
});
$('#liveSearchList').on('click', function() {
var holderName = $(this).find("a").html();
console.log("Holder: ",holderName);
$('#holdername').val(holderName);
$('ul#liveSearchList').empty()
});
});
This creates the list as it should however when any item in the list is selected (clicked) it will only ever populate the input box with the first item in the list. Am not sure why it is doing this, if I hover down the list the link shows the different values for hldr as it should so it appears it is working as it should. The console.log confirms the item selected is only ever the first on the list
You added click event on whole ul, so $(this).find("a").html(); select all <a> elements and return value of first
You should add click event to all <li> or <a> elements. Try this:
$('#liveSearchList').on('click', 'li', function() {
var holderName = $(this).find("a").html();
console.log("Holder: ",holderName);
$('#holdername').val(holderName);
$('ul#liveSearchList').empty()
});
I've created a very basic form that has 2 dropdown lists.
Each list contains the same entries:
<option value='1234:0'>Closed</option>
<option value='4567:2'>Open</option>
<option value='6857:1'>Dead</option>
<option value='9856:1'>Alive</option>
<option value='0000:0'>Other</option>
If an entry in dropdown 1 is selected, then that entry should be removed from dropdown 2
If a different entry is selected in dropdown 1, then that should be removed from dropdown 2 and the original entry returned to dropdown 2
if nothing is selected in dropdown 1, then all options should be shown in dropdown 2.
I've created a FIDDLE, showing how far I've got... it's not very far.
Can any one help with this ?
Thanks
Try this
$(function(){
$('#test').change(function () {
var selected = $(this).val();
$("#test2 option").show();
$("#test2 option[value='" + selected + "']").hide();
});
});
If you want to use text you can try this
$(function(){
$('#test').change(function () {
var selected = $('option:selected', this).text();
$("#test2 option").each(function(){
if($(this).text() == selected) {
$(this).hide();
} else {
$(this).show();
}
})
});
});
Since the value of each the options are identical, you can use value attribute to select the match in second select.
$('form').on('change', 'select[name="test"]', function() {
var selected = $(this).val();
$("#test2 option").show();
$("#test2 option[value='" + selected + "']").hide();
});
Demo
I know this has been asked before, but this is a slight variation.
I know how to change the selected value of a dropdown using with the selectedIndex or the option value..
$("#colA"+id).prop("selectedIndex", 0);
$("#colA"+id).val("1");
But can it be done for the option TEXT. eg:
<option value='1234'>**Entry 1**</option>
Can we change based on Entry 1 ? The value is dynamic, the text is static.
I can't find anyway to do this especially as I'm using $("#colA"+id)
Resolved using :
var defaultVal = "Event 1";
$("#ColA"+id).each(function () {
$('option', this).each(function () {
if ($.trim($(this).text().toLowerCase()) == $.trim(defaultVal.toLowerCase())) {
$(this).attr('selected', 'selected');
};
});
});
I've got two dropdowns, as a result of changing the first one it triggers a jquery change() that does a post with the company id from the first dropdown. That then runs a sql query to get a list of people that work for that company and fills the select box with options. This is working fine and I've got the sql query set to ORDER BY admin_name. But when jquery starts inserting the options into the dropdown it appears to be sorting by the option value instead (admin_id). What can I do to keep the options ordered by the admin_name (the text of the option). Below is the jQuery code responsible for adding the options:
$.post("listSignedBy.php", { company_id: company_id },
function(data) {
alert(data); <-- this shows that the data is sorted correctly by the admin name.
var select = $('#signed_by');
if(select.prop) {
var options = select.prop('options');
}
else {
var options = select.attr('options');
}
$('option', select).remove();
var obj = jQuery.parseJSON(data);
options[options.length] = new Option('-- Select Signed By --', '');
$.each(obj, function(val, text) {
options[options.length] = new Option(text, val);
});
select.val(selectedOption);
});
Thank you for any assistance and please let me know if you need any further information to help troubleshoot/fix.
As requested, example JSON data:
{"19082":"Aaron Smith","19081":"Becky Doe"}
So in this case what I WANT is:
<option value='19082'>Aaron Smith</option>
<option value='19081'>Becky Doe</option>
But instead of sorting by the text, it's sorting by the value so I get:
<option value='19081'>Becky Doe</option>
<option value='19082'>Aaron Smith</option>
The object is not sorted.. It is actually getting inserted in the order how it is iterated.
However, in case if the order of returned response is not in the desired order then the best way is it insert the options first and sort the options. See below,
DEMO: http://jsfiddle.net/gGd82/3/
// convert OPTIONs NodeList to an Array
// - keep in mind that we're using the original OPTION objects
var ary = (function(nl) {
var a = [];
for (var i = 0, len = nl.length; i < len; i++) {
a.push(nl.item(i));
}
return a;
})(options);
// sort OPTIONs Array
ary.sort(function(a, b) {
return a.text < b.text ? -1 : a.text > b.text ? 1 : 0;
});
// remove all OPTIONs from SELECT (don't worry, the original
// OPTION objects are still referenced in "ary") ;-)
options.length = 0;
// (re)add re-ordered OPTIONs to SELECT
select.html(ary);
select.prepend($('<option />').text('-- Select Signed By --').val(''));
References: Sorting dropdown list using Javascript
I was able to get it working by creating the following function and then referencing that function just after the .each() that entered all of the options in:
function Sort(a, b) {
return (a.innerHTML > b.innerHTML) ? 1 : -1;
};
$.post("listSignedBy.php", { company_id: company_id },
function(data) {
var select = $('#signed_by');
if(select.prop) {
var options = select.prop('options');
}
else {
var options = select.attr('options');
}
$('option', select).remove();
var obj = jQuery.parseJSON(data);
options[options.length] = new Option('-- Select Signed By --', '');
$.each(obj, function(val, text) {
options[options.length] = new Option(text, val);
});
$('#signed_by option').sort(Sort).appendTo('#signed_by');
select.val(selectedOption);
});