PDA

View Full Version : HtmlEditor Popup modal window displayed behind main window



vizcano
29 Oct 2009, 8:08 AM
Hi, to everyone

I was trying to do something like http://www.extjs.com/forum/showthread.php?t=75073 but the new window displays under the window where the htmleditor is and i don't know why.

The window-code wich contains the htmleditor is:



var optionWindow = null;

var launchOptionWindow = function(title, data, mode) {
if (!optionWindow) createOptionWindow();

var nodeActiv = treePanel.getSelectionModel().getSelectedNode();

optionWindow.setTitle(title || 'Datos del nuevo documento');
// newsWindow.parent = parent;
optionWindow.data = data;
optionWindow.mode = mode;

optionWindow.show();
optionWindow.hide();

var form = optionWindow.formPanel.getForm();


form.findField('tipo_opcion').store.loadData([['database', 'Texto'], ['link', 'Enlace / Url']]);
documentalStore.load();


optionWindow.setHeight(430);

if (mode == 'edit') {
form.findField('id_option').setValue(data.ID_OPTION);
form.findField('label').setValue(data.OPTION_LABEL);
form.findField('tipo_opcion').setValue(data.OPTION_TYPE);
switch(data.OPTION_TYPE){
case "database":
form.findField('tipo_opcion').enable();

form.findField('description').setValue(data.OPTION_CONTENTS);
Ext.getCmp('content_opt_html').show();
Ext.getCmp('content_opt_url').hide(); // .ownerCt
Ext.getCmp('content_opt_doc').hide();
form.findField('description').enable();
form.findField('url').setValue('');
form.findField('url').disable();
form.findField('documental').disable();
break;
case "link":
form.findField('tipo_opcion').enable();
form.findField('url').setValue(data.OPTION_URL);
Ext.getCmp('content_opt_url').show(); // .ownerCt
Ext.getCmp('content_opt_html').hide();
Ext.getCmp('content_opt_doc').hide();
form.findField('url').enable();
form.findField('documental').disable();
form.findField('description').disable();
break;
case "filemanager":
getDocumentalActivo(data.ID_OPTION);
form.findField('tipo_opcion').enable();
Ext.getCmp('content_opt_doc').show(); // .ownerCt
Ext.getCmp('content_opt_url').hide();
Ext.getCmp('content_opt_html').hide();
form.findField('documental').enable();
form.findField('url').setValue('');
form.findField('url').disable();
break;
default:
form.findField('tipo_opcion').store.loadData([['filesystem', 'Interna']]);
form.findField('tipo_opcion').setValue(data.OPTION_TYPE);
//form.findField('tipo_opcion').disable();
Ext.getCmp('content_opt_doc').hide(); // .ownerCt
Ext.getCmp('content_opt_url').hide();
Ext.getCmp('content_opt_html').hide();
form.findField('documental').enable();
form.findField('url').setValue('');
form.findField('url').disable();
form.findField('documental').disable();
form.findField('description').enable();
}
//


} else {
optionWindow.formPanel.form.reset();
form.findField('id_option').setValue('');
form.findField('tipo_opcion').setValue('database');
Ext.getCmp('content_opt_html').show();
Ext.getCmp('content_opt_url').hide();
Ext.getCmp('content_opt_doc').hide();
form.findField('description').enable();
form.findField('url').setValue('');
form.findField('url').disable();
form.findField('documental').disable();

}
form.findField('id_section').setValue(nodeActiv.attributes.id);
form.findField('mode').setValue(mode);
form.findField('id_language').setValue(id_language);
}

