PDA

View Full Version : [Ext3.3] Multiselect in form in window



senacle
14 Dec 2010, 3:05 AM
Ext version tested:

Ext 3.3


Adapter used:

ext


css used:

only default ext-all.css
custom css (include details)



.icon-admin {
background-image: url('key.png') !important;
background-repeat: no-repeat;
background-position: 0 6px;
}
.icon-calendrier {
background-image: url('calendrier.png') !important;
background-repeat: no-repeat;
background-position: 0 6px;
}
.icon-courrier {
background-image: url('email.png') !important;
background-repeat: no-repeat;
background-position: 0 6px;
}
.icon-connexion {
background-image: url('lock_open.png') !important;
background-repeat: no-repeat;
background-position: 0 6px;
}
.icon-toto {
background-image: url('toto.png') !important;
background-repeat: no-repeat;
background-position: 0 6px;
}
.icon-deconnexion {
background-image: url('lock.png') !important;
background-repeat: no-repeat;
background-position: 0 6px;
}
.icon-doc {
background-image: url('book.png') !important;
background-repeat: no-repeat;
background-position: 0 6px;
}
.icon-enquete {
background-image: url('loupe.gif') !important;
background-repeat: no-repeat;
background-position: 0 6px;
}
.icon-erase {
background-image: url('erase.png') !important;
background-repeat: no-repeat;
background-position: 0 6px;
}
.icon-export {
background-image: url('export.png') !important;
background-repeat: no-repeat;
background-position: 0 6px;
}
.icon-ferme {
background-image: url('decline.png') !important;
background-repeat: no-repeat;
background-position: 0 6px;
}
.icon-graphe {
background-image:url('chart_bar.png') !important;
}
.icon-imprimante {
background-image: url('imprimante.png') !important;
background-repeat: no-repeat;
background-position: 0 6px;
}
.icon-info {
background-image: url('info.png') !important;
background-repeat: no-repeat;
background-position: 0 6px;
}
.icon-sol {
background-image: url('lightbulb.png') !important;
background-repeat: no-repeat;
background-position: 0 6px;
}
.icon-sql {
background-image: url('sql.png') !important;
background-repeat: no-repeat;
background-position: 0 6px;
}
.icon-suivi {
background-image: url('chart_bar.png') !important;
background-repeat: no-repeat;
background-position: 0 6px;
}
.icon-telephone {
background-image: url('telephone.png') !important;
background-repeat: no-repeat;
background-position: 0 6px;
}

#idjs_info_detail .x-panel-body {
padding: 10px;
background: #eee;
color: #555;
}
#idjs_info_detail h2 {
color: #369;
font-size: 20px;
}
#idjs_info_detail p {
margin-bottom: 5px;
font-size: 15px;
}

h1 {
font-family : Arial;
font-size : 18px;
font-weight : normal;
color : #ae3d37;
}
h2 {
font-family : Arial, Helvetica, sans-serif;
font-size : 16px;
color : #014495;
}
h3 {
font-size : 14px;
color : #111111;
}
h4 {
font-size : 13px;
color : #bbbbbb;
}

a:link {
font-size : 12px;
color : #014495;
text-decoration : none;
font-weight : bold;
}
a:visited {
font-size : 12px;
color : #014495;
text-decoration : none;
font-weight : bold;
}
a:hover {
font-size : 12px;
color : #014495;
text-decoration : underline;
font-weight : normal;
}
a:active {
font-size : 12px;
color : #014495;
text-decoration : none;
font-weight : normal;
}

.contentpaneopen {
width : 100%;
border-spacing : 0;
padding-left : 5px;
padding-right : 5px;
margin-bottom : 5px;
font-family : Arial, Verdana, Helvetica, sans-serif, Tahoma;
font-size : 12px;
}
.contentheading {
border-bottom : 1px solid #ae3d37;
font-weight : bold;
font-size : 16px;
line-height : 16px;
text-transform : uppercase;
text-align : left;
text-indent : 0;
color : #ae3d37;
width : 100%;
padding : 1px;
margin : 3px 0px;
}
.componentheading {
border-bottom : 1px solid #0F3861;
color : #0F3861;
font-weight : bold;
font-size : 15px;
line-height : 16px;
margin : 3px 0 12px;
padding : 1px;
text-align : left;
text-indent : 0;
text-transform : uppercase;
width : 100%;
}
.sectiontableentry1 {
vertical-align : center;
padding : 3px;
background : none;
border-bottom : 1px solid #ffffff;
line-height : 25px;
}

.sectiontableentry2 {
vertical-align : center;
padding : 3px;
border-bottom : 1px solid #ffffff;
background : #f5f5f5;
line-height : 25px;
}





Browser versions tested against:

IE6
IE7
IE8
FF3.6 (firebug 1.6 installed)
Chrome 8


Operating System:

WinXP Pro


Description:

Scrollbar and bottom border of multiselect field doesn't appaear correctly.


Test Case:

The window


var fenetre_abonnement = new Ext.Window({
animateTarget: 'idjs_checkbox_abonnement',
autoHeight: true,
border: true,
closable: true,
closeAction: 'hide',
hidden: true,
iconCls: 'icon-courrier',
id: 'idjs_fenetre_abonnement',
items:[
form_abonnement
],
listeners: {
hide: function() {
updateSpot(false);
Ext.getCmp('idjs_checkbox_abonnement').setValue(false);
}
},
resizable: false,
shadow: 'drop',
shadowOffset: 10,
title: 'Abonnement aux informations',
width: 850
});


The form


var form_abonnement = new Ext.FormPanel ({
bodyStyle:'padding:5px 5px 0',
border: false,
buttonAlign: 'center',
buttons: [{
cls: 'button',
formBind: true,
handler: function () {
var form_abonnement = Ext.getCmp('idjs_abonnement_form').getForm();
if (form_abonnement.isValid()) {
form_abonnement.submit({
waitMsg: 'Enregistrement en cours...',
success: function (result, action) {
obj = Ext.decode(action.response.responseText);
var message = obj.message;
Ext.Msg.show({
title: 'Information',
msg: message,
closable: false,
buttons: Ext.MessageBox.OK,
icon: Ext.MessageBox.INFO
});
},
failure: function(result, action) {
obj = Ext.decode(action.response.responseText);
var message = obj.errors;
Ext.Msg.show({
title: 'Information',
msg: message,
closable: false,
buttons: Ext.MessageBox.OK,
icon: Ext.MessageBox.INFO
});
}
});
} else {
Ext.Msg.show({
title: 'Erreur',
msg: 'Veuillez remplir les champs obligatoires !',
closable: false,
buttons: Ext.MessageBox.OK,
icon: Ext.MessageBox.ERROR
});
}
},
iconCls: 'icon-save',
id: 'idjs_abonnement_envoyer',
scale: 'medium',
text: 'Enregistrer'
}, {
cls: 'button',
formBind: true,
handler: function() {
Ext.getCmp('idjs_abonnement_form').form.reset();
},
iconCls: 'icon-erase',
scale: 'medium',
text: 'Effacer'
}, {
cls: 'button',
formBind: true,
handler: function() {
Ext.getCmp('idjs_fenetre_abonnement').hide();
},
iconCls: 'icon-ferme',
scale: 'medium',
text: 'Fermer'
}],
height: 500,
id: 'idjs_abonnement_form',
items: [{
border: false,
layout: 'column',
items:[{
border: false,
columnWidth:.45,
defaults: {labelStyle: 'font-weight:bold; color:#990033;'},
layout: 'form',
items: [{
allowBlank: false,
columns: 1,
id: 'idjs_abonnement_form_abonnement',
items: [
{boxLabel: 'S\'abonner', name: 'abonnement', inputValue: 'abonnement'},
{boxLabel: 'Se désabonner', name: 'abonnement', inputValue: 'desabonnement'},
{boxLabel: 'Modifier l\'abonnement', name: 'abonnement', inputValue: 'modifier'}
],
width: 216,
xtype: 'radiogroup'
},{
allowBlank: false,
enableKeyEvents: true,
fieldLabel: 'Nom ',
id: 'idjs_abonnement_form_nom',
listeners: {
keyup : function(field, event) {
nom = this.getValue().toLowerCase();
prenom = Ext.getCmp('idjs_abonnement_form_prenom').getValue().toLowerCase();
Ext.getCmp('idjs_abonnement_form_courriel').setValue(prenom + '.' + nom + '@');
}
},
name: 'abonnement_nom',
regex : RegExp('^[a-zA-Z]+$'),
regexText : 'Nom incorrect',
width: 216,
xtype: 'textfield'
},{
allowBlank: false,
enableKeyEvents: true,
fieldLabel: 'Prénom ',
id: 'idjs_abonnement_form_prenom',
listeners: {
keyup : function(field, event) {
nom = Ext.getCmp('idjs_abonnement_form_nom').getValue().toLowerCase();
prenom = this.getValue().toLowerCase();
Ext.getCmp('idjs_abonnement_form_courriel').setValue(prenom + '.' + nom + '@');
}
},
name: 'abonnement_prenom',
regex : RegExp('^[a-zA-Zéčôď]+$'),
regexText : 'Prénom incorrect',
width: 216,
xtype: 'textfield'
},{
allowBlank: false,
fieldLabel: 'Courriel ',
id: 'idjs_abonnement_form_courriel',
name: 'abonnement_courriel',
vtype: 'verif_courriel',
width: 216,
xtype: 'textfield'
},{
allowBlank: true,
fieldLabel: 'Tél. Portable ',
id: 'idjs_abonnement_form_telelphone',
name: 'abonnement_telephone',
vtype: 'verif_telephone_portable',
width: 216,
xtype: 'textfield'
},{
allowBlank: false,
displayField: 'nom_service',
editable: false,
fieldLabel: 'Service ',
id: 'idjs_abonnement_form_service',
lastQuery: '',
name: 'abonnement_service',
store: 'store_service',
triggerAction: 'all',
valueField: 'id_service',
width: 216,
xtype: 'combo'
},{
fieldLabel: 'Code postal ',
id: 'idjs_abonnement_code_postal',
listeners: {
blur: function(field) {
Ext.getCmp('idjs_abonnement_ville').store.removeAll();
code_postal = this.getValue();
Ext.getCmp('idjs_abonnement_ville').store.load({
callback: function(r, option, success) {
if (!success) {
Ext.Msg.show({
title: 'Information',
msg: 'Il n\'y a pas de ville avec le code postal ' + code_postal,
closable: false,
buttons: Ext.MessageBox.OK,
icon: Ext.MessageBox.INFO
});
}
},
params: {abonnement_code_postal: this.getValue()}
});
}
},
name : 'abonnement_code_postal',
regex : RegExp('^[0-9]{5}$'),
regexText : 'Ce code postal n\'est pas correct',
width: 50,
xtype : 'numberfield'
},{
displayField: 'nom_ville',
editable: false,
emptyText:'Entrer un code postal...',
fieldLabel: 'Ville ',
id: 'idjs_abonnement_ville',
lastQuery: '',
name : 'abonnement_ville',
store: 'store_ville',
triggerAction: 'all',
valueField: 'id_ville',
xtype : 'combo'
}]
},{
border: false,
columnWidth:.55,
defaults: {labelStyle: 'font-weight:bold; color:#990033;'},
layout: 'form',
items: [{
allowBlank: false,
displayField: 'display_categorie',
fieldLabel: 'Newsletter ',
id: 'idjs_abonnement_id_categorie',
height: 300,
listeners: {
render: function(ms) {
new Ext.ux.DataTip({
tpl: '{description_categorie}'
}).init(ms.view);
}
},
name: 'abonnement_id_categorie',
store: info_categorie,
tbar:[{
text: 'Tout sélectionner',
handler: function(){
Ext.getCmp('idjs_abonnement_form').getForm().findField('abonnement_id_categorie').selectAll();
}
},{
text: 'Tout désélectionner',
handler: function(){
Ext.getCmp('idjs_abonnement_form').getForm().findField('abonnement_id_categorie').reset();
}
}
],
valueField: 'value_categorie',
width: 250,
xtype: 'multiselect'
}]
}]
}],
labelWidth: 130,
plugins: new Ext.ux.DataTip({
anchor: 'top',
anchorOffset: 85
}),
url: 'some.php'
});


The result that was expected:

Scrollbar must appear only in the multiselect and the bottom border must appear.


The result that occurs instead:

See the attached files


Screenshot or Video:

attached


Debugging already done:

I did'nt find anything to debbug.


Possible fix:

not provided

Condor
14 Dec 2010, 3:55 AM
There are several things wrong with the layout you posted (overnesting and missing layouts).

Please post a simpler testcase without these mistakes.

senacle
14 Dec 2010, 5:10 AM
Here's the viewport which contains the window (simpler than which one i use, but the bug is the same).

I hope it's OK to help you to debug.



Ext.onReady(function() {
var viewport = new Ext.Viewport({
layout:'border',
items:[
new Ext.TabPanel({
activeTab: 1,
defaults: {autoScroll: true},
deferredRender: true,
enableTabScroll: true,
id: 'tabpanel',
region: 'center',
items:[{
border: false,
iconCls: 'icon-info',
id: 'idjs_tab_info',
items: [
new Ext.Panel({
border: false,
bodyCfg: {
tag: 'center'
},
items: [{
border: false,
boxLabel: 'S\'abonner aux listes/se désabonner des listes',
height: 30,
id: 'idjs_checkbox_abonnement',
listeners: {
check: function() {
if (this.checked) {
//info_categorie.load();
//store_service.load();
fenetre_abonnement.show();
updateSpot('idjs_fenetre_abonnement');
Ext.getCmp('idjs_abonnement_form').form.reset();
Ext.getCmp('idjs_abonnement_ville').store.removeAll();
} else {
fenetre_abonnement.hide();
updateSpot(false);
}
}
},
xtype: 'checkbox'
}]
})
],
title: 'Information'
}]
})
]
});
});

