Click event not firing on MenuItem with submenu - node-webkit

In my nw.js app I have a menubar with a 'Parent' menuitem. 'Parent' has both a click event and a submenu. I noticed the click event on parent does not trigger when there is a submenu. Is there any way to capture the click event on the parent menuitem of the submenu? Or is this simply expected behavior?
var menubar = new window.gui.Menu({ type: 'menubar' });
var fileMenu = new window.gui.Menu();
fileMenu.append(new window.gui.MenuItem({
label: 'New',
click: function() {
window.alert("New");
}
}));
fileMenu.append(new window.gui.MenuItem({
label: 'Open',
click: function() {
window.alert("Open");
}
}));
menubar.append(new window.gui.MenuItem({
label: 'Parent',
submenu: fileMenu,
click: function() {
window.alert("Does not fire when submenu set");
}
}));
window.win.menu = menubar;

This is expected behavior. In other desktop applications, you also don't see a menu item without a submenu attached to it...

Related

Dojo enable button by event handler

I am working with IBM Content Navigator 2.0.3, that uses DOJO 1.8 for the GUI development. I am new in dojo, and I have to enhance one of the forms: add an event handler to the dataGrid so when the row of the grid is selected one of the buttons become enabled.
I've managed to add event handler as was advised in this issue: dojo datagrid event attach issue
but I still can't enable the button. Here is html of the form:
Add
Remove
<div class="selectedGridContainer" data-dojo-attach-point="_selectedDataGridContainer">
<div class="selectedGrid" data-dojo-attach-point="_selectedDataGrid" ></div>
</div>
The attached image describes how it looksenter image description here.enter image description here
And the js file code of postCreate function is following:
postCreate: function() {
this.inherited(arguments);
this.textDir = has("text-direction");
domClass.add(this._selectedDataGridContainer, "hasSorting");
this._renderSelectedGrid();
this.own(aspect.after(this.addUsersButton, "onClick", lang.hitch(this, function() {
var selectUserGroupDialog = new SelectUserGroupDialog({queryMode:"users", hasSorting:true, callback:lang.hitch(this, function (user) {
this._onComplete(user);
this._markDirty();
})});
selectUserGroupDialog.show(this.repository);
})));
this.own(aspect.after(this.removeUsersButton, "onClick", lang.hitch(this, function() {
if (this._selectedGrid != null) {
var selectedItems = this._selectedGrid.selection.getSelected();
if (selectedItems.length > 0) {
array.forEach(selectedItems, lang.hitch(this, function(item) {
this._selectedGrid.store.deleteItem(item);
}));
}
this._selectedGrid.selection.clear();
this._selectedGrid.update();
}
this._markDirty();
})));
// the following handler was added by me
dojo.connect(this.myGrid, 'onclick', dojo.hitch(this, function(){
console.log(" before ");
this.removeUsersButton.set('disabled', true);
console.log(" after ");
}));
},
so this.own(aspect.after(this.removeUsersButton..... works fine and worked before my interference. So it somehow accesses this.removeUsersButton and processes the event. But my handler dojo.connect(this.myGrid.... only prints console.log() before and after without enabling the Remove button. The Button has no Id, only data-dojo-attach-point. How do I enable the Remove button when the daaGrid is selected?
With this.removeUsersButton.set('disabled', true); you are setting the button to be disabled. If you want to enable it you need to set it to false.
this.removeUsersButton.set('disabled', false);

Panel listener when a window is opened inside of it

I have a Panel which acts as a desktop. When a button is clicked a window is opened up inside the panel. I set the following in the config:
var win = Ext.create('window', {
renderTo : currentPanel.getLayout().getTarget(),
constrain : true
});
win.show();
So my window is being open and constrained in the main panel. I want the panel to listen for when any window is open inside of it so I can monitor it. Are there any listener that will do this? I tried 'add' and 'added' but the window has to be added to the panel via:
panel.add(window);
But in my case I'm not adding it to the container, but I'm opening it and constraining it to my container using the renderTo.
What I would do is create a subclass of panel for your desktop and a subclass of window for your windows. Add a 'windowOpened' listener to your custom panel, and fire this event from your custom window's 'show' listener.
Something like this:
DesktopPanel.js
Ext.define('App.view.DesktopPanel', {
extend: 'Ext.panel.Panel',
alias: 'widget.desktoppanel',
initComponent: function() {
this.callParent();
this.addListener('windowOpened', function(newWindow){
//Do whatever it is you want to do here
});
}
});
DesktopWindow.js
Ext.define('App.view.DesktopWindow', {
extend: 'Ext.window.Window',
alias: 'widget.desktopwindow',
constrain: true,
initComponent: function() {
this.renderTo = this.ownerPanel.getLayout().getTarget();
this.callParent();
this.addListener('show', function(){
this.ownerPanel.fireEvent('windowOpened',this);
});
}
});
Then your code would be something like this:
var win = Ext.create('App.view.DesktopWindow', {
ownerPanel: MyDesktop, //an instance of 'DesktopPanel'
});
win.show();

Dojo DropDownButton, can I differentiate between a click on button vs. down arrow?

I'm using Dojo to create a DropDownButton within a Toolbar. The Toolbar, and button are created dynamically, like this:
this.widget = new Toolbar({ style: "background:black;" }, "toolbar");
this.dropMenu = new DropDownMenu({tooltip : "ToolTip", style: "display: none;"});
this.button = new DropDownButton({dropDown: this.dropMenu});
this.button.set('label', '<img src="data:image/png;base64,'+ this.icon + '"/>');
this.widget.addChild(this.button);
Note that the above code is dynamically creating an icon as part of the button from a base64 encoded string through setting an img src for the label property of the button.
I want to differentiate between a click on the "label" element for the DropDownButton and a click on the down arrow for the button, but am not sure if this is possible. Ie, when clicking on the label, I capture the onClick, but don't cause the drop down to be displayed. However, if the down arrow is clicked on or any other place on the button is clicked, the drop down will be displayed.
One alternate would be to split this into a standard Button, and then a drop down button adjacent to it, but I'm wondering if there is any way to do this from a single standard DropDownButton?
Check whether or not its the downarrow or buttontext class in the clicked element. To properly hook into the 'flow' of events, you should override the classfunction _onDropDownMouseDown
var customDropDownButton = declare("customDropDownButton", [ DropDownButton ], {
toggleDropDown: function() {
console.log('toggling');
this.inherited(arguments);
},
_onDropDownMouseDown: function(evt) {
console.log(arguments, evt.srcElement.className);
if (/dijitButtonText/.test(evt.srcElement.className)) {
// negate popup functionality
console.log('negating');
return false;
}
this.inherited(arguments);
return true;
}
});
var b = new customDropDownButton({
label: "hello!",
name: "programmatic1",
dropDown: someMenu
});
Alternatively, if you can live with popup showing and then immediately closing again - easy way is:
var b = new DropDownButton({
label: 'hello!',
name: "programmatic2",
dropDown: someMenu,
onClick: function(evt) {
if(/dijitButtonText/.test(evt.srcElement.className)) {
// negate popup
popup.close(this.dropDown);
}
}
}, 'button');

Adding a button and navigating between views

1.) I need to add 2 buttons, one below another. My working so far is demonstrated below; It only shows one button, but how can i add another button with a different button image below this button ?
2.) When the user clicks a button, i need to navigate to another screen. How can i do this ?
I need the equivalent of the following objective-c code ?
View1 *view1 = [[View1 alloc] initWithNibName:#"View1" bundle:nil];
[self.navigationController pushViewController:View1 animated:YES];
3.) How can i add a navigation Bar (equivalent to the navigation bar shown in iPhone)
The code for the 1st question;
{
items:[
{
xtype:'button',
text: 'Submit',
ui:'confirm',
handler: function(){
var values = Ext.getCmp('contactForm').getValues();
Ext.Ajax.request({
url: 'http://loonghd.com/service/',
failure: function (response) {
//do something
}, success: function (response) {
// do something
}
});
}
}
]
}
1) For getting two buttons one below the other, you can add two separate buttons (with different ui property) as childs of a form panel. I think, this is what you need.
Just like this,
....
....
items : [
{
xtype:'button',
text: 'Submit',
ui:'confirm', // makes the button color as green
handler: function(){
var values = Ext.getCmp('contactForm').getValues();
Ext.Ajax.request({
url: 'http://loonghd.com/service/',
failure: function (response) {
//do something
},
success: function (response) {
// do something
}
});
}
},
{
xtype:'button',
text:'Second button',
ui:'decline', // makes the button color as red.
listeners : {
tap : function() {
Ext.Msg.alert('You just clicked Second button');
}
}
}
]
....
....
2) 3) For your 2nd and 3rd question, navigationview is the solution.
Solution posted by M-x is great, but it's very advanced level example & also difficult to understand at first instance.
Here's an easy solution of navigatioview from Sencha Docs.
//create the navigation view and add it into the Ext.Viewport
var view = Ext.Viewport.add({
xtype: 'navigationview',
//we only give it one item by default, which will be the only item in the 'stack' when it loads
items: [
{
//items can have titles
title: 'Navigation View',
padding: 10,
//inside this first item we are going to add a button
items: [
{
xtype: 'button',
text: 'Push another view!',
handler: function() {
//when someone taps this button, it will push another view into stack
view.push({
//this one also has a title
title: 'Second View',
padding: 10,
//once again, this view has one button
items: [
{
xtype: 'button',
text: 'Pop this view!',
handler: function() {
//and when you press this button, it will pop the current view (this) out of the stack
view.pop();
}
}
]
});
}
}
]
}
]
});
Maybe a navigation view will work for you? It's the same idea but it's like starting with a UITableView:
http://docs.sencha.com/touch/2-0/#!/example/navigation-view
In the app/controller/Application.js, when you tap on a contact, the detail view gets pushed. All the source is in the examples directory.
onContactSelect: function(list, index, node, record) {
var editButton = this.getEditButton();
if (!this.showContact) {
this.showContact = Ext.create('AddressBook.view.contact.Show');
}
// Bind the record onto the show contact view
this.showContact.setRecord(record);
// Push the show contact view into the navigation view
this.getMain().push(this.showContact);
},

