Better way to do this via pure javascript - javascript

if(window.location.href.indexOf("=38805") > -1
|| window.location.href.indexOf("=38807") > -1
|| window.location.href.indexOf("=38816") > -1
|| window.location.href.indexOf("=38815") > -1
|| window.location.href.indexOf("=38814") > -1
|| window.location.href.indexOf("=38813") > -1
|| window.location.href.indexOf("=38811") > -1
){
do something
}
Basically, I am using a separate css for the pages that contain these strings. I might over 50 pages. Wondering if there is a cleaner way to write this. Put them into an array?

JS some function, is exactly for stuff like that:
let options = ["=38805","=38807","=38816"]; //...and the others
let link = window.location.href;
if( options.some( option => link.includes(option))){
console.log('yay! =)');
}
You're actually going through your array of options, and asking a question about each of the elements in the array : "Are you present at my URL?".
Then, the some method will return true (and in this case- active the if statment ) only if one or more elements in the options array is answering true to your includes question.
And by the way-
JS have another method that cover a similar set of mind. the every metohd.
This method, as you can understand by its name, will return true only if all the elements in the array is answering true to your question.

How about something like this to clean it up a bit:
const ids = [38805, 38807, 38811, 38813, 38814, 38815, 38816];
let windowHrefHasId = false;
for (let id of ids) {
if (window.location.href.indexOf('=' + id.toString()) > -1) {
windowHrefHasId = true;
break;
}
}
if (windowHrefHasId) {
// do something
}

Related

Javascript Filter Refactor

I am filtering an array of objects using a function that looks like this
var val = 'some text value'
this.someList = this.someList.filter(containsQuery);
function containsQuery(listItem) {
return listItem.Key_One.toLowerCase().indexOf(val) > -1 ||
listItem.Key_Two.toLowerCase().indexOf(val) > -1 ||
listItem.Key_Three.toLowerCase().indexOf(val) > -1
}
My question is what is a better way of filtering on each of the list item key values without having to write a new line for each one? i.e so I can avoid going
listItem.Key_Four.toLowerCase().indexOf(val) > -1
listItem.Key_Five.toLowerCase().indexOf(val) > -1
etc..
Any advice would be great.
Thanks!
You could use get keys of the object with Object.keys and iterate with Array#some.
function containsQuery(listItem) {
return Object.keys(listItem).some(function (k) {
return listItem[k].toLowerCase().indexOf(val) > -1;
});
}
Just a suggestion, array containing all the keys and loop them?
Like
var keys = ['key_one', 'key_two', 'key_three', 'key_four'];
for (i=0; i<keys.length; i++){
if (listItem[keys[i]].toLowerCase().indexOf(val) > -1) return true;
}
return false;
Ah damn, same idea as above, just took too long writing :D

Does Javascript have a way to simplify multiple checks for a value to be one of?

