I found this while going through some cycle plugin options:
$('#prev')[index == 0 ? 'hide' : 'show']()
I hate to admit but i'm having a hard time expanding this into it's 'long' form.
I know that if index is 0 element gets hidden otherwise it's visible.
It's the $('#prev')[index == 0 that is tripping me up :-(
Normally, you would write either $("#prev").hide() or $("#prev").show() depending on what you want to do.
However, you can access properties on objects by using square brackets [] with the property name as a string - among other things, this allows for object keys that contain characters that wouldn't be valid otherwise. Even something like obj["some property name"] would be valid here.
So basically, what your ternary operator is doing is choosing whether to get the show or hide string, which is then used to retrieve that property of the jQuery object (in this case, the methods) and calling them.
To make it simple for you, the code below:
$('#prev')[index == 0 ? 'hide' : 'show']();
is same as doing:
if (index == 0) {
$('#prev').hide();
} else {
$('#prev').show();
}
All that's really happening here is a test on the index variable. If it is equal to zero then the element is being hidden, otherwise it is being shown:
var elem = $('#prev');
if ( index == 0 ) {
elem.hide();
} else {
elem.show();
}
The 'hide' and 'show' strings are merely the names of the functions. Which function needs to be called is decided by the ternary conditional statement. Both of those functions are functions of the element and therefor you call them on the actual element. The brackets at the end of the statement is what actually calls the function.
Related
str.indexOf(searchValue[, fromIndex])
The index of the first occurrence of searchValue, or -1 if not found.
- MDN web docs
Why was -1 chosen to be the returned value by .indexOf if it doesn't find a match in the array?
console.log([].indexOf()) // -> -1
Would it not be more suitable to have 0 instead? It would make sense because there are indeed 0 matching element. And this way we could have used it directly in a conditional statement, for example:
if( Array.indexOf(String) ) { ... }
Instead of
if( Array.indexOf(String) !== -1 ) { ... }
Why is that? Any particular reason? I've seen the same in Java, C++ and C. Is this because of how the native function was designed?
Would it not be more suitable to have 0 instead?
No. Indexes start from zero.
var str = "ABC";
console.log(str[0]);
console.log(str.indexOf("A"));
(The same is true of arrays, which you used for your examples despite quoting the documentation for strings).
Well. It's pretty straight forward as to why. indexOf returns the position of an element not if it exists or not. Plus all ( 99% ) programming languages are 0 indexed, or better say strings and arrays are 0 indexed which means that the first element is at position 0.
Think of position as the offset of an element from the start of the array. So the distance/offset of the first element from the start of the array is, well, 0 :)
Maybe you are looking for includes() which checks if an element is inside an array.
const arr=[1,2,3]
// classic
if (!arr.includes(4)) {
console.log('4 does not exist (classic)')
}
// or short circuit
!arr.includes(4) && console.log('4 does not exist (short circuit)')
// conditional (ternary) operator
!arr.includes(4) ? console.log('4 does not exist (ternary)') : ""
Observation
Also you shouldn't use indexOf() as a boolean condition because for example
let arr=['a','b','c']
arr.indexOf('a') ? console.log('true') : console.log('false')
In the above example, indexOf(a) returns it's position 0. In a boolean condition 0 is treated as false by javaScript. So it would not give you the expected result.
Everyone else is saying the same thing, but let me try another wording of the answer.
In Javascript arrays are indexed starting with element 0. So if the string qas found at the begining the valid return value would be 0. If string not found was reported as 0 you would not know if it was not found or found at the beginning. -1 is never a valid value for a position in a string.
As to your test
if( Array.indexOf(String) ) { ... }
you could instead use
if( 1+Array.indexOf(String) ) { ... }
to avoid using the !== -1 test.
As a general consideration, the result of Array.indesOf() is overloaded. The result contains both the funciton result and an error code. This overloading allows the function call to be used directly in a test. Consider, however, that if the function call is in the if statement you probably will need to call the function again, which is an efficiency loss. If before the if you made an assignment of the result and then tested the result you would be computationally more efficient. There is not even a memory cost because variables in funtions are on the stack which is cleared on function return if you keep the variable local.
A function that returned a structure containing a success/fail flag and a result is a clean way to do such a thing that generalizes function calls that may fail, and is a convenient place to put exception handling without complicating the simple test you want to do.
Because in almost every programming language, 0 is the first position of an array.
indexOf() gives you the position of the element in the array and valid index of array starts from 0, 1, ... and so on till the array.length-1 so if the indexOf() would return 0 for non existence element then that would be incorrect as 0 is a valid index. Thus -1 is used.
I have a function I'm testing that takes two arguments Definition and Element, and has a ternary statement in it that goes like
otherThingName: (_.has(Definition.thing, 'thingName') ? Element[Definition.thing.thingName] : null)
Now Definition.thing.thingName will exist, but Element does not have a property named Definition.
Is that property being set on Element while at the same setting otherThingName?
A ternary expression is sort of a short hand if/else, so in the first instance, its testing the statement (_.has(Definition.thing, 'thingName').
I don't work with underscore, but it looks like this test is checking if Definition.thing has a property of thingName.
If this comes back true, it will set otherThingName to be Element[Definition.thing.thingName].
Otherwise it will set it to null.
Element[Definition.thing.thingName] is looking at an object called Element, and pulling back the property with the key matching the value of Definition.thing.thingName.
For example, if
Definition.thing.thingName == "name",
Element[Definition.thing.thingName] == Element["name"] == Element.name.
Hope this helps.
Expanding out the text it becomes a bit more clear:
var str;
if (_.has(Definition.thing, 'thingName')) {
str = Element[Definition.thing.thingName]
} else {
str = null;
}
...
otherThingName: str
It looks like it is defining the member of some object 'otherThingName' to be either whatever Element has set for field Definition.thing.thingName if that exists, or null otherwise.
Let's say I have the following code:
var t = $("#objectID").html();
Checking that t is defined and has a proper value is easy.
if (typeof(t) === 'undefined' || t == null || t == '')
t = 'something else';
OR
var t = $("#objectID").html() || 'something else';
My question is though, what if you have something like the following: How would would you check it for undefined values before continuing?
$("#object").find("element").html().replace(/ |t/g, '').trim();
How do I ensure that each part of the object is legitimate before continuing down the line without having a large block of checks?
What if there's many things similar to .replace and .trim, like 10 or so? How do you check for each one?
You can use the function parameter of .html()
$("#object").find("element").html(function(html){
return ((html || 'Something').replace(/ |t/g, '') || 'Something else').trim();
});
So, what you are doing is first you're checking html has value and give it some default value if it doesn't have one. Then you group the returned string from replace and check if it has truthy value or give it a default value too and then trim it.
Here's how I would do that, checking as needed.
var element = $("#object").find("element");
var t = element.length ? element.html() : '';
t = t.replace(/ |t/g, '').trim();
First step is making a variable called element to save the jQuery object. Anytime you use the same jQuery search more than once, it's a good idea to save it to a variable: it avoids repetition and speeds up performance.
The next step is calling jQuery's length method to test if it really found any HTML elements. If either "#object" or "element" are not found, element becomes an empty jQuery object with a length of 0, and 0 is considered false in a JavaScript conditional check.
If the length of element is at least 1, then we know it's legitimate, and call safely html() on it.
If length is 0, then t is just set to an empty string. Checking length was necessary because calling html() on an empty jQuery object would have returned undefined instead of a string and caused an error.
I used the ? conditional operator for brevity but you can do the exact same check with an if statement
var element = $("#object").find("element");
if (element.length) {
var t = element.html();
} else {
var t = '';
}
t = t.replace(/ |t/g, '').trim();
I like making t default to an empty string, to ensure the variable is always a string. That way I can call replace() or trim() or any other string method with it.
An empty string also evaluates to false in JavaScript conditions, making it easy to check later on.
if (t) {
doSomethingWith(t);
}
Is this the notation to use for Not Equal To in JS, in jquery code
!== OR !=
None of them work
Here is the code I am using
var val = $('#xxx').val();
if (val!='') {
alert("jello");
}
Thanks
Jean
Equality testing in JQuery works no different from "standard" JavaScript.
!= means "not equal to", but !== makes sure that both values have the same type as well. As an example, 1 == '1' is true but not 1 === '1', because the LHS value is a number and the RHS value is a string.
Given your example, we cannot really tell you a lot about what is going on. We need a real example.
.val() is used to retrieve or set values from input in forms mostly, is that what you want to do? If not maybe you mean using .text() or .html().
If that is indeed what you want to do maybe you have your selector wrong and its returning null to you, and null does not equal '', or maybe you actually have data there, like whitespaces. :)
May be you have whitespace in your #xxx node, that why both !== and != failing, you could try following to test non whitespace characters
var val = $('#xxx').val();
if (/\S/.test(val)){
alert('jello');
}
Note: I assume jQuery's .val() won't return null because of this line in jQuery source
return (elem.value || "").replace(/\r/g, "");
If not, you need to do like this
if (val && /\S/.test(val)){
alert('jello');
}
It's both, but the latter is strict on type, see here:
https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Operators/Comparison_Operators
It is working with jquery and normal java script.
You should check (alert/debug) your val variable for its value and null.
You should also check $('#xxx').length whether you are getting elements or not otherwise you will get, hence your if condition will be false.
This is surely a JS beginner question.
My issue is I want to use the value of the variable type to access the relevant checkbox; however it is treating the variable as a string. I have tried it to two ways.
function toggleGroup(type) {
if (document.getElementById(type).checked == true){
alert("foo");
}
}
or
function toggleGroup(type) {
if (document.nav.type.checked == true){
alert("foo");
}
}
We have no way of knowing how type should be treated - you haven't show us how the function is being called (in particular, we don't know what you are passing as its argument).
If it is a string (matching the id of an element), than document.getElementById(type).checked should work (although == true is redundant).
document.nav.type.checked should not work, because dot-notation property names are not interpolated. You have to use square bracket notation for that: document.forms.nav.elements[type].checked. This will match on name or id - if you have multiple elements with the same name, then document.forms.nav.elements[type] will be an object you can treat as an array (and won't have a checked property).
you can as well compare with "true"