I'm trying to create a simple button manager to select and eventually unselect allready checked img elements which contains CSS class .my_class, why this doesn't work?
var last_selected;
$("img.my_class").click ( function () {
if (last_selected != null) alert ($(this) == last_selected); // returns false everytime
last_selected = $(this);
});
It doesn't work because each time you call $(this) a new jQuery wrapper object is created.
Instead, try just saving "this":
var last_selected;
$("img.my_class").click ( function () {
if (last_selected != null) alert (this === last_selected);
last_selected = this;
});
why not assign a 'selected' class to the currently selected img?
$('img.my_class').click(function()
{
// remove the selected class from the previous selected
$('img.my_class.selected').removeClass('selected');
// flag the current one as selected
$(this).addClass('selected');
});
Each time you wrap this you create a new jQuery object. Two jQuery objects are not equal to each other just because they wrap the same element ($(this) != $(this)).
Instead, assign this itself to last_selected and everything should work as expected.
var last_selected;
$("img.my_class").click ( function () {
if (last_selected != null) alert (this == last_selected);
last_selected = this;
});
Related
In HTML5 I have a dropdown menu . When choosing different options I hide or show different parts of my page. Here is that script:
document
.getElementById('target')
.addEventListener('change', function () {
'use strict';
var vis = document.querySelector('.vis'),
target = document.getElementById(this.value);
if (vis !== null) {
vis.className = 'inv';
}
if (target !== null ) {
target.className = 'vis';
}
});
However what I want to do now, in another script is to preload an option from the dropdown. I can do it easily with this script:
setSelectedIndex(document.getElementById('target'),'content_1');
function setSelectedIndex(s, valsearch)
{
// Loop through all the items in drop down list
for (i = 0; i< s.options.length; i++)
{
if (s.options[i].value == valsearch)
{
// Item is found. Set its property and exit
s.options[i].selected = true;
break;
}
}
return;
}
This is where my problem comes up, my dropdow will get the value I want, but the part that I want to be shown when choosing that option won't come up.
That is because change events need to happen from the browser.
When the user commits the change explicitly (e.g. by selecting a value
from a 's dropdown with a mouse click, by selecting a date
from a date picker for , by selecting a file in the
file picker for , etc.);
If your using Jquery you can:
$("#id").val("value").trigger('change');
or you can use javascript if your not worried about building the event object:
if ("createEvent" in document) {
var evt = document.createEvent("HTMLEvents");
evt.initEvent("change", false, true);
element.dispatchEvent(evt);
}
else
element.fireEvent("onchange");
I would recommend moving your anonymous onchange function into a named function that you can call once onload, and again onchange.
Here is the function I wrote:
function setContent(id) {
//get the current visible content
var vis = document.querySelector('.vis');
//get the target element by id
var target = document.getElementById(id);
//make current vis element inv
if (vis) vis.className = "inv";
//make target element vis
if (target) target.className = 'vis';
}
and a fiddle
edited: got rid of querySelectorAll to stick closer to OP original code and updated fiddle. clarified and commented code.
The problem you have is changing a vale or the selected value of an input with JavaScript does not trigger any change event. So you would need to manually trigger the event.
function setSelectedIndex(s, valsearch)
{
// Loop through all the items in drop down list
for (i = 0; i< s.options.length; i++)
{
if (s.options[i].value == valsearch)
{
// Item is found. Set its property and exit
s.options[i].selected = true;
break;
}
}
//Setting the selected value with JavaScript does not trigger the change event so you need to manually trigger the change event
if ("createEvent" in document) {
var evt = document.createEvent("HTMLEvents");
evt.initEvent("change", false, true);
s.dispatchEvent(evt);
} else {
s.fireEvent("onchange");
}
return;
}
I have a selected object that was clicked. When this happens, i would like to retrieve the object and then find the children with a specific class value so i can disable them.
I am able to get the object but when i access the children i always get "undefined" even though i can see the children.
I browsed the object and i can see the class attributes values i am looking for.
Can somebody please tell me if i am referencing this correctly?
Below is my code,
The specific line with the issue is,
var kids = clicked_obj.children('.ui-selected');
// manually trigger the "select" of clicked elements
$(".page").click(function (e) {
console.log(e);
//var selected_divs = $(".page").find("div[class*='ui-selected']");
var selected_divs = $(".page").find(".existingFieldItem.ui-selected");
selected_divs.each(function () {
if (e.ctrlKey == true) {
var clicked_obj = e.target.parentElement;
var kids = clicked_obj.children('.ui-selected');
console.log("Ctrl clicked");
console.log($(this).attr("id"));
kids.each(function () {
$(this).removeClass("ui-selected");
});
// if command key is pressed don't deselect existing elements
$(this).removeClass("ui-selected");
$(this).addClass("ui-selecting");
}
else {
if ($(this).hasClass("ui-selected")) {
// remove selected class from element if already selected
$(this).removeClass("ui-selected");
}
else {
// add selecting class if not
$(this).addClass("ui-selecting");
}
}
});
$(".page").data("ui-selectable")._mouseStop(null);
});
});
You're missing a jQuery selection:
var clicked_obj = $(e.target.parentElement);
e.target.parentElement is a DOM element object, not a jQuery selection.
Currently I have this code to delete a table row:
var remove = document.getElementById(dataID); (this is the id of an object in the row I wish to hide)
if(remove!=null){
var v = remove.parentNode.parentNode.rowIndex;
document.getElementById(tid).deleteRow(v); (tid is the table id, not the row id)
}
However, instead of delete it, I'd just like to hide it. What's a good way to do this?
Also, in the future, I'm going to want to 'unhide' it at user request, so how can I check if it has been hidden? The if(remove!=null) is what checked if a row was already removed, so I'd need something similar.
Thank you for your time.
document.getElementById(tid).children[dataID].style.display = 'none';
You may need -1 on dataID
And block to show it again (or inline or whatever it originally was, for a div it's block).
JQuery:
$('#'+tid+':nth-child('+dataID+')').hide();
My own approach, in plain JavaScript:
function toggleRow(settings) {
// if there's no settings, we can do nothing, so return false:
if (!settings) {
return false;
}
// otherwise, if we have an origin,
// and that origin has a nodeType of 1 (so is an element-node):
else if (settings.origin && settings.origin.nodeType) {
// moving up through the ancestors of the origin, until
// we find a 'tr' element-node:
while (settings.origin.tagName.toLowerCase() !== 'tr') {
settings.origin = settings.origin.parentNode;
}
// if that tr element-node is hidden, we show it,
// otherwise we hide it:
settings.origin.style.display = settings.origin.style.display == 'none' ? 'table-row' : 'none';
}
// a simple test to see if we have an array, in the settings.arrayOf object,
// and that we have a relevant table to act upon:
else if ('join' in settings.arrayOf && settings.table) {
// iterate through that array:
for (var i = 0, len = settings.arrayOf.length; i < len; i++) {
// toggle the rows, of the indices supplied:
toggleRow({
origin: table.getElementsByTagName('tr')[parseInt(settings.arrayOf[i], 10)]
});
}
}
}
// you need an up-to-date browser (you could use 'document.getElementById()',
// but I'm also using 'addEventListener()', so it makes little difference:
var table = document.querySelector('#demo'),
button = document.querySelector('#toggle');
// binding a click event-handler to the 'table' element-node:
table.addEventListener('click', function (e) {
// caching the e.target node:
var t = e.target;
// making sure the element is a button, and has the class 'removeRow':
if (t.tagName.toLowerCase() === 'button' && t.classList.contains('removeRow')) {
// calling the function, setting the 'origin' property of the object:
toggleRow({
origin: t
});
}
});
// binding click-handler to the button:
button.addEventListener('click', function () {
// calling the function, setting the 'arrayOf' and 'table' properties:
toggleRow({
'arrayOf': document.querySelector('#input').value.split(/\s+/) || false,
'table': table
});
});
JS Fiddle demo.
References:
document.querySelector().
e.target.addEventListener().
Node.nodeType.
String.split().
As you've asked for a jQuery solution...how about
var $remove = $('#' + dataID);
if ($remove) {
$remove.closest('tr').closest().hide();
}
?
I have two inputs where I am checking to make sure that they are not empty before the form submits.
My issue is that it only validates #from_date. Is the issue that .val will only check the last id in the list?
$('#submitDates').click(function () {
// Get the fields you want to validate
var name = $("#to_date, #from_date");
// Check if field is empty or not
if (name.val()=='') {
alert ('Please Select Dates')
return false;
} ;
});
});
Any specific reason you're hooking on .click and not .submit?
You can iterate through the selected elements and check for a violating element using .each
var found = false;
$("#to_date, #from_date").each(function(i,name){
// Check if field is empty or not
if (!found && $(name).val()=='') {
alert ('Please Select Dates')
found = true;
} ;
});
return !found;
In your example var name = $("#to_date, #from_date"); is giving you a collection of two inputs and by doing if (name.val()=='') jQuery is checking only the first element in the collection, so it's not working. You may try this
$('#submitDates').click(function () {
var name = $("#to_date, #from_date");
if ( name[0].value == '' || name[1].value == '' ) {
alert ('Please Select Dates');
return false;
}
});
In the above example name[0].value refers to the first element and name[1].value refers to the second element. If you want to use jQuery's val() method then you can use it like $(name[0]).val() and $(name[1]).val().
Also you should consider to use submit event of the form instead of button's click event.
I wrote this function:
jQuery(document).ready(function() {
jQuery('input[type=text]').each( function(i) {
thisval = jQuery(this).val();
jQuery(this).blur( function() {
if (jQuery(this).val() == '') {
jQuery(this).val(thisval);
}
}); // end blur function
jQuery(this).focus( function() {
if (jQuery(this).val() == thisval) {
jQuery(this).val('');
};
});// end focus function
}); //END each function
}); // END document ready function
It's designed to get the value of an input, then if the user clicks away without entering a new value, the old value returns. This works properly with one of the inputs on the page, but not the others. However, when I remove the .blur and .focus functions and just use alert(thisval); it alerts the name of each input, so something is wrong with my function, but I can't figure out what. Any help?
You need var when declaring your variable so it's not a global one being shared, like this:
var thisval = jQuery(this).val();
Also since you're dealing specifically with text inputs you can just use the .value DOM property, like this:
jQuery(function() {
jQuery('input[type=text]').each(function(i) {
var thisval = this.value;
jQuery(this).blur( function() {
if (this.value == '') this.value = thisval;
}).focus( function() {
if (this.value == thisval) this.value = '';
});
});
});
thisval is a global variable so it is replaced with each loop. Make it local [stick var in front of it] and it should work like magic.
You should not just keep creating jQuery(this) over and over again. That is very inefficient. jQuery(this) is expensive. You should store one copy in a variable and use the variable.