How to catch opened event on a ComboBox with Dojo? - 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");
});

Related

Using the same InfoWindow for two AttributeInspectors

I've got two editable feature layers in my application, and I'm trying to attach the appropriate attribute inspector depending on which feature layer my user is trying to edit.
I create the Attribute Inspectors for both feature layers when my application loads and then attach the appropriate attribute inspector to the map's InfoWindow when the user is trying to edit a feature layer.
All works well, until the user tries to edit another feature layer. When I try and attach a different attribute inspector to the infowindow, it just comes up blank.
Here's roughly what I'm doing:
// AttributeEditor1 for FeatureLayer1 in Class1
constructor: function(options) {
this.options = lang.mixin(this.options, options);
this.map = options.map;
this.configureAttributeEditor1();
},
configureAttributeEditor1: function() {
this.attributeEditor1 = new AttributeInspector({
layerInfos: layerInfos
}, domConstruct.create("div"));
// here I add a Save and Delete button and various event handlers
this.attributeEditor1.startup();
},
// I call this when I know that the user wants to edit FeatureLayer 1
attachEditor1: function() {
this.map.infoWindow.setContent(this.attributeEditor1.domNode);
this.map.infoWindow.resize(350, 240);
},
// AttributeEditor2 for FeatureLayer2 in Class2
constructor: function(options) {
this.options = lang.mixin(this.options, options);
this.map = options.map;
this.configureAttributeEditor2();
},
configureAttributeEditor2: function() {
this.attributeEditor2 = new AttributeInspector({
layerInfos: layerInfos
}, domConstruct.create("div"));
// here I add a Save and Delete button and various event handlers
this.attributeEditor2.startup();
},
// I call this when I know that the user wants to edit FeatureLayer 2
attachEditor2: function() {
this.map.infoWindow.setContent(this.attributeEditor2.domNode);
this.map.infoWindow.resize(350, 240);
},
Thanks in advance.
When you update the content of infoWindow using map.infoWindow.setContent, it destroys the previous content and then updated the new content. So basically your AttributeInspector1 will be destroyed when you updated the info window with AttributeInspector2.
You need not create multiple AttributeInspector, while working on multiple FeatureLayer. The layerInfos property is an array type, you could set upd multiple layers.
But, I guess you have different needs/actions to be taken when you switch between layers. The best thing you could do is to either create new AttributeInspector every time you switch, or just update the layerInfos and save and delete events. Make sure you remove the previous save and delete event handles.

Use existing buttons in datatables

I am trying to trigger an onClick event when click on next or previous buttons in data tables. I checked the IDs of the buttons and they are auto generated. couldn't use those IDs. Is this possible ?
You have a page.dt event, fired each time the paging is updated :
table.on('page.dt', function() {
var info = table.page.info();
console.log('Showing page: '+info.page+' of '+info.pages);
});
If you want to target click on the previous / next buttons you can easily do that. To my experience dataTables seems to "eat" the click event simply by updating the view immediately - but you can stay upfront in the chain by listening on the mousedown event instead :
$('.dataTables_wrapper').on('mousedown', '.previous', function() {
console.log('previous clicked')
})
$('.dataTables_wrapper').on('mousedown', '.next', function() {
console.log('next clicked')
})
You need to use a delegated event handler because the dataTable controls is recreated each time the dataTable is redrawn. .dataTables_wrapper, .next and .previous is common for all dataTables.
demo -> http://jsfiddle.net/6jpbyvd4/

dojo make a widget react to a published event

Im trying to figure out how to close a pop up dialog based on a published event .. i.e when a person moves the mouse to another part of the page.(i only want it closed when i move to this part of the page) Is this possible
i have a topic published when the user moves off this area.
_hoverOffArea : function() {
topic.publish("messageRollOver/close");
},
how do i get my popup to subscribe to this topic and close itself ?
var tooltip = new TooltipDialog({
onMouseLeave : function() {
},
onBlur : function() {
}
});
messageTooltip.set("content", rollOver.domNode);
popup.open({
popup: tooltip,
around: e
});
You may be over thinking it. The dojo/topic module has a subscribe method which takes a topic name ("messageRollOver/close") and a function to fire when the message is published.
topic.subscribe('messageRollOver/close',function(args){
console.log('close tooltip');
});
You can pass arbitrary parameters to the publish message that are then passed to the subscribe:
topic.subscribe("messageRollOver/close",function(arg1){
console.log("arg1 = ",arg1);
});
var tooltip = new TooltipDialog(/*params*/);
topic.publish("messageRollOver/close",tooltip);
when the subscribe function is invoked, arg1 would be the second argument to the topic#publish function call.

