/[suikacvs]/test/suikawebwww/style/ui/widget-values.js.u8
Suika

Contents of /test/suikawebwww/style/ui/widget-values.js.u8

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.3 - (hide annotations) (download)
Tue Jan 6 07:05:50 2009 UTC (17 years, 6 months ago) by wakaba
Branch: MAIN
CVS Tags: HEAD
Changes since 1.2: +20 -3 lines
Relicensed under the terms that are compatibile with Perl's license

1 wakaba 1.1 function WidgetValues (c) {
2     if (c) {
3     this.container = c;
4     this._init ();
5     }
6     } // WidgetValues
7    
8     WidgetValues.prototype._init = function () {
9     var ta = this.container.getElementsByTagName ('textarea')[0];
10     if (!ta) return;
11    
12     this.name = this.container.getAttribute ('data-widget-name') || ta.name || '';
13    
14     this.separatorPattern
15     = new RegExp (this.container.getAttribute ('data-widget-separator')
16     || '\\s+');
17    
18 wakaba 1.2 this.defaultValues = ta.defaultValue.length
19     ? ta.defaultValue.split (this.separatorPattern) : [];
20     this.initialValues = ta.value.length
21     ? ta.value.split (this.separatorPattern) : [];
22 wakaba 1.1
23     this.clear ();
24     this.appendValues (this.initialValues);
25     }; // _init
26    
27     WidgetValues.prototype._clear = function () {
28     this.firstField = null;
29     this.lastField = null;
30     this.container.innerHTML = '';
31     }; // _clear
32    
33     WidgetValues.prototype.appendValues = function (values) {
34     var self = this;
35     for (var i = 0; i < values.length; i++) {
36     var field = this.createField (values[i]);
37     field.wvRemove = function () { self._removeField (this) };
38     field.wvMoveUp = function () { self._moveUpField (this) };
39     field.wvMoveDown = function () { self._moveDownField (this) };
40     var parent = this.lastField ? this.lastField.parentNode : null;
41     parent = parent ? parent : this.fieldsParent;
42     parent.insertBefore (field, this.lastField ? this.lastField.nextSibling : null);
43     this.lastField = field;
44     this.firstField = this.firstField || field;
45     }
46     }; // appendValues
47    
48     WidgetValues.prototype.reset = function () {
49     this.clear ();
50     this.appendValues (this.defaultValues);
51     }; // reset
52    
53     WidgetValues.prototype._removeField = function (field) {
54     if (this.firstField == field) {
55     this.firstField = this._getNextField (field);
56     }
57     if (this.lastField == field) {
58     this.lastField = this._getPreviousField (field);
59     }
60     field.parentNode.removeChild (field);
61     }; // _removeField
62    
63     WidgetValues.prototype._moveUpField = function (field) {
64     this._swapFields (field, this._getPreviousField (field));
65     }; // _moveUpField
66    
67     WidgetValues.prototype._moveDownField = function (field) {
68     this._swapFields (field, this._getNextField (field));
69     }; // _moveDownField
70    
71     WidgetValues.prototype._swapFields = function (f1, f2) {
72     if (!f1 || !f2) return;
73     var ph = document.createElement (f1.tagName || 'x');
74     f1.parentNode.replaceChild (ph, f1);
75     f2.parentNode.replaceChild (f1, f2);
76     ph.parentNode.replaceChild (f2, ph);
77     }; // _swapFields
78    
79     WidgetValues.prototype._getNextField = function (field) {
80     var n = field.nextSibling;
81     while (n != null) {
82     if (this.isField (n)) {
83     return n;
84     }
85     n = n.nextSibling;
86     }
87     return null;
88     }; // _getNextField
89    
90     WidgetValues.prototype._getPreviousField = function (field) {
91     var n = field.previousSibling;
92     while (n != null) {
93     if (this.isField (n)) {
94     return n;
95     }
96     n = n.previousSibling;
97     }
98     return null;
99     }; // _getPreviousField
100    
101     WidgetValues.prototype.createButton = function () {
102     var el;
103    
104     try {
105     el = document.createElement ('button');
106 wakaba 1.2 el.setAttribute('type', 'button');
107 wakaba 1.1 } catch (e) {
108     el = document.createElement ('<button type=button>');
109     }
110    
111     return el;
112     }; // createButton
113    
114     WidgetValues.prototype.isField = function (n) {
115     return n.wvIsField;
116     }; // isField
117    
118    
119    
120    
121     WidgetValues.prototype.createField = function (value) {
122     var field = document.createElement ('div');
123     field.wvIsField = true;
124    
125     var input = document.createElement ('input');
126     input.name = this.name;
127     input.value = value;
128     field.appendChild (input);
129    
130     var removeButton = this.createButton ();
131     removeButton.innerHTML = 'Remove';
132     removeButton.onclick = function () { field.wvRemove () };
133     field.appendChild (removeButton);
134    
135     var moveUpButton = this.createButton ();
136     moveUpButton.innerHTML = 'Move up';
137     moveUpButton.onclick = function () { field.wvMoveUp () };
138     field.appendChild (moveUpButton);
139    
140     var moveDownButton = this.createButton ();
141     moveDownButton.innerHTML = 'Move down';
142     moveDownButton.onclick = function () { field.wvMoveDown () };
143     field.appendChild (moveDownButton);
144    
145     return field;
146     }; // createField
147    
148     WidgetValues.prototype.clear = function () {
149     var self = this;
150    
151     this._clear ();
152    
153     var fields = document.createElement ('div');
154     this.container.appendChild (fields);
155     this.fieldsParent = fields;
156    
157     var addButton = this.createButton ();
158     addButton.innerHTML = 'Add';
159     addButton.onclick = function () { self.appendValues (['']) };
160     this.container.appendChild (addButton);
161    
162     var resetButton = this.createButton ();
163     resetButton.innerHTML = 'Reset';
164     resetButton.onclick = function () { self.reset () };
165     this.container.appendChild (resetButton);
166     }; // clear
167    
168     if (window.WidgetValuesOnLoad) WidgetValuesOnLoad ();
169    
170     /*
171    
172     Usage:
173    
174     <script src="http://suika.fam.cx/www/style/ui/widget-values.js.u8" charset=utf-8></script>
175     <script>
176     window.onload = function () {
177     new WidgetValues (document.getElementById ('c'));
178     };
179     </script>
180    
181     <div id=c data-widget-name=test-value data-widget-separator="[\r\n]+">
182     <textarea name=test-values>
183     default
184     values
185     separated
186     by
187     newlines
188     </textarea>
189     </div>
190    
191     The |WidgetValues| constructor takes an argument, which represents the
192     container element. The container element MUST contain a |textarea|
193     element, which represents the default values. The content of the
194     container element is replaced by indivisual input fields (called
195     "fields" in this script) and additional contents such as an "add"
196     button.
197    
198     The |data-widget-name| attribute of the container element represents
199     the name of the control, used by the form controls in the fields as
200     the |name| attribute value. This attribute is REQURIED.
201    
202     The |data-widget-separator| attribute of the container element
203     represents a JavaScript regular expression that matches to substrings
204     used to separate values in the |textarea| element. This attribute is
205     optional; the default separator is /\s+/ (i.e. spaces).
206    
207     You can customize how fields and additional contents are organized in
208     the container element by creating a subclass and inheriting
209     |createField| and |clear| methods, like the example below:
210    
211 wakaba 1.2 // <http://suika.fam.cx/~wakaba/-temp/test/misc/jswidgets/values/values-2.html>
212 wakaba 1.1
213     function MyNumbersWidget (c) {
214     WidgetValues.apply (this, [c]);
215     }
216    
217     MyNumbersWidget.prototype = new WidgetValues;
218    
219     MyNumbersWidget.prototype.createField = function (value) {
220     var field = document.createElement ('span');
221     field.wvIsField = true;
222    
223     var input = document.createElement ('input');
224 wakaba 1.2 input.setAttribute ('type', 'number');
225 wakaba 1.1 input.setAttribute ('min', 1);
226     input.setAttribute ('max', 10);
227     field.appendChild (input);
228    
229     return field;
230     };
231    
232     MyNumbersWidget.prototype.clear = function () {
233     var self = this;
234    
235     this._clear ();
236    
237     var fields = document.createElement ('span');
238     this.container.appendChild (fields);
239     this.fieldsParent = fields;
240    
241     var addButton = this.createButton ();
242     addButton.innerHTML = '+';
243     addButton.onclick = function () { self.appendValues ([5]) };
244     this.container.appendChild (addButton);
245     };
246    
247     Latest version of this script is available at
248     <http://suika.fam.cx/www/style/ui/widget-values.js.u8>. Old versions
249     of this script are available from
250     <http://suika.fam.cx/www/style/ui/widget-values.js.u8,cvslog>.
251    
252     */
253    
254     /* ***** BEGIN LICENSE BLOCK *****
255 wakaba 1.3 * Copyright 2008 Wakaba <[email protected]>. All rights reserved.
256     *
257     * This program is free software; you can redistribute it and/or
258     * modify it under the same terms as Perl itself.
259     *
260     * Alternatively, the contents of this file may be used
261     * under the following terms (the "MPL/GPL/LGPL"),
262     * in which case the provisions of the MPL/GPL/LGPL are applicable instead
263     * of those above. If you wish to allow use of your version of this file only
264     * under the terms of the MPL/GPL/LGPL, and not to allow others to
265     * use your version of this file under the terms of the Perl, indicate your
266     * decision by deleting the provisions above and replace them with the notice
267     * and other provisions required by the MPL/GPL/LGPL. If you do not delete
268     * the provisions above, a recipient may use your version of this file under
269     * the terms of any one of the Perl or the MPL/GPL/LGPL.
270     *
271     * "MPL/GPL/LGPL":
272     *
273 wakaba 1.1 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
274     *
275     * The contents of this file are subject to the Mozilla Public License Version
276     * 1.1 (the "License"); you may not use this file except in compliance with
277     * the License. You may obtain a copy of the License at
278     * <http://www.mozilla.org/MPL/>
279     *
280     * Software distributed under the License is distributed on an "AS IS" basis,
281     * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
282     * for the specific language governing rights and limitations under the
283     * License.
284     *
285     * The Original Code is WidgetValues code.
286     *
287 wakaba 1.3 * The Initial Developer of the Original Code is Wakaba.
288 wakaba 1.1 * Portions created by the Initial Developer are Copyright (C) 2008
289     * the Initial Developer. All Rights Reserved.
290     *
291     * Contributor(s):
292     * Wakaba <[email protected]>
293     *
294     * Alternatively, the contents of this file may be used under the terms of
295     * either the GNU General Public License Version 2 or later (the "GPL"), or
296     * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
297     * in which case the provisions of the GPL or the LGPL are applicable instead
298     * of those above. If you wish to allow use of your version of this file only
299     * under the terms of either the GPL or the LGPL, and not to allow others to
300     * use your version of this file under the terms of the MPL, indicate your
301     * decision by deleting the provisions above and replace them with the notice
302 wakaba 1.3 * and other provisions required by the LGPL or the GPL. If you do not delete
303 wakaba 1.1 * the provisions above, a recipient may use your version of this file under
304     * the terms of any one of the MPL, the GPL or the LGPL.
305     *
306     * ***** END LICENSE BLOCK ***** */

[email protected]
ViewVC Help
Powered by ViewVC 1.1.24