PDA

View Full Version : Problems using MultiSelect control



bjnelson62
19 Nov 2012, 1:38 PM
This is my first time doing a form, much less using a MultiSelect control.

When the user clicks a menu item in my grid, I pop up a window/panel with a textfield (where they enter a name for the group they want to create), and I populate a MultiSelect control with values from a store.

I've cobbled this code together from various samples I could find (multiselect demo, contact us demo, etc). My real code is slightly different (the store is populated from a server, and then I set some initial values), but this sample code demonstrates all the problems I'm seeing.

Here are the problems I'm seeing:

1. Putting an ID into any of the fields on the form causes problems when the form is Canceled and then launched again.

2. The config "labelAlign: 'top'" seems to be ignored for the MultiSelect control. I tried putting it in fieldDefaults and directly on the 'multiselect' control, neither worked.

3. Is there a way to get the selected items other than calling Form.getValues()?

4. Is there a way to enforce that at least one item is selected in the MultiSelect control? "allowBlank: 'false'" doesn't do that. Calling Form.isValid() returns TRUE even if allowBlank is false and nothing has been selected. I looked at the isValid() code, and the only check seems to be if an error has been set. Should I set an error instead of pre-selecting the first item?

Once at least one item is selected, then it's not possible for the user to unselect them all. That's good, but I wish I could enforce this from the time the control is rendered.

Here's the code:



Ext.Loader.setConfig({
enabled: true,
paths: {
'Ext.ux': '../extjs/examples/ux/'
}
});

Ext.require('Ext.ux.form.MultiSelect');

Ext.define('MyApp.view.MyForm', {
extend: 'Ext.form.Panel',

height: 250,
width: 400,
layout: {
align: 'stretch',
type: 'vbox'
},
bodyPadding: 10,

fieldDefaults: {
labelAlign: 'top',
labelPad: 10,
labelStyle: 'font-weight:bold',
afterLabelTextTpl: '<span style="color:red;font-weight:bold" data-qtip="Required">*</span>',
},

initComponent: function() {
var me = this;

Ext.applyIf(me, {
items: [
{
xtype: 'textfield',
anchor: '100%',
fieldLabel: 'Group Name',
allowBlank: false,
value: 'NewGroup',
name: 'NewGroupTextfield',
},
{
xtype: 'multiselect',
store: Ext.create('Ext.data.ArrayStore', { fields: ['field'] }),
msgTarget: 'side',
fieldLabel: 'Select nodes for group',
flex: 1,
allowBlank: false,
name: 'NewGroupMultiselect',
id: 'NewGroupMultiselect',
itemId: 'NewGroupMultiselect',
// value: Ext.StoreMgr.lookup('MyStore').first(),
},
{
xtype: 'displayfield',
id: 'NewGroupDisplayField',
itemId: 'NewGroupDisplayField',
fieldLabel: 'Nodes selected',
value: 1,
},
],
buttons: [
{
text: 'Cancel',
handler: function() {
this.up('form').getForm().reset();
this.up('window').hide();
}
},
{
text: 'Create',
handler: function() {
var myForm = this.up('form').getForm(),
values;

if (myForm.isValid()) {
// In a real application, this would submit the form to the configured url
// this.up('form').getForm().submit();
myForm.reset();
this.up('window').hide();
values = myForm.getValues();
Ext.MessageBox.alert('Form is valid with the following values: <br/>' + values);
}
else {
Ext.MessageBox.alert('Form is invalid.');
}
}
},
],
});

me.callParent(arguments);
}

});


Ext.onReady(function(){

function launchPanel() {
var win;

win = Ext.widget('window', {
title: 'New Group',
closeAction: 'hide',
width: 400,
height: 400,
layout: 'fit',
resizable: true,
modal: true,
items: Ext.create('MyApp.view.MyForm')
});

win.show();
}

var mainPanel = Ext.widget('panel', {
renderTo: Ext.getBody(),
title: 'MultiSelect Test',
width: 500,
bodyPadding: 20,

items: [{
xtype: 'component',
html: 'Click the button to launch the panel.',
style: 'margin-bottom: 20px;'
}, {
xtype: 'container',
style: 'text-align:center',
items: [{
xtype: 'button',
cls: 'contactBtn',
scale: 'large',
text: 'Launch Panel',
handler: launchPanel
}]
}]
});

});

mitchellsimoens
22 Nov 2012, 6:08 AM
1. Don't use the id config, it's really not needed.

2. labelAlign : 'top' is working for me when I put it on the multiselect

3. You can execute getValue method on the actual field.

4. There isn't a config, you would need to do it yourself.

bjnelson62
26 Nov 2012, 7:02 AM
Thanks for the reply.

The reason I was going to use an ID, is so I could get access to the control later using Ext.getCmp(ID). Why do you say it's not needed? Accessing a control from another context is a very common thing in UI programming (in my case, I want to check some things when the user clicks OK).

When I use 'top' for labelAlign, the label is at the BOTTOM of the MultiSelect control. I tried both in fieldDefaults, and directly on the control, same issue either way. Could you post your code that's working?

I didn't notice getValue() on the field, thanks!

As for #4, I sorta figured that was the case, but wanted to make sure.


Brian

bjnelson62
26 Nov 2012, 12:13 PM
I figured out the weirdness about why using an ID config for the MultiSelect control caused problems (duplication of things in subsequent invocations): it's because I'm hiding the form/panel/window. I was using the following:

closeAction: 'hide'

and the .hide() method. Once I used 'destroy', then subsequent invocations work just fine. That makes some sense, although why an ID triggered it I don't know, because you'd think the duplication would occur no matter what when a form is re-shown.

But if there's another way to get access to a control other than by using the ID config (and I know about up/down and such, but you don't always have the correct context to get where you're going), that would be useful to know.

qbert65536
19 Apr 2013, 12:00 PM
I have this issue as well, left and right work, but labelAlign: top always shows at the bottom. Using 4.1, and 4.2