Jquery Issues with IE8 and Android - javascript

Having an issue with the following code on IE8 and some android versions. The variable "method" is always unset throwing the alert even when the object it refers to is checked. This works in most every other browser except IE8 and possibly IE9, as well as some android OS's (haven't nailed down exactly which ones).
$(document).ready(function() {
$('#choose_shipper').click(function(){
var method = $('#fedex_method:checked').val();
if (!method){
alert('Please select a shipping option');
}else{
DO SOMETHING ELSE HERE
}
});
});
EDIT
Simple answer, stupid habit... I was using multiple instances of the same id... Older browsers don't like that and treat all duplicate instances like they do not exist. SO! Changing "fedex_method" from an ID to a CLASS solved all the problems! My BAD!

To evaluate a single checkbox, try this instead
var method = $("#fedex_method").prop("checked");
To evaluate multiple checkboxes, something like
var method = $("#fedex_method:checked").length;
Or (since you should not have multiple checkboxes with the same id):
var method = $("input:checkbox[name=fedex_method]:checked").length;
Per the jquery documentation:
According to the W3C forms specification, the checked attribute is a boolean attribute, which means the corresponding property is true if the attribute is present at all—even if, for example, the attribute has no value or is set to empty string value or even "false". This is true of all boolean attributes.
Nevertheless, the most important concept to remember about the checked attribute is that it does not correspond to the checked property. The attribute actually corresponds to the defaultChecked property and should be used only to set the initial value of the checkbox. The checked attribute value does not change with the state of the checkbox, while the checked property does. Therefore, the cross-browser-compatible way to determine if a checkbox is checked is to use the property:
if ( elem.checked )
if ( $( elem ).prop( "checked" ) )
if ( $( elem ).is( ":checked" ) )

Related

How can I determine if an HTML element has a value, even if it is empty?

I have an element that can exist as:
<input type="hidden" name="simple_search_criteria" id="simple_search_criteria" value="" />
or
<input type="hidden" name="simple_search_criteria" id="simple_search_criteria"/>
and my code needs to know whether the value exists and what the value is. I have code that works below, but feels kludgy since I'm doing two calls on the element, any suggestions on improving the code below?
if ($('#simple_search_criteria').attr('value') !== undefined) {
var searchCriteria = $('#simple_search_criteria').val();
// Do stuff with searchCriteria, even if it is an empty string
}
I like the code below but it doesn't work since .val() returns an empty string in both situations...
var searchCriteria = $('#simple_search_criteria').val();
if (searchCriteria) {
// do stuff with searchCriteria
}
Any improvements would be appreciated, I'm always trying to improve my js!
It would be faster to use regular JavaScript. Try hasAttribute and getElementById
var searchCriteria = document.getElementById('simple_search_criteria').hasAttribute('value');
I don't know if there is a jquery helper for checking the existance of an attribute but javascript has the method hasAttribute natively.
document.getElementById("simple_search_criteria").hasAttribute("value");
The idea is to check that val() returns anything and if so check if what is there is not empty.
To respond to a comment (that was deleted), typeof will return 'undefined' if for example the element (which corresponds here to $('#simple_search_criteria')) does not exist. Documentation for typeof can he also useful. You may have a look here.
var searchCriteria = $('#simple_search_criteria').val();
if (typeof(searchCriteria) !== 'undefined' and searchCriteria.length > 0) {
// do stuff with searchCriteria
}
An input element always has a value, even if its value attribute is omitted in the markup, which is why .val() doesn't distinguish between the presence of the attribute with an empty value, and the absence of the attribute. Critically, your form will submit with the same simple_search_criteria= (empty string) data in both cases, so the server receiving the form submission will not be able to distinguish the two. This is something you'll need to keep in mind when designing your form. If you want to omit this parameter you need to omit this particular input element altogether, not just its value attribute.
Nevertheless, if you want your application to behave based on the presence or absence of the attribute you need to check that directly. You can save some overhead by caching the selector in a separate variable:
var searchCriteriaInput = $('#simple_search_criteria');
if (searchCriteriaInput.attr('value') !== undefined) {
var searchCriteria = searchCriteriaInput.val();
// Do stuff with searchCriteria, even if it is an empty string
}
You can instead use the typeof attribute to distinguish between undefined and the empty string in this case:
typeof(document.getElementById("simple_search_criteria"))==='string';
More details here

.attr("value") is always returning undefined?

I have a hidden element and within my jQuery:
<input type="hidden" id="1val" value="24">
var valID = $("#1val").attr("value");
However when I try to print valID it is always printed as undefined? What am I doing wrong?
Thanks
It's always safer to use the .prop() or .val() method to get the current value property:
var valID = $("#1val").val();
// or
var valID = $("#1val").prop("value");
As of jQuery version 1.9, the .attr() method will only get the element's attribute, which may not actually reflect the element's actual property.
According to the version 1.9 release notes, under .attr() versus .prop():
The value property versus attribute on input elements is another example of this ambiguity. The attribute generally reflects the value that was read from the HTML markup; the property reflects the current value. Since the .val() method is the recommended jQuery way to get or set the values of form elements, this confusion usually does not affect users.
However, when a selector like input[value=abc] is used, it should always select by the value attribute and not any change made to the property by the user, for example from them typing into a text input. As of jQuery 1.9, this behaves correctly and consistently. Earlier versions of jQuery would sometimes use the property when they should have used the attribute.
Under the hood, as of version 1.9, the .attr() method will only return the current attribute of the element (and not the property). The attribute and the property may not actually be the same. For instance, if there was initially no attribute on the element, and then the value was programatically set using a method such as .val(), then the attribute wouldn't have changed meaning that .attr('value') would return undefined.
As stated above, use the .prop() or .val() method in order to get the element's current value property.
Use $('#input-id').val(); to get value of input.

