Disable a button on a specific drop down value - javascript

Trying to work out a small issue with dojo, where if the value of myCode equals selCode (Value selected from dropdown)
the button needs to be disabled. Where am I going wrong here?
Example
var myCode = "CC";
dojo.addOnLoad(function() {
dojo.connect(dojo.byId('#codes'), "onchange", function(evt) {
var selCode = this.val();
if (selCode == myCode) {
dojo.attr('#submit', disabled);
}
dojo.stopEvent(evt);
});
});
<select name="codes" id="codes" class="codes">
<option selected="selected" value="">Select Below</option>
<option value="AA">AA</option>
<option value="BB">BB</option>
<option value="CC">CC</option>
<option value="DD">DD</option>
</select>

Two issues:
1. Dojo doesn't use CSS selectors like that. Don't use a #.
2. The attr function takes three params (when doing what you want to do): id/dojoObj, attr name, attr value.
var myCode="CC";
dojo.addOnLoad( function() {
dojo.connect(dojo.byId('codes'), "onchange", function(evt) {
if(this.value == myCode){
dojo.attr('submit', 'disabled', 'disabled');
}
dojo.stopEvent(evt);
});
});

Well, I don't know anything about Dojo, but is sure looks like you're trying to use jQuery methods .val() and .attr(), unless Dojo has the same methods. (I couldn't find docs for them.)
Abandoning the library code for the native API would work like this:
var myCode="CC";
dojo.addOnLoad( function() {
dojo.connect(dojo.byId('#codes'), "onchange", function(evt) {
var selCode = evt.target.options[evt.target.selectedIndex].value;
if(selCode == myCode){
document.getElementById('submit').disabled = true;
}
dojo.stopEvent(evt);
});
});
Example: http://jsfiddle.net/BmSjb/21/
EDIT: Based on the comment below, you want it to toggle based on matching selection.
var myCode = "CC";
dojo.addOnLoad(function() {
dojo.connect(dojo.byId('#codes'), "onchange", function(evt) {
var selCode = evt.target.options[evt.target.selectedIndex].value;
document.getElementById('submit').disabled = (selCode == myCode);
dojo.stopEvent(evt);
});
});
Example: http://jsfiddle.net/BmSjb/32/
Now the .disabled property will be set to the result of selCode == myCode, so when true it will be disabled. When false, enabled.

Related

HTML conditional-based validation of the select option doesn't work

I would like to validate my select option list in HTML.
The full code is available here:
https://jsfiddle.net/crgfp8ud/
Where I want to distinguish the one option, which will make the other query below active.
I found a couple of solutions:
Jquery Conditional validation based on select text
https://www.py4u.net/discuss/962973
from where I've picked up the code and tried to adapt it for my purposes. Unfortunately they didn't work properly:
$(document).ready(function(){
$('input[name=proposed_cable_route]').validate({
rules: {
cname: { required: true },
select1: { valueNotEquals: "0" },
other: { required: function(element){
return $("#cf_proposed_cable_route option:selected").text() == "Internal";
}
}
}
});
and the other one
/*
$('select').change(function() {
var text = $('select option:selected').text();​​​​​​​​​
if(text == 'Internal') {
$('input[name=building_post_2000]').attr('disabled', true);
}
});
*/
the last one tried was:
$("input[name=proposed_cable_route]").on('select', function() {
var blockNumber = $('#cf_building_post_2000');
// if is company
if ($(this).val() == "Internal") {
// show panel
blockNumber.show();
// remove disabled prop
blockNumber.find('input,select,radio').prop('disabled', false);
} else {
// if is not company, hide the panel and
add disabled prop
//blockNumber.hide();
blockNumber.find("input").val("");
blockNumber.find('input,select,radio').prop('disabled', true);
}
});
Is there any way to make the validation based on the select option value?
I think this would do the trick. It gets the currently relevant SELECT and gets its value:
$('#cf_proposed_cable_route').change(function() {
var text = $(this).val();
console.log(text);
$('input[name=building_post_2000]').prop("disabled", text === 'Internal');
});
i think that you don't need to select event you just need to change event when you select one option the value of select tag will be change to be the same value of selected option
For Example
<select>
<option value="0">Select car:</option>
<option value="1">Audi:</option>
<option value="2">BMW</option>
<option value="3">Citroen</option>
<option value="4">Ford</option>
</select>
JS Validation
var sel = $("select");
sel.change(function () {
var opt = $("select option:checked")
if(opt.text() === "BMW") {
console.log(opt.text())
}
});
or you can create a loop
Example
var sel = $("select");
sel.change(function () {
for(var i = $("option").length; i >= 1; i--) {
if($(this).val() === $("option:nth-child("+i+")").val()) {
if($("option:nth-child("+i+")").text() === "BMW") {
console.log($("option:nth-child("+i+")").text())
}
}
}
});

How to run another event based on click event in jQuery?

I'd like to run a change event when user click a button.
$('#b1').on('click', function(){
$('#select_item').trigger('change');
});
$('#select_item').on('change', function(){
var jbyr = $(this).find('option:selected').val();
if(jbyr == 1){
alert('Option 1');
}
else if(jbyr == 2){
alert('Option 2');
}
else{
alert('Option 3');
}
});
What I am looking for is when I click button, the combobox change its option from previously 1 to 2 for example and fire the select_item change script so the alert('Option 2') is displayed.
addition:
#b1 is a button, not submitting anything. It just force changes the combobox option to option 2. When the combobox change by the button click, the combobox change event should fired. So, user not touch the combobox
This seems to be a simple case of do it the hard way. There is no reason, since you own both pieces of subscription code, to trigger any events what so ever. So don't do that, just encapsulate the change code into a new function. Also I highly recommend reading Decoupling Your HTML, CSS, and JavaScript - Philip Walton # Google Engineer.
$(document).ready(function() {
$('.js-alert').on('click', function() {
onSelectedChanged($('.js-select'));
});
$('.js-select').on('change', function() {
onSelectedChanged($(this));
});
function onSelectedChanged($element){
var jbyr = $element.find('option:selected').val();
if (jbyr == 1) {
alert('Option 1');
} else if (jbyr == 2) {
alert('Option 2');
} else {
alert('Option 3');
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="button" value="click me" class="js-alert" />
<select class="js-select">
<option value="1">Option 1</option>
<option value="2" selected>Option 2</option>
<option value="3">Option 3</option>
</select>
I'm uncertain about the coding need of triggering a change event on click...
"Cascading events" sure is not the idea of the year.
What I can say from here is you to define a function to call either on click or change of the elements you like.
So just create a named function:
myFunction(){
//Do whatever...
}
Then call myFunction() in the event handler you like:
$(element).on("click",myFunction);
or:
$(element).on("change",myFunction);
You need to set the the value of the combobox like this.
$('#b1').on('click', function () {
$('#select_item').val(2);
$('#select_item').trigger('change');
});
$('#select_item').on('change', function () {
var jbyr = $(this).find('option:selected').val();
if (jbyr == 1) {
alert('Option 1');
} else if (jbyr == 2) {
alert('Option 2');
} else {
alert('Option 3');
}
});

Change event triggering too early on select box

Here is a simplified version of my problem:
The HTML:
<select id="mySelect">
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
The jQuery:
$('#mySelect').change( function() {
// do stuff
} );
The problem is that when I move my mouse cursor over the options, do stuff happens as I hover over one of the options, before I actually select the new option. How do I avoid this behaviour so that .change() is triggered only when I have finished choosing a new option in the select?
Edit 1: Further information
Apparently this code would not cause behaviour described. In the actual code the select boxes are being updated as further data is loaded via .get() and processed.
Edit 2: Actual function that updates a select box
This function is the one in my code that updates one of the select boxes after more data has loaded. The global variable padm_courses is an array of course objects, that have a code and name property used to populate the course filter select box.
function loadCourseFilter() {
var selected = '';
var sel = $('<select>').attr('id','padmCourseFilter');
$(padm_courses).each(function() {
sel.append($("<option>").attr('value',this.code).text(this.name));
});
if($('#padmCourseFilter').length) {
selected = $('#padmCourseFilter').val();
$('#padmCourseFilter').replaceWith(sel);
if(selected != '') $('#padmCourseFilter option[value="'+escape(selected)+'"]').prop('selected', true);
} else {
sel.appendTo('#padm_hub_filters');
}
$('#padmCourseFilter').change( function() {
processMCRsByCourse($('#padmCourseFilter').val());
var tables = $('.sv-datatable').DataTable();
tables.rows('.duplicate').remove().draw();
filterTheBlockFilter();
} );
}
Try changing your change event
$(document).on('change', '#mySelect', function() {
// do stuff
});
Okay, I found a solution. It seems that when triggered, the function loadCourseFilter was recreating the selectbox from scratch each time and overwriting the old one. This caused weird behaviour when hovering over one of the options.
A revised version of the function adds only new options, and does not update the filter if nothing was actually added...
function loadCourseFilter() {
var sel, output;
if($('#padmCourseFilter').length) {
var count = 0;
sel = $('padmCourseFilter');
output = [];
$(padm_courses).each(function() {
if($('#padmCourseFilter option[value="'+this.code+'"]').length == 0) {
count++;
output.push('<option value="'+this.code+'">'+this.name+'</option>');
}
});
if(count > 0) {
sel.append(output.join(''));
sortDropDownListByText('padmCourseFilter');
}
} else {
sel = $('<select>').attr('id','padmCourseFilter');
$(padm_courses).each(function() {
sel.append($("<option>").attr('value',this.code).text(this.name));
});
sel.appendTo('#padm_hub_filters');
}
$('#padmCourseFilter').change( function() {
processMCRsByCourse($('#padmCourseFilter').val());
var tables = $('.sv-datatable').DataTable();
tables.rows('.duplicate').remove().draw();
filterTheBlockFilter();
} );
}

How to create a set of dropdowns where the list reduces as you select?

I have a HTML form like this:
All of the dropdowns contain the same list: Option 1, Option 2, Option 3 and the user needs to select a value for each key. This works as expected with no worries:
However, I want to enhance as it. Both the Keys and Options List can become relatively large (say 20). There is expected to be a one-to-one mapping and you can't select a value in two places. But when the list is large, it becomes easy to make a mistake and select the same value in two places. We do some client-side validation to check for duplicates but I would prefer a user experience that works by removing the selected option from other dropdowns such that it cannot be selected again. Like this:
How can I go about this?
FINAL SOLUTION
I initially selected the Knockout solution but on second thought, I preferred Rick Hitchcock's plain JQuery solution because I can easily plug it in anywhere without any additional setup. Here's how I modified Rick's solution to be more reusable:
function reducingDropdowns(dropDownSelector){
var $dropdowns = $(dropDownSelector);
$dropdowns.change(function() {
// First enable all options.
$dropdowns.find('option').prop('disabled', false);
// Then for each dropdown, get its current value and
// disable that option in other dropdowns.
$dropdowns.each(function() {
var $currDropdown= $(this);
var currDropdownValue= $currDropdown.val();
if(currDropdownValue !== ''){
var $otherDropdowns = $dropdowns.not($currDropdown);
$otherDropdowns.find('option').each(function() {
var $option = $(this);
var optionIsAlreadySelected = $option.val() === currDropdownValue;
if(optionIsAlreadySelected)
$option.prop('disabled', true);
});
}
});
});
}
now you can just give all your related dropdowns a common class and call something like this anywhere you need it:
reducingDropdowns('.myDropdownClass');
Thank you all for the help.
PS: I also realized that for my application, I preferred to disable the options that were already used instead of removing them from the list completely.
Here's a very simple way of doing it and this can be made more efficient, but here's the basic idea:
Html
<select data-bind="value: value1, options: options1, optionsCaption: ''"></select>
<select data-bind="value: value2, options: options2, optionsCaption: ''"></select>
<select data-bind="value: value3, options: options3, optionsCaption: ''"></select>
View Model
var self = this;
this.options = ko.observableArray(['Option 1', 'Option 2', 'Option 3']);
this.value1 = ko.observable();
this.value2 = ko.observable();
this.value3 = ko.observable();
this.options1 = ko.computed(function() {
return ko.utils.arrayFilter(this.options(), function(f) {
return f != self.value2() && f != self.value3();
});
}, this);
this.options2 = ko.computed(function() {
return ko.utils.arrayFilter(this.options(), function(f) {
return f != self.value1() && f != self.value3();
});
}, this);
this.options3 = ko.computed(function() {
return ko.utils.arrayFilter(this.options(), function(f) {
return f != self.value1() && f != self.value2();
});
}, this);
JSFiddle
You can hide the used options like this:
$('select').change(function() {
$('option').show();
$('select').each(function() {
var val= $(this).val();
$(this).siblings('select')
.find('option')
.filter(function() {
return $(this).val() === val && $(this).val() !== '';
})
.hide();
});
});
Working Fiddle #1
An alternative to removing the items is to disable them:
$('select').change(function() {
$('option').prop('disabled', false);
$('select').each(function() {
var val= $(this).val();
$(this).siblings('select')
.find('option')
.filter(function() {
return $(this).val() === val && $(this).val() !== '';
})
.prop('disabled', true);
});
});
Working Fiddle #2
There is even a cleaner and easier way of doing this: http://jsfiddle.net/ejs1d3zb/5/
$(function () {
$('select').change(function (){
var val = $(this).val();
$('select option[value='+val+']').not(this.children).remove();
});
});
There is an OnChange event should have some kind of taken and available list and check against each for each comobbox

Filtering html fields with jQuery

I have read about filtering table plugins. What I'm searching for is like this popup window.
(source: staticflickr.com)
When the user starts typing in the search-box, the relevant channel/category (as selected on previous dropdown box) should filter up. Also some animated loading action should happen while the filter process is going on.
I am looking for jQuery plugins which will make my filter-job easier to implement.
I think it is to ambigous to have a plugin for it. Just do something like this:
function filter($rows, category, search) {
$rows.each(function() {
if (category == ($("td:eq(2)", this).text() || category == "all") && (search. === "" || $("td:eq(1)", this).text().indexOf(search) !== -1) {
$(":checkbox", this).removeAttr("disabled");
$(this).show();
}
else
$(this).hide(function(){
$(":checkbox", this).attr("disabled", "disabled");
});
});
}
$("select.category").change(function() {
filter ($(this).closest("form").find("tr"), $(this).val(), $(this).closest("form").find("input.search").val());
});
$("input.search").keyUp(function() {
filter ($(this).closest("form").find("tr"), $(this).closest("form").find("select.catagory").val(), $(this).val());
});
You may need to make a few adjustments in order to make it work with the exact format of html.
Update to make it into a PLUGIN
$.fn.filter_table = function(options) {
options = $.extend(options, {
show: $.noop(), //Callback when a row get shown
hide: $.noop(), // Callback when a row gets hidden
entries: "table tr", // Selector of items to filter.
map: {} //Required parameter
//TODO Add default ajustment parameters here to remove ambiguity and assumptions.
});
return this.each(function() {
var form = this;
function each(callback) {
for (var selector in options.map) {
var check = options.map[selector];
$(selector, form).each(function(){
callback.call(this, check);
});
}
}
function show(row) {
if (!$(row).is(":visible")) {
options.show.apply(row);
$(row).show();
}
}
function hide(row) {
if ($(row).is(":visible"))
$(row).hide(options.hide);
}
function run_filter() {
$(options.entries, form).each(function() {
var row = this, matched = true;
each(function(check) {
matched &= check.call(this, row);
});
matched ? show(this) : hide(this);
})
}
//Bind event handlers:
each(function() {
$(this).bind($(this).is(":text") ? "keyup" : "change", run_filter);
});
});
};
You can use this plugin as follows:
$("form").filter_table({
map: {
//These callback define if a row was matched:
"select.category": function(row) {
//this refers to the field, row refers to the row being checked.
return $(this).val() == "all" || $(this).val() == $("td:eq(2)", row).text();
},
"input.search": function(row) {
return $(this).val() == "" || $(this).val() == $("td:eq(1)", row).text();
}
},
entries: "tr:has(:checkbox)", //Filter all rows that contain a checkbox.
show: function() {
$(":checkbox", this).removeAttr("disabled");
},
hide: function() {
$(":checkbox", this).attr("disabled", "disabled");
}
});
Okay it should work once it was debugged. I haven't tested it. I think that part is up to you.
If your HTML looks like this:
<form id="filterForm">
<input type="text" id="filterBox">
<input type="submit" value="Filter">
</form>
<div id="checkboxContainer">
<label><input type="checkbox" id="checkbox123"> Checkbox 123</label>
</div>
You could do something like...
//Set variables so we only have to find each element once
var filterForm = $('#filterForm');
var filterBox = $('#filterBox');
var checkboxContainer = $('#checkboxContainer');
//Override the form submission
filterForm.submit(function() {
//Filter by what the label contains
checkboxContainer.find('label').each(function() {
//If the value of filterBox is NOT in the label
if ($(this).indexOf(filterBox.val()) == -1) {
//Hide the label (and the checkbox since it's inside the label)
$(this).hide();
} else {
//Show it in case it was hidden before
$(this).show();
}
});
//Prevent the form from submitting
return false;
});
You can use this tablesorterfilter plugin to achieve what you need
Working Fiddle
And also please have a look at http://datatables.net/
There are many options out there. Here is a good place to start: http://www.wokay.com/technology/32-useful-jquery-filter-and-sort-data-plugins-62033.html
Filtering like this isn't incredibly complicated. It may be worth looking at the source of a couple plugins that come close to what you want and then try to write your own. You'll learn a lot more if you do it yourself!

Categories