Condor
14 Dec 2010, 5:43 AM
1. Also overnested.
2. Don't use tag:'center'. Use a hbox layout with pack:'center' instead.
3. What does this viewport have to do with your multiselect problem? It doesn't contain a multiselect.

senacle
14 Dec 2010, 6:33 AM
1. Also overnested.

What does it mean ?


2. Don't use tag:'center'. Use a hbox layout with pack:'center' instead.
OK
I've modified :

bodyCfg: {
tag: 'center'
},
by

layout:'hbox',
pack:'center',




3. What does this viewport have to do with your multiselect problem? It doesn't contain a multiselect.
Because you said "missing layouts" in the first post. I was thinking you want all my layout.

Condor
14 Dec 2010, 6:50 AM
1. Overnesting
Using a container when it is not needed in a layout.

Example:

{
xtype: 'tabpanel',
items: {
title: 'Tab 1',
items: {
xtype: 'grid',
...
}
}
}
should be:

{
xtype: 'tabpanel',
items: {
title: 'Tab 1',
xtype: 'grid',
...
}
}

2. Missing layout
Using a container without specifying a layout.

Example:

{
xtype: 'tabpanel',
items: {
title: 'Tab 1',
items: {
xtype: 'fieldset',
...
}
}
}
should be:

{
xtype: 'tabpanel',
items: {
title: 'Tab 1',
layout: 'anchor',
items: {
anchor: '100%',
xtype: 'fieldset',
...
}
}
}
(selected layout depends on desired sizing)

joesik
14 Dec 2010, 7:53 PM
I've also got this problem, mine sample is very simple, just use the sample provided in extjs 3.3.1 (multiselect-demo.html), if you run the sample, you will got no problem at IE8, but If I add a DOCTYPE infront of it, ie,

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

the bottom fieldset line and the bottom of scrollbar will seems to be 'chop'

hope this can help to analyse the case =D>

senacle
15 Dec 2010, 4:46 AM
No need - Duplicate of next post

senacle
15 Dec 2010, 5:31 AM
Hello Condor !

Maybe i've some fog on my eyes, but i didn't find in my code the mistakes you speak about (overnesting and missing layouts).

I take the Dynamic form sample number 3 and put a multiselect inside :



var form_abonnement = new Ext.FormPanel ({
frame:true,
title: 'Multi Column, Nested Layouts and Anchoring',
bodyStyle:'padding:5px 5px 0',
width: 600,
items: [{
layout:'column',
items:[{
columnWidth:.5,
layout: 'form',
items: [{
xtype:'textfield',
fieldLabel: 'First Name',
name: 'first',
anchor:'95%'
}, {
xtype:'textfield',
fieldLabel: 'Company',
name: 'company',
anchor:'95%'
}]
},{
columnWidth:.5,
layout: 'form',
items: [{
xtype:'textfield',
fieldLabel: 'Last Name',
name: 'last',
anchor:'95%'
},{
xtype:'multiselect',
fieldLabel: 'Email',
store: my_store,
name: 'coucou'
}]
}]
}]
)};


as you can see in the attached files, there's the bug i speak about in my first post.

Condor
15 Dec 2010, 7:38 AM
1. Overnesting: FormPanel has a layout:'form' by default, but there is no reason it couldn't be layout:'column', so you don't need that extra container.
2. Missing layout: A multiselect needs a fixed width to display correctly, so you should specify a 'width' or an 'anchor'.
3. This entire layout doesn't specify heights anywhere.
- Any container that should determine it's height based on the children size should be autoHeight:true.
- A MultiSelect doesn't have a default height - you need to give it a fixed height.

senacle
16 Dec 2010, 5:57 AM
I did all the corrections that you advise (i hope !) :



