Dojo button created programmatically-Scope problem - dojo

Dear All,
I've created a new Dojo button programatically. I'm doing that in one of my custom dojo class. While creating the button, I've defined an onClick method which should be called when the button is clicked. This method is part of the class. I'm not able to invoke that method, since the scope of "this" is different when the button is clicked. Can some one please help me to do fix this?
dojo.declare("CustomClass",null,{
createCustomButton:function(){
var button = new dijit.form.Button({onClick:function(){
removetrack();
testDataGrid.filter({status:"COMPLETED"});
}},"testButton1");
},
removetrack:function(){
//some logic
}
});
var customObj=new CustomClass();
customObj.createCustomButton();
I need removetrack() method to be called when I click on the Button created.

Use dojo.hitch();
dojo.declare("CustomClass",null,{
createCustomButton:function(){
var button = new dijit.form.Button({
onClick:dojo.hitch(this, function(){
this.removetrack();
testDataGrid.filter({status:"COMPLETED"});
})
},"testButton1");
},
removetrack:function(){
//some logic
}
});
var customObj=new CustomClass();
customObj.createCustomButton();

I cannot manage to do better way, in case you need urgent fix
var button = new dijit.form.Button({
label: "Custom!",
onClick:function(){
CustomClass().removetrack();
}},"result");
Hope someone can give you better option.

Related

How to catch opened event on a ComboBox with Dojo?

I want to know whether a combo box has been opened and call a function that displays an progress bar while it loads the data from a store. I've check the API but no I didn't find any suitable event for what I'm doing.
EDIT
What I want to do is start a progress bar while the combobox is populated from the store. I've created a widget with the combobox and the progress bar (a custom class) and "decorate" openDropDown function with aspect.before. This is the code I've written:
postCreate: function() {
this.inherited(arguments);
aspect.before(
this.comboBox, 'openDropDown',
lang.hitch(this, function(){
this.progressBar.increase();
})
);
on(
this.comboBox,
'search',
lang.hitch(this.progressBar, 'decrease')
);
}
But it seems is not using the right progressBar object.
It sounds like you are looking for something like an "onOpen" event. as of Dojo 1.10 The Dijit/Combobox widget does not support an event like the one you are describing, however it does support a number of other events that might meet your requirements.
I recommend looking into the api for a list of possible events: http://dojotoolkit.org/api/
However the following code will create a custom "onOpen" event like what you are describing. I've provided a jsfiddle which demos this new event
http://jsfiddle.net/kagant15/z4nvzy44/
var comboBox = new ComboBox({
id: "stateSelect",
name: "state",
value: "California",
store: stateStore,
searchAttr: "name"
}, "stateSelect")
// grab the existing openDropDown method
var openDropDownFunction = comboBox.openDropDown;
newFunction = function(){
topic.publish("openDropDown") // add the custom "openDropDown" event trigger
return openDropDownFunction.apply(this);
}
// replace the old comBox method will our new function
comboBox.openDropDown = newFunction;
// Subscribe to the custom openDropDown event and do something when it fires
topic.subscribe("openDropDown", function(){
console.log("Open Drop Down even trigger");
});

Backbone: how to test preventDefault to be called without testing directly the callback

Let's say we have a simple Backbone View, like this:
class MyView extends Backbone.View
events:
'click .save': 'onSave'
onSave: (event) ->
event.preventDefault()
# do something interesting
I want to test that event.preventDefault() gets called when I click on my element with the .save class.
I could test the implementation of my callback function, pretty much like this (Mocha + Sinon.js):
it 'prevents default submission', ->
myView.onSave()
myView.args[0][0].preventDefault.called.should.be.true
I don't think it's working but this is only to get the idea; writing the proper code, this works. My problem here is that this way I'm testing the implementation and not the functionality.
So, my question really is: how can I verify , supposing to trigger a click event on my .save element?
it 'prevents default submission', ->
myView.$('.save').click()
# assertion here ??
Thanks as always :)
Try adding a listener on the view's $el, then triggering click on .save, then verify the event hasn't bubbled up to the view's element.
var view = new MyView();
var called = false;
function callback() { called = true; }
view.render();
// Attach a listener on the view's element
view.$el.on('click', callback);
// Test
view.$('.save').trigger('click');
// Verify
expect(called).toBeFalsy();
So you want to test that preventDefault is called when a click event is generated, correct?
Couldn't you do something like (in JavaScript. I'll leave the CoffeeScript as an exercise ;)):
var preventDefaultSpy;
before(function() {
preventDefaultSpy = sinon.spy(Event.prototype, 'preventDefault');
});
after(function() {
preventDefaultSpy.restore();
});
it('should call "preventDefault"', function() {
myView.$('.save').click();
expect(preventDefaultSpy.callCount).to.equal(1);
});
You might want to call preventDefaultSpy.reset() just before creating the click event so the call count is not affected by other things going on.
I haven't tested it, but I believe it would work.
edit: in other words, since my answer is not that different from a part of your question: I think your first approach is ok. By spying on Event.prototype you don't call myView so it's acting more as a black box, which might alleviate some of your concerns.

Dojo1.8: I am not able to update label of each Button instance while creating instances from Button

I am not able to update label of each Button instance while creating instances from button.
How do I work around it? Or can I not code it as follows?
registry.byId(new Obj_Button({
id:'star'+ i,
label:'Button '+ i, //it will not work, so how to solve it???
}).placeAt(dom.byId('new1')));
Also please see my jsfiddle - http://jsfiddle.net/clementyap/sTxbh/42/
regards
Clement
Your widget needs to be coded to handle label
declare("Obj_Button", [_WidgetBase], {
postMixInProperties: function() {
if(!this.label)
this.label = 'New Button Instance';
},
buildRendering: function () {
// create the DOM for this widget
this.domNode = domConstruct.create("button", {
innerHTML: this.label
});
}
});
Also, you can just instantiate the widget, the registry.byId call is not needed.

How do I determine open/closed state of a dijit dropdownbutton?

I'm using a dijit DropDownButton with an application I'm developing. As you know, if you click on the button once, a menu appears. Click again and it disappears. I can't seem to find this in the API documentation but is there a property I can read to tell me whether or not my DropDownButton is currently open or closed?
I'm trying to use a dojo.connect listener on the DropDownButton's OnClick event in order to perform another task, but only if the DropDownButton is clicked "closed."
THANK YOU!
Steve
I had a similar problem. I couldn't find such a property either, so I ended up adding a custom property dropDownIsOpen and overriding openDropDown() and closeDropDown() to update its value, like this:
myButton.dropDownIsOpen = false;
myButton.openDropDown = function () {
this.dropDownIsOpen = true;
this.inherited("openDropDown", arguments);
};
myButton.closeDropDown = function () {
this.dropDownIsOpen = false;
this.inherited("closeDropDown", arguments);
};
You may track it through its CSS classes. When the DropDown is open, the underlying DOM node that gets the focus (property focusNode) receives an additional class, dijitHasDropDownOpen. So, for your situation:
// assuming "d" is a dijit.DropDownButton
dojo.connect(d, 'onClick', function() {
if (dojo.hasClass(d.focusNode, 'dijitHasDropDownOpen') === false) {
performAnotherTask(); // this fires only if the menu is closed.
}
});
This example is for dojo 1.6.2, since you didn't specify your version. It can, of course, be converted easily for other versions.

Dojo - How to programatically create ToolTip Dialog on link click

As the title says. I want to create TooltipDialog, after I click link and load custom content into that dialog. The tooltip body is complete placeholder, I just haven't done any server logic to handle this.
So far i got to this point:
PreviewThread: function (ThreadID) {
var tooltip = new dijit.TooltipDialog({
href: "/Account/SingIn?ReturnUrl=" + Jaxi.CurrentLocation
});
},
Preview
The point is not even how to load content, into dialog, but how to open it in the first place ?
After more googling and trial & error I finally got to this:
PreviewThread: function (ThreadID) {
var tooltip = new dijit.TooltipDialog({
href: "/Account/SingIn?ReturnUrl=" + Jaxi.CurrentLocation,
closable: true
});
dojo.query(".thread-preview").connect("onclick", function () {
dijit.popup.open({ popup: tooltip, around: this });
});
},
It's somehow working. ToolTipDialog opens, but.. I have to click twice and and I can't close dialog after click outside it, or after mouseleave.
Ok this, going to start look like dev log, but hopefully it will save others some headchace:
I finally managed to popup it where I want to:
PreviewThread: function (ThreadID) {
var tooltip = new dijit.TooltipDialog({
href: "/Account/SingIn?ReturnUrl=" + Jaxi.CurrentLocation,
closable: true
});
dijit.popup.open({ popup: tooltip, around: dojo.byId("thread-preview-" + ThreadID) });
},
<a href="javascript:Jaxi.PreviewThread(#thread.ThreadID)" id="#tp.ToString()" >Click Me</a>
Note that I'm using Asp .NET MVC.
Now only thing left is to close damn thing in user friendly manner..
There are afaik two ways you can do this, and neither one is very elegant tbh :-P
The first is to use dijit.popup.open() and close() to show and hide the dialog. In this case, you have to provide the desired coordinates. I see that you only provide your PreviewThread function with a thread id, but assuming you also tack on the event object, you can do:
PreviewThread: function (ThreadID, event) {
Jaxi.tooltip = new dijit.TooltipDialog({
href: "/Account/SingIn?ReturnUrl=" + Jaxi.CurrentLocation
});
dijit.popup.open({
popup: Jaxi.tooltip,
x: event.target.pageX,
y: event.target.pageY
});
}
When you're using this method, you also have to manually close the popup, for example when something outside is clicked. This means you need a reference to your tooltip dijit somewhere, for example Jaxi.tooltip like I did above. (Side note: dijit.TooltipDialog is actually a singleton, so there won't be lots of hidden tooltips around your page). I usually end up with something like this for hiding my tooltip dialogs.
dojo.connect(dojo.body(), "click", function(event)
{
if(!dojo.hasClass(event.target, "dijitTooltipContents"))
dijit.popup.close(Jaxi.tooltip);
});
This may of course not work for you, so you'll have to figure out something that suits your particular arrangement.
The second way is to use the dijit.form.DropDownButton, but styling it as if it was a link. I'm not going to go into details on this, just instantiate a DropDownButton on your page and use Firebug to tweak it until it looks like your regular links. FYC, link to DropDownButton reference guide.
You may try:
PreviewThread: function (ThreadID) {
var tooltip = new dijit.TooltipDialog({
href: "/Account/SingIn?ReturnUrl=" + Jaxi.CurrentLocation,
closable: true,
onMouseLeave: function(){dijit.popup.close(tooltip);}
});
dijit.popup.open({ popup: tooltip, around: dojo.byId("thread-preview-" + ThreadID) });
},
This will close the dialog as soon as you moove the mouse out of the dialog.
Check the API for all possible events:
http://dojotoolkit.org/api/