yii2 button click event precedes data-confirm message - button

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

Related

HTML in createNotice with Gutenberg shows [object Object]

I’m playing around with creating a custom notice in Gutenberg, and based on whether the data validates when the post is saved, the notice may include some HTML links.
I ended up only seeing the raw HTML output, so after some searching on Google I found this post on Github suggesting to use RawHTML.
So I put this code together which does create the red notice, but it doesn’t show the actual HTML only [object Object]. So I’m clearly doing something wrong here, but not sure what? Anyone who can point me in the right direction how to make the notices show the raw HTML?
wp.data.dispatch( 'core/notices' ).createNotice(
'error',
wp.element.createElement( wp.element.RawHTML, null, '<p>test</p>' ),
{
id: 'wpslupdate', // prevent duplicates
isDismissible: true
}
);
The notice component has an actions property which enables links to be rendered inside a notice, removing the need to use RawHTML.
options.actions [Array]: User actions to be presented with notice.
A notice can have one or more actions, each action has a label and must specify either a url or onClick function, eg:
wp.data.dispatch('core/notices').createNotice(
'error', // type of notice
'Something went wrong..', // message
{
id: 'wpslupdate', // prevent duplicates
isDismissible: true,
actions: [
{
label: 'Option A',
url: '#link' // styled as plain link
},
{
label: 'Option B',
onClick: () => { alert('ok') } // styled as a button link
}
]
}
);
Result:

Is it possible to share a promise between to sibling components via the redux store?

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.

How to click a link or button with random IDs?

How can I ckick the button or link with a random ID?
Have this button or link a number?
For Example:
#b.link(:number => "1").click
or
#b.button(:number => "1").click
Anyone idea?
If the element is a button, look for some of these static elements:
If the name attribute is known, try: b.button(:name => 'submit').click
If the value (text on the button) is known, try: b.button(:value => 'Submit').click
If the button is an image, you can use a regex on the source: b.button(:src => /destination-url/).click
If the element is a link, look for some of these static elements:
If the name attribute is known, try: b.link(:name => "link").click
If the href attribute is known, try: b.link(:href => "http://example.com").click
If the text of the button is static, b.link(:text => "Text of link here.").click
If these don't work, you can always look to parent elements. Hopefully this helps. I'm glad to elaborate if you provide more information about your specific case.
It works:
#b.link(:index => 1).click

Conditionally setting CSS style from ruby controller

I'm trying to dynamically change (if it got clicked) a normal table header (which is a link) to another defined CSS class 'th.hilite'. This link simply sorts this column and the header should got highlighted every time a user sorts the list.
The view where the class in question should be changed, looks like this:
%table#mytable
%thead
%tr
%th= link_to 'Title', mytable_path(:sort => 'title'), :id => 'title_header'
My question is simply: How and where could I dynamically set the class to %th.hilite if the header is clicked?
You can bind it from the view directly:
%th{:class => ("hilite" if #sort == "title")}= link_to 'Movie Title'...
However, you will also have to declare the #sort instance variable in your controller, and set it to either title or release, according to which column you are sorting. (i.e. #sort = params[:sort])
Be careful not to put logic (even conditionals) in your views if you can find a way around it. In order to avoid this common mistake, you need to make good use of the params and session hashes and set appropriate variables in controllers
# In your view
%th{:class => #title_header}= link_to 'Title', my_path(:sort => 'title'), :id => 'title_header'
# In your controller
sort = params[:sort] || session[:sort]
if sort == 'title'
ordering = {:order => :title}
end
BTW as long as values of your param match column name - no need to code each one
def index
#by=params[:by]
#movies = Movie.order(params[:by]).all
end
Javascript or jquery is not required..
The following HAML will work
%th{:class=>('title' == #sortby)?'hilite':""}= link_to 'Movie Title', movies_path(:sort => 'title'), :id => 'title_header'
You should use JavaScript to do this. I think it's good idea for you to use jQuery instead of pure JavaScript. Here are some examples
http://api.jquery.com/click/
http://api.jquery.com/css/

Problem with CSS style on formtastic buttons

If i have a formtastic button with a CSS override like this:
-f.buttons do
=f.commit_button :button_html => { :class => 'button positive' }
I am seeing the rendered style as "button positive update" in the browser. How do I get it to only reflect the CSS class that I want to use and dump the "update" class?
No can do, it's part of formtastic
button_html.merge!(:class => [button_html[:class], key].compact.join(' '))
The key in there is the 'create' or 'update' string.

Resources