こんにちは、Habr!
どういうわけか、1年前、私はWebサイト上のフォームの開発を容易にする小さなライブラリについて書きました。 私は最近、3番目のバージョンをリリースしました。実際には、より正確で便利になるようにゼロから書き直されました。 しかし、私の記事ではREADMEとDEMOを繰り返しませんが、実際には、より少ないコードを書くのにどのように役立つかを示します。
しかし、最初に、新しいバージョンについて少し情報を提供したいと思います。 その中で、ファイルを送信するためのmalsup jquery.form依存関係を取り除き 、一般的なオールインワンアセンブリを維持しながら、1つの大きなリポジトリをいくつかの小さな独立したリポジトリに分割しました。
- 追加のフォームイベントのサポート( form-extra-events );
- フォーム属性のHTML5ポリフィル( form-association-polyfill );
- 古いブラウザのiframeを介したファイル送信のサポート( jquery-iframe-ajax );
- そして、実際には、ライブラリ自体( paulzi-form )。
追加のフォームイベント
ライブラリの2番目のバージョンでは、スクリプトを接続する特定の順序を遵守する必要があるという問題に遭遇しました。 たとえば、標準のYii2検証スクリプトの前にこのスクリプトを接続することが不可能になる前は、すべてのスクリプトが送信イベントでハングし、送信を処理する必要があり、特に検証する必要があります。
preventDefault()
ます。 したがって、誤った接続順序の場合、フォームは最初にブロックされてから検証され、検証エラーがある場合は、フォームを再送信できなくなりました。 form-extra-eventsはこの問題を解決し、いくつかの新しいタイプのフォームイベントを提供します。1つはフォームの送信を保証し、このプロセスを中断することはできません。 さらに、フォーム送信の開始および完了のイベントが生成され、ライブラリの他のすべての機能で使用されます。
プロトタイプサイト
ライブラリの有用性を示すために、Bootstrapの典型的なオンラインストアのプロトタイプをスケッチしました。
http://paulzi.ru/paulzi-form-site/
スクリプトのうち、jQuery、bootstrap、paulzi-form.all.jsのみを使用します。 このプロトタイプでは、プロトタイプサイト専用に記述された1行のJSコードを使用しません。
HTML5フォーム属性
HTML5フォーム属性は何に役立ちますか? たとえば、 バスケットでは、選択した商品に対していくつかのアクションが計画されています-お気に入りに追加、電子メールで送信、ダウンロード。 もちろん、1つのアクションを実行することもでき、パラメーターで実行する必要があることを正確に渡します。 しかし、これは
switch($action)
使用を作成するため、特定のアクション(Yii2など)にすぐに向けるのではなく、見苦しいです。 モーダルウィンドウを開くと、送信ボタンはフォーム自体の外部で実行する必要があることがわかりますが、
form
属性が指定されているため、機能し続けます。 そして最も重要なことは、これらの属性は、HTML標準で禁止されている小さなフォームを大きなフォームに作成する必要がある場合に非常に役立ちます。
空のフィールドを送信しないでください
ここで、 カタログ内のフィルターに注目しましょう。 「Intel Core i5」にチェックマークを付けてこのフォームを送信すると、他のフィールドが入力されていなくても、移行後も長いパラメーターのシートが表示されます。
?proce_from=&proce_to=&tdp_from=&tdp_from=&line[]=i5
ライブラリを使用して、 data-submit-empty="false"
属性をフォームdata-submit-empty="false"
追加するとdata-submit-empty="false"
空白のフィールドは送信されず、その結果、よりわかりやすいURLが取得されます。
?line[]=i5
ブロックを再送信
コールバック注文フォームを検討してください。 送信ボタンをダブルクリックすると、フォームが2回送信され、2つの文字が届きます。 これは間違っているため、スクリプトはデフォルトで、リクエストが完了するまでフォームを再送信する機能をブロックします。 正しい操作の例は、「Write to us」フォームにあります。 この動作は、属性
data-lock="false"
設定することにより制御されます
出荷ステータス表示
フォームの送信プロセスには時間がかかる場合があり(ファイルの送信、プロセッサを集中的に使用するプロセッサ、インターネットの速度が遅い)、フォームが送信中であることを示すことができない場合、ユーザーは遅かれ早かれ、ボタンやハングアップしたものはクリックしなかったと考え、もう一度ボタンを押します。 そのようなフォームの例は、「Write to us」フォームです。 ライブラリにはいくつかのオプションがあり、プロトタイプでは
data-loading-text
および
data-loading-icon
属性を使用しました。これらの属性はボタンテキストを変更し、アイコンを追加します。 また、
form-loading
クラスと
btn-loading
クラスがフォームとボタンに追加されるため、CSSを介して状態を安定させることができます。
AJAXフォーム送信
最も重要なことは、これがAJAXを介してフォームを送信できることです。 実際、プロトタイプでは、モーダルウィンドウに2つのフォームがあります。送信ボタンをクリックすると、ページ間を遷移せず、モーダルウィンドウを閉じて成功メッセージを表示するだけです。 そして、ここではすべてが非常に簡単です
data-via="ajax"
属性を追加すると、フォームはAJAXを介して送信されます。 それだけでなく、AJAXを介したファイルの転送に少なくとも一度関与した人は、ファイルの送信のサポートがXMLHttpRequrest 2から始まったため、これがそれほど簡単ではないことを知っています。特別なハンドラーの一部であり、ファイルを一時フォルダーに保存してから、別のリクエストでフォームを送信するときにそこから取得します。 私たちの場合、それについて考える必要はほとんどありません。フォームが標準的な方法で送信された場合と同じようにすべてが進みます。 必要に応じて、
uploadprogress
イベントにしがみついて送信されたデータの割合を簡単に表示できます。
AJAX応答の処理
もっと複雑な例を見てみましょう- カタログページのバスケットに追加ボタン。 クリックすると、リクエストを実行してメッセージを表示するだけでなく、バスケット内の商品の数のカウンターをホバーして更新するときに、バスケットの中身の短いリストを更新する必要があります。 この点も考慮され、AJAX応答の最も柔軟なハンドラーを作成しようとしました。 プロトタイプの[カートに追加]をクリックすると表示される答えを考えてください。
<span class="badge" data-insert-context="document" data-insert-to=".cart-block .badge" data-insert-mode="replaceWith">43</span> <div class="alert alert-success alert-dismissible" role="alert" data-insert-context="document" data-insert-to=".alert-fixed"> <button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">×</span></button> ! </div> <div class="cart-block-hover" data-insert-context="document" data-insert-to=".cart-block-hover" data-insert-mode="replaceWith"> <div class="row"> <div class="col-xs-6 text-left">AMD K6</div> <div class="col-xs-6">10 .</div> </div> <div class="row"> <div class="col-xs-6 text-left">Intel Celeron</div> <div class="col-xs-6">12 .</div> </div> <div class="row"> <div class="col-xs-6 text-left">Intel Core i7</div> <div class="col-xs-6">1 .</div> </div> <div class="row cart-block-total"> <div class="col-xs-6 text-left">:</div> <div class="col-xs-6"><span class="price"><span>117 000</span> ₽</span></div> </div> </div>
ご覧のとおり、答えはdata-insert-to
、 data-insert-context
、 data-insert-mode
属性を持つ3つのhtml要素で構成されています。 これらの属性は、たとえば最初のspan.badge
data-insert-context="document" data-insert-to=".cart-block .badge" data-insert-mode="replaceWith"
場合、各要素を挿入する方法と場所を決定しますdata-insert-context="document" data-insert-to=".cart-block .badge" data-insert-mode="replaceWith"
は、この要素を使用して.cart-block .badge
を置き換える必要があり、このセレクターを含む検索領域はドキュメント全体であることを意味します。 これにより、1行のコードなしで上記の手順を実行できます。
シナリオ
カートページに戻る。 すでに上で説明したように、異なるアクションを意味するボタンがいくつかあります。 たとえば、「記入」をクリックすると、標準のメカニズムでフォームを送信し、注文情報を含むページにリダイレクトするのが論理的です。 ただし、[お気に入りに追加]をクリックした場合は、ページを離れずに、AJAXを介してフォームを送信し、成功またはエラーに関するメッセージを表示することをお勧めします。 このために、スクリプトが実装されています-任意のボタンに
data-via
属性を指定できます。これは、クリックしたときにフォームを送信する方法を示します。
設定
何かが気に入らなかったり、競合がある場合は、 設定を使用してライブラリを大幅に変更できます 。 たとえば、デフォルトですべてのフォームの再送信をブロックするかどうか。 すべての属性名も変更できます。
おわりに
その結果、10 kbのライブラリを接続すると、最も重要なものが得られます-さまざまな小さなフォームのコードを書く必要が少なく(またはまったく書かなくても)、付属資料には追加のフォームイベント、iframeトランスポート、AJAXなどの優れた機能があります-ファイルの送信など