I have this code:
if (tes.test.userTestStatusId != UserTestStatus.MarkedByAdmin &&
tes.test.userTestStatusId != UserTestStatus.MarkedByUser &&
tes.test.userTestStatusId != UserTestStatus.Paused &&
tes.test.userTestStatusId != UserTestStatus.Completed) {
Is there some way I could simplify this so as not to repeat "tes.test.userTestStatusId" each time?
If strict equality is OK, you can store the values as an array and use indexOf:
var statuses = [UserTestStatus.MarkedByAdmin, ...];
if (statuses.indexOf(userStatusId) === -1) {
//...
}
you can cache the value
var userId = tes.test.userTestStatusId;
if (userId != UserTestStatus.MarkedByAdmin &&
userId != UserTestStatus.MarkedByUser &&
userId != UserTestStatus.Paused &&
userId != UserTestStatus.Completed)
{
put the status in an array
var statuses = [ UserTestStatus.MarkedByAdmin, UserTestStatus.MarkedByUser, UserTestStatus.Paused, UserTestStatus.Completed];
now check the index
if ( statuses.indexOf( userId ) == -1 )
This won't be much less code, but it will be much more stable — you'll be able to add/remove cases from the status object without having to change the code.
The idea is to iterate through UserTestStatus properties and look for any that match:
if (!Object.keys(UserTestStatus).some(function(key) {
return UserTestStatus[key] == test.test.userTestStatusId;
})) {
// no matches found
}
Now if you come back and add a new case (maybe UserTestStatus.Failed or UserTestStatus.NotStarted) that code won't have to change.
You can use Array.some():
if (![
'MarkedByAdmin',
'MarkedByUser',
'Paused',
'Completed'
].some((p) => UserTestStatus[p] === tes.test.userTestStatusId)) {
// ...
}
But I personally think that the vanilla conditional approach is cleaner.
If I understand your question correctly, you can save the id in a new var and then use it in the if condition like below:
var statusId=tes.test.userTestStatusId;
if ( statusId!= UserTestStatus.MarkedByAdmin &&
statusId != UserTestStatus.MarkedByUser &&
statusId != UserTestStatus.Paused &&
statusId != UserTestStatus.Completed) {
But if you are looking for the way to combine multiple logical check in a single usage, it will not be effective as far as I know

How to set a variable depending on which nodeList is not empty in JavaScript?

I'm wondering if there is a nicer way to do this:
I'm trying to set target to either "[data-update]" or div.ui-content to be found within an element.
Originally I wanted to do something like this:
target = el.querySelectorAll("[data-update]") || el.querySelectorAll("div.ui-content");
But this will not work, because the first expression will always be defined, even if it is an empty nodeList [].
So now I have this, which works, but I'm not happy with it:
target = container.querySelectorAll("[data-update]")
if (target.length === 0) {
target = container.querySelectorAll("div.ui-content");
}
if (target.length === 0) {
util.errorHandler({"error": "updatePageSection: No target found"});
} else {
// do stuff
}
Question:
Is there an easier way to do this? Pure JavaScript only.
Thanks!
Use the conditional operator, and check the length of the selection:
target = el.querySelectorAll("[data-update]").length
? el.querySelectorAll("[data-update]")
: el.querySelectorAll("div.ui-content");
Basically a ? b : c means if a is true, take b, else take c. More infor on: Contional operator.
Besides, if you don't want to repeat the first selection, you can add an extra step:
target = el.querySelectorAll("[data-update]");
target = target.length ? target : el.querySelectorAll("div.ui-content");
The first tme you see this syntax is really strange. But you'll soon get used to it.
NOTE: in JavaScript, zero is treated as false. And a none-zero number is treated as true.
You can do this:
target = ( el.querySelectorAll("[data-update]").length>0 &&
el.querySelectorAll("[data-update]") ) ||
( el.querySelectorAll("div.ui-content").length> 0 &&
el.querySelectorAll("div.ui-content") );
But it is absolutely unreadable and too much DOM calls. But "one-line".
Fiddle: http://jsfiddle.net/3X2Nd/

How to use IndexOf in JQuery

if($('#this').val().indexOf('4289')){
Do something
else
Do something.
This works only with that 4289,
When I try to add other numbers to be indexed next to it using 'or', it doesn't work. How should I put other number. E.g
IndexOf('4289||78843')
I want this to check this numbers and if the number in the input field is not one of this, to echo error.
Here's more which happens to die when one revisits the field.
$('#Zip').blur(function(){
if (($(this).val().indexOf('0860') > -1)||($(this).val().indexOf('0850') > -1)){
$('#Status_Zip').html("No way.")
$(this).alterClass('*_*', 'Success')
return false;
}else{$('#Status_Code').hide()
$(this).alterClass('*_*', 'Error')
$(this).css('border-color', '#F00').css('background-color', '#FFC').effect("pulsate",{times:4},2)
return true;
}
})
That's because it would be looking for the string '4289||78843', which doesn't exist in the target I'm assuming. Logical operators can't just be tossed in anywhere, only where there are actual values to logically operate on. Something like this:
if(($('#this').val().indexOf('4289') > -1) ||
($('#this').val().indexOf('78843') > -1))
The return value of the indexOf() function is the numeric index of that value in the target value, or -1 if it's not found. So for each value that you're looking for, you'd want to check if it's index is > -1 (which means it's found in the string). Take that whole condition and || it with another condition, and that's a logical operation.
Edit: Regarding your comment, if you want to abstract this into something a little cleaner and more generic you might extract it into its own function which iterates over a collection of strings and returns true if any of them are in the target string. Maybe something like this:
function isAnyValueIn(target, values) {
for (var i = 0; i < values.length; i++) {
if (target.indexOf(values[i]) > -1) {
return true;
}
}
return false;
}
There may even be a more elegant way to do that with .forEach() on the array, but this at least demonstrates the idea. Then elsewhere in the code you'd build the array of values and call the function:
var values = ['4289', '78843'];
var target = $('#this').val();
if (isAnyValueIn(target, values)) {
// At least one value is in the target string
}

Check presence of an element with jquery

I have a page in which i need to check the presence of a HTML element dynamically.Therefore I need to know the correct way of doing this
You could do:
$(function() {
if ($('.myElement').length > 0) {
console.log('There is one or more elements with class="myElement"');
}
});
$('#id').length === 0; // element does not exist
$('#id').length > 0; // element exists
Personally I like very much the "presence" idiom from Ruby on Rails, so I have added this to my JS set up:
jQuery.fn.presence = function presence() {
return this.length !== 0 ? this : null;
};
and now use this in my code:
if (el.presence()) { ... }
and better yet
const ul = el.parents('UL').first().presence() ?? el.siblings('UL').first()
(If you can't afford ??, || would do just as well here.)

Categories