i have this code to show a notification:
(new js/Notification "call me" (clj->js {
:onclick (js* "new MozActivity({name:'dial',number:'12345678'})")
:sticky "true"
:silent "true"
:body (v "number")
:icon "app://communications.gaiamobile.org/dialer/style/icons/dialer_84.png"}))
The problem is the onclick function, without it, it shows correctly the notification. But if i leave it as stated it shows the dialing screen (?!?!?!?!)
i've tried also with
:onclick (js/MozActivity. (clj->js {:name "dial" :data {:number "12345678"}}))
and also behaves in the same manner
what is the correct way to pass a function to the onclick property of Notification?
`
:onclick #(js/MozActivity. #js {:name "dial" :number "12345678"})
Related
If an element is not actionable on the page (in this case, covered by another element) and you try to click it, Cypress will show an error like this:
CypressError: Timed out retrying: cy.click() failed because this element:
<span>...</span>
is being covered by another element:
Great! But is there any way to assert that this is the case, aka that the element cannot be clicked?
This doesn't work:
should.not.exist - the element does exist
should.be.disabled - the element is not disabled
should.not.be.visible - the element is visible (just covered by another, transparent element)
using cy.on('uncaught:exception', ...), since this is not an exception
See the Cypress tests at click_spec.coffee.
it "throws when a non-descendent element is covering subject", (done) ->
$btn = $("<button>button covered</button>")
.attr("id", "button-covered-in-span")
.prependTo(cy.$$("body"))
span = $("<span>span on button</span>")
.css(position: "absolute",
left: $btn.offset().left,
top: $btn.offset().top,
padding: 5, display: "inline-block",
backgroundColor: "yellow")
.prependTo(cy.$$("body"))
cy.on "fail", (err) =>
...
expect(err.message).to.include "cy.click() failed because this element"
expect(err.message).to.include "is being covered by another element"
...
done()
cy.get("#button-covered-in-span").click()
Simplest would be to mimic this test, even though docs recommend only using cy.on('fail') for debugging.
This is similar to a unit test using expect().to.throw() to check that an exception occurs as expected so I feel the pattern is justified here.
To be thorough, I would include a call to click({force: true}).
it('should fail the click() because element is covered', (done) => {
// Check that click succeeds when forced
cy.get('button').click({ force: true })
// Use once() binding for just this fail
cy.once('fail', (err) => {
// Capturing the fail event swallows it and lets the test succeed
// Now look for the expected messages
expect(err.message).to.include('cy.click() failed because this element');
expect(err.message).to.include('is being covered by another element');
done();
});
cy.get("#button-covered-in-span").click().then(x => {
// Only here if click succeeds (so test fails)
done(new Error('Expected button NOT to be clickable, but click() succeeded'));
})
})
As a custom command
I'm not sure how to make the chai extension you asked for, but the logic could be wrapped in a custom command
/cypress/support/index.js
Cypress.Commands.add("isNotActionable", function(selector, done) {
cy.get(selector).click({ force: true })
cy.once('fail', (err) => {
expect(err.message).to.include('cy.click() failed because this element');
expect(err.message).to.include('is being covered by another element');
done();
});
cy.get(selector).click().then(x => {
done(new Error('Expected element NOT to be clickable, but click() succeeded'));
})
})
/cypress/integration/myTest.spec.js
it('should fail the click() because element is covered', (done) => {
cy.isNotActionable('button', done)
});
Note
I was expecting done() to time out when the premise of the test (i.e. that the button is covered) is false.
This does not happen (reason unknown), but by chaining .then() off the 2nd click allows done() to be called with an error message. The then() callback will only be called if the click succeeds, otherwise the cy.once('fail') callback handles click failure (as per Cypress' own test).
Another way without having to catch the error when the element is clicked is to check whether or not pointer-events has been set.
For example:
cy.get('element').should('have.css', 'pointer-events', "none") // not clickable
cy.get('element').should('have.css', 'pointer-events', "auto") // clickable
Not a general answer, but it may be sufficient just to specify the z-indexes if the elements are known and known to overlap:
cy.get('element1').should('have.css', 'z-index', '2');
cy.get('element2').should('have.css', 'z-index', '1');
I have two components, DeleteCards and ConfirmModal. The DeleteCards component shows cards that can be deleted.
When the user clicks deleteCard an action updates the state like so:
{ showModal : true, title : 'Delete card', body : 'Are you sure?'}
So, this now causes my modal window to show up asking the user to confirm. The problem is that I need my deleteCard function to now wait and listen to the confirmation click inside the modal.
I can technically do this:
{ showModal : true, title : 'Delete card', body : 'Are you sure?', promise: promiseRef }
But, I know this is an anti-pattern. So, what are my options here? Or what would be the redux way of accomplishing this?
Technically that's not a Redux related issue, you could just pass a function as a prop:
<ConfirmModal onConfirm={this.onModalConfirm}/>
Or, if you're 100% decided into Redux, just make a flag, kind of, modalConfirmed, add it to mapStateToProps, in your componentDidUpdate, check for that prop, and then control the function you needed.
So I'm running a parenscript tutorial using the following code:
(defparameter *js-string-delimiter* #\")
(hunchentoot:define-easy-handler (tutorial1 :uri "/tutorial1") ()
(cl-who:with-html-output-to-string (s)
(:html
(:head (:title "Parenscript tutorial, example 1"))
(:body (:h2 "Parenscript totorial: 1st example")
"Please click the link below." :br
(:a :href "#" :onclick (parenscript:ps (alert "Hello World!"))
"Hello World!")))))
The page renders, but the clickable link does not work. When I view the source, I get the following:
<html><head><title>Parenscript tutorial, example 1</title></head><body><h2>Parenscript totorial: 1st example</h2>Please click the link below.<br /><a href='#' onclick='alert('Hello World!');'>Hello World!</a></body></html>
Which does not work. I need the alert function closed in quotes ", not semi-quotes '. What am I doing wrong?
OK, after a bunch of looking around, I found that it appears the tutorial is wrong. Instead of using parenscript:ps to generate the code, you should use parenscript:ps-inline to get the quoting correct.
Hope this helps someone else.
I have used data-confirm attribute with Html::a tags in datagrids and it worked. But now I want to use it with a button like this:
<?php echo Html::button("<span class='icon delete'></span>", [
"class" => "delete",
"title" => Yii::t("app-upload-list", "delete"),
"data-confirm" => Yii::t("yii", "Are you sure you want to delete this item?"),
])
I don't use anchor here because this button doesn't do anything in server-side.
But when I attach a click event to the button, it precedes the confirm box. I can get round it by write the confirm code myself in the click event and use a data-my-confirm (or so) attribute to prevent the double confirm boxes, but it is not so nice. Can I do that with data-confirm?
I had the same problem. Here is Yii's listener (yii.js, line 486):
// handle data-confirm and data-method for clickable and changeable elements
$(document).on('click.yii', pub.clickableSelector, handler)
.on('change.yii', pub.changeableSelector, handler);
It uses Event Delegation
Event delegation allows us to attach a single event listener, to a
parent element, that will fire for all descendants matching a
selector, whether those descendants exist now or are added in the
future.
In this case, the listener is attached to the document node, which is listening for clicks to bubble up from the clicked element. Listeners placed on the clickable elements themselves or anything that is a child of the document node will fire before those on the document node i.e. before Yii's listener.
To ensure Yii's listener fires before your listener you will have to attach your listener to the document node as Yii has done; Listeners on the same node are invoked in the order of their registration.
$(document).on('click', '.delete', yourHandlerFunction);
Note: Event delegation is used when you need a listener for elements that don't necessarily exist when the listener is added or to listen to a single node rather than several. It is usually recommended to use the nearest parent element that exists at the time of adding the listener and that continues to exist while needed. I wouldn't suggest putting listeners on the document node without good reason.
Even if it's an old question I'd like to contribute what I know.
In case you want to use html::button() instead of html::a()
Here is an example
<?php echo Html::button("<span class='icon delete'></span>", [
"class" => "delete",
"title" => Yii::t("app-upload-list", "delete"),
"onclick" => 'if(confirm("Are you sure you want to delete this item?")){
return true;
}else{
return false;
}',
]) ?>
I'm sure it should work.
I think you can find an example of something similar to that in the Yii2 template of a View.
In my view I have the following code:
<?= Html::a('Delete', ['delete'], [
'class' => 'btn btn-danger',
'data' => [
'confirm' => 'Are you sure you want to delete this item?',
'method' => 'post',
],
]) ?>
I have to admit that I have not try to use it with Html::button. But you can try something like this:
<?php echo Html::button("<span class='icon delete'></span>", [
"class" => "delete",
"title" => Yii::t("app-upload-list", "delete"),
"data" => [
'confirm' => 'Are you sure you want to delete this item?',
'method' => 'post',
],
]) ?>
EDIT:
Yes, this way do not Work.
What is recommended is to use a link (Html::a) and style it as you wish.
If you want to submit a Form you should use: Html::submitButton()
If you want to use a button... you can make it work with jQuery as mentioned by Stu here: https://stackoverflow.com/a/12697511/2437857
There are multiple places in my app when I'd like to be able to do something like
Router.go 'foo', {}, {query: '', extra_data: {bar: 1}}
I don't want bar in the URL because I don't want it there on reload or history forward/back or when sharing the URL, I just need bar during the next foo action function that occurs.
It’s just this simple (assuming your code is CoffeeScript):
Router.go 'foo', {bar: 1}
Then in your next route, for example in onBeforeAction, you should have #params.bar.