Need to set the attribute (isOpen) of an element. When I "hardcode" the value to true or false it works but when I get the value from the "test" method it sets the value and the icon changes but the accordion doesn't open and close.
_title = d.create('h1')
.setClasses(['h2', 'pull-left'])
.setAttributes([['id', ++number + "values"], ['ng-click', 'isOpen = test(isOpen)'], ['ng-init', 'isOpen = true']])
.setInnerHTML(_titleHtml)
.toElement();
This is the method it calls:
scope.test = function (isOpen) {
isOpen = !isOpen;
return isOpen;
}
The compiled code from the inspector is as follows:
I have read about using $apply and $compile but not sure how to make it work.
Appreciate the help.
UPDATE:
I am including a bit more explanation to help you help me. I need to send the isOpen value to the test method because I need to implement additional logic elsewhere depending on whether the isOpen is true or false at that time.eg: if another button is clicked, if the the accordion is already open do nothing but if closed expand etc
_title = d.create('h1')
.setClasses(['h2', 'pull-left'])
.setAttributes([['id', ++number + "values"], ['ng-click', 'isOpen=!isOpen'], ['ng-init', 'isOpen=true']])
.setInnerHTML(_titleHtml)
.toElement();
There is no need to use a method....
Related
My requirement is to click on each and every payment method (pay-safe, visa, bit-pay etc.)
and then validate using assert method by comparing URL.
Problem : Unable to click on element. I'm getting null value in variable. Tried using val() as well as html() method.
I tried below code.
//cy.get('.real-money--providers-list') = allPaymentMethods
depositFiat.allPaymentMethods().find('[src*="providers/logo"]').each(($element, index, $list) => {
var namePaymentProvider = $element.find('[alt*="safe"]').text()
cy.log(namePaymentProvider)
cy.wait(1000)
if(namePaymentProvider.includes('class')){
$element.find('.provider-content--choice').click()
//cy.get('.provider-content').invoke('removeAttr','src').click()
//depositFiat.secureCheckout().click()
//cy.back()
}
})
As cypress unable to handle child windows I tried to use invoke method but no luck.
Find HTML here
<div class="provider-img"><img alt="safecharge_paysafecard" class="style__Logo-a3ugi5-2 fAwRoV visible" src="https://static.xyz.com/1234123463/img/providers/logo_safecharge_paysafecard.svg"></div>
As per your HTML fiddle, I could see that for every payment provider you can use the css selector img[class*="style__Logo"]
For one payment method you can use:
cy.get('img[class*="style__Logo"]').eq(0).invoke('attr', 'src').should('contain', 'https: //static.xyz.com/')
You are finding an image, then trying to click on it.
Most likely the click-event sits on the button
Instead try to click on the button:
cy.get('.provider-content').each($element => {
cy.wrap($element).click()
// Assert something here
})
If the click action opens up a new tab/window, and you want to assert that it moved you do this new link, then Cypress does not support this directly.
Instead, you would either get the url that should be opened by the click and verify that.
Or
Stub the browser window so that the new tab opens up in the same tab you are currently in.
You can use Recursion and Jquery .removeAttr :
cy.get('[src*="providers/logo"]') //You need to make sure here is the correct selector that covers all methods here
.then(methods => {
checkPaymentMethod
function checkPaymentMethod(methodNumber = 0) {
if(methodNumber < methods.length) {
Cypress.$(methods[methodNumber]).removeAttr("target");
cy.get(methods[methodNumber])
.click()
.should('not.exist')
cy.url().should('eq', 'targetUrl')
cy.visit('yourPageUrl')
cy.url().should('eq', 'yourPageUrl')
methodNumber ++
checkPaymentMethod(methodNumber)
}
}
})
i have created some custom woocommerce fields and i'm changing the value of a checkbox using javascript based on some criteria.
var setborder = document.getElementById("setborder");
setborder.disabled = true;
setborder.checked = true;
in the frontend it works perfect, however i'm passing the value of this checkbox in the cart using:
add_filter( 'woocommerce_cart_item_name', 'cart_item_name', 10, 3 );
function cart_item_name( $name, $cart_item, $cart_item_key ) {
if ($cart_item['setborder'] == 'on') {
$setborder = __('with border','conditional-single-product');
}
return $setborder;
}
When the value is set to checked through Javascript, the if condition is NOT met.
of course if a user clicks the button the if condition is met.
it doesn't make sense to mee.
do you have any clues?
your question is not clear enough and your code snippets are somewhat confusing. However, you should make changes to the checkbox attributes (in this case the value attribute of the checkbox) using keypress or click event of the your search criteria element then update your display to visualize behavior. Then pass your value to PHP via ajax call
For some really wierd reason the issue is resolved if i remove
setborder.disabled = true;
i found a workaround by adding
setborder.style.display = "none";
Some insight on this would be really helpful.
I've got a problem with switching between element classes - probably sth stupid, but I couldn't find the answer.
In my system I display a list of items. Now I want to be able to promote items, so that they appear at the top of the list. I created some backend infrastructure which works ok and added things to my frontend: a star (a span with star bg) next to every item's title and a jQuery script which is supposed to:
listen to 'click' event - when I click on a star
get some data- attributes from the span
post them to my controller
the controller checks if I'm allowed to promote items and replies 'true' or 'false'
if 'true' then I switch between 'gold-star' and 'silver-star' classes of the item
For some reason the classes don't switch - only when I refresh the page I can see the effect. I tried debugging with Firebug - it gets to the toggle line, but then nothing happens.
Here's the code:
<span class="silver-star promote">
$(".promote").bind("click", function() {
var $this = $(this);
var itemId = $this.attr("data-id"),
isPromoted = true;
if ($this.hasClass("gold-star")) {
isPromoted = false;
}
$.post('/promoteitems', { itemId: itemId, isPromoted: isPromoted }, function(allowPromotion) {
if (allowPromotion == true) {
$this.toggleClass("silver-star").toggleClass("gold-star");
}
});
});
Thanks in advance!
When you are getting a response back it might not recognise it as a boolean simple test would be to check response as string
From your comment on the question:
...the allowPromotion value is 'True' (with a capital T)...
That tell us it's a string, not a boolean. You don't want to just do if (allowPromotion), because that will toggle the classes even if you get back "False".
Instead:
if (allowPromotion == "True") { // Note the quotes and capital T
// ...toggle the classes
}
Or if you want to allow for possibly getting back something with a lower-case T at some point in the future:
if (/^\s*true\s*$/i.test(allowPromotion)) {
// ...toggle the classes
}
That's over-engineering it a bit (it'll work with "True", "true", " True " [note the spaces], and even an actual boolean true)...
I am new to jQuery. I have created a form where I hide some fields. I have created a function on the click of a button field. Here in this function definition I unhide the hidden fields one being my text field and another a button. I code that I use is:
finishOrder: function() {
document.getElementById("create-pwd").style.display = "block"
document.getElementById("finish-ok").style.display = "block" // this is my another button
// do further processing
},
Now on the click of another button (please see the comment "this is my another button") I call another function like this:
FinishcheckPassword: function() {
var pas = document.getElementById("pos-password")
var user = new db.web.Model("res.users").get_func("read")(this.session.uid, ['password']).pipe(function(result) {
if(pas.value == result.password){
return true
});
},
After the if condition returns true value, I want to the control to be transferred to the first function where I can do further processing. Is it possible, if yes how can this be achieved? Any help will be appreciated.
Sure, something like this:
$('#finish-ok').click(function(){
if(FinishcheckPassword()){
finishOrder();
}
}
Of course, this is probably not exactly the right code for you. The fact that you are assigning all your functions with : rather than = suggests that they are inside of some larger object. Therefore, they'd have to be called like myObject.finishOrder(). But the general approach of what I wrote above will work.
As a couple side notes, you have tagged the question with jQuery and refer to it in your post, but there isn't actually a single line of jQuery in your code.
What I've got is an ASP.NET MasterPage/ContentPage, where the ContentPage utilizes an UpdatePanel with UpdateMode set to "Conditional". This ContentPage is basically a MultiView that has 3 views: Setup, Confirm, and Complete. I've got navigation buttons that when clicked, go to the server, do what they need to do and finally update the UpdatePanel so it can come back. My problem lies in my JavaScript.
I have the following Global object literal named PAGE:
PAGE = {
panel : undefined,
currentView: undefined,
buttons : {
all : undefined,
cont : undefined
},
views : {
setup : {},
confirm : {},
complete : {}
}
};
My PAGE.init() function looks like this:
PAGE.init = function() { console.log("PAGE.init() fired");
this.panel = $('div[id$="Panel_Page"]');
this.currentView = this.panel.find('input[id$="Hidden_CurrentView"]').val();
this.buttons.all = this.panel.find('input[type="submit"]');
this.buttons.cont = this.panel.find('input[id$="Button_Continue"]');
this.buttons.all.click(function() { PAGE.panel.hide(); });
switch (this.currentView) {
case "confirm" : this.views.confirm.init(); break;
case "complete" : this.views.complete.init(); break;
default : this.views.setup.init(); break;
}
};
And last, but not least, it all gets kicked off by:
// Fire events on initial page load.
PAGE.init();
// Fire events for partial postbacks.
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(PAGE.init);
My issue is that when it first fires Page.init() everything is great, however, when you click a button it immediately throws an error of: Uncaught TypeError: Cannot set property 'all' of undefined. Now I've tried to figure this out, but I'm at a loss. It seems as though this happens to ANY nested object literal off of the root of PAGE. The immediate properties like PAGE.panel work just fine, but as soon as you need access to PAGE.buttons.all or PAGE.views.setup, it throws this error. I have never seen this before.
Any ideas out there?
Use a getter for your panel property. Seeing as everything else appears to be a property of panel this should do it - you might be losing the reference to panel during the postback, so instead of getting the object once, get it every time:
get_panel: function() { return $get("Panel_Page"); }
Again, if I just have this.panel = $get(myElement) and then my partial page update destroys the node that was returned to this.panel when I created my object initially, this.panel will become undefined. Use a getter.
Hope that helps - happy coding.
EDIT:
Actually - now that I look at it again, you'll probably want to use getters for all of your properties instead of relying on get_panel().find(..) for currentView, for example, I'd do another getter there:
get_currentView: function() { return $get("Hidden_CurrentView", this.get_panel()); }
B
Instead of using this inside of the PAGE.init() function, I used PAGE and that corrected the issue. Apparently this was not referring to PAGE but rather PAGE.init. Still not sure why, as I do this elsewhere and it works.
For instance, the following use of this works and it's no different than how I use it in my OP:
PAGE.views.setup = {
buttons : {
all : undefined,
cont : undefined
},
init: function() {
var self = this,
buttons = self.buttons;
buttons.all = PAGE.panel.find('input[type="submit"]');
buttons.all.click(function() { alert(this.id + " clicked"); });
}
}