PDA

View Full Version : FieldReplicator. A Field which keeps adding clones of itself until left blank.



Animal
7 Aug 2009, 7:38 AM
Just like mailto addresses, sometimes you want multiple identical versions of an input field until the user has had enough, and leaves the last one blank.

This is a plugin to any Field which makes it self replicating. Blanking out any Field in the series deletes it (Unless it was the last one!)

Just configure the Field with



plugins: [ Ext.ux.FieldReplicator ],




Ext.ux.FieldReplicator = {
init: function(f) {
f.replicator = this;
f.enableKeyEvents = true;
f.on('change', this.onChange, this);
f.onKeyDown = f.onKeyDown.createInterceptor(this.onKeyDown);
},

// If tabbing out and the change event will be fired, flag that
// the change handler must focus the correct sibling field.
onKeyDown: function(e) {
if ((e.getKey() == Ext.EventObject.TAB) && (String(this.startValue) !== String(this.getValue()))) {
if (e.shiftKey) {
this.focusPrev = true;
} else {
this.focusNext = true;
}
}
},

// Handle the field either being changed to blank or from blank.
onChange: function(f, n, o) {
var c = f.ownerCt, l,
ps = f.previousSibling(),
ns = f.nextSibling();
if (Ext.isEmpty(n)) {
if (!Ext.isEmpty(o)) {
// The Field has been blanked, and it is not the only one left, remove it
if ((ps && (ps.replicator === this)) || (ns && (ns.replicator === this))) {
l = f.findParentBy(function(p) {
return !Ext.isDefined(p.ownerCt);
});
c.remove(f);
l.doLayout();
}
}
} else {
if (Ext.isEmpty(o)) {
// Field filled, insert a clone as the next sibling
ns = new f.constructor(f.cloneConfig());
c.insert(c.items.indexOf(f) + 1, ns);
c.doLayout();
l = f.findParentBy(function(p) {
return !Ext.isDefined(p.ownerCt);
});
l.doLayout();
}
}
if (f.focusPrev) {
delete f.focusPrev;
ps.focus(false, true);
} else if (f.focusNext) {
delete f.focusNext;
ns.focus(false, true);
}
}
};

aconran
7 Aug 2009, 8:15 AM
Very nice, I like how you've added this behavior via a plugin. :)

mystix
7 Aug 2009, 9:36 AM
i like :)

p.s. would it be a good idea to delete the id from the cloned Field config tp prevent possible conflicts?

Animal
7 Aug 2009, 9:40 AM
i like :)

p.s. would it be a good idea to delete the id from the cloned Field config tp prevent possible conflicts?

Yes, well spotted.

I will update the first post.

Animal
7 Aug 2009, 9:45 AM
Component.cloneConfig generates a new ID, so all will be well with the original code.

I'll add some extra stuff to the cloneConfig documentation to make it clearer.

Animal
7 Aug 2009, 9:47 AM
Very nice, I like how you've added this behavior via a plugin. :)

It's definitely best in a lot of cases.

I originally extended Ext.form.TextField, but realized that left TriggerFields high and dry.

mystix
7 Aug 2009, 9:48 AM
spotted one more thing:


if (Ext.isEmpty(n)) {
if (!Ext.isEmpty(o)) {
// ... ... ...
}
} else {
if (Ext.isEmpty(o)) {
// ... ... ...
}
}



in the interests of efficiency, might i suggest the following modifications:


if (!n && o) {
// ... ... ...
} else if (!o) {
// ... ... ...
}

mystix
7 Aug 2009, 9:54 AM
i realise my suggested mod allows empty arrays, but all other bases are covered
(does anyone set arrays into Fields?)

Animal
7 Aug 2009, 10:07 AM
The getValue() values are whatever the Field returns, so that could be anything.

I think we should allow people to write Fields which can return any kind of Object.

mystix
7 Aug 2009, 10:11 AM
I think we should allow people to write Fields which can return any kind of Object.

i'm beginning to like that concept.
i recant for now. :)

jmariani
1 Apr 2010, 11:52 AM
Handy and dandy plugin but, when a form.reset() happens, didn't the new fields must be deleted? Or, how to delete the new fields when a form.reset() happens?

Animal
1 Apr 2010, 12:31 PM
Good point! Add that, and lets get it put back in!

pkli
1 Apr 2010, 6:17 PM
Very usefull in many cases.
May I suggest an evolution : clone a group of fields.

Lobos
20 Apr 2010, 9:33 PM
Very usefull in many cases.
May I suggest an evolution : clone a group of fields.

+1

swaffoja
22 Nov 2010, 10:42 AM
When loading a form I would expect a replicated field to take an array of values and create one field for each value:


["Replicated field value 1","Replicated field value 1"]
Doing this currently concatenates both values into a single text field. How are people loading data into forms containing replicated fields? If this functionality doesn't exist, any suggestions on the best way to implement?

israel.galan
6 Jan 2011, 11:39 PM
+1
Is this supposed to help? I am interested in duplicating several fields at a time. How would this be done?