PDA

View Full Version : dynamic form creation, columns, and determining which one to populate



jbowman
21 May 2007, 10:04 AM
I'm trying to dynamically create a form that really isn't much more than one radio group.

The scenario is I'm setting up a mini-gallery, where the user uploads a photo and the response includes a url to the generated thumbnail, which is loaded up in one of 4 columns in an Ext.form that have already been created. The columns have id's of vPF(0-3).

Now I know how to get the columns using DomQuery



myColumns = Ext.select('div [id^=vPF]');


What I'm trying to do is that when a new image is loaded, the first column with the lowest number of images already in it, gets the new image.

I believe this gets me the number of images in a column?


Ext.get(column).query('img').length;


Trying to wrap my head around this DomQuery stuff. Every time I see someone post something they've done using, it, others have come back and said 'it's quicker to do it this way' and posted a solution thats much less code than the original author.

So, can I can get some insight if i'm on the right path here? I'm thinking now I can use these to somehow build 2 arrays to cross reference to determine the correct column to place a new image in. But something tells me I'm over thinking this a bit too much and shouldn't need to come up with multiple arrays for this calculation.

Animal
21 May 2007, 10:43 AM
That sounds right, where Ext.get(column) actually returns an Element that represents the Column's DOM wrapper element. If you hold references to all four column objects:



var myForm = new Ext.form.Form();
for (var i = i; i < 4; i++) {
this.pictureColumn[i] = myForm.column();
myForm.end; // close the column
}
myForm.render("container-id");


then you can just use the getEl() method of the Column object and query that.

jbowman
21 May 2007, 11:47 AM
yea, that's exactly how I build the 4 column form, I'm trying to populate it now and that's where I think i'm over thinking things.

That for exists.

I upload a photo, and am returned a JSON output, which includes {"thumb": "images/picture.gif"}

I handle the parsing, am finally left with something like picObj.thumb property.

Now I have to figure out which column I'm going to place that picObj.thumb in. The idea is it's 4 columns, and initially they all have 0 pictures in them

0, 0, 0, 0

Upload a picture, since


Ext.get('vPF0').query('img').length == 0


The picture goes in vPF0, so now the columns look like

1, 0, 0, 0

Upload another picture, then it should go into the second column.. this is the part I'm trying to figure out the best way to do, to get to

1, 1, 0, 0

upload
1, 1, 1, 0

upload
1, 1, 1, 1

upload
2, 1, 1, 1

etc etc...

jbowman
21 May 2007, 6:33 PM
in case anyone was curious, here's the solution



var columns = [];
for (var i=0; i<Ext.get('picForm').query('div [id^=vPF]').length; i++)
{
columns.push(['vPF' + i, Ext.get('vPF' + i).query('img').length]);
}

var cds = new Ext.data.Store({
proxy: new Ext.data.MemoryProxy(columns),
reader: new Ext.data.ArrayReader({}, [
{name: 'columnId'},
{name: 'images', type: 'float'}
])
});
cds.load();
cds.sort('images', 'ASC');
myFS = cds.getAt(0).data.columnId;
Ext.get(myFS).createChild({
tag:'img',
src:pData.thumb
});



I'm now working on a way to do a 4 column form layout without modifying css rules. I'll post that solution when I'm done with it as well.

jbowman
21 May 2007, 6:42 PM
And here's creating 4 rows without changing css



for (var i=0;i<4;i++)
{
if (i%2==0){
vPicForm.column();
}
vPicForm.column({
id: 'vPF' + i
});
vPicForm.end();
if (i%2!=0) {
vPicForm.end();
}
}


Not 100 percent pretty, as it creates kind of a gap between the two main columns. I'll figure something out for that later.

Animal
21 May 2007, 10:53 PM
It looks a bit strange - you're creating 6 Columns? If I assume right, you're wrapping each pair of vPFn Columns in a wrapper Column for spacing?.

If this is just for layout purposes, just style the Column using the style config attribute.

With Column being a Component, you can also use the autoCreate confrig option so that you can add your own class as well to style using stylesheet rules rather than inline styles.



for (var i=0;i<4;i++)
{
var s = (i & 2) ? "" : "margin-left:20px";
this.photoColumn[i] = vPicForm.column({
id: 'vPF' + i,
style: s,
autoCreate: "{tag: 'div', cls: 'x-form-ct photo-column'}"
});
vPicForm.end();
}


The column choosing looks a bit tortured.

How about:



var targetColumn;
var lowestImageCount = Number.MAX_VALUE;
for (var i = 0; i < 4; i++)
{
var count = this.photoColumn[i].getEl().query("img").length;
if (count < lowestImageCount) {
lowestImageCount = count;
targetColumn = this.photoColumn[i];
}
}


You'll get targetColumn as the Column object to which to add the new img element.

jbowman
22 May 2007, 3:11 AM
yea, I was creating the parent columns to get around the fact that the default class for the columns includes a 48% width, meaning you can only get 2 inside any parent, side by side.

I'll look at your suggestions for other ways to approach this tonight after I get off work. Thanks Animal.

Edit: Looking at your column choosing algorithm and I think that's what I was looking for :) I knew I was over thinking the problem, and just couldn't quite get at it that way in my head for some reason. Thanks!

jbowman
22 May 2007, 4:50 PM
Thanks Animal, got both solutions in

Columns


for (var i=0;i<4;i++)
{
vPicForm.column({
id: 'vPF' + i,
autoCreate: {tag: 'div', cls: 'x-form-ct photo-column'}
});
vPicForm.end();
}



CSS (still being tweaked, but this is functional)


.x-form-ct .photo-column {
float:left;
margin:0pt;
overflow:hidden;
padding:1pt;
width:24%;
}


Code to choose which column and populate it
(this is a callback for the upload form submit. It creates the new form (if it's not already there) and then locates and populates the correct column.


var pData = r.result.data;
newvPicForm();

var targetColumn;
var lowestImageCount = Number.MAX_VALUE;
for (var i=0; i<Ext.get('picForm').query('div [id^=vPF]').length; i++)
{
var count = Ext.get('vPF' + i).query('img').length;
if (count < lowestImageCount) {
lowestImageCount = count;
targetColumn = 'vPF' + i;
}
}
Ext.get(targetColumn).createChild({
tag:'img',
src:pData.thumb
});