var form_abonnement = new Ext.FormPanel ({
autoHeight: true,
height: 'auto',
frame:true,
title: 'Multi Column, Nested Layouts and Anchoring',
bodyStyle:'padding:5px 5px 0',
layout:'column',
items:[{
columnWidth:.5,
layout: 'form',
items: [{
xtype:'textfield',
fieldLabel: 'First Name',
name: 'first',
anchor:'95%'
}, {
xtype:'textfield',
fieldLabel: 'Company',
name: 'company',
anchor:'95%'
}]
},{
columnWidth:.5,
layout: 'form',
items: [{
xtype:'textfield',
fieldLabel: 'Last Name',
name: 'last',
anchor:'95%'
},{
xtype:'multiselect',
fieldLabel: 'Email',
store: info_categorie,
name: 'coucou',
width: 250,
height: 300
}]
}]/
});



1.Overnesting: FormPanel has a layout:'form' by default, but there is no reason it couldn't be layout:'column', so you don't need that extra container.
Remove the first "items: [{ }]" which is not necessary in this example


2. Missing layout: A multiselect needs a fixed width to display correctly, so you should specify a 'width' or an 'anchor'.
Add a width property for the multiselect


3. This entire layout doesn't specify heights anywhere.
- Any container that should determine it's height based on the children size should be autoHeight:true.
- A MultiSelect doesn't have a default height - you need to give it a fixed height.
Add autoHeight for the containers and a height property for multiselect.

Remember that the form_abonnement panel is inside a window :


var fenetre_abonnement = new Ext.Window({
animateTarget: 'idjs_checkbox_abonnement',
autoHeight: true,
border: true,
closable: true,
closeAction: 'hide',
height: 'auto',
hidden: true,
iconCls: 'icon-courrier',
id: 'idjs_fenetre_abonnement',
items:[
form_abonnement
],
listeners: {
hide: function() {
updateSpot(false);
Ext.getCmp('idjs_checkbox_abonnement').setValue(false);
}
},
resizable: false,
shadow: 'drop',
shadowOffset: 10,
title: 'Abonnement aux informations',
width: 850
});


But....the problem is always here :(

Condor
16 Dec 2010, 7:04 AM
1. Don't use height:'auto', only use autoHeight:true.
2. The window will need a layout too (and since you want it autoHeight:true, I recommend layout:'anchor').

senacle
16 Dec 2010, 11:59 PM
1. Don't use height:'auto', only use autoHeight:true.
height:'auto' is the default property. No need to have clearer code. OK.

2. The window will need a layout too (and since you want it autoHeight:true, I recommend layout:'anchor').

Here's my new code :

The window


var fenetre_abonnement = new Ext.Window({
animateTarget: 'idjs_checkbox_abonnement',
autoHeight: true,
border: true,
closable: true,
closeAction: 'hide',
height: 'auto',
hidden: true,
iconCls: 'icon-courrier',
id: 'idjs_fenetre_abonnement',
items:[
form_abonnement
],
layout: 'anchor',
listeners: {
hide: function() {
updateSpot(false);
Ext.getCmp('idjs_checkbox_abonnement').setValue(false);
}
},
resizable: false,
shadow: 'drop',
shadowOffset: 10,
title: 'Abonnement aux informations',
width: 850
});


The form:


var form_abonnement = new Ext.FormPanel ({
autoHeight: true,
frame:true,
title: 'Multi Column, Nested Layouts and Anchoring',
bodyStyle:'padding:5px 5px 0',
layout:'column',
items:[{
columnWidth:.5,
layout: 'form',
items: [{
xtype:'textfield',
fieldLabel: 'First Name',
name: 'first',
anchor:'95%'
}, {
xtype:'textfield',
fieldLabel: 'Company',
name: 'company',
anchor:'95%'
}]
},{
columnWidth:.5,
layout: 'form',
items: [{
xtype:'textfield',
fieldLabel: 'Last Name',
name: 'last',
anchor:'95%'
},{
xtype:'multiselect',
fieldLabel: 'Email',
store: info_categorie,
name: 'coucou',
width: 250,
height: 300
}]
}]
});


And you know what ?
OK under IE6, IE7, IE8 and Chrome 8 under WinXP.
OK under FF3.6 under Ubuntu10.04.
NOK under FF3.6 under WinXP Pro.

Crazy, isn't it ?

Condor
17 Dec 2010, 12:57 AM
Making the window layout:'anchor' isn't enough. You also have to configure the items (= your form) with an anchor, e.g. anchor:'100%'.

senacle
17 Dec 2010, 5:43 AM
Sorry, Condor, but it does'nt solve the problem....

senacle
4 Aug 2011, 11:44 PM
After searching in other post, i've found this solution : http://www.sencha.com/forum/showthread.php?120450-MultiSelect-scroll-bar-not-showing-when-expected&p=633810

In the multiselect.js, i've changed :

height: this.height
to

height: this.height-37
and it works for all multiselect fields i use.