Prototype 1.6.0とscript.aculo.us 1.8.0
script.
新機能の部分が枯れるまではまだしばらくは1.
では、
$$() 関数
2621: function $$() {
2622: return Selector.findChildElements(document, $A(arguments));
2623: }
2621行目からは$$()関数です。
先ほどのSelector.
Form オブジェクト
2624: var Form = {
2625: reset: function(form) {
2626: $(form).reset();
2627: return form;
2628: },
2629:
2624行目からはFormオブジェクトです。reset(), serializeElements()しか定義されていませんが、
2625行目からの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() です。
渡された要素の配列を、
各フォーム要素の値を得るにはgetValue() (定義は Form.
最後に、
Form.Methods オブジェクト
2649: Form.Methods = {
2650: serialize: function(form, getHash) {
2651: return Form.serializeElements(Form.getElements(form), getHash);
2652: },
2653:
2649行目からはForm.
2650行目からはserialize()です。これは次のgetElements()を使って指定されたフォーム以下の入力要素の一覧を取得し、
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()です。
フォーム要素を渡すと、
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'などと指定して限定したり、
typeName, nameの両方とも指定されていなければ、
そうでなければ、
2680: disable: function(form) {
2681: form = $(form);
2682: Form.getElements(form).invoke('disable');
2683: return form;
2684: },
2685:
2680行目はdisable()です。
Form.
2686: enable: function(form) {
2687: form = $(form);
2688: Form.getElements(form).invoke('enable');
2689: return form;
2690: },
2691:
2686行目からは enable() です。
disable()と同様で、
2692: findFirstElement: function(form) {
2693: return $(form).getElements().find(function(element) {
2694: return element.type != 'hidden' && !element.disabled &&
2695: ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
2696: });
2697: },
2698:
2692行目からはfindFirstElement()です。
getElements()で入力要素すべてを取得し、
イテレータ内の条件は<input type="hidden">ではなく、
2699: focusFirstElement: function(form) {
2700: form = $(form);
2701: form.findFirstElement().activate();
2702: return form;
2703: },
2704:
2699行目はfocusFirstElement()です。単純に先ほどのfindFirstElement()を呼んで、
2705: request: function(form, options) {
2706: form = $(form), options = Object.clone(options || {});
2707:
2708: var params = options.parameters;
2709: options.parameters = form.serialize(true);
2710:
2711: if (params) {
2712: if (typeof params == 'string') params = params.toQueryParams();
2713: Object.extend(options.parameters, params);
2714: }
2715:
2716: if (form.hasAttribute('method') && !options.method)
2717: options.method = form.method;
2718:
2719: return new Ajax.Request(form.readAttribute('action'), options);
2720: }
2721: }
2722:
2723: /*--------------------------------------------------------------------------*/
2724:
2705行目からはrequest()です。
フォームを簡単にAjax.
まず、
フォームの送信に使うHTTPメソッドは、
最後にAjax.
Form.Element オブジェクト
2725: Form.Element = {
2726: focus: function(element) {
2727: $(element).focus();
2728: return element;
2729: },
2730:
2731: select: function(element) {
2732: $(element).select();
2733: return element;
2734: }
2735: }
2736:
2725行目からはForm.
focus(), select()共に渡された要素のfocus(), select()メソッドを呼んでいるだけです。両方続けて呼んでくれるForm.
Form.Element.Methods オブジェクト
2737: Form.Element.Methods = {
2738: serialize: function(element) {
2739: element = $(element);
2740: if (!element.disabled && element.name) {
2741: var value = element.getValue();
2742: if (value != undefined) {
2743: var pair = {};
2744: pair[element.name] = value;
2745: return Hash.toQueryString(pair);
2746: }
2747: }
2748: return '';
2749: },
2750:
2737行目からはForm.
まずはserialize()です。単一要素の保持している値を、
disabledプロパティが偽で、
2751: getValue: function(element) {
2752: element = $(element);
2753: var method = element.tagName.toLowerCase();
2754: return Form.Element.Serializers[method](element);
2755: },
2756:
2751行目からはgetValue()です。
Form.
2757: clear: function(element) {
2758: $(element).value = '';
2759: return element;
2760: },
2761:
2757行目からはclear()です。
単にvalueプロパティに空文字列を設定しているだけです。そのため、
2762: present: function(element) {
2763: return $(element).value != '';
2764: },
2765:
2762行目からはpresent()です。
valueプロパティが空文字でなければ真を返します。
2766: activate: function(element) {
2767: element = $(element);
2768: try {
2769: element.focus();
2770: if (element.select && (element.tagName.toLowerCase() != 'input' ||
2771: !['button', 'reset', 'submit'].include(element.type)))
2772: element.select();
2773: } catch (e) {}
2774: return element;
2775: },
2776:
2766行目からはactivate()です。
まずfocus()を呼んで、
IEでは要素がdisplay:noneやvisibility:hiddenの場合に、
2777: disable: function(element) {
2778: element = $(element);
2779: element.blur();
2780: element.disabled = true;
2781: return element;
2782: },
2783:
2777行目からはdisable()です。
要素のblur()メソッドを呼んでフォーカスを外し、
2784: enable: function(element) {
2785: element = $(element);
2786: element.disabled = false;
2787: return element;
2788: }
2789: }
2790:
2791: /*--------------------------------------------------------------------------*/
2792:
2784行目からはenable()です。
こちらはdisabledプロパティにtrueを設定しているだけで、
2793: var Field = Form.Element;
2794: var $F = Form.Element.Methods.getValue;
2795:
2796: /*--------------------------------------------------------------------------*/
2797:
2793行目ではForm.
また、
Form.Element.Serializers オブジェクト
2798: Form.Element.Serializers = {
2799: input: function(element) {
2800: switch (element.type.toLowerCase()) {
2801: case 'checkbox':
2802: case 'radio':
2803: return Form.Element.Serializers.inputSelector(element);
2804: default:
2805: return Form.Element.Serializers.textarea(element);
2806: }
2807: },
2808:
Form.
2799行目からはinputハンドラです。
type別に処理を分けていて、
2809: inputSelector: function(element) {
2810: return element.checked ? element.value : null;
2811: },
2812:
2813: textarea: function(element) {
2814: return element.value;
2815: },
2816:
inputSelector()では、
textareaハンドラでは、
2817: select: function(element) {
2818: return this[element.type == 'select-one' ?
2819: 'selectOne' : 'selectMany'](element);
2820: },
2821:
2822: selectOne: function(element) {
2823: var index = element.selectedIndex;
2824: return index >= 0 ? this.optionValue(element.options[index]) : null;
2825: },
2826:
2827: selectMany: function(element) {
2828: var values, length = element.length;
2829: if (!length) return null;
2830:
2831: for (var i = 0, values = []; i < length; i++) {
2832: var opt = element.options[i];
2833: if (opt.selected) values.push(this.optionValue(opt));
2834: }
2835: return values;
2836: },
2837:
2838: optionValue: function(opt) {
2839: // extend element because hasAttribute may not be native
2840: return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
2841: }
2842: }
2843:
2844: /*--------------------------------------------------------------------------*/
2845:
2817行目からはselectハンドラです。<select>タグのtypeが'select-one'かどうかによって後述するselectOne(), selectMany()関数を使い分けています。例えばXHTMLで <select multiple="multiple"> と記述されている場合、
selectOne()関数ではselectedIndexプロパティに選択されている<option>タグのインデックス値が入っているので、
selectMany()関数では、
optionValue()関数 では、