2012年1月21日土曜日

jQueryでドラッグ&ドロップ

自分用のブログエンジンを作っていて、
要素をドラッグ&ドロップしながら章立てできるようなものにしたいなと思い
要素をどんどん追加していこうと思い、
最初draggable,droppable辺りを利用していたんだけど、
追加したい場所や、追加した要素の順番を変更したりと
sortableが必要だったので少し書いてみる。


何がしたいか?
・ドラッグして要素の追加 ・ドラッグしたものは残す ・ドラッグしたものを変更 ・ドロップする場所は順序変更が可能 これによりコンテンツを編集していく感じ
ソートの準備
まずソートしたい要素に対して
 $(".content-box").sortable({
  placeholder:'ui-state-highlight',
  connectWith: $('.content-box'),
  axis:'y',
  update : function (event,ui) {
   //順序を変更した後
  },
  receive : function (event,ui) {
   //他から要素が追加された場合
  }
 });
と行います。 placeholder:移動する場所に対してのスタイルを指定します。 これで色の変更などを行なって移動を行いやすくします。 connectWith:移動できる場所を自分自身のみにしています。 axis:yを指定して縦方向だけ移動できるようにしています。 update,receiveはイベントですが、 updateは順序を変更した場合のみに発生、receiveは他から要素が入ってきた時です。 receive発生時もupdateは発生します。 一旦はこれだけでcontent-box内の要素の順序変更ができるようになります。
ドラッグしてくる側の設定
ここが一番苦労したというか気づかなかったというか。 ドラッグする側に対してもsortableで対応しないと、ドラッグできないのではないか?と 思ってそうしてたのですが、cloneが効かなかったり、何かとやりたい事に対して うまくいかなかったのですが、まず ドラッグしたい要素に対して、ドラッグをできるようにします。
 // アイテムのドラッグ
 $('.item').draggable({
    cursor: 'move', 
    opacity: 0.7,
    connectToSortable: $('.content-box'),
          helper:'clone'
 });
cursor:カーソルの変更 opacity:移動時の透明度 connectToSortable:指定した場所にはsortableの対象として扱ってくれるので 上記で指定した「ui-state-highlight」をやってくれます。 helper:移動中の表示をコピーにしています。 これに対しては実際はfunctionも扱えるので 移動する時に表示を変えたい場合はfunctionを指定して戻り値でタグを返します。
まぁこれで大体できるんだけど、、、
私の場合はitemの部分とcontent-box内の要素が違います。 この状態で行うとitemのタグがそのまま配置されてしまうので receiveイベントの時に
    var addTag = createContentItem(itemName);
    var dropItem = $(this).children(".item");
    dropItem.after(addTag);
    dropItem.remove();
新しくタグを追加してあげて、ドロップした要素を削除しています。 当初はどちらもsortableを指定しないと要素の追加場所がわからないのではないか? と思って指定していたのですが、片方をドラッグにしてcloneを行えば良い事に気付いたので 後は追加要素を追加削除するだけでした。 connectToSortableに気づいたら非常に簡単にできました。 ただsortableでhelperにclone指定をした場合にうまく動作しなかったのが 少し解せない感じでした。

0 件のコメント: