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.
Related
How to remove defaut context menu in vala?
https://valadoc.org/webkit2gtk-4.0/WebKit.ContextMenu.html
this code, not working
var cm = new WebKit.ContextMenu();
cm.remove_all();
According to the documentation, you could do something like that.
my_web_view.context_menu.connect ((menu, evt, hit_test) => { return true; });
This signal is emitted every time a context menu is about to be shown. Returning true in the handler will just prevent the menu to appear.
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.
I am trying out dojotoolkit 1.8 and cant figure out how to hook up an onchange event for a dojo/form/select
Nothing happens with this
require(["dojo/dom","dojo/on"], function(dom,on){
on(dom.byId("myselect"),"change",function (evt){
alert("myselect_event");
});
If instead, the following hook into click works:
on(dom.byId("myselect"),"click",function (evt){
but i want to capture the value after user clicks and changes
I am sure it is simpler than going back to Plain ol javascript onChange...
Thx
You could try something like this:
var select = dijit.byId('myselect');
select.on('change', function(evt) {
alert('myselect_event');
});
I've seen this in the reference-guide multiple times, eg in the dijit/form/select' s reference-guide at 'A Select Fed By A Store'.
Maybe it even returnes the handle, i haven't looked this up so far. But i guess it should work.
EDIT:
Considering #phusick's comment, i want to add, that you could also simply change the "change" to "onChange" or the dom to dijit within calling on(...)
Following in the footsteps of #nozzleman's answer try
var select = registry.byId('myselect');
select.on('change', function(evt) {
alert('myselect_event');
});
If you use on instead of connect then you don't have to write onChange, you can simply write change.
Similar to above answers do a dijit.ById to find the correct element and then register the 'onItemClick' event.
creating the select dropdown programatically appends a _menu to whatever node you create the select items so 'search' becomes 'search_menu' on a page init you can do the following:
dojo.connect(dijit.byId('search_menu'),'onItemClick',function(){
//console.log("search menu");
doSearch('recreation');
});
As others have pointed out, you're trying to access the Dijit using DOM. Also, the parameter to the anonymous function for the "change" event is the value selected by the user, not the event itself.
Here's your code modified to access the Dijit and process the "change" event:
require(["dijit/registry", "dojo/on"], function(registry, on) {
on(registry.byId("myselect"), "change", function (value) {
alert("change_event.value = " + value);
});
});
Late to the party, but I recently ran into the issue. Hopefully my answer will help some poor soul maintaining some legacy code. The answer is for combobox but worked for select as well -
onChange not sufficient to trigger query from Dojo Combobox. Need to attach listener to dropdown items.
select.dropDown.on("itemClick", function(dijit, event) {
var node = dijit.domNode;
console.log(domAttr.get(node, "data-info-attribute"));
// or
console.log(node.dataset.infoAttribute);
});
Ref: https://stackoverflow.com/a/12422155/4564016
I am trying to do something like : when user click on the button, the child panel will show/hide
the issue is the 'onbtnClick' function is working just once. when i click on the button the panel shows and then when i click it again nothing happens and no errors tho ! the panel should hide
By the looks of it, there isn't really much need to pass a boolean param to the function.
If you purely want a 'toggle' function, based on the panels visibility and you have a reference to the Ext component, you can use the isVisible() function:
http://docs.sencha.com/ext-js/4-1/#!/api/Ext.panel.Panel-method-isVisible
So your onBtnClick function would look something like this:
onbtnClick: function (){
var childPanel = Ext.getCmp('p');
if(childPanel.isVisible()) {
childPanel.hide();
}
else {
childPanel.show();
}
}
onbtnClick: function (){
var childPanel = Ext.getCmp('p');
if (!childPanel.isHidden()) {
childPanel.hide();
} else {
childPanel.show();
}
}
Instead isVisible() use method isHidden() because method isVisible may return false when the panel is covered by other components or is not rendered yet (even when your panel has not got hidden property (hidden = false)).
panel.getEl().toggle();
will serve your purpose.
-YP
you have setVisible, taking a boolean parameter to know what to do.
childPanel.setVisible( ! childPanel.isVisible() )
This example will actually toggle the visibility at each execution.
dojo newbie - giving it a shot.
After submitting a form, If an error is returned from the server I would like to show that message on the dijit.form.ValidationTextBox
var user_email = dijit.byId("login_user_email");
user_email.set("invalidMessage", data["result"]["user_email"]);
//need to force show the tooltip but how???
Any help much appreciated.
See it in action at jsFiddle.
Just show tooltip:
var textBox = bijit.byId("validationTextBox");
dijit.showTooltip(
textBox.get("invalidMessage"),
textBox.domNode,
textBox.get("tooltipPosition"),
!textBox.isLeftToRight()
);
Temporarily switch textBox validator, force validation, restore the original validator:
var originalValidator = textBox.validator;
textBox.validator = function() {return false;}
textBox.validate();
textBox.validator = originalValidator;
Or do both at once.
I think you can show the tooltip via myVTB.displayMessage('this is coming from back end validation'); method
you need to do the validation in the validator-method. like here http://docs.dojocampus.org/dijit/form/ValidationTextBox-tricks
you also need to focus the widget to show up the message! dijit.byId("whatever").focus()
#arber solution is the best when using the new dojo. Just remember to set the focus to the TextBox before calling the "displayMessage" method.
I am using dojo 1.10 which works create as follows:
function showCustomMessage(textBox, message){
textBox.focus();
textBox.set("state", "Error");
textBox.displayMessage(message);
}
Dojo reference guid for ValidationTextBox: https://dojotoolkit.org/reference-guide/1.10/dijit/form/ValidationTextBox.html
I know this question is ancient, but hopefully this'll help someone. Yes, you should use validators, but if you have a reason not to, this will display the message and invalidate the field:
function(textbox, state /*"Error", "Incomplete", ""*/, message) {
textbox.focus();
textbox.set("state", state);
textbox.set("message", message);
}
You can call directly the "private" function:
textBox._set('state', 'Error');
You get the same result as #phusick suggested but with less code and arguably in a more direct and clean way.
Notes:
_set is available to ValidationTextBox as declared on its base class dijit/_WidgetBase.
Live demo:
http://jsfiddle.net/gibbok/kas7aopq/
dojo.require("dijit.form.Button");
dojo.require("dijit.form.ValidationTextBox");
dojo.require("dijit.Tooltip");
dojo.ready(function() {
var textBox = dijit.byId("validationTextBox");
dojo.connect(dijit.byId("tooltipBtn"), "onClick", function() {
dijit.showTooltip(
textBox.get('invalidMessage'),
textBox.domNode,
textBox.get('tooltipPosition'), !textBox.isLeftToRight()
);
});
dojo.connect(dijit.byId("validatorBtn"), "onClick", function() {
// call the internal function which set the widget as in error state
textBox._set('state', 'Error');
/*
code not necessary
var originalValidator = textBox.validator;
textBox.validator = function() {return false;}
textBox.validate();
textBox.validator = originalValidator;
*/
});
});