Dojo Exception on hiding a dijit.Dialog

I have a Dialog with a form inside. The following code is just an example of what I'm trying to do. When you close a dijit.Dialog, if you dont't destroy recursively his children, you just can't reopen it (with the same id).
If you don't want to destroy your widget you can do something like that :
var createDialog = function(){
try{
// try to show the hidden dialog
var dlg = dijit.byId('yourDialogId');
dlg.show();
} catch (err) {
// create the dialog
var btnClose = new dijit.form.Button({
label:'Close',
onClick: function(){
dialog.hide();
}
}, document.createElement("button"));
var dialog = new dijit.Dialog({
id:'yourDialogId',
title:'yourTitle',
content:btnClose
});
dialog.show();
}
}
I hope this can help but with this code the error thrown is :
exception in animation handler for: onEnd (_base/fx.js:153)
Type Error: Cannot call method 'callback' of undefined (_base/fx.js:154)
I have to say I'm a little lost with this one ! It is driving me crazy ^^
PS : sorry for my "French" English ^^
I'll introduce you to your new best friend: dojo.hitch()
This allows you to bind your onClick function to the context in which it was created. Chances are, when you push the button in your code, it is calling your .show() .hide() form the context of the global window. var dlg was bound to your createDialog function, so it's insides are not visible to the global window, so the global window sees this as undefined.
Here's an example of what I changed to your code:
var createDialog = function(){
// try to show the hidden dialog
var dlg = dijit.byId('yourDialogId');
dlg.show();
// create the dialog
var btnClose = new dijit.form.Button({
label:'Close',
onClick: function(){
dojo.hitch(this, dlg.hide());
}
}, document.createElement("button"));
dlg.domNode.appendChild(btnClose.domNode);
var btnShow = new dijit.form.Button({
label : 'Open',
onClick : function() {
dojo.hitch(this, dlg.show());
}
}, document.createElement("Button"));
dojo.body().appendChild(btnShow.domNode);
};
dojo.ready(function() {
createDialog();
});
Note the use of dojo.hitch() to bind any future calls or clicks of the various buttons to the context in which the dlg was created, forever granting the button's onclick method access to the inside of the createDialog function, where var dlg exists.
hi if i understand correctly, you didn't need to destroy dijit.Dialog every time. E.g.:
HTML: define simple button:
<button id="buttonTwo" dojotype="dijit.form.Button" onclick="showDialog();" type="button">
Show me!
</button>
Javascript:
// required 'namespaces'
dojo.require("dijit.form.Button");
dojo.require("dijit.Dialog");
// creating dialog
var secondDlg;
dojo.addOnLoad(function () {
// define dialog content
var content = new dijit.form.Button({
label: 'close',
onClick: function () {
dijit.byId('formDialog').hide();
}
});
// create the dialog:
secondDlg = new dijit.Dialog({
id: 'formDialog',
title: "Programatic Dialog Creation",
style: "width: 300px",
content: content
});
});
function showDialog() {
secondDlg.show();
}
See Example and reed about dijit.dialog