失われたコードを思い出して書く。フォームのコントロールを設定したり取得したり
それにしても、一度書いたものはそこそこ覚えているものなのに、最近忘れっぽい。
思い出すのも一苦労。ふぅ〜
<!DOCTYPE html> <title></title> <meta charset="UTF-8"> <style> </style> <form> <p> <input type="text" name="@hoge" value="0"> <input type="text" name="@hoge" value="0"> <input type="text" name="@hoge" value="0"> <p> <select name="@fuga" multiple> <option selected>aaa <option value="bbb">BBB <option value="ccc">CCC <option value="ddd">DDD </select> <select name="@fuga"> <option selected>aaa <option value="bbb">BBB <option value="ccc">CCC <option value="ddd">DDD </select> <select name="@fuga"> <option selected>aaa <option value="bbb">BBB <option value="ccc">CCC <option value="ddd">DDD </select> <select name="@fuga"> <option selected>aaa <option value="bbb">BBB <option value="ccc">CCC <option value="ddd">DDD </select> <p> <input type="checkbox" name="@piyo" value="aaa" checked>AAA <input type="checkbox" name="@piyo" value="bbb">BBB <input type="checkbox" name="@piyo" value="ccc">CCC <p> <input type="radio" name="@babu" value="aaa" checked>AAA <input type="radio" name="@babu" value="bbb">BBB <input type="radio" name="@babu" value="ccc">CCC </form> <script> (function () { var A = Array.prototype; //前後の空白を取り除く function trim (str) { return str.replace (/^\s+|\s+$/g, ''); } //name を単一化 function normalizeByName (a, b) { return (-1 < a.indexOf (b.name)) ? a: a.concat (b.name); } // フォームのコントロールか? function isControls (e) { switch (e.tagName) { case 'INPUT' : switch (e.type) { case 'submit' : case 'reset' : case 'button' : case 'image': return false; } case 'TEXTAREA' : case 'SELECT' : return !!(e.name /*|| e.id*/); //@name の有無 } return false; } //使われている name をすべて取得 function getAllControlsName () { return A.filter.call (this.form.elements, isControls) .reduce (normalizeByName, []); } //_______________________ function Controller (form) { this.form = form; } //_______________________ function getControl (name) { return getControlsByName.call (this, name).reduce (function (result, e) { switch (e.type) { case 'radio' : case 'checkbox' : return (e.checked) ? result.concat (e.value): result; case 'select-one' : case 'select-multiple' : return result.concat (A.reduce.call (e.options, function (result, opt) { return (opt.selected) ? result.concat ((opt.hasAttribute ('value')) ? opt.value: trim (opt.text)) : result; }, [])); default : return result.concat (e.value); } }, []); } //_______________________ // フォームの要素に、値を取得 function getControlsValue (/*Array or Object or String, Array or Object or String, ..*/) { if (1 > arguments.length) // すべての名前を取得 return getAllControlsName.call (this).map ( function (name) { return [name, getControl.call (this, name)]; }, this); return A.map.call (arguments, function (arg) { switch (true) { // 配列ならば case (arg instanceof Array) : return arg.map (function (name) { return [name, getControl.call (this, name)]; }, this); // オブジェクトならば case ('object' === typeof arg) : for (var i in arg) if (arg.hasOwnProperty (i)) arg[i] = getControl.call (this, i); // result[i] = getControl.call (this, i); return result; return arg; //文字列ならば case ('string' === typeof arg) : return getControl.call (this, arg); default: throw new Error ('引数が不正'); } }, this) } //_______________________ function setAryOptions (opt) { var v = opt.hasAttribute ('value') ? opt.value: trim (opt.text); var r = (-1 < this.value.indexOf (v)); opt.selected = r; } function setOptions (opt) { var v = opt.hasAttribute ('value') ? opt.value: trim (opt.text); var r = (this.value === v); if (r) opt.selected = r; return r; } // 要素に、値をセット function setControls (obj) { if (obj.value instanceof Array) //配列ならば、文字列化 obj.value.forEach (function (v, i) { this.value[i] = String (v); }, obj); else obj.value = String (obj.value); this.getControlsByName (obj.name).forEach (function (e, i) { var val = (this.value instanceof Array) ? this.value[i] || '': this.value; switch (e.type) { case 'select-one' : A.some.call (e.options, setOptions, {'value': val }); //途中で中止なので some break; case 'select-multiple' : A.forEach.call (e.options, setAryOptions, this); break; case 'radio' : //e.checked = (e.value === val); break; case 'checkbox' : e.checked = (this.value instanceof Array) ? (-1 < this.value.indexOf (e.value)) : (e.value === this.value); break; default : e.value = val; } }, obj); } // フォームの要素に、値をセットする。 function setControlsValue (parm/*[name, value], [],..*/) { if (1 > arguments.length) throw new Error ('引数がない'); A.slice.call (arguments, 0).map (function (arg) { var i, buf = []; switch (true) { // name が配列なら case (arg instanceof Array) : return {'name': arg[0], 'value': arg[1] }; // name がオブジェクトなら case ('object' === typeof arg) : for (i in arg) if (arg.hasOwnProperty (i)) buf.push ({'name' : i, 'value': name[i]}); return buf; } }).forEach (setControls, this) } //_______________________ // 指定した名前のコントロールのを返す(1個でも配列で返す) function getControlsByName (name) { var es = this.form.elements[name]; return ('tagName' in es) ? [es]: A.slice.call (es, 0); } // フォームのリセット function reset () { this.form.reset (); return this; } //_______________________ function create (form) { if (form) if ('FORM' === form.nodeName) return new Controller (form); else return null; } //_______________________ Controller.prototype.setControlsValue = setControlsValue; // Controller.prototype.getControlsValue = getControlsValue; // コントロールの値を返す Controller.prototype.getControlsByName = getControlsByName; // コントロールを配列で返す Controller.prototype.reset = reset; this.FormController = create; /* フォームのコントロールを操作する var xxx = FormController (document.querySelector ('form')); 値の設定 xxx.setControlsValue ([name1, value1], [name2, value2], ...); xxx.setControlsValue ([name1, [value1, value2, value3], ...); xxx.setControlsValue ({ 'name1': value1, 'name2': [value2_1, value2_2], ... }); 値の取得 xxx.getControlsValue (); // ==> [[name1, value1],[name2, value2],..] xxx.getControlsValue (name1, nam2, ..); // ==> [[name1, value1], [name2, value2], ..] xxx.getControlsValue (name1, arrName, object, ..); [[value1], [[aryName1, aryValue1],..], object,..] var obj = { 'name1': null, 'name2': null, ... }; xxx.getControlsValue (obj); // == > { 'name1': value1, 'name2': value2, ... } */ })(); var f = FormController (document.querySelector ('form')); f.setControlsValue (['@hoge', 123], ['@fuga', 'bbb'], ['@piyo', 'ccc'], ['@babu', 'aaa']); alert ('設定値を変えた'); f.setControlsValue (['@hoge', [123, 456, 789]], ['@fuga', ['aaa', 'bbb', 'ccc', 'ddd']], ['@piyo', ['aaa', 'bbb', 'ccc']], ['@babu', ['aaa', 'bbb']]); alert ('設定値を変えた'); alert('値の取得 引数無し\n' + f.getControlsValue ().join("\n")); alert('値の取得 複数の引数\n' + f.getControlsValue ('@hoge', '@fuga', '@piyo', '@babu').join("\n")); alert('値の取得 配列で\n' + f.getControlsValue (['@hoge', '@fuga', '@piyo', '@babu']).join("\n")); var obj = { '@hoge': null, '@fuga': null, '@piyo': null, '@babu': null }; f.getControlsValue (obj); alert('値の取得 オブジェクトで\n' + [ obj['@hoge'], obj['@fuga'], obj['@piyo'], obj['@babu']].join ("\n")); </script>