Reputation: 18795
I'm instantiating a dijit button inside a custom widget. That bit all works fine. In widget code I'm binding an onclick event handler but when I click the button the event fires twice. Also a second issue is that it also binds the click event to other buttons in the page that aren't related to the widget. Below is a simplified version I what I have. Can anyone tell me why it's doing that. I've spent the last couple of hours trying to fix it.
The code is below but you can also see it here
This is the html page which instantiates the custom widget https://github.com/screenm0nkey/dojo/blob/master/widgets/destroy-widget.html
This is the custom widget https://github.com/screenm0nkey/dojo/blob/master/js/tag/widgets/DestroyWidget/Widget.js
This is the template which contains the nested widget https://github.com/screenm0nkey/dojo/blob/master/js/tag/widgets/DestroyWidget/templates/template.html
This is the html inside the widget template;
<div style="border: solid 1px pink">
<h3>${name}</h3>
<div dojoType="dijit.form.Button" data-dojo-attach-point="removeBtn" class="removeBtn">
click me.
</div>
This is the JavaScript inside the widget which binds the handler;
define('tag/Widget', ['dojo', 'dojo/parser', 'dijit/_Widget', 'dijit/_TemplatedMixin'],
function(d, parser) {
return d.declare('tag.Widget', [dijit._Widget, dijit._TemplatedMixin], {
templateString : d.cache("tag", "/templates/template.html"),
widgetsInTemplate : true,
name : 'no name',
button : 'no button',
postCreate : function() {
parser.parse(this.domNode);
this.placeAt(d.byId('authorContainer'));
},
startup : function() {
dijit.registry.forEach(dojo.hitch(this, function(w) {
if (w.class === 'removeBtn') {
this.button = w;
return;
}
}))
this.button.connect('onclick', function(evt) {
console.log(evt.target);
});
},
}); });
And this is the console output;
<input type="button" value="" class="dijitOffScreen" tabindex="-1" role="presentation" data-dojo-attach-point="valueNode">
<span class="dijitReset dijitInline dijitButtonText" id="dijit_form_Button_0_label" data-dojo-attach-point="containerNode">click me.</span>
Upvotes: 4
Views: 5977
Reputation: 15587
I've been having this problem on a maintenance job..
I've ended up stopping event propagation:
clickFunction: function(e) {
// business logic here...
e.stopPropagation();
window.event.cancelBubble = true; // IE
},
I believe my template (in jade, sorry) is correct:
button(data-dojo-type="dijit.form.ToggleButton",
data-dojo-attach-event="onClick: clickFunction") Text
Works for me!
Upvotes: 0
Reputation: 770
use data-dojo-attach-event
to automatically connect a handler for you.
in your javascript, add a function that you want to have called when the button is clicked:
// somewhere in your dojo.declare...
remove: function () {
// do your remove stuff here
},
then in your template, you would have some markup like this:
<div data-dojo-type="dijit.form.Button" data-dojo-attach-event="onClick:remove">
Remove
</div>
what that markup means is that you want to connect the onClick
of the button to the remove
function of the widget that owns that template.
as a bonus, the management of this connection is handled for you so you don't need to do anything to have it properly disconnected when your widget is destroyed. if you were to do the dojo.connect
yourself then you should be storing a reference to the handle returned by dojo.connect
and doing a dojo.disconnect
when your widget is destroyed.
Upvotes: 1
Reputation: 27745
dijit.form.Button is dispatching the second click event on its internal button input. Check the source. I couldn't tell you why.
I'd recommend connecting to the widget's onClick event rather than the DOM event. missingno's answer describes the setup.
Upvotes: 1
Reputation: 69934
I don't know precisely why you get your problem but I think you might have avoided it if you used a more "Dojo style" way of doing things instead of your current "JQuery style" that uses classes for navigation:
Try using the new data-dojo attributes instead of the old dojoType style:
<div data-dojo-type="dijit.form.Button" class="remove">
Use explicit attach points to reference inner widgets:
<div data-dojo-type="dijit.form.Button"
data-dojo-attach-point="removeBtn"
class="remove">
Click me
</div>
The attach point will set a property of the main widget. You can access the button through it
dojo.connect(this.removeBtn, ...
Use onClick to connect to widgets instead of onclick
dojo.connect(this.removeBtn, 'onClick', function(){ ... });
Upvotes: 5