Using 2 conditions with an IF statement in Cypress - javascript

Hello I'm trying to run the following code but somehow it does not work. The same code will work if I simply separate the IF statement in 2 and nest it.
My intention is to select only one element from the dropdown list but buy using includes, I'm getting 2 results; that is why I was trying to add an extra condition to it.
cy.get("#autocomplete").type("ne");
cy.get(".ui-menu-item").each(($el) => {
if ($el.text().includes("Netherlands" && $el.text().length === 11)) {
cy.wrap($el).click();
}
Do you happen to know why that is? is there a better way of doing this? thank you

You could do it with a .filter() with a function parameter.
This variation is not currently in the Cypress docs, but they are using jQuery under the hood so refer here jQuery docs, filter(function).
Note the function receives the raw DOM element so use innerText instead of jQuery .text().
You can add multiple criteria, but with === it checks for an exact match and the length check isn't needed.
cy.get("#autocomplete").type("ne");
cy.get('.ui-menu-item') // all items
.filter((index, el) => el.innerText === "Netherlands") // precise match
.eq(0) // take the first
.click(); // select it

There is a ) missing after the text Netherlands, you have to add that and there is an extra bracket ) added after 11, you have to remove that. So, your code should be:
cy.get("#autocomplete").type("ne");
cy.get(".ui-menu-item").each(($el) => {
if ($el.text().includes("Netherlands") && $el.text().length === 11) {
cy.wrap($el).click();
}

I had a somewhat similar issue where I want to select an item in a custom select component (so not a native select element).
I used a derivation of the most upvoted answer to achieve this:
cy.get('my-component .ng-dropdown-panel .ng-option')
.filter((_, el) => {
return el.querySelector('span.badge-location')?.textContent === locationName
&& el.querySelector('span.platform-name')?.textContent === platformName;
})
.should('have.length', 1)
.click();
The code loops through all possible option elements and finds the one I'm looking for and clicks on that one.

Related

JS making a forEach match more efficient

variants is an object of objects and selectedOptions is an object of option1, option2, option3. The below forEach searches through the variants to find a match.
Is there a more efficient way, using an array method or similar, to do the following:
Object.values(variants).forEach(variant => {
if (variant.options.option1 === selectedOptions.option1 && variant.options.option2 === selectedOptions.option2 && variant.options.option3 === selectedOptions.option3) {
selectedVariant = variant.gid;
}
});
One thing you're doing here is loop through all the variants, overwriting selectedVariant each time you find a match. And if there's supposed to be only one match, you still visit all the other variants when there's no need for it anymore.
More efficient would be:
selectedVariant = Object.values(variants).find(variant => (
variant.options.option1 === selectedOptions.option1 &&
variant.options.option2 === selectedOptions.option2 &&
variant.options.option3 === selectedOptions.option3
)).gid;
That way you stop the moment you find a match.
And to be perfectly honest, setting a variant equal to another variant's gid looks wrong. Either name the variable you assign to selectedVariantGid, or assign the entire variant, and later use the .gid property once you need it. Clear naming is important.

jquery .each , if statements do not work

I am trying to remove empty columns in sharepoint display forms. I am quite new to JQuery so bear with me!
I have:
$("td.ms-formbody").each(function (index) {
if (index=6)
{
console.log("Mobile");
So it loops through all the formbody tags and when it comes to the sixth one it should display "Mobile" to console.log but it is just logging 'Mobile' x the count of the formbody tags. So it seems that the IF is not working. Can anyone advise ?
With index = 6 you are setting the value of the variable index. You should change it to index == 6 or index === 6 (in case you'd like to respect the type of the compared values).
$("td.ms-formbody").each(function (index) {
if (index === 6) {
console.log("Mobile");
}
}
By the way, it seems that you'd like to apply something to the sixth column. You could use a direct selector for that, no need to search for it with a loop.
:nth-child() selector
Change :
if (index =6)
{
console.log("Mobile");
}
To :
if (index == 6)
{
console.log("Mobile");
}
If you use a simple '=' you set the variable
$("td.ms-formbody").each(function (index) {
if (index == 6) {
console.log("Mobile");
}
}
It look like you are new to passing functions as parameters as well.
Consider the following code:
$("td.ms-formbody").each(function(){});
In this example I am parsing through all occurrences of the td.ms-formbody selector. I am passing a function through to each occurrence which can then operate on each instance of that selector. Currently I'm doing nothing.
Now consider the following:
$("td.ms-formbody").each(function(){
$("td.ms-formbody").index($(this));
});
This is one way of obtaining the index of each element. What JQuery is doing is getting all elements matching the selector and assigning them an arbitrary number based on the order in which they appear in the DOM. I can now operate on this information.
Using the correct conditional operator(==) and closing my if statement correctly, this will now log to the console if and when the each() function comes across a 6th element matching the selector.
$("td.ms-formbody").each(function(){
if($("td.ms-formbody").index($(this)) == 6){
console.log('Mobile');
}
});

Any chance to reduce the size of this snippet of code?

IS there any way I could reduce the size of the snippet of code below? Something like if (!$('body#pagina_blog_1 to body#pagina_blog_10).length) Online javascript minifier tools do not help.
jQuery(function($){
if (!$('body#pagina_blog_1, body#pagina_blog_2, body#pagina_blog_3, body#pagina_blog_4, body#pagina_blog_5, body#pagina_blog_6, body#pagina_blog_7, body#pagina_blog_8, body#pagina_blog_9, body#pagina_blog_10').length)
return;
// do stuff
});
Yes you can: $('*[id^="pagina_blog_"]')
For more details refer jquery selectors: http://api.jquery.com/attribute-starts-with-selector/
If you know it's an id on the body tag, you don't even need to use selectors as you can just get the id string directly and compare it to anything you want using a regex. For example, you could do this:
if (document.body.id.match(/^pagina_blog_\d+$/)) {
// code here
}
Or, for just any one or two digits at the end:
if (document.body.id.match(/^pagina_blog_\d{1,2}$/)) {
// code here
}
Or, if you wanted to actually see if the number after the id is in some specific numeric range such as 1-10, you could do this:
var num, matches = document.body.id.match(/^pagina_blog_(\d+)$/);
if (matches) {
num = +matches[1];
if (num >= 1 && num <= 10) {
// code here
}
}
It's not really minifying, but how about just
if ( $('[id^="pagina_blog_"]').length === 0 ) {
// do stuff
}
Give them a shared class to select on.
If you must use the ids for some reason, I would suggest...
!$('body').is('[id^="pagina_blog_"]')
The reason you do not want to put the id selector as the first selector is this would result in a complete dom scan, which is not desired. However in your logic it looks like your only concerned with the body tag having it.

_.findWhere from underscorejs to JQuery

I am trying to implement this code: http://jsfiddle.net/wQysh/351/ in my project.
Everything is fine except for the line:
t = _.findWhere(sc, { id : Number(a.trim()) });
They have used underscorejs and I want to translate this to JQuery without using another lib.
I went through the doc and it stated:
findWhere_.findWhere(list, properties)
Looks through the list and returns the first value that matches all of the key-value pairs listed in properties.
If no match is found, or if list is empty, undefined will be returned.
But still I am confused about this since I am not sure what to return exactly (as first value). Can anyone give me a JQuery alternative to that line?
Thanks in advance..
If you don't the generic nature of _.findWhere() you can use a simple while loop, and compare the id to the numeric value of a (fiddle):
t = 0; // t is used as a counter
aValue = Number(a.trim()); // assign the value to a variable instead of iterating it
while (t < sc.length && sc[t].id !== aValue) { t++; }; // find the index where the id is the as the aValue
t < sc.length && toSet.push(sc[t]); // if t is less the sc.length we found the item in the array
If you need a findWhere without underscore try this gist.
I also used this example in my project. And also needed use JQuery instead of Underscore.
Here is my solution:
t = sc.filter(function (el) { return el.id === a });
It work perfect for me;
If you use number for ids, you can also convert a to integer
t = sc.filter(function (el) { return el.id === parseInt(a, 10) });

Trying to get some jQuery functions to run in order. Is callback the issue?

I'm trying to do some things in order, and I'm having some trouble.
When the button with the id #sub_button is clicked,
Make sure each element with class ".verify" has it's own object value (see code)...
... if not, blur that element (will run some other code and create an object for it).
AFTER the above IF check is COMPLETE (now all elements should have an object), THEN run function "isitgood". (The "isitgood" function is running before all elements get their object values, which is done on blur)
$("#sub_button").click(function() {
$(".verify").each(function(){
objtitle = $(this).attr('id');
if (!myObj[objtitle]) {
$("#"+objtitle).blur(); // Define anything undefined
}
}); // end each
isitgood();
}); // end click function
function isitgood(){
if (myObj.login_id == "ok" && myObj.email == "ok") {
// submit the form
} else {
// shows error
}
}
Also, once I get this executing in the right order, it would be nice to do some sort of .each loop to check if all the object values == "ok" instead of specifying all of them in the function. All of the names of the objects (ie. login_id, email) are the ID attr of any element with class name .verify.
Well, you could do a quick index check in the click callback:
var sub_buttons = $("#sub_button");
sub_buttons.click(function() {
$(".verify").each(function(index){
objtitle = $(this).attr('id');
if (!myObj[objtitle]) {
$("#"+objtitle).blur(); // Define anything undefined
}
if (index == sub_buttons.length - 1)
isitgood();
}
}); // end each
}); // end click function
This will check if you're on the last element in the jQuery object, and if so, will run the isitgood() function. This way, you make sure that you're finished with the $.each method before executing isitgood()
Javascript is asynchronous. Your isitgood() will always fire while .each is still doing it's thing.
That said from your code it's not clear what you're trying to accomplish. The way you're using .each seems to indicate that you have multiple of the same ID attributes on your tags. That won't work, IDs have to be unique. Also you seem to be mixing jQuery and regular Javascript. Use one or the other. Actually just use jQuery, you'll save yourself time and effort!
If you do have unique ids then you shouldn't need the .each at all. Just check the appropriate ids with your if statement.
Please provide more of your code and i can update this with a better answer. For instance what does your myObj look like? How do elements of it get the value of ok? It doesn't seem to get set within your call to .each().

Categories

Resources