Prevent MessageBox from closing - extjs

I have a MessageBox configured like that
Ext.MessageBox.show({
buttons:Ext.MessageBox.OKCANCEL,
prompt:true,
buttonText:{ok:"Button1",cancel:"Button2"},
fn:function(btn, text, cBoxes){
if(btn=='ok'){
// do not close
// return false does not help
}
}
});
I do not know how to prevent it from closing on button click. In particular, I do not want to make it close when the user hits "ok" button. I've seen overrides on the Web, but do not know how to poperly configure buttons properties. I guess, there should be a very simple solution for this task.

You should use a regular window over which you'll have full control.
In your case, that would be something like this:
Ext.widget('window', {
autoShow: true
,closable: false
,modal: true
,title: "My window"
,defaults: {
margin: 5
}
// you can obviously compose the items you want; an input field
// is what you get with the prompt window
,items: [{
xtype: 'textfield'
,itemId: 'inputField'
}]
,buttons: [{
text: "Button1"
,handler: function(button) {
// here's how to get a ref to the window (for closing)
var win = button.up('window'),
// here's the value of the field
input = win.down('#inputField').getValue();
// you can close the window if you want, or not
if (!Ext.isEmpty(input)) {
win.close();
}
}
},{
text: "Button2"
,handler: function() {
// ...
}
}]
});

Related

Uncaught TypeError: Cannot read property 'dom' of null

When click first time on showbutton then window open perfectly but when i close window and again open this then its giving error("Cannot read property 'dom' of null ") on line 'shiftWindow.show();'. Any help is appreciated.
var shiftWindow = Ext.create('Ext.window.Window', {
title: 'Edit Shift',
resizable: false,
id: 'shiftwindow',
width: 465,
//bodyPadding: 5,
modal: true,
store: shiftStorePlanner,
items: {
xtype: 'form',
id: 'idFormShift',
bodyPadding: 10,
items: shiftViewModelPlannerData
},
buttons: [{
text: 'Save',
cls: 'planner-save-button',
overCls: 'planner-save-button-over',
handler: function () {
var wi = this.up('.window');
var form = Ext.getCmp('idFormShift');
if (form.isValid()) {
shiftTimemappingarray = [];
// getShiftTime();
setShiftTimeDetails();
}
}
}, {
text: 'Cancel',
handler: function () {
this.up('.window').close();
}
}]
});
shiftWindow.show();
If you are calling close() on the window, the window is destroyed. It no longer exists in the DOM. You'll have to create it again before calling show().
Alternatively, instead of closing it, you can hide() the window. Then it will remain and not require another creation. Note that the upper right-hand 'x' will still fire the close event.
On Cancel click of your window,
instead of using
this.up('.window').close();
You should use
this.up('.window').destroy();
because then only it will destroy the whole window including dom. So everytime you open it, it will new and fresh.. ;)
Maybe you just not define a div element in the body like me.
<div id="helloWorldPanel">
</div>

Dispalying more than one message box one after other

