I'm in a medium project and a issue occurs.
I have extracted the essence of the problem to this fiddle
What this code is
$(".6").focusout(function(){
if( $(".6").filter(function(){ return this.value;}).not(this).length>0)
{ $(this).val("duplicated");}
What this code should do is get this.value and search it in other inputs, if it productive, alert the user and prevents the blur. The setback is in searching by value (if()), it does'nt working.
UPDATE
I have made a change in fiddle above: now the event sets a new value to input instead alert() and focus()
I have noticed that filters by "have a value" and not "have the value".
The main issue is regarding the filter.
.filter(function(){ return this.value;})
The jQuery filter method will return all jQuery objects where the return value is true. In the above code, every input that has a value will result to true.
To fix this, first save the value of the current input being modified, and then compare it with each value of the elements:
$(".6").focusout(function (e) {
var val = this.value;
if( $(".6").filter(function(){ return this.value === val;}).not(this).length>0){
$(this).val("duplicated");
}
})
A few additional tips. If you use the not() method first, then you will reduce the number of filter queries by 1.
$(".6").focusout(function (e) {
var val = this.value;
if( $(".6").not(this).filter(function(){ return this.value === val;}).length>0){
$(this).val("duplicated");
}
})
Even better, you can use the siblings() selector instead to only select other elements.
$(".6").focusout(function (e) {
var val = this.value;
if ($(this).siblings(".6").filter(function () { return this.value == val; }).length > 0) {
$(this).val("duplicated");
}
})
In this particular case, you can omit >0 in the if statement
$(".6").focusout(function (e) {
var val = this.value;
if ($(this).siblings(".6").filter(function () { return this.value == val; }).length) {
$(this).val("duplicated");
}
})
see: http://jsfiddle.net/tleish/VM2fy/4/
Related
I have a javascript function to get a property from a style attribute.
I am then checking if the attribute is equal to a specific point.
However, when I console.log() the value of the attribute, it is as expected but when I test the attribute value, it returns as false?
here is my code and screenshots:
var $paywhirlWidget = $(".payment-signup-section .container .row .col-xs-12:first-child iframe#paywhirl_frame"),
$widgetRow = $(".payment-signup-section .container .row .col-xs-12:first-child");
$.fn.inlineStyle = function (prop) {
var styles = this.attr("style"),
value;
styles && styles.split(";").forEach(function (e) {
var style = e.split(":");
if ($.trim(style[0]) === prop) {
value = style[1];
}
});
return value;
};
function checkForChanges() {
if ($(window).width() < 998) {
console.log(Boolean($paywhirlWidget.inlineStyle("height").toLowerCase() == "620px"));
console.log($paywhirlWidget.inlineStyle("height").toLowerCase());
if ($paywhirlWidget.inlineStyle("height").toLowerCase() == "620px") {
console.log("im here!!");
$widgetRow.css("display", "none");
}
} else {
if ($paywhirlWidget.inlineStyle("height") == "300px") {
console.warn("im here too!!");
$widgetRow.css("display", "none");
}
}
}
setInterval(checkForChanges, 500);
As an example, here is the "620px" test, as you can see, the first console.log() returns false, even though the second one shows the value as being exactly what I am testing for!
This is really confusing as I cannot understand why a value that is clearly true is returned as false when Boolean tested.
It looks like your style attribute has a space at the start of the value. Try using trim:
$.trim( $paywhirlWidget.inlineStyle("height").toLowerCase() ) === "620px"
Or update your inlineStyle plugin so that it does the trimming:
value = $.trim( style[1] );
Simpler to just use jQuery height() which returns number representing pixels
if ($paywhirlWidget.height() == 620)
I have a Jquery event that will collect the list of selected checkboxes and I am currently experimenting their behaviours by trying to access them 1 by 1.
$('#sub').click(function () {
var cb = $("input[type='checkbox']:checked");
var count = cb.length;
alert(cb[0].prop('checked'));
if (count == 0) {
alert('No subjects selected');
return false;
} else {
return confirm(count + " row(s) selected, proceed?");
}
});
Accessing cb directly won't work for some reason.
I need to do something like this :
cb.each(function (i) {
alert($(this).prop('checked'));
});
But this will require me to loop through all of them when I only need the first element of the array, to see if it's true.
Are there any methods and can someone tell me why my first approach didn't work? I tried using for loop but no luck.
What you are trying to do is to check whether at least one item is selected, since cb has only checked items you can just check whether the set has atleast one item like
$('#sub').click(function () {
var cb = $("input[type='checkbox']:checked");
if (!cb.length) {
alert('No subjects selected');
return false;
} else {
return confirm(count + " row(s) selected, proceed?");
}
You can use eq()
alert(cb.eq(0).prop('checked'));
or cb[0] will return dom object
alert(cb[0].checked);
Ref : https://learn.jquery.com/using-jquery-core/faq/how-do-i-pull-a-native-dom-element-from-a-jquery-object/
This:
var cb = $("input[type='checkbox']:checked");
Doesn't return a single element, it potentially returns many.
This will target the first checked checkbox:
var cb = $("input[type='checkbox']:checked:first");
This will target the first checkbox regardless of state:
var cb = $("input[type='checkbox']:first");
Ok, there is no problem, but i just got curious how to shorten this function.
$('input#sum').blur(function() {
var fieldVal = $(this).val();
$(this).val(formatNumber(fieldVal));
});
I get field value on blur modify it with formatNumber custom function and return. But is see I have 3 selectors there, is there a way to shorten this?
Format number function is:
function formatNumber(input) {
// modify and return input
}
You sure can, by passing a function to val():
$('input#sum').blur(function() {
$(this).val(function(_,v){ return formatNumber(v); });
});
Documentation
val() - function
$('input#sum').blur(function() {
this.value = formatNumber(this.value);
});
//1 selector!
I don't even see why you would need jQuery there. Don't abuse jQuery when you don't actually need it.
Take a look at jQuery's source code at line 7294:
val: function( value ) {
var hooks, ret, isFunction,
elem = this[0];
if ( !arguments.length ) {
if ( elem ) {
hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
return ret;
}
ret = elem.value;
return typeof ret === "string" ?
// handle most common string cases
ret.replace(rreturn, "") :
// handle cases where value is null/undef or number
ret == null ? "" : ret;
}
return;
}
//...
}
If you get rid of the hook part which simply replace newlines into \r\n and ignore the bottom special null case, the only thing left is just ret = elem.value. Now you know that you can safely use this.value instead of $(this).val().
$('input#sum').blur(function() {
$(this).val(formatNumber($(this).val()));
});
Doesn't solve your selectors problem, but it's shorter..
You can directly put formatted value in .val(). And use id selector $('#sum') instead of $('input#sum') directly, but make sure that you have unique id through out the html page.
$('#sum').blur(function() {
$(this).val(formatNumber($(this).val()));
});
You can use normal Javascript and create a formatNumber function extends String (or another type).
// Your function
String.prototype.formatNumber = function () {
// return the modified value of this
return this;
};
$('selector').blur(function() {
this.value = this.value.formatNumber();
});
UPDATED:
Better you can extends the HTMLInputElement and add the function to it.
// Extends the HTMLInputElement
HTMLInputElement.prototype.formatNumber = function(){
// Your function here
this.value = this.value.toFixed(0); // An example
};
$('input').blur(function() {
this.formatNumber(); // 1 line
});
i have been using jquery for a while now but only thing i know about jquery is probably a dozen of functions that get my job done. but i want to understand how jquery evolved from simpl plain javascript i.e how
$("#xyz").val();
is converted to
document.getElementById('xyz').value;
i have searched for my answer on the web but most of the writers are happy to show how you can hook on to different DOM elements with jquery, selector details etc. but nothing can be found about how actually the transition was made. can anyone refer me to some tutorial where i can get my required material?
thanks
jQuery is not a compiler. jQuery does not get compiled into javascript.
.val is a method of an object. The jQuery object.
Specifically it is
function (value) {
if (!arguments.length) {
var elem = this[0];
if (elem) {
if (jQuery.nodeName(elem, "option")) {
// attributes.value is undefined in Blackberry 4.7 but
// uses .value. See #6932
var val = elem.attributes.value;
return !val || val.specified ? elem.value : elem.text;
}
// We need to handle select boxes special
if (jQuery.nodeName(elem, "select")) {
var index = elem.selectedIndex,
values = [],
options = elem.options,
one = elem.type === "select-one";
// Nothing was selected
if (index < 0) {
return null;
}
// Loop through all the selected options
for (var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++) {
var option = options[i];
// Don't return options that are disabled or in a disabled optgroup
if (option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && (!option.parentNode.disabled || !jQuery.nodeName(option.parentNode, "optgroup"))) {
// Get the specific value for the option
value = jQuery(option).val();
// We don't need an array for one selects
if (one) {
return value;
}
// Multi-Selects return an array
values.push(value);
}
}
return values;
}
// Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
if (rradiocheck.test(elem.type) && !jQuery.support.checkOn) {
return elem.getAttribute("value") === null ? "on" : elem.value;
}
// Everything else, we just grab the value
return (elem.value || "").replace(rreturn, "");
}
return undefined;
}
var isFunction = jQuery.isFunction(value);
return this.each(function (i) {
var self = jQuery(this),
val = value;
if (this.nodeType !== 1) {
return;
}
if (isFunction) {
val = value.call(this, i, self.val());
}
// Treat null/undefined as ""; convert numbers to string
if (val == null) {
val = "";
} else if (typeof val === "number") {
val += "";
} else if (jQuery.isArray(val)) {
val = jQuery.map(val, function (value) {
return value == null ? "" : value + "";
});
}
if (jQuery.isArray(val) && rradiocheck.test(this.type)) {
this.checked = jQuery.inArray(self.val(), val) >= 0;
} else if (jQuery.nodeName(this, "select")) {
var values = jQuery.makeArray(val);
jQuery("option", this).each(function () {
this.selected = jQuery.inArray(jQuery(this).val(), values) >= 0;
});
if (!values.length) {
this.selectedIndex = -1;
}
} else {
this.value = val;
}
});
}
If we break the above wall down we can get
function (value) {
if (arguments.length === 0) {
return (this[0].value || "")
}
this.value = val;
return this;
}
Of course jQuery has a lot more code to deal with various edge cases and special things.
In essence jQuery takes a selector. finds the elements. Stores them internally then returns you an object.
This object has all kinds of methods that allow you to mutate the underlying dom objects stored internally. .val is one of them.
There are plenty of articles on how jQuery works (there are screencasts too).
jQuery, as you've noticed, is basically a bunch of methods operating on an array of elements. It is also intended to normalize browser differences under the hood.
Take the basic usage $("#xyz").val();
I can even tell you what jQuery is doing behind the scenes, but I don't think you really want to know. :)
var jQuery = function( selector, context ) {
// The jQuery object is actually just the init constructor 'enhanced'
return new jQuery.fn.init( selector, context );
},
// ...
jQuery.fn = jQuery.prototype = {
init: function( selector, context ) {
// ...
},
// ...
};
// Give the init function the jQuery prototype for later instantiation
jQuery.fn.init.prototype = jQuery.fn;
So basically $(selector) means newjQuery.fn.init(selector), it's just a shortcut for easier typing (and also to prevent the "bug" where fogetting new binds this to the global object, instead of the current instance).
Also, the so-called plug-ins added as jQuery.fn.ext are mapped to jQuery.fn.init.prototype as you can see in the last line, it's another shortcut. So when you call $(selector) everything that is added to jQuery.fn will also be on jQuery.fn.init.prototype and so the new instance will have those methods as $(selector).ext(...).
// as you use it today
jQuery.fn.plugin = function ( ... ) { ... }
$(selector).plugin( ... )
// as it would be without shortcuts
jQuery.fn.init.prototype.plugin = function ( ... ) { ... }
(new jQuery.fn.init(selector)).plugin( ... )
How do I get the id of an input element based on its value? The values will always be unique and there are only seven of them. I have tried this:
$('#wrapper').find("input[value='"+value+"']").each(function(){
return this.id;
});
But nothing is returned!
Try
$(this).id nope, this.id works, no need to create a jQuery object for the ID.
or
$(this).attr('id')
HTH
EDIT:
This might work:
$('#wrapper').find("input[value='"+value+"']").attr('id');
You write return this.id;… Return where? You simply return value from anonymous functions and I don't see where you ever trying to use it. So the answer is:
var idYouAreSearchingFor = $('#wrapper').find("input[value='"+value+"']").attr('id');
your code is almost good:
$('#wrapper').find("input[value='"+value+"']").each(function(){
return $(this).attr("id")
});
check here
http://jsfiddle.net/5xsZt/
edit: i have just tested it with this.id it works to. Your code is right. Your error is somewhere else: check it:
http://jsfiddle.net/5xsZt/3/
You can solve this using a filter. Like this:
$('#wrapper input').filter(function() {
return $(this).val() == value;
}).each(function() {
return this.id;
});
Here's a version that will definitely work in all mainstream browsers:
function getInputWithValue(wrapper, value) {
var inputs = wrapper.getElementsByTagName("input");
var i = inputs.length;
while (i--) {
if (inputs[i].value === value) {
return inputs[i];
}
}
return null;
}
var wrapper = document.getElementById("wrapper");
var input = getInputWithValue(wrapper, "some value");
window.alert(input.id);