Upgrade to ExtJS 3.2.2 - Released 06/02/2010
[extjs.git] / examples / ux / FieldReplicator.js
1 /*!
2  * Ext JS Library 3.2.2
3  * Copyright(c) 2006-2010 Ext JS, Inc.
4  * licensing@extjs.com
5  * http://www.extjs.com/license
6  */
7 Ext.ns("Ext.ux");
8
9 /**
10  * @class Ext.ux.FieldReplicator
11  * <p>A plugin for Field Components which creates clones of the Field for as
12  * long as the user keeps filling them. Leaving the final one blank ends the repeating series.</p>
13  * <p>Usage:</p>
14  * <pre><code>
15     {
16         xtype: 'combo',
17         plugins: [ Ext.ux.FieldReplicator ],
18         triggerAction: 'all',
19         fieldLabel: 'Select recipient',
20         store: recipientStore
21     }
22  * </code></pre>
23  */
24 Ext.ux.FieldReplicator = {
25     init: function(f) {
26         f.replicator = this;
27         f.enableKeyEvents = true;
28         f.on('change', this.onChange, this);
29         f.onKeyDown = f.onKeyDown.createInterceptor(this.onKeyDown);
30     },
31
32 //  If tabbing out and the change event will be fired, flag that
33 //  the change handler must focus the correct sibling Field.
34     onKeyDown: function(e) {
35         if ((e.getKey() == Ext.EventObject.TAB) && (String(this.startValue) !== String(this.getValue()))) {
36             if (e.shiftKey) {
37                 this.focusPrev = true;
38             } else if (!e.shiftKey && !e.altKey) {
39                 this.focusNext = true;
40             }
41         }
42     },
43
44 //  Handle the field either being changed to blank or from blank.
45     onChange: function(f, n, o) {
46
47 //              Ensure that "change" is only fired once.
48         f.startValue = n;
49
50         var c = f.ownerCt, l,
51             ps = f.previousSibling(),
52             ns = f.nextSibling();
53         if (Ext.isEmpty(n)) {
54             if (!Ext.isEmpty(o)) {
55 //              The Field has been blanked, and it is not the only one left, remove it
56                 if ((ps && (ps.replicator === this)) || (ns && (ns.replicator === this))) {
57                     l = f.findParentBy(function(p) {
58                         return !Ext.isDefined(p.ownerCt);
59                     });
60                     c.remove(f);
61                     l.doLayout();
62                 }
63             }
64         } else {
65             if (Ext.isEmpty(o)) {
66 //              Field filled, insert a clone as the next sibling
67                 ns = new f.constructor(f.cloneConfig());
68                 c.insert(c.items.indexOf(f) + 1, ns);
69                 c.doLayout();
70                 l = f.findParentBy(function(p) {
71                     return !Ext.isDefined(p.ownerCt);
72                 });
73                 l.doLayout();
74             }
75         }
76         if (f.focusPrev) {
77             delete f.focusPrev;
78             ps.focus(false, true);
79         } else  if (f.focusNext) {
80             delete f.focusNext;
81             ns.focus(false, true);
82         }
83     }
84 };