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();
} );
}
Related
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())
}
}
}
});
I have a form where people sign up for a shift. There are multiple shifts on the page, and I have an onchange event that sends the sign-up via Ajax.
<select name="user" class="assign_user" id="user1">
<option value="user1234" selected="selected">Joe Bloggs</option>
<option value="">No-one</option>
<option value="user1235">Jane Mahon</option>
<option value="user1236">Ahmed Kitab</option>
<option value="user1237">Dave Smew</option>
</select>
If <option value="">No-one</option> is selected, I want to highlight the select element in yellow.
I cannot think of a way to do this with just CSS. I tried
select[value=''] {
background-color:lightyellow;
}
but the attribute filter in the square brackets doesn't accept empty values, as far as I know.
EDIT: just to be clear, empty select elements should be highlighted when the page loads, as well as when the element changes
CSS
.empty {
background-color: lightyellow;
}
Javascript
function userChanged(select) {
select = $(select);
if (select.val() === "") select.addClass("empty");
else select.removeClass("empty");
}
// UPDATED: Initialization
$(function() {
var user1 = $("#user1");
user1.change(function() { userChanged(user1); });
// Highlights select when page loads.
userChanged(user1);
});
UPDATE: Future solution uses CSS only. From: Is there a CSS parent selector?
select:has(option:checked[value='']) {
background-color: lightyellow;
}
This is my solution
jQuery
$(document).ready(function() {
$('.assign_user').on('change', function() {
var user_number = $(this).val();
var shiftid = $(this).siblings('input[name=shiftid]').val();
/*send data to database via Ajax*/
$.ajax({
url: "/admin/saveshift",
type: "GET",
data: { 'action': 'update', 'shiftid': shiftid, 'user_number': user_number },
success: function()
{
console.log("added a shift ");
/* message to user to say the record is updated */
$('#assigned').html('Updated');
$('#assigned').show();
setTimeout(function () {
$('#assigned').fadeOut();
return false;
}, 10000);
}
});
/* if null is selected, add class unassigned */
if ($(this).val() == '') {
$(this).addClass('unassigned');
} else {
$(this).removeClass('unassigned');
}
});
/* when page loads, if null is selected, add class unassigned */
$('.assign_user').each(function() {
if ($(this).val() == '') {
$(this).addClass('unassigned');
}
});
});
CSS
select.unassigned {
background-color:lightyellow;
}
I couldn't think of a way to do this with just CSS, hence the jQuery.
HTML <select> <option>s are selected by mouse click. Multiple selections are possible by CTRL+click or mouse click+drag. Deselection is possible by CTRL+click.
I would like to allow deselection of a previously selected option by clicking on it again. Any click then would toggle the selection.
var option = document.createElement('option');
option.onclick = function() {
if(this.selected) {
this.selected=false;
};
};
https://jsfiddle.net/L0L3378q/1/
Unfortunately, it seems that onclick is evaluated after the browser (Firefox in my case) handles the click itself, which results in "select" followed immediately by the "deselect" of my onclick function.
Now it would seem that all the browser does every time is "select" the option on click, which would render the function useless, if it never gets the actual selected state.
Is there a way to ensure that onclick is evaluated first, the brower's click is suppressed, or that the selected state can be tracked independently (custom property)?
as per your requirement try this
var option = document.createElement('option');
option.onmousedown = function() {
if (this.selected) {
this.selected = false;
return false;
}
else
{
this.selected = true;
return true;
}
};
option.innerHTML = "hey, hoh, gelato!";
var select = document.getElementById("sel");
select.appendChild(option);
hope it work for you
OK, specifically, on Windows 7 it doesn't work with Chrome, Firefox, Opera, Internet Explorer. On Android it doesn't even look like a pulldown menu, but that's just a jsfiddle problem, nothing to do with the code. I'll try on Windows 10 later this week.
The approach with a custom property seems to work:
https://jsfiddle.net/L0L3378q/3/
HTML:
<select id="sel" size="3" multiple="multiple">
<option>First!</option>
</select>
JavaScript:
var option = document.createElement('option');
option.myselected = false;
option.onclick = function() {
if (this.myselected) {
this.selected = false;
this.myselected = false;
}
else {
this.myselected = true;
};
};
option.innerHTML = "hey, hoh, gelato!";
var select = document.getElementById("sel");
select.appendChild(option);
I've created a script to clone a div, which works fine, however but the javascript chained function within it no longer works for any cloned elements. Works ok for the first one as expected.
I've created a jsfiddle here: https://jsfiddle.net/bvcebmbw/
The javascript is as follows (for both chained and clone functions)
$(document).ready(function () {
$(".Targeting").each(function () {
$('#TargetingAdd').click(function () {
var num = $('.clonedTargeting').length, // Checks to see how many "duplicatable" input fields we currently have
newNum = new Number(num + 1), // The numeric ID of the new input field being added, increasing by 1 each time
newElem = $('#entryTargeting' + num).clone().attr('id', 'entryTargeting' + newNum).fadeIn('slow'); // create the new element via clone(), and manipulate it's ID using newNum value
// Insert the new element after the last "duplicatable" input field
$('#entryTargeting' + num).after(newElem);
// Enable the "remove" button. This only shows once you have a duplicated section.
$('#TargetingDel').attr('disabled', false);
init(newElem.children(".Targeting"));
// Right now you can only add 4 sections, for a total of 5. Change '5' below to the max number of sections you want to allow.
if (newNum == 5)
$('#TargetingAdd').attr('disabled', true).prop('value', "You've reached the limit"); // value here updates the text in the 'add' button when the limit is reached
});
$('#TargetingDel').click(function () {
// Confirmation dialog box. Works on all desktop browsers and iPhone.
if (confirm("Are you sure you wish to remove this Targeting?")) {
var num = $('.clonedTargeting').length;
// how many "duplicatable" input fields we currently have
$('#entryTargeting' + num).slideUp('slow', function () {
$(this).remove();
// if only one element remains, disable the "remove" button
if (num - 1 === 1)
$('#TargetingDel').attr('disabled', true);
// enable the "add" button
$('#TargetingAdd').attr('disabled', false).prop('value', "add section");
});
}
return false; // Removes the last section you added
});
});
// Enable the "add" button
$('#TargetingAdd').attr('disabled', false);
// Disable the "remove" button
$('#TargetingDel').attr('disabled', true);
});
;(function($, window, document, undefined) {
"use strict";
$.fn.chained = function(parent_selector, options) {
return this.each(function() {
/* Save this to child because this changes when scope changes. */
var child = this;
var backup = $(child).clone();
/* Handles maximum two parents now. */
$(parent_selector).each(function() {
$(this).bind("change", function() {
updateChildren();
});
/* Force IE to see something selected on first page load, */
/* unless something is already selected */
if (!$("option:selected", this).length) {
$("option", this).first().attr("selected", "selected");
}
/* Force updating the children. */
updateChildren();
});
function updateChildren() {
var trigger_change = true;
var currently_selected_value = $("option:selected", child).val();
$(child).html(backup.html());
/* If multiple parents build classname like foo\bar. */
var selected = "";
$(parent_selector).each(function() {
var selectedClass = $("option:selected", this).val();
if (selectedClass) {
if (selected.length > 0) {
if (window.Zepto) {
/* Zepto class regexp dies with classes like foo\bar. */
selected += "\\\\";
} else {
selected += "\\";
}
}
selected += selectedClass;
}
});
/* Also check for first parent without subclassing. */
/* TODO: This should be dynamic and check for each parent */
/* without subclassing. */
var first;
if ($.isArray(parent_selector)) {
first = $(parent_selector[0]).first();
} else {
first = $(parent_selector).first();
}
var selected_first = $("option:selected", first).val();
$("option", child).each(function() {
/* Remove unneeded items but save the default value. */
if ($(this).hasClass(selected) && $(this).val() === currently_selected_value) {
$(this).prop("selected", true);
trigger_change = false;
} else if (!$(this).hasClass(selected) && !$(this).hasClass(selected_first) && $(this).val() !== "") {
$(this).remove();
}
});
/* If we have only the default value disable select. */
if (1 === $("option", child).size() && $(child).val() === "") {
$(child).prop("disabled", true);
} else {
$(child).prop("disabled", false);
}
if (trigger_change) {
$(child).trigger("change");
}
}
});
};
/* Alias for those who like to use more English like syntax. */
$.fn.chainedTo = $.fn.chained;
/* Default settings for plugin. */
$.fn.chained.defaults = {};
})(window.jQuery || window.Zepto, window, document);
$(document).ready(function(){
$("#connectionSub").chained("#connectionType");
$("#apppagesoptions").chained("#connectionSub");
$("#phoneVersion").chained("#phoneBrand");
$("#osVersionMin").chained("#phoneVersion");
$("#osVersionMax").chained("#phoneVersion");
});
and the HTML is 3 chained inputs:
<div class="Targeting">
<select id="connectionType" name="connectionType[]">
<option disabled value="">--</option>
<option value="pages">Facebook Pages</option>
<option value="apps">Apps</option>
<option disabled value="">--</option>
<option value="advanced">Advanced Connections</option>
</select>
<select id="connectionSub" name="connectionSub[]">
<option value="">--</option>
<option value="page_like" class="pages">People who like your Page</option>
<option value="page_friend" class="pages">Friends of people who like your Page</option>
<option value="page_exclude" class="pages">Exclude people who like your Page</option>
<option value="app_like" class="apps">People who like your App</option>
<option value="app_friend" class="apps">Friends of people who like your App</option>
<option value="app_exclude" class="apps">Exclude people who like your App</option>
</select>
<select id="apppagesoptions" name="apppagesoptions[]" multiple>
<option>test</option>
</select>
</div>
</div><!-- end #entry1 -->
<div id="addDelButtons">
<input type="button" id="TargetingAdd" value="add section">
<input type="button" id="TargetingDel" value="remove section above">
</div>
Appreciate any help with this!
For all the <div class="Targeting"> the select element's ids are remain same. that's why it's only working for first one.
i am writing following javascript application to get the data from user.
When user select the values from select menu, it show different form elements,
based on the option value. I have following code
HTML
<select>
<option value="">hi</option>
<option value="1">1</option>
</select>
<div></div>
Javascript
var myFunc = function () {
var string = '<input><span>+</span>';
$(string).appendTo('div');
$('span').on('click', function () {
myFunc();
})
};
$('select').on('change', function () {
var value = $(this).val();
if (value == 1) {
myFunc();
}
})
My question is when the user click on the plus icon it should show another
input element with the plus mark. when user select the last plus mark same thing should happen.
but the previous plus marks should become a minus. and when the user click on minus all the element below to the that minus mark should be removed.
currently my code generates the input elements. but i dont understand the
way of adding a minus marks and removing other elements. and also i need to limit the number of input elemnts to 5. Please help me. :)
DEMO
You can try this:
var myFunc = function () {
var string = '<input /><span>+</span>';
$('div span').html('-');
$(string).appendTo('div');
$('span').click(function () {
if ($(this).text() == '-')
{
$(this).nextAll().remove();
$(this).html('+');
}
else
myFunc();
});
};
$('select').on('change', function () {
var value = $(this).val();
if (value == 1) {
myFunc();
}
})
Fiddle