var createOptionWindow = function() {

var nodeActiv = treePanel.getSelectionModel().getSelectedNode();

optionWindow = new Ext.Window({
//animateTarget: "west",
draggable: true, modal: true,
layout: 'fit',
formPanel: null,
width: 600, height: 420,
closeAction: 'hide',
plain: true,
forceLayout: true,
items: [
new Ext.FormPanel({
labelWidth: 100, // label settings here cascade unless overridden
labelAlign: 'top',
frame: true,
// formbind: true,
fileUpload: true,
bodyStyle:'padding:5px 5px 0; overflow-y: auto',
defaultType: 'textfield',
items: [{
xtype: 'hidden',
name: 'id_option',
value: ''
},{
xtype: 'hidden',
name: 'id_section',
value: ''
},{
xtype: 'hidden',
name: 'id_language',
value: ''
},{
xtype: 'hidden',
name: 'mode',
value: ''
},{
fieldLabel: '<b>Etiqueta/Título</b> (obligatorio)',
name: 'label',
value: '',
width: 400,
allowBlank: false,
maxLength: 255,
blankText: 'Este campo es obligatorio'
},{
id: 'content_opt_type',
xtype: 'combo',
width: 400, listWidth: 400,
hiddenName: 'tipo_opcion',
editable: false, forceSelection: true,
lazyInit: false, lazyRender: false,
fieldLabel: 'Tipo',
itemCls: 'required',
displayField: 'label',
hideParent: true,
valueField: 'id',
// value: 'textonly',
typeAhead: false,
editable: false,
forceSelection: true,
disableKeyFilter: true,
triggerAction: 'all',
listClass: 'x-combo-list-small',
mode: 'local',
store: new Ext.data.SimpleStore({
fields: ['id', 'label'],
data: []
}),
listeners: {
'select' : {
fn : function(combo, record) {
var form = optionWindow.formPanel.getForm();
switch (record.data.id) {
case 'database':
Ext.getCmp('content_opt_html').show();
Ext.getCmp('content_opt_url').hide(); // .ownerCt
Ext.getCmp('content_opt_doc').hide();
form.findField('description').enable();
form.findField('url').setValue('');
form.findField('url').disable();
form.findField('documental').disable();
break;
case 'link':
Ext.getCmp('content_opt_url').show(); // .ownerCt
Ext.getCmp('content_opt_html').hide();
Ext.getCmp('content_opt_doc').hide();
form.findField('url').enable();
form.findField('documental').disable();
form.findField('description').disable();
break;
case 'filemanager':
Ext.getCmp('content_opt_doc').show(); // .ownerCt
Ext.getCmp('content_opt_url').hide();
Ext.getCmp('content_opt_html').hide();
form.findField('documental').enable();
form.findField('url').setValue('');
form.findField('url').disable();
break;
}
}, scope: this
}
}
},
new Ext.Panel({
layout: 'form',
id: 'content_opt_doc',
items:[
new Ext.form.ComboBox({
width: 400, listWidth: 400,
hiddenName: 'documental',
editable: false, forceSelection: true,
lazyInit: false, lazyRender: false,
fieldLabel: 'Documental',
itemCls: 'required',
displayField: 'LABEL',
hideParent: true,
valueField: 'ID',
// value: 'textonly',
typeAhead: false,
editable: false,
forceSelection: true,
disableKeyFilter: true,
triggerAction: 'all',
listClass: 'x-combo-list-small',
mode: 'remote',
store: documentalStore
})]

}),
new Ext.Panel({
layout: 'form',
id: 'content_opt_html',
items: [
new Ext.form.HtmlEditor({
id: 'content_opt_editor',
enableFont: false, enableFontSize: false,
fieldLabel: 'Descripción',
width: 540, height: 170,
maxLength: 200,
name: 'description',
plugins: [
new Ext.ux.form.HtmlEditor.Divider(),
new Ext.ux.form.HtmlEditor.Picture({
uploadUrl:'php/up-img.php',
downloadUrl:'php/get-images.php',
flashUrl:'js/swfupload.swf'
})
]

})]
}),
new Ext.Panel({
layout: 'form',
id: 'content_opt_url',
labelAlign: 'top',
items: [{
xtype: 'textfield',
vtype:'url',
fieldLabel: 'Enlace web ó Url',
name: 'url',
value: '',
hideParent: true,
width: 400,
maxLength:255,
allowBlank: false,
emptyText: 'Este campo es obligatorio'
}]
})]
})
],
buttons: [{
text:'Aceptar',
type: 'submit',
handler: function() {
var form = optionWindow.formPanel.getForm();
var formIsValid = true;
switch(Ext.getCmp("content_opt_type").getValue()) {
case "database":
formIsValid = (Ext.getCmp('content_opt_html').getComponent(0).getValue() != "");
break;
case "link":
formIsValid = (Ext.getCmp('content_opt_url').getComponent(0).getValue() != "");
break;
case "filemanager":
formIsValid = (Ext.getCmp('content_opt_doc').getComponent(0).getValue() != "");
break;

}
if (form.isValid() && formIsValid == true) {
pbar = Ext.Msg.progress('Espere unos instantes', 'cargando datos', 'actualizando datos . . .');

form.submit({
url: String.format('?do=awejson.request&what={0}&which={1}', 'sections', 'setOption'),
waitTitle: 'Por favor, espere',
waitMsg: 'Grabando datos ...',
method: 'POST',
reset: false,
failure: function(form, response) {
pbar.hide();
var msg = (response && response.result && response.result.message)
? response.result.message : 'Error no definido. Compruebe el formulario.'
Ext.MessageBox.show({
title: 'Error',
msg: msg,
buttons: Ext.MessageBox.OK,
icon: Ext.MessageBox.ERROR // Ext.MessageBox.WARNING
});
},
success: function(form, response) {
pbar.hide();
Ext.MessageBox.show({
title: 'Proceso',
msg: response.result.message,
buttons: Ext.MessageBox.OK,
icon: Ext.MessageBox.INFO,
fn: function() {
if (optionWindow.mode == 'new' && gridPanel.rowIndex) {
gridPanel.rowIndex = 0;
}
optionWindow.hide();
getOptions(nodeActiv.attributes.id);
if (Ext.getCmp("content_opt_type").getValue() != 'filemanager') {
if(nodeActiv.parentNode)
nodeActiv.parentNode.reload();
}else {
treePanel.root.reload();
treePanel.getLoader().load(nodeActiv);
}



}
});
}
});
} else {
Ext.MessageBox.show({
title: 'Error',
msg: 'Compruebe el formulario, existen errores.',
buttons: Ext.MessageBox.OK,
icon: Ext.MessageBox.ERROR // Ext.MessageBox.WARNING
});
}
},
scope: this
},{
text: 'Cancelar',
handler: function() {
optionWindow.hide();
}
}]
});
optionWindow.formPanel = optionWindow.items.items[0];
}