I have requirement to show multiple info/alert messages one after other.
Here is my sample code
var messageQueueStore = Ext.create('Ext.data.Store', {
fields: ['type','Title','text','buttonConfig','callback'],
storeId: 'messageQueueStore'
});
function displayMessage(type, Title, Text, buttonConfig, callback){
messageQueueStore.loadData([{type: type, Title : Title, Text: Text, buttonConfig:buttonConfig, callback:callback}], true);
if(!Ext.MessageBox.isVisible()){
displayEachMessage();
}
}
function displayEachMessage(){
var firstRecord = messageQueueStore.getAt(0);
//We are currently handling only alert messages. If needed this method can be extended to hande other type of messages
if(firstRecord.get('type') == 'alert'){
Ext.MessageBox.show({
title : firstRecord.get('Title'),
msg : firstRecord.get('Text'),
buttons: Ext.Msg.OK,
listeners: {
beforeclose : function(){console.log("Before close");},
close : function(){console.log("close");},
hide : function(){console.log("hide");},
beforehide : function(){console.log("beforehide");},
},
fn : messageClosed
})
}
}
function messageClosed(){
// before close event needs to be handled as well
messageQueueStore.removeAt(0);
if(messageQueueStore.count() != 0){
displayEachMessage();
}
}
// And this is how i use this functionality
displayMessage('alert','first',"You are now seeing the first message");
displayMessage('alert','second',"This is the second message");
displayMessage('alert','third',"Here comes the third");
displayMessage('alert','fourth',"And this is the last");
This works perfectly fine when user clicks on the OK button. However when user clicks on the (x) button on the message box top right corner none of the events i am trying to listen are triggered.
And hence the subsequent messages are not displayed.
Any pointers on how to handle the close event on message box will be very helpful
Here is working sample: http://jsfiddle.net/kTpct/2/
function myAlert(title, message){
Ext.create('Ext.window.Window', {
width: 300,
height: 120,
autoDestroy: true,
title: title,
modal: true,
layout: 'fit',
bodyStyle: 'border:none; background-color: transparent;',
buttonAlign: 'center',
items: [{
xtype: 'container',
html: message
}],
buttons: [{
text: 'Ok',
listeners: {
click: {
fn: function (item, e) {
this.up('window').close();
}
}
}
}]
}).show();
}
for(i = 1; i <= 3; i++ ) myAlert('message ' + i, 'content of message ' + i);
You cannot achieve this with the Ext.MessageBox because it is a singleton and there is no way to guarantee that the previous alert was reset before you are updating the properties for the next alert. Only one can be visible at a time and back to back alerts with no blocking will cause you timing issues.
"Busy-Blocking" is also bad anyway because there is no "Await-Callback" in javascript.

extjs - How to define a window as unique ?

Is there a way to define a window as unique ?
What I mean exactly is: when the window is already open, I want it to get focus, instead of opening it again.
For now my menu click event just does:
onMenuItemClick: function(){
Ext.create('Mb.view.UniqueWindow').show()
},
Give it a unique id, then verify if it already exists before creating it, otherwise just show it, something like
function onMenuItemClick() {
var wnd = Ext.getCmp('myUniqueWindow');
if (!wnd) {
wnd = Ext.create('Ext.window.Window', {
id: 'myUniqueWindow',
title: 'Unique Window',
height: 200,
width: 400,
layout: 'fit',
closeAction: 'hide', // This is really important otherwise closing it will destroy the window!
items: { // Let's put an empty grid in just to illustrate fit layout
xtype: 'grid',
border: false,
columns: [{
header: 'Hello World'
}], // One header just for show. There's no data,
store: Ext.create('Ext.data.ArrayStore', {}) // A dummy empty data store
}
});
} else {
wnd.getEl().highlight()
}
wnd.show();
}
You can see a working sample here
Save a reference to it:
if (!MyApp.someWin) {
MyApp.someWin = new Ext.window.Window();
}
MyApp.someWin.show();

extjs onKeyEnter not firing

