0

トーナメントを追跡するアプリのフロントエンドを開発しています。1 つのページで、ユーザーはトーナメントの結果を更新する必要があります。これは、処理のために PHP バックエンドに送信する、右側の最終結果テーブル内の左側のリストからプレイヤーをドラッグすることによって行われます (私はバックエンドを開発していません)。 、POST 経由で正しいデータを送信する必要があります)。私の要件は次のとおりです。

  1. プレイヤーのリストを持っている
  2. 各行の位置が固定された結果テーブルを用意します (1 行目に 1 行、2 行目に 1 行)。
  3. 各位置には 4 つの関連する入力があり、すべて という名前が付けられposition-1-NAME、同じ行に異なる列があります。
  4. ユーザーはプレーヤーを各位置にドラッグできる必要があります
  5. 1 人のプレーヤーは 1 つのポジションにのみ配置でき、各ポジションには 1 人のプレーヤーしか配置できません
  6. プレーヤーがテーブルに配置されたら、リストから削除する必要があります

私はいくつかのアプローチを試しましたが、近いものはDragula JSプラグインを使用することです。

ul次に、 を使用してプレイヤーのリストを作成しid、Dragula のコンテナーにします。

 <ul id="players-container">
   <li>
     Player 1
   </li>
 </ul>

次に、タグtable内にformがあり、フィールドの名前はすべて、次のように位置に従って名前が付けられますposition-1-name-of-the-input

<form method="POST" action="file_to_process_form.php">
  <thead>
   <th>Position</th>
   <th>Player</th>
   ...
  </thead>
  <tbody>
     <tr>
       <td>
         1st Position
       </td>           
       <td class="target">
         <input type="text" name="position-1-player-name" value="" hidden>
       </td>
       <td>
         ...other inputs 
       </td>
     </tr>
  </tbody>

次に、JavaScript で、ドラッグされたtext()からを取得し、 のの属性内に配置するハックを作成して、最初の位置にあるプレーヤーの名前をバックエンドに送信できるようにしました。コード:livalueinputtable

dragula([document.querySelector('#players-container'), document.querySelector('.target')], {
  isContainer: function(el){
    return el.classList.contains('target');
  },
  revertOnSpill: true
}).on('drop', function(el, target, source, sibling){
  elValue = $(el).text();
  $(target).find('input').attr('value', elValue);
});

これまでのところ、これはいくつかのバグで動作しています:

  1. 同じ に 2 人のプレーヤーをドロップできますtd。両方とも UI にドラッグliされて表示されますが、フォームには最後にドロップされたプレーヤーの値しかありません。

  2. プレーヤーをすべての位置に次々とドラッグすると、別のプレーヤーをその位置にドラッグするまで、すべての入力がその名前の値になります。

だから、私はいくつかのことを達成したい:

  1. 各 内に 1 人のプレーヤーのみを許可しますtd class="target"tdクラスを削除して無効にしようとしました.targetが、ドロップされた後、プレーヤーを再び移動できません。

  2. プレーヤーをドラッグするときに入力の値を削除します。

私はこれがちょっとしたハックであることを知っていますが、私は JS/jQuery の経験があまりなく、これが今のところリモートで機能する唯一のソリューションです。

私の質問:

  1. tdDragulaまたはJS / jQueryコードを使用して、複数のプレーヤーフォームが同じフォームにドラッグされるのを防ぐにはどうすればよいですか?

  2. [解決済み - 編集を参照]プレーヤーを からドラッグしたときにvalueを削除するにはどうすればよいですか?inputtd

  3. 推奨するこれらの要件を実装するより良い方法を知っていますか?

編集

次のコードを追加することで、質問2を解決できました。

dragulaObject.on('drag', function(el, source) {
   $(source).find('input').attr('value', '');
});
4

1 に答える 1

0

そのため、質問を投稿した後、バグ/質問1と2に対するいくつかの解決策をハックすることができました:

複数のプレイヤーが同じ位置にいるのを防ぐために、dragula オブジェクトの初期化のオプションに次のコードを追加しました。

accepts: function(el, target, source, sibling) {
    if($(target).attr('class') == 'target' && $(target).find('li').length <= 1) {
      return true;
    } else {
      return false;
    }
  }

最初の条件は、プレーヤーが 1 つの位置に配置された後にリストにドラッグして戻されるようにするためのものです。これは、リストに複数のプレーヤーが含まれておりli、最初の条件がないと、リスト ドラッグに戻ることが無効になるためです。

いくつかのアニメーション バグがまだあります (ドラッグされているプレーヤーは別のプレーヤーの位置の内側に短時間表示されますが、ドロップするとドラッグは完了しません)。

バグ/質問2を解決するために、次のコードを追加しました(元の回答で編集したものと同じ):

dragulaObject.on('drag', function(el, source) {
   $(source).find('input').attr('value', '');
});

したがって、Dragula オブジェクトの完全なコードは次のとおりです。

  dragula([document.querySelector('#players-container'), document.querySelector('.target')], {
      isContainer: function(el){
        return el.classList.contains('target');
      },
      revertOnSpill: true,
      accepts: function(el, target, source, sibling) {
        if($(source).attr('class') == 'target' || $(target).find('li').length <= 1) {
          return true;
        } else {
          return false;
        }
      }
  }).on('drop', function(el, target, source, sibling){
    elValue = $(el).text();
    $(target).find('input').attr('value', elValue);
  }).on('drag', function(el, source) {
    $(source).find('input').attr('value', '');
  });

最も美しいコードではありませんが、問題は解決しました。同様のことをしようとしている他の人に役立つことを願っています。

于 2016-03-07T20:24:38.237 に答える