In backbone.js how do I bind a keyup to the document

I've been following along with a Railscast tutorial of backbone.js and I wanted to extend the functionality to include keyboard control. I added the following to my show view:
class Raffler.Views.EntryShow extends Backbone.View
template: JST['entries/show']
events:
'click .back': 'showListing'
'keyup': 'goBack'
showListing: ->
Backbone.history.navigate("/", trigger: true)
goBack: (e) ->
console.log e.type, e.keyCode
render: ->
$(#el).html(#template(entry: #model))
this
On my show template I have the following:
Back
<%= #entry.get('name') %></td>
If I select the back link using the tab key, then start hitting random keys I get output in my javascript console. However if I load the page and do not select the link and just start hitting keys I get no output in my console.
How do I bind the event to the document so that it will listen to any keys pressed when loading the screen?
You will need to work around backbone's scope for views.
when you are doing something like this:
events:
'click .back': 'showListing'
'keyup': 'goBack'
you are binding your goBack function to the keyup event raised on your container element of your view. (by default the div in which the view is rendered)
instead of doing that, if you want to bind to something outside your view (which doesn't have it's own view!(*))
Raffler.Views.EntryShow = Backbone.View.extend({
template: JST['entries/show'],
events: {
'click .back': 'showListing'
},
initialize: function () {
$('body').keyup(this.goBack);
},
showListing: function () {
Backbone.history.navigate("/", trigger: true);
},
goBack: function (e) {
console.log e.type, e.keyCode;
},
render: function () {
$(this.el).html(this.template(entry: #model));
return this;
}
});
(*)remark as marked above, you best do this only when the item you want to bind to does not have it's own view, if you have a view for your full page (an app view or something like that) you could bind the keyup in there, and just raise an event App.trigger('keypressed', e); for example.
you can then in your EntryShow view, bind to that App's keypressed event.
App.bind('keypressed', goBack);
keep in mind that you should do something as a delayed event or grouping keypresses together in some situations, as firing every keypress that happens in the body, might be a big performance hit. especially on older browsers.
Your events will be scoped to your view element #el. To capture events on the document, you have to roll that yourself:
initialize: ->
$(document).on "keyup", #goBack
remove: ->
$(document).off "keyup", #goBack
Should do the trick.

extjs How to get a grid

In Designer I set my grid name to equal MyGrid
On clicking the button addRecord is called, it fails where rows is attemting to get an undefined grid.
How do I define this MyGrid so that it references the grid within the panel?
Ext.define('MyApp.view.MyPanel', {
extend: 'MyApp.view.ui.MyPanel',
initComponent: function() {
var me = this;
me.callParent(arguments);
var button = me.down('button[text=Submit]');
button.on('click', me.onSubmitBtnClick, me);
},
addRecord: function(myRecordArray) {
var rows = grid.getStore().getRange(); // ERROR happens here
console.log(rows);
},
onSubmitBtnClick: function() {
this.addRecord(["ll", "kk", "mm"]);
}
});
Chrome Javascript Debugger Console ->
Uncaught ReferenceError: grid is not defined
Before you call grid.getStore() you need to define "grid". You can just do var grid = this; right before the call because you are defining the addRecord function from inside of the grid.
EDIT:
I just noticed that this wasn't being called from inside the grid panel with the store but some other panel. What you will have to do to is set an id config on your grid panel. E.g. id: MyGridPanel There may already be an id config set on it and you just have to find out what it is. If you are using the ExtJS designer it may actually already be set to "MyGridPanel". Then you would call it like so:
var grid = Ext.getCmp("MyGridPanel");
then you would do:
grid.getStore().getRange()
try changing button.on('click', me.onSubmitBtnClick, me) to button.on('click', Ext.bind(me.onSubmitBtnClick, me), me)
This looks like a scope issue, in your onSubmitBtn() method, this probably refering to the wrong object (e.g. window, or the button), and not the grid object, which is what you want.