Hello i have the following RowEditing plugin i use
ar rowEditing = Ext.create('Ext.grid.plugin.RowEditing', {
clicksToMoveEditor: 1,
autoCancel: false,
errorSummary:false,
onEnterKey: function(e) { console.log(e); },
listeners:{
'beforeedit':function(grid,eOpts){
},
'canceledit':function(grid, eOpts){
if(grid.grid.store.data.getAt(0).data.id == "new"){
grid.grid.store.removeAt(0);
}
},
'afteredit':function(editor, changes, record, rowIndex){
editor.grid.store.reload();
},
'validateedit': handleUpdate{{params.alias}}
}
});
But the enter action is still performed and no console log is performed... i tried to put it inside the listeners as well but no change...
here's my item in my grid
{
header: 'Description',
width: 160,
align: 'left',
dataIndex: 'description',
filters: {
type: 'string'
},
enableKeyEvents: true,
editor: {
xtype: 'textfield',
allowBlank: false,
listeners: {
keydown: {
element: 'el',
fn: function(el){
if (el.ENTER){
alert('test');
return false;
}
}
},
},
}
}
so my next try as to 'disable' the firing of the enter (or submitting the rowedit) inside the field itself. but a return false still submits the form, and a onEnterKey doesn't work there either... anyone has an idea what i am doing wrong?
I did find that onEnterKey is part of the parent Editing class but it doesn't say how i should call that..
First of all, onEnterKey is marked as private, so you shouldn't be overriding it, especially not upon instantiation. If you want to override class methods, you should do that by creating a new class which inherits from the class containing the methods:
Ext.define('My.grid.plugin.Editing', {
extends: 'Ext.grid.plugin.RowEditing',
onEnterKey: function() {
this.callParent(arguments);
// your code here
}
});
Regarding your problem, I suggest one of the following approaches:
A) If you really want to disable the ENTER key event only, you should do that on the editor field(s). Your attempt was close, but the event listener was not doing the right things yet:
editor: {
allowBlank: false,
listeners: {
keydown: function(e){
if (e.getKey() == e.ENTER){
e.stopEvent();
}
}
}
}
Note that with this approach the user will still be able to submit any change by just clicking the "Update" button of the row editing plugin.
B) If you just want to prevent the editing plugin from writing the changes to the store under certain conditions, you can also use the validateedit event on the editing plugin:
listeners: {
validateedit: function(editor, e) {
if (true) { // your condition here
return false;
}
}
}
This will also work, if the user clicks on the "Update" button.

Building a TriggerField with PopUp Window

I built a triggerField and when i press at it, i want to have a popup, that is appended to the button in the triggerfield(so when i click anywhere else it shall disappear and it shall pop out up to the button when i click at the button just like a datepicker-popup)
I somehow managed to do something like that with an Ext.window but the offset and postion doesnt match.
This all should be contained in a row editor.
my Code:
new Ext.grid.GridPanel({
store: Store,
region:'center',
height:150,
//minWidth:700,
autoScroll:true,
listeners:{},
plugins:[new Ext.ux.grid.RowEditor()],
tbar: [{
iconCls: 'icon-user-add',
text: ' hinzufügen',
handler: function(){
alert("abc");
}
},{
ref: '../removeBtn',
iconCls: 'icon-user-delete',
text: 'löschen',
disabled: true,
handler: function(){
editor.stopEditing();
var s = grid.getSelectionModel().getSelections();
for(var i = 0, r; r = s[i]; i++){
store.remove(r);
}
}
}],
columns: [{
header: 'Monate',
dataIndex: 'MONAT',
width: 50,
sortable: true,
editor:
new Ext.form.TriggerField({"id":"EditorMonate",items:[],
"onTriggerClick":function(thiss){
if(!Ext.getCmp("autoWMonate")){
var monate=new Ext.Window({"x":Ext.getCmp("EditorMonate").x,closeAction:"hide",width:275,id:"autoWMonate",layout:"table",layoutConfig: {columns: 10}});
var text;
for(var mon=1;mon<13;mon++){
text=mon;
mon?mon:text="0";
if(mon<10)
text="0"+mon;
monate.items.add(
new Ext.Button({cls:"x-btn",value:parseInt(text),selected:true,"text":text,id:text
}}}));}
} Ext.getCmp("autoWMonate").hidden?Ext.getCmp("autoWMonate").show():Ext.getCmp("autoWMonate").hide();
}})
}
}]
})
Problem sovled with:
{
header: 'WochenTage',
dataIndex: 'WOCHE',
width: 100,
sortable: true,
editor: new Ext.form.TriggerField({
onTriggerClick: function(e) {
if (!this.menu) {
this.menu = new Ext.menu.Menu({
items:[{xtype:"label",text:"1"},{xtype:"label",text:"2"}]
// the items should have event listeners that set the field value accordingly
});
}
// here you would want to sync the items in the menu with the field value (this.getValue())
// before you show the menu -- keep in mind that the menu and its children might not be rendered yet
this.menu.showAt(e.getXY()); // or this.menu.show(this.getEl(), 'tl-bl?');
}
})
}
I did something like this by looking at the code of the date picker and generalizing the idea there - use a menu component for the popup behavior, and put whatever you like as a single component contained by the menu.

Resources