I'm having a button toggle whether a referenced div is visible or not. Originally, I was using the code:
$('#search-options-btn').click(function() {
if ($('#search-options').is('.hidden')) {
$('#search-options').removeClass('hidden');
} else {
$('#search-options').addClass('hidden');
}
});
However, in an attempt to find cleaner code, I came across the jQuery toggle() method, which according to the API has a method implementation
.toggle( showOrHide )
showOrHide: A Boolean indicating whether to show or hide the elements.
This description leads me to believe this is a shortcut implementation method for showing or hiding by passing the...identifier? showOrHide into the toggle() method.
Of course, attempting this:
$('#search-options-btn').click(function() {
$('#search-options').toggle(showOrHide);
});
yields an error in my firebug console:
showOrHide is not defined
[Break On This Error] $('#search-options').toggle(showOrHide);
I've also tried defining showOrHide as a boolean initialized to false; the error goes away, but the issue is not fixed.
According to the jQuery online API, this is supposed to be equivalent to
if ( showOrHide == true ) {
$('#foo').show();
} else if ( showOrHide == false ) {
$('#foo').hide();
}
unless I'm completely missing how this works. Can anyone fill me in on what I'm doing wrong here? I haven't been able to find a similar implementation.
you should just need toggle(), nothing else.
$('#search-options-btn').click(function() {
$('#search-options').toggle();
});
showOrHide is the internal name. You pass in a bool:
$('#...').showOrHide(true)
if you want the item to be visible, false if you want it hidden.
Its just toggle between class and not with boolean..
$('#search-options-btn').click(function() { $('#search-options').toggle('yourClassName'); });
If yourClassName is found, then it will remove the same, otherwise it will add it.
Related
I need to check for fullscreen support with my Go WASM Canvas project, before switching to fullscreen mode. I have the following code so far:
var fullscreenFunc js.Value
var fullscreenNotSupported bool
set with the following logic:
fullscreenFunc = app.Get("requestFullscreen")
if fullscreenFunc.IsUndefined() {
fullscreenFunc = app.Get("mozRequestFullScreen")
if fullscreenFunc.IsUndefined() {
fullscreenFunc = app.Get("webkitRequestFullscreen")
if fullscreenFunc.IsUndefined() {
fullscreenFunc = app.Get("msRequestFullscreen")
if fullscreenFunc.IsUndefined() {
fullscreenNotSupported = true
println("Fullscreen not supported")
}
}
}
}
I was expecting to be able to call the correct function with js.Invoke, but I see no way to tell the Invoke upon which object the call should be made. My 'app' value is being interpreted just as a param.
func Fullscreen(app js.Value) {
if fullscreenNotSupported {
return
}
fullscreenFunc.Invoke(app)
}
resulting in:
panic: JavaScript error: 'mozRequestFullScreen' called on an object that does not implement interface Element.
So am I correct in my thinking that the only way I can call the correct method, is not to store the Function, but to store a string of the function name, and then 'invoke' / 'call' it using the following approach?
app.Call(fullscreenFunctionNameString)
It feels like I misunderstood the purpose of Invoke. Is it only for js.Global() type calls?
[edit] Using 'Call', at least it seems possible to derive the function name without having to repeat the above browser specifics:
fullscreenFunctionName = fullscreenFunc.Get("name").String()
app.Call(fullscreenFunctionNameString)
It doesn't answer the question, but is probably of help to someone trying to do the same.
The arguments to invoke get turned into arguments for the javascript function it wraps. Since those fullscreen functions don't need any arguments, I think you might just need to change:
fullscreenFunc.Invoke(app)
To:
fullscreenFunc.Invoke()
...assuming app is the same JS element in both places. If not your Call solution is probably your best bet.
I'm using Cypress for my automated tests. I'm trying to find a product on a page and click on it. If the product not displayed on the page, go to the next one until it is found.
I've been trying a lot of things already: while loop, each loop, simple cy.get but none of them work. Can anyone help me to solve this?
You'll need a recursive command, implementation of which will depend on your specific scenario. There's no one-size-fits-all solution, but generally it will look something like this:
function findElem ( targetSelector ) {
// first, we need to query a container (could be table, or a generic item
// container). The important thing is, this container must exist on every
// page you'll traverse.
cy.get('.someContainer').then( $container => {
// synchronously find the target element, however you want. In this
// example I use an attribute selector, but you can do whatever you
// want.
if ( $container.find(targetSelector).length ) {
return true;
} else {
return false;
}
}).then( found => {
if ( found ) {
return cy.log(`found elem "${targetSelector}"`);
} else {
// synchronously check if there's a next page/table
if ( Cypress.$('.nextPageButton').length ) {
// when know that there is a next page, click it using cypress
cy.get('.nextPageButton').click();
// here, assert that next page/table is loaded, possibly by
// asserting that current page/table is removed from DOM
// then, recurse
return findElem(targetSelector);
} else {
throw new Error(`Couldn't find elem "${targetSelector}" on any page`);
}
}
});
}
it('test', () => {
findElem(`[data-id="42"]`);
});
The crux of the solution is using a combination of commands to query a container, and synchronous inspection (using jQuery or whatever) to find the actual element. Learn more at Conditional Testing.
For a concrete implementation, you can refer to an older answer I gave to a similar question.
I need to check if the pop up exists, if it does then I need to check if its displayed then perform certain action on it.
I have implemented the below. I was wanting to know if there is any better way of achieving this.
licenseUpdate.isPresent().then(function (item) {
if (item == true) {
licenseUpdate.isDisplayed().then(function (res) {
if (res == true){
licenseUpdate.click();
};
});
}
});
If you are using page object (you should) you can write something like this:
clickLicenseUpdate() {
const licenseUpdate = $(licenseUpdateCssSelector);
return licenseUpdate.isPresent()
.then((isPresent) => {
if (!isPresent) { return false; }
return licenseUpdate.isDisplayed();
})
.then((isDisplayed) => {
if (!isDisplayed) { return false; }
return licenseUpdate.click().then(() => true);
})
}
Note that if you are using and old JS version (you shouldn't) you need to replace arrow functions with traditional anonymous functions.
Some helpful links about Page Object Design Pattern:
PageObjects
Martin Fowler PageObject
Code explained (or at least, that is the plan):
Using $ to locate an element but you can use any strategy
supported by Protractor.
browser.findElement(by.className('license')) equivalent to
$('license'), browser.findElement(by.id('license')) equivalent to
$('#license'). Check Protractor documentation for more examples.
Once you a have found a web element that match your locator, you can
use isPresent method to determine whether the element is present on
the page. isPresent returns a promise that resolve to a boolean
value.
then always return a promise. You can return a primitive value from
onFulfilled callback and that value would be cast to a promise with
resolve with same value. That is what is done here: if (!isPresent) { return false; }; or you can return another promise
from onFulfilled callback and the promise returned by then will be resolved or rejected with same value of returned promise.
That is what is done here: return licenseUpdate.isDisplayed();. isDisplayed() also return a
promise that will resolve with whether this element is currently
visible on the page.
This can be a bit overwhelming if you are not
used to deal with promises. Check this out Promises/A+
Finally, if the element is present and is displayed, click the element with theclick method that, surprise, also return a
promise (WebDriverJS API is based on promises).
Note that if element is not present, isPresent is false in this
line if (!isPresent), returning false immediately bypass
licenseUpdate.isDisplayed() execution and resolve with a false value. In that
case isDisplayed value is false and again false is returned
immediately bypassing the licenseUpdate.click() execution.
Also note that clickLicenseUpdate return a promise that will
resolve to false if the element is not present or if is present but not
displayed. To keep clickLicenseUpdate returned value consistent, I recommend you to wait for licenseUpdate.click() and then return a boolean value as it is done here: return licenseUpdate.click().then(() => true); (using implicit return from arrow functions) because promise returned by click() resolve with a void value.
That is harmless but is considered a good practice maintain a consistent return value, always a boolean value, not sometime a boolean and others a void value.
I am using ember-cli:2.5.0 and ember-validations:v2.0.0-alpha.5
In my ember-component i have a validation which is running automatically for each change in a attribute but i want to run this validation only if i call "validate()" method in technical term call validation lazily.
Please find the below code samples,
import Ember from 'ember';
import EmberValidations, { validator } from 'ember-validations';
export default Ember.Component.extend(EmberValidations, {
didReceiveAttrs() {
this.set('newBook', this._bookModel().create());
},
_bookModel(data = {}) {
return Ember.Object.extend(EmberValidations, {
bookVersion: null,
isEditable: false,
validationActive: false,
validations: {
bookVersion: {
inline: validator(function() {
if(this.validationActive){ //Here this.validationActive always return undefined
var version = this.model.get('bookVersion') || "",
message = [];
if (Ember.isEmpty(bookVersion)) {
message.push("Book Version is mandatory!!!");
}
if (message.length > 0) {
return message.join(',');
}
}
})
}
}
}, data);
}
});
actions: {
this.get('newBook').set("validationActive",true);
this.get('newBook').validate().then(() => {
//Do the action
}
}
I want the above validation to run only calling "this.get('newBook').validate()". I am entirely new to ember so down-voter please put your comments before down-voting for others kindly let me know for any more code samples.
Your help should be appreciable.
The addon you are using for validations ("ember-validations") is a very popular one and its documentation is pretty well when compared to others. If you look at the documentation there is a part named "Conditional Validators" in documentation. You can use a boolean property to control when the validation is to be performed.
You can see an illustration of what I mean in the following twiddle. I have created a simple validation within the application controller for user's name. The name field must have a length of at least 5 and the validation is to be performed only if the condition validationActive is true. Initially; the condition is false; which means validator did not work and isValid property of Controller (which is inherited from EmberValidations Mixin) is true. If you toggle the property with the button provided; the validation will run (since the condition is now set to true; hence validation is triggered) and isValid will return to false. If you change the value; the validation result will change appropriately with respect to the value of user's name. If you toggle the condition once again to set it to false; then isValid will become true no matter what the valie of user's name is.
I hope this gives you an insight about how to control when your validations should work.
Here is what you should do after your edit: The field is undefined because you are trying to reach component's own validationActive field within inline validator. Please get validationActive as follows this.model.get('validationActive') and give a try. It should work.
The test can be found here. I would like to be able to pass my plugin a new option string of 'false' and have my timer stop. http://www.jsfiddle.net/j78nk/2/
There is no element with the class gallery2 on that page, so pressing the button won't do anything.
Also, you are not checking the set options, only the defaults. And you return right away, before you do anything:
if (!defaults.running) {
return;
console.log('timer is inactive');
}
That code needs to be:
if (!options.running) {
console.log('timer is inactive');
return;
}