prototype.jsを読み解く
第9回 Prototypeライブラリ(2621~2845行目)
Prototype 1.6.0とscript.aculo.us 1.8.0
script.aculo.us 1.8.0がアナウンスされ,Prototypeも1.6.0のタグが打たれたようです。
新機能の部分が枯れるまではまだしばらくは1.5.1.1でいいとは思いますが,Prototypeに依存するライブラリも徐々に1.6.0に移行していくと思われるので,早いうちから慣れておいたほうがよいかもしれません。
では,今回は少なめですが,主にForm関係のクラスたちを見ていきます。
$$() 関数
2621: function $$() {
2622: return Selector.findChildElements(document, $A(arguments));
2623: }
2621行目からは$$()関数です。
先ほどのSelector.findChildElements()をdocumentトップから検索するようにしたショートカット関数となっています。
Form オブジェクト
2624: var Form = {
2625: reset: function(form) {
2626: $(form).reset();
2627: return form;
2628: },
2629:
2624行目からはFormオブジェクトです。reset(), serializeElements()しか定義されていませんが,Element.addMethods()でObject.extend(Form, Form.Methods)されているので,最終的にはForm.Methodsのメソッドも持つことになります。
2625行目からのreset()は,ブラウザ側のHTMLFormElementインターフェイスのreset()を呼んでいるだけです。
2630: serializeElements: function(elements, getHash) {
2631: var data = elements.inject({}, function(result, element) {
2632: if (!element.disabled && element.name) {
2633: var key = element.name, value = $(element).getValue();
2634: if (value != null) {
2635: if (key in result) {
2636: if (result[key].constructor != Array) result[key] = [result[key]];
2637: result[key].push(value);
2638: }
2639: else result[key] = value;
2640: }
2641: }
2642: return result;
2643: });
2644:
2645: return getHash ? data : Hash.toQueryString(data);
2646: }
2647: };
2648:
2630行目からはserializeElements() です。
渡された要素の配列を,Array.inject({})を使ってループ処理します。そのイテレータ関数内では,disabledプロパティが偽で,nameプロパティがセットされているものだけが対象になっています。また,同じnameを持つ要素が複数出てきた場合は,値を配列として格納するようになっています。
各フォーム要素の値を得るにはgetValue() (定義は Form.Element.Methods.getValue())を用いています。
最後に,getHashフラグが真ならハッシュのまま,そうでなければtoQueryString()して文字列形式で返しています。
Form.Methods オブジェクト
2649: Form.Methods = {
2650: serialize: function(form, getHash) {
2651: return Form.serializeElements(Form.getElements(form), getHash);
2652: },
2653:
2649行目からはForm.Methodsオブジェクトです。結局FormにObject.extend()するので,なぜわざわざ分割しているのかは不明です。
2650行目からはserialize()です。これは次のgetElements()を使って指定されたフォーム以下の入力要素の一覧を取得し,それを先ほどのForm.serializeElements()に渡しています。
2654: getElements: function(form) {
2655: return $A($(form).getElementsByTagName('*')).inject([],
2656: function(elements, child) {
2657: if (Form.Element.Serializers[child.tagName.toLowerCase()])
2658: elements.push(Element.extend(child));
2659: return elements;
2660: }
2661: );
2662: },
2663:
2654行目からはgetElements()です。
フォーム要素を渡すと,それ以下でgetElementsByTagName('*')で全タグを取得し,Form.Element.Serializersにシリアライズ用ハンドラが存在するなら対応している要素とみなして返り値用の配列にpush()します。具体的には<input>, <textarea>, <select>に対応しています。
2664: getInputs: function(form, typeName, name) {
2665: form = $(form);
2666: var inputs = form.getElementsByTagName('input');
2667:
2668: if (!typeName && !name) return $A(inputs).map(Element.extend);
2669:
2670: for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
2671: var input = inputs[i];
2672: if ((typeName && input.type != typeName) || (name && input.name != name))
2673: continue;
2674: matchingInputs.push(Element.extend(input));
2675: }
2676:
2677: return matchingInputs;
2678: },
2679:
2664行目からはgetInputs()です。
typeNameに'radio'などと指定して限定したり,さらにnameを指定して絞り込んだりできます。
typeName, nameの両方とも指定されていなければ,指定されているフォーム要素以下の<input>タグすべてを返します。
そうでなければ,取得した<input>タグをループして,typeName, nameの指定に沿ったものを集めてそれだけを返しています。
prototype.jsを読み解く
- 第10回 Prototypeライブラリ(2846~3276行目)
- 第9回 Prototypeライブラリ(2621~2845行目)
- 第8回 Prototypeライブラリ(2277~2620行目)
- 第7回 Prototypeライブラリ(2052~2276行目)
- 第6回 Prototypeライブラリ(1609~2051行目)
- 第5回 Prototypeライブラリ(1290~1608行目)
- 第4回 Prototypeライブラリ(932~1289行目)
- 第3回 Prototypeライブラリ(640~931行目)
- 第2回 Prototypeライブラリ(198~639行目)
- 第1回 Prototypeライブラリ(1~197行目)