And if try to override Ext.form.HtmlEditor with



Ext.override(Ext.form.HtmlEditor, {
//Ya que tengo aqui un override hago tb el del link
createLink : function() {
Ext.MessageBox.prompt("aaa","bbb");
}
});


The Ext.MessageBox.prompt is always under the windowOption and its not accesible, anyone could help me?

vizcano
29 Oct 2009, 2:40 PM
No one can help me? :((

Jaitsu
29 Oct 2009, 2:42 PM
i've had this before and it was to do with css positioning of the container in question, it needed position: absolute and it didn't have it...

not really sure what else it could be but maybe that could point you in the right direction?

vizcano
29 Oct 2009, 11:43 PM
I'll take a look to the css...

vizcano
30 Oct 2009, 4:14 AM
Finally i solved it with windowgroup, but now, i have the same problem with Ext.Msg and don't know how to solve it, so i need from your help again, could anyone help me?



Ext.override(Ext.form.HtmlEditor, {
createLink : function() {
var r;
if (this.getDoc().selection)
r = this.doc.selection.createRange().duplicate();
var url=''; var target='';

var myWindowGroup1 = new Ext.WindowGroup();
var myWindowGroup2 = new Ext.WindowGroup();
myWindowGroup1.zseed = 10000;
myWindowGroup2.zseed = 11000;

var LinkWindow = new Ext.Window({
title: "Insertar Enlace",
width: '400',
resizable: false,
modal: true,
hideParent: true,
closeAction: 'hide',
manager: myWindowGroup1,
items: [{
itemId: 'insert-link',
xtype: 'form',
border: false,
plain: true,
bodyStyle: 'padding: 10px;',
labelWidth: 60,
labelAlign: 'right',
items: [{
xtype: 'textfield',
vtype:'url',
allowBlank: false,
fieldLabel: 'URL',
name: 'url',
width: 300
},{
xtype: 'combo',
allowBlank: false,
fieldLabel: 'Target',
name: 'target',
emptyText:'Abrir enlace en...',
mode:'local',
displayField: 'label',
hideParent: true,
valueField: 'id',
editable: false,
forceSelection: true,
store:new Ext.data.SimpleStore({
fields: ['id', 'label'],
data: [
['_blank', 'Nueva ventana'],
['_self', 'Misma ventana']
]
}),
width: 300
}]
}],
buttons: [{
text: 'Insertar',
handler: function() {
var frm = LinkWindow.getComponent('insert-link').getForm();
url = frm.findField('url').getValue();
target = frm.findField('target').getValue();
if((url && url != 'http:/'+'/') && (target!='')) {
var sel = false;
if (window.getSelection) {
sel = this.getWin().getSelection();
} else if (document.getSelection) {
sel = this.getDoc().getSelection();
}
if (sel) {
if(sel!='')
this.insertAtCursor('<a target="'+target+'" href="'+url+'">'+sel+'</a>');
else{
this.insertAtCursor('<a target="'+target+'" href="'+url+'">'+url+'</a>');
}

} else if (document.selection) {
if (r === undefined)
r = this.getDoc().selection.createRange();
if(r.text!='')
r.pasteHTML('<a target="'+target+'" href="'+url+'">'+r.text+'</a>');
else
r.pasteHTML('<a target="'+target+'" href="'+url+'">'+url+'</a>');

}
LinkWindow.close();
}
else{
var errorWindow = Ext.Msg.show({
buttons : Ext.Msg.OK,
icon : Ext.Msg.ERROR,
title : 'aaa',
msg : 'bbb',
width : 300
}).getDialog();
Ext.WindowMgr.unregister(errorWindow);
errorWindow.manager = myWindowGroup2;
}
},
scope: this
},{
text:'Cancelar',
handler:function(){
LinkWindow.close();
}
}]
});
LinkWindow.show();

}
});

vizcano
30 Oct 2009, 5:16 AM
I solved it, this is my solution



Ext.override(Ext.form.HtmlEditor, {
createLink : function() {
var r;
if (this.getDoc().selection)
r = this.doc.selection.createRange().duplicate();
var url=''; var target='';

var myWindowGroup1 = new Ext.WindowGroup();
myWindowGroup1.zseed = Ext.WindowMgr.zseed + 1000;

var LinkWindow = new Ext.Window({
title: "Insertar Enlace",
width: '400',
resizable: false,
modal: true,
hideParent: true,
closeAction: 'hide',
manager: myWindowGroup1,
items: [{
itemId: 'insert-link',
xtype: 'form',
border: false,
plain: true,
bodyStyle: 'padding: 10px;',
labelWidth: 60,
labelAlign: 'right',
items: [{
xtype: 'textfield',
vtype:'url',
allowBlank: false,
fieldLabel: 'URL',
name: 'url',
width: 300
},{
xtype: 'combo',
allowBlank: false,
fieldLabel: 'Target',
name: 'target',
emptyText:'Abrir enlace en...',
mode:'local',
displayField: 'label',
hideParent: true,
valueField: 'id',
editable: false,
forceSelection: true,
store:new Ext.data.SimpleStore({
fields: ['id', 'label'],
data: [
['_blank', 'Nueva ventana'],
['_self', 'Misma ventana']
]
}),
width: 300
}]
}],
buttons: [{
text: 'Insertar',
handler: function() {
var frm = LinkWindow.getComponent('insert-link').getForm();
url = frm.findField('url').getValue();
target = frm.findField('target').getValue();
if((url && url != 'http:/'+'/') && (target!='')) {
var sel = false;
if (window.getSelection) {
sel = this.getWin().getSelection();
} else if (document.getSelection) {
sel = this.getDoc().getSelection();
}
if (sel) {
if(sel!='')
this.insertAtCursor('<a target="'+target+'" href="'+url+'">'+sel+'</a>');
else{
this.insertAtCursor('<a target="'+target+'" href="'+url+'">'+url+'</a>');
}

} else if (document.selection) {
if (r === undefined)
r = this.getDoc().selection.createRange();
if(r.text!='')
r.pasteHTML('<a target="'+target+'" href="'+url+'">'+r.text+'</a>');
else
r.pasteHTML('<a target="'+target+'" href="'+url+'">'+url+'</a>');

}
LinkWindow.close();
}
else{
Ext.WindowMgr.zseed=myWindowGroup1.zseed;
var errorWindow = Ext.Msg.show({
buttons : Ext.Msg.OK,
icon : Ext.Msg.ERROR,
title : 'Error',
msg : 'Todos los campos son obligatorios',
width : 300
});
}
},
scope: this
},{
text:'Cancelar',
handler:function(){
LinkWindow.close();
}
}]
});
LinkWindow.show();

}
});

extci
31 Oct 2009, 12:46 AM
Hi, I had the same problem when extending the htmlEditor with a custom createLink function. It seems that the htmlEditor instance keeps busy doing something. Even explicitly setting the popup inFront() didn't do the trick, but this rather crude solution works.

setup a timed task (which by the way kills any others)


var hrefSelectInFront = new Ext.util.DelayedTask(function(){
Ext.getCmp('hrefselect-win').toFront();
});

simple function to create a popup window to allow the user to specify an url instead of the default prompt box.


function hrefSelect (cb){
var hrefSelectWin = new Ext.Window({
id:'hrefselect-win', title:'Link selector',
layout:'fit', width:450, height:400, x:20, y:30, stateful: false,modal:true,
closable:true, collapsible: true, resizable: false, border:false,
items:new Ext.FormPanel({
id:'hrefselect_form',
labelWidth: 75, // label settings here cascade unless overridden
frame:true, bodyStyle:'padding:5px 5px 0',
items: [{
xtype:'textfield', fieldLabel: 'URL', name: 'url', width:200, allowBlank:false }
],
buttons:[
{text: 'Apply', handler:function(){
var href= getFormPanel(this).getForm().getValues();
cb.dosetLink(href.url);
topCmp(this).destroy();
}
},
{text: 'Cancel', handler:function(){ topCmp(this).destroy() } }
]
})
});
hrefSelectWin.show();
}

extending the htmlEditor


Ext.ux.HtmlEditor = Ext.extend(Ext.form.HtmlEditor, {
initComponent:function() {
Ext.ux.HtmlEditor.superclass.initComponent.apply(this, arguments);
},

onRender:function() {
// call parent
Ext.ux.HtmlEditor.superclass.onRender.apply(this, arguments);
},

createLink : function(){
if (Ext.isIE) {
this.tr = this.doc.selection.createRange(); // create textRange object
this.tr.select(); // Makes the selection equal to the current object.
}
hrefSelect(this);
hrefSelectInFront.delay(2);
},

dosetLink : function(url){
if (Ext.isIE) {
this.tr.execCommand("Unlink",false,null);
if (url) this.tr.execCommand("CreateLink",false,url);
} else
this.relayCmd('createlink', url);
},

:
:
}); //eo extend Ext.form.HtmlEditor
Ext.reg('uxHtmlEditor', Ext.ux.HtmlEditor);

The createLink invokes the popup window and then using the delayedTask forces the popup in front. The createRange / select is required for IE because the selection is lost as soon as the url-textfield gets focus.