Is access and modification of 'HTMLInputElement.<property>' faster than "Element.(g/s)etAttribute('<property>')"?

For example, if I want to check if an input element is disabled what would be faster?
//assuming node is an <input> element
var a = node.getAttribute('disabled');
//or
var a = node.disabled;
Similarly, if I wanted to change the value,
//assuming node is an <input> element
node.setAttribute('disabled', true);
//or
node.disabled = true;
//(Both change the DOM node)
Native access is a fastest way because no compatibility navigator check is do.
In your case, disabled property is defined in famous navigator but an "special" event or property can be undefined.
So, if you want have fastest/performance solution, try to avoid framework property/event access and use an specific native script.

jQuery MultiSelect Library Uses Incorrect Method to Handle "Select All"?

I'm trying to update a large web application that uses an extended version of Cory S.N. LaViska's jQuery.multiSelect plugin.
I updated to the latest code and it fixed a problem I was encountering. However, it introduced a new problem: Checking the Select All option now unchecks everything instead of checking it.
I'm not super advanced in JavaScript but have isolated the problem to the following code:
currentMultiSelect.next('.multiSelectOptions').find('INPUT.selectAll').click(function () {
if ($(this).attr('checked') == true)
$(this).parent().parent().find('INPUT:checkbox').attr('checked', true).parent().addClass('checked');
else
$(this).parent().parent().find('INPUT:checkbox').attr('checked', false).parent().removeClass('checked');
});
The problem is that $(this).attr('checked') returns "checked". And so $(this).attr('checked') == true will always be false. And the code never detects that this option is, in fact, checked!
Okay, so I understand the problem. But why would it ever be written this way, and what is the most reliable way to fix this? I'd be interested to know how a JavaScript/jQuery expert would address this.
checked is a property, you should use prop method, when a boolean attribute like disabled or checked is set to an element, the value is mapped to the relevant DOM property of the element(browser do this), as of jQuery 1.6 for modifying properties, prop method should be used instead of attr.
So you code should looks like this
currentMultiSelect.next('.multiSelectOptions').find('INPUT.selectAll').click(function () {
if ($(this).is(':checked'))
$(this).parent().parent().find('INPUT:checkbox').prop('checked', true).parent().addClass('checked');
else
$(this).parent().parent().find('INPUT:checkbox').prop('checked', false).parent().removeClass('checked');
});
Better if you use .is(":checked") for checking whether the checkbox is checked or not. But use prop to set the checked property of checkbox.
Rather than using $(this).attr('checked') == true which will return a string try $(this).prop('checked') == true
$.prop() will return boolean true when the element is checked or boolean false when it is not.
A little extra information on $.attr() is it returns the contents of the attribute. So if your html is:
<input id="elem" type="checkbox" checked="checked" />
Then $('#elem').attr("checked") is only going to return the string inside that attribute of the selected element.
If you really wanted to use $.attr() you could do this.
if ($(elem).attr("checked") != '') { ... }

checked = "checked" vs checked = true

What is the difference between the below two usages?
document.getElementById('myRadio').checked = "checked";
and
document.getElementById('myRadio').checked = true;
For me, both are behaving the same way. But, I am just curious to know why there exist two methods to do the same.
Which one will be the ideal usage? I need to support IE7 and higher versions.
document.getElementById('myRadio').checked is a boolean value. It should be true or false
document.getElementById('myRadio').checked = "checked"; casts the string to a boolean, which is true.
document.getElementById('myRadio').checked = true; just assigns true without casting.
Use true as it is marginally more efficient and is more intention revealing to maintainers.
The element has both an attribute and a property named checked. The property determines the current state.
The attribute is a string, and the property is a boolean. When the element is created from the HTML code, the attribute is set from the markup, and the property is set depending on the value of the attribute.
If there is no value for the attribute in the markup, the attribute becomes null, but the property is always either true or false, so it becomes false.
When you set the property, you should use a boolean value:
document.getElementById('myRadio').checked = true;
If you set the attribute, you use a string:
document.getElementById('myRadio').setAttribute('checked', 'checked');
Note that setting the attribute also changes the property, but setting the property doesn't change the attribute.
Note also that whatever value you set the attribute to, the property becomes true. Even if you use an empty string or null, setting the attribute means that it's checked. Use removeAttribute to uncheck the element using the attribute:
document.getElementById('myRadio').removeAttribute('checked');
The original checked attribute (HTML 4 and before) did not require a value on it - if it existed, the element was "checked", if not, it wasn't.
This, however is not valid for XHTML that followed HTML 4.
The standard proposed to use checked="checked" as a condition for true - so both ways you posted end up doing the same thing.
It really doesn't matter which one you use - use the one that makes most sense to you and stick to it (or agree with your team which way to go).
document.getElementById('myRadio') returns you the DOM element, i'll reference it as elem in this answer.
elem.checked accesses the property named checked of the DOM element. This property is always a boolean.
When writing HTML you use checked="checked" in XHTML; in HTML you can simply use checked. When setting the attribute (this is done via .setAttribute('checked', 'checked')) you need to provide a value since some browsers consider an empty value being non-existent.
However, since you have the DOM element you have no reason to set the attribute since you can simply use the - much more comfortable - boolean property for it. Since non-empty strings are considered true in a boolean context, setting elem.checked to 'checked' or anything else that is not a falsy value (even 'false' or '0') will check the checkbox. There is not reason not to use true and false though so you should stick with the proper values.
checked attribute is a boolean value so "checked" value of other "string" except boolean false converts to true.
Any string value will be true. Also presence of attribute make it true:
<input type="checkbox" checked>
You can make it uncheked only making boolean change in DOM using JS.
So the answer is: they are equal.
w3c

Categories