PDA

View Full Version : Selection List - suggestions wanted



MH61
14 Aug 2009, 5:44 AM
I'm working on a studies application and am currently using the ux.wiz (http://extjs.com/forum/showthread.php?t=36627) extension to allow for add/edit of a study. one of the steps of this study requires the user to select every country the study is taking place in,l from a list of every country in the world. I've been trying to do this for weeks now.

first I tried the ItemSelector (http://extjs.com/forum/showthread.php?t=73423) - which looked horrible in the wizard - had a lot of trouble with sizing and scrolling. I tried upgrading to 3.0 in the hope the ItemSelector might work a little better but it didn't change a thing.

I then tried to have a checkbox tree(http://extjs.com/forum/showthread.php?t=76531 (http://extjs.com/forum/showthread.php?t=76531&page=2)), where there were branches for each world region so that there would be less need to scroll. but for sopme reason when the tree was placed inside the wizard it was impossible to expand the bottom branch, and it would always scroll up to the second-last branch

I then needed a quick fix because we needed to present the app to our users, and 3.0 was breaking a few pieces of the application, so i had to roll back to 2.2 and use a multiselect, which works:
15672

But upon showing the app to the users, they made the following complaints:
-too much scrolling
-need to hold ctrl the whole time
-if they let go of ctrl they unselect everything

I've also investigated using grid drag and drop, check boxes in accordian layout and SuperBoxSelect. But neither look like the perfect solution to me.

Just wondering if anyone has any suggestion as to how i should implement this. I could be overlooking something obvious. Ideally it will have following features:
-minimal scrolling, can allow for grouping by region
-must fit comfortably into wizard, i don't want the wizard being as big as the screen. I've already had to make the wizard bigger than default size and the elements on the other wizard steps look dwarfed by the huge amount of blank space
-convenient for making many (50+) selections - cannot lose all selections in once click
-can fit long names in like 'South Georgia and the South Sandwich Islands'
-preferrably provides a list of all selected items like drag and drop does (though this may not be possible considering the above

thanks for any suggestions

Animal
14 Aug 2009, 9:58 AM
Use the TreePanel.

It should work just fine. You did something wrong.

MH61
17 Aug 2009, 8:04 AM
well i tried it and it works. I have no idea why it works now and it didn't before.


var tree = new Ext.tree.TreePanel({
//renderTo:'tree-div',
loader: new Ext.tree.TreeLoader({
dataUrl: 'Lookup/List',
requestMethod:'GET'
}),

region : 'center',
//title: 'My Task List',
height: 350,
width: 400,
useArrows:true,
autoScroll:true,
animate:true,
enableDD:false,
containerScroll: true,
rootVisible: false,
//frame: true,
root: {
nodeType: 'async'
},

// auto create TreeLoader


listeners: {
'checkchange': function(node, checked){
if(checked){
node.getUI().addClass('complete');
}else{
node.getUI().removeClass('complete');
}
}
},

buttons: [{
text: 'Get Completed Tasks',
handler: function(){
var msg = '', selNodes = tree.getChecked();
Ext.each(selNodes, function(node){
if(msg.length > 0){
msg += ', ';
}
msg += node.text;
});
Ext.Msg.show({
title: 'Completed Tasks',
msg: msg.length > 0 ? msg : 'None',
icon: Ext.Msg.INFO,
minWidth: 200,
buttons: Ext.Msg.OK
});
}
}]
});

the listener and buttons are just the code from the examples. What i want to do is have a message underneath that displays how many items have been selected. I can't see any properties in the api that would allow this, so just wondering what the best way is. do i need to add a label underneath or can i utilize one of the treePanel's properties?

MH61
18 Aug 2009, 7:23 AM
Still haven't got the count label working - first I'm just trying to get basic functionality.

I've got saving working, but now i'm trying to load... dataIndex doesn't seem to work (property is an int list so was hoping it'd just select the nodes that had each number as an id.



STUDIES.Study.StudyInfo4 = Ext.extend(Ext.ux.Wiz.Card, {
StudyRecord : null,
isReadOnly: null,

initComponent : function() {

var tree = new Ext.tree.TreePanel({
loader: new Ext.tree.TreeLoader({
dataUrl: 'Lookup/List',
requestMethod:'GET'
}),
region : 'center',
dataIndex : 'Countries',
height: 350,
width: 400,
useArrows:true,
autoScroll:true,
animate:true,
enableDD:false,
containerScroll: true,
rootVisible: false,
root: {
nodeType: 'async'
}
});

Ext.apply(this,
{
title : 'Study Information Part 4',
monitorValid : true,
defaults : {
labelStyle : 'font-size:11px',
anchor : '100%',
validationDelay : VALIDATION_DELAY,
disabled: this.isReadOnly
},
labelAlign : 'top',
items : [
{
border : false,
bodyStyle : 'background:none;padding-bottom:15px;',
html : 'Study Info',
disabled: false
},
tree
]
});

this.on('activate', function() {
//Populate the form if it an edit
//Do not reload the values if they could have been changed in any way
if (this.wizard.lastAction == 'previous')
return;

if (!this.wizard.isNew) {
var form = this.getForm();
if (form.isDirty())
return;
//Populate form with existing data
form.loadRecord(this.StudyRecord);
//Populate tree from here if dataIndex doesnt work - but how?
}
}, this);

STUDIES.Study.StudyInfo4.superclass.initComponent.apply(this, arguments);
}
});


Any ideas?

MH61
18 Aug 2009, 8:11 AM
I've updated the listener to try and work around the dataIndex not working. Not only does this work around not work, but even if it did i'd still not be happy because it is pretty horrible code and i'm sure there is a much easier way to do this:



this.on('activate', function() {
//Populate the form if it an edit
//Do not reload the values if they could have been changed in any way
if (this.wizard.lastAction == 'previous')
return;

if (!this.wizard.isNew) {
var form = this.getForm();
if (form.isDirty())
return;
//Populate form with existing data
form.loadRecord(this.StudyRecord);

for(var branch in tree.nodeHash){
for(var id in this.StudyRecord.data.Countries){
var node = tree.getNodeById(branch).findChild('id', id);
if(node)
node.checked = true
}
}
}
}, this);


please help

Animal
18 Aug 2009, 10:50 AM
What's this about loading a Record? Where's the Record coming from? Have you set a breakpoint and checked that it's really a Record? Because I don't see who's sending it.

MH61
18 Aug 2009, 11:03 AM
Accepted as param


STUDIES.Study.StudyInfo4 = Ext.extend(Ext.ux.Wiz.Card, {
StudyRecord : null,
//Filtered out
});


Accepted as param by wizard, Passed in upon construction of card


STUDIES.Study.Wizard = Ext.extend(Ext.ux.Wiz, {
StudyRecord : null,
//Filtered out
new STUDIES.Study.StudyInfo4({StudyRecord : this.StudyRecord, isReadOnly: this.isReadOnly}),
//Filtered out
});


Which comes from a grid that has an edit button


onEditStudyClick : function() {
// Check which item (if any) are selected
var selectedStudy = this.getSelectionModel();
var studyRec = selectedStudy.selections.items[0];

if (studyRec) {
var studyWiz = new STUDIES.Study.Wizard({
StudyRecord:studyRec,
isNew: false,
isReadOnly: false,
saveStudyCallback : this.saveStudyDelegate.createDelegate(this)
});
studyWiz.show();
} else {
Ext.Msg.alert('Could not complete action','You need to select a study first');
}
},



And upon breaking on the loadRecord line:

15740

MH61
19 Aug 2009, 4:38 AM
Just bumping this thread, I'm still having trouble with this

Animal
19 Aug 2009, 4:42 AM
With what, where?

MH61
19 Aug 2009, 4:53 AM
-Cannot get dataIndex to populate tree with data from record



I've got saving working, but now i'm trying to load... dataIndex doesn't seem to work (property is an int list so was hoping it'd just select the nodes that had each number as an id.



STUDIES.Study.StudyInfo4 = Ext.extend(Ext.ux.Wiz.Card, {
StudyRecord : null,
isReadOnly: null,

initComponent : function() {

var tree = new Ext.tree.TreePanel({
loader: new Ext.tree.TreeLoader({
dataUrl: 'Lookup/List',
requestMethod:'GET'
}),
region : 'center',
dataIndex : 'Countries',
height: 350,
width: 400,
useArrows:true,
autoScroll:true,
animate:true,
enableDD:false,
containerScroll: true,
rootVisible: false,
root: {
nodeType: 'async'
}
});

Ext.apply(this,
{
title : 'Study Information Part 4',
monitorValid : true,
defaults : {
labelStyle : 'font-size:11px',
anchor : '100%',
validationDelay : VALIDATION_DELAY,
disabled: this.isReadOnly
},
labelAlign : 'top',
items : [
{
border : false,
bodyStyle : 'background:none;padding-bottom:15px;',
html : 'Study Info',
disabled: false
},
tree
]
});

this.on('activate', function() {
//Populate the form if it an edit
//Do not reload the values if they could have been changed in any way
if (this.wizard.lastAction == 'previous')
return;

if (!this.wizard.isNew) {
var form = this.getForm();
if (form.isDirty())
return;
//Populate form with existing data
form.loadRecord(this.StudyRecord);
//Populate tree from here if dataIndex doesnt work - but how?
}
}, this);

STUDIES.Study.StudyInfo4.superclass.initComponent.apply(this, arguments);
}
});
Any ideas?

-not sure best way to display a message showing how many check boxes are selected

Animal
19 Aug 2009, 4:59 AM
"Cannot get dataIndex to populate tree with data from record" doesn't mean much to me.

dataIndex is used by ColumnModels to know what field to pull from a Store, that's the only context I know it in.

You are using a TreePanel here, so.... wibble.

MH61
19 Aug 2009, 5:25 AM
I'm confused here.

I pull json data to populate a grid, the user selects a record and clicks the edit button, which pulls up a wizard - it passes the selected record to the wizard. (code already posted in this thread). every text field in the wizard uses the dataIndex property so that it is populated with its associated field from the selected record in the grid. combo boxes are populated by a lookups store, but still use dataIndex so that they are pre-selected with the value that was displayed in the grid.

The same concept should apply with the TreePanel, the treepanel is populated by lookup data, i.e. the list of countries to be shown. but if the user is performing an edit, the tree should be pre-populated with checks next to all the countries that were selected when the record was originally added. the record that the grid stores has a countries property which is an integer list of the countries that have been saves for the selected study. so by adding the property dataIndex:Countries to the treePanel I would expect if Countries was a list of values 3,4,5 that the nodes of the treePanel with ids of 3, 4 and 5 should be checked when the treePanel is loaded.

If you are saying that the dataIndex will not work in any way for a treePanel, then i will need to find another way to check these nodes in the treePanel. In attempt at this i tried the following code but had no luck, so I would like to know the best approach to take


this.on('activate', function() {
//Populate the form if it an edit
//Do not reload the values if they could have been changed in any way
if (this.wizard.lastAction == 'previous')
return;

if (!this.wizard.isNew) {
var form = this.getForm();
if (form.isDirty())
return;
//Populate form with existing data
form.loadRecord(this.StudyRecord);

for(var branch in tree.nodeHash){
for(var id in this.StudyRecord.data.Countries){
var node = tree.getNodeById(branch).findChild('id', id);
if(node)
node.checked = true
}
}
}
}, this);



thanks

Animal
19 Aug 2009, 7:35 AM
You've lost me. TreePanel has nothing to do with any dataIndex. If YOU have some scheme for loading a TreePanel, and YOU use something YOU call a dataIndex, then maybe your code has some problem.

I don't know what's going on.

MH61
19 Aug 2009, 7:45 AM
Ok, lets step back a second. The main page of the application is a gridPanel, it contains a list of studies. When the user selects a record and clicks the edit button, a wizard pops up and over about 10 cards presents the user with each of the properties of the study to edit.
Regardless of whether i use a wizard, window or whatever else to allow the user to edit the record pulled from the grid, the editing will be done with textfields, combos and a check tree panel.

Are you saying that passing the record from the grid and populating these objects with this record is the wrong way to do this?