Dispalying more than one message box one after other - extjs

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.

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>

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();

Prevent MessageBox from closing

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() {
// ...
}
}]
});

ExtJS 4.2.1, treepanel disappearing

I am working with ExtJS 4.2.1
I have a button to make appear a panel.
This panel is containing my treepanel, five checkboxes below, and finally one valid button (to close the treepanel and valid the fact that we checked some nodes) and one cancel button (just to cose the treepanel).
I can make my panel appear and it works fine. But if I click on my cancel or my valid button, the panel will hide (ok), and next time I try to show it it doesn't contain my treepanel anymore, only the five checkboxes and the two buttons (attention, the two panels are different, the panel is containing my treepanel).
I don't understand because there is no reason for it to disappear. When I check the treepanel with some console.log() I can see, passing by treepanel.store.tree.root that my treepanel still exists and is properly filled. When I pass through treepanel.view.all I can see the right elements are present in my view. But when I check treepanel.body.dom with chrome debugging I can't see where the element is (ordinary when you pass over the dom with the mouse on chrome debugging you can see the corresponding part of the page colored).
Here is the concerned part of my code:
var button = Ext.get('ProductSelectionButton');
var treeSelector = createTree('stAddAction.do?action=product_tree_selector', 550, 490, '', 'lbl_st_tree_selection_empty', true, 'productlist');
button.on('click', function(){
treeSelector.store.proxy.url = 'stAddAction.do?action=product_tree_selector';
treeSelector.store.reload();
var productPanel = Ext.create('Ext.FormPanel',{
fieldDefaults:{
labelWidth: 75 // label settings here cascade unless overridden
},
frame:true,
title: document.getElementById('applicability').innerHTML + ' - ' + document.getElementById('lbl_st_product_tree_win').innerHTML,
style:'padding: 5px 5px 0; margin-top: 0;',
width: 550,
items: [treeSelector,
{
xtype: 'checkboxgroup',
items: [
{boxLabel: document.getElementById('lbl_status_deleted').innerHTML, name: 'status_2', checked: false, ctCls:'check-status-2',
listeners: {
change: function(newValue, oldValue, eOpts ){
if(newValue.checked){
// To show items with status 2 which is Deleted status
Ext.Array.remove(statusToHide, "2");
ProductList.showIdsStatus(2);
}
else{
// To hide items with status 2 which is Deleted status
Ext.Array.push(statusToHide, "2");
ProductList.hideIdsStatus(2);
}
}
},
... four others checkboxes
}],
buttons: [{
icon : 'img/st_little_valid.png',
style:'width:20px!important;',
handler: function(){
var data = '',
selNodes = treeSelector.getCheckedNodes(treeSelector.getRootNode());
precedentlyCheckedNodes = selNodes;
xhr = getXhr();
xhr.onreadystatechange = function(){
if (xhr.readyState == 4 && xhr.status == 200) {
var myLoad = eval(myDataGrid);
productgrid.store.loadData(myLoad);
productgrid.getView().refresh();
win.hide();
enableSave();
}
}
var params = "action=set_iceproduct&datatoadd=" + data + "&datatoremove=" + strUnchecked;
xhr.open("POST", "stAddAction.do", true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.setRequestHeader('Content-length', params.length);
xhr.send(params);
}
},
{
icon : 'img/st_little_cancel.png',
handler: function(){
/* restore all nodes how they were before (checked or unchecked) */
treeSelector.verifyCheckedNodes(precedentlyCheckedNodes);
win.hide();
/* Only expand the first level */
treeSelector.collapseAll();
treeSelector.getRootNode().expand();
}
}]
});
I don't know if it really is quite explicit...
Anyway, any idea could be welcomed!
How can this treepanel disappear from my panel and still exist!
Thank you
You are calling Ext.create in the buttons click event function every time. This means that the first time you create it, it's okay. But when you click the button again, it will create another panel with the same configuration, only you can't have treeSelector in both because it is already somewhere else. Change your code to something like:
var button = Ext.get('ProductSelectionButton');
var treeSelector = createTree('stAddAction.do?action=product_tree_selector', 550, 490, '', 'lbl_st_tree_selection_empty', true, 'productlist');
button.on('click', function(button){
treeSelector.store.proxy.url = 'stAddAction.do?action=product_tree_selector';
treeSelector.store.reload();
if(!button.productPanel)
{
button.productPanel = Ext.create('Ext.FormPanel',{
fieldDefaults:{
labelWidth: 75 // label settings here cascade unless overridden
},
frame:true,
title: document.getElementById('applicability').innerHTML + ' - ' + document.getElementById('lbl_st_product_tree_win').innerHTML,
style:'padding: 5px 5px 0; margin-top: 0;',
width: 550,
items: [
treeSelector,
{
xtype: 'checkboxgroup',
items: [
{boxLabel: document.getElementById('lbl_status_deleted').innerHTML, name: 'status_2', checked: false, ctCls:'check-status-2',
listeners: {
change: function(newValue, oldValue, eOpts ){
if(newValue.checked){
// To show items with status 2 which is Deleted status
Ext.Array.remove(statusToHide, "2");
ProductList.showIdsStatus(2);
}
else{
// To hide items with status 2 which is Deleted status
Ext.Array.push(statusToHide, "2");
ProductList.hideIdsStatus(2);
}
}

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