前回はドラッグ&ドロップを実現する方法を紹介したが、今回はそれを応用した画面コンポーネントであるSortableとSliderを使ってみよう。なお、今回は都合によりメソッドやオプションをごく一部しか紹介できない。詳細は画面コントロールのWikiページを参照していただきたい。

項目の並べ替え

Sortable.create( IDまたはDOMオブジェクト [, オプション] ); // 並べ替え可能にする
Sortable.destroy( IDまたはDOMオブジェクト ); // 並べ替え不能にする

Sortableは、<ul>などで列挙した項目をドラッグによって並べ替えられるようにする。項目をドラッグしている間は、その表示位置のみが変更されるが、ドロップ後は、その位置に最も近いところにHTMLタグの構成も変更される。

【例】「マイコミジャーナル」という項目をドラッグで最上行に移動する

Sortable.create( 'demo' );

[対象となる要素]
<ul id="demo">
  <li>Prototype.js</li>
  <li>Script.aculo.us</li>
  <li>JavaScript</li>
  <li>マイコミジャーナル</li>  ← この項目をドラッグする
</ul>

[CSS設定]
li {  /* 説明のために設定したもので、必須ではない */
  margin  : 5px;
  padding : 5px;
  cursor  : move;
  border  : 1px solid #9f9;
  background-color :  #cf9;
}

図1 ドラッグする前

図2 「マイコミジャーナル」をドラッグして……

図3 最上段に移動した

デフォルトでは、<li>の項目をドラッグするときに上下にしか移動できないようになっている。また、図2を見てのとおり、<ul>のマーカーを表示させていると、項目とマーカーとの位置がドラッグ時にずれてしまう。それが気になるようであれば、CSS設定でマーカーを表示させないようにすると良いだろう(ul { list-style-type : none; })。

なお、この例は<ul>だけでなく<ol>でも有効だ。

【例】横に並んだ項目を並べ替え可能にする

Sortable.create( 'demo', {
  overlap    : 'horizontal',
  constraint : 'horizontal'
} );

[CSS設定]
li {  /* 説明のために設定したのもで、必須ではない */
  display : inline;
  /* 他は前の例と同じ */
}

図4 ドラッグする前

図5 「マイコミジャーナル」をドラッグして……

図6 左端に移動した

<li>は、この例のように display : inline を設定することで横に並べて表示することもできる。この場合は、ドラッグされた項目を左右に移動させなくてはならないので、overlap, constraintにそれぞれ'horizontal'を設定しておく。

【例】<p>でも並べ替えられるようにしたい

Sortable.create( 'demo', { tag : 'p' } );

Sortableのデフォルトでは、ドラッグ可能な項目が<li>に設定されているが、tagオプションを変更すれば、それ以外の要素を並べ替え可能にできる。たとえばリスト1の場合、それぞれの<p><div id="demo">の範囲内で並べ替え可能となる。

リスト1それぞれの<p><div id="demo">の範囲内で並べ替え可能

<div id="demo">
  <p>Prototype.js</p>
  <p>Script.aculo.us</p>
  <p>JavaScript</p>
  <p>マイコミジャーナル</p>
</div>

ツマミをドラッグするスライダ

Control.Slider( ツマミのIDまたはDOMオブジェクト, 可動範囲を示すタグのIDもしくはDOMオブジェクト [, オプション] );

Sliderは、ツマミとなる要素を左右もしくは上下の可動範囲の間でスライドさせることができる。逆に言えば、Sliderを表示させるためには、2つの要素が必要となる。ツマミの左端から右端までの値の範囲をオプションで設定しておくと、現在のツマミの位置での値を取得することもできるので、色の調節や画像の拡大/縮小などに利用できるだろう。

【例】0から100までの値をとり、最初はツマミが中央に表示されるSliderを作成する

new Control.Slider( 'slider', 'track',
      { range : $R( 0, 100 ), sliderValue : 50 } );

[対象となる要素]
<div id="track">             ← ツマミの可動範囲
  <div id="slider"></div>    ← ドラッグで左右に動くツマミ
</div>

[CSS設定]
div#slider  {  /* ツマミ */
  position : relative;   top : -7px;
  width : 10px;    height : 30px;
  background-color : #fc9;
}
div#track  {   /* ツマミの可動範囲 */
  width : 200px;    height : 15px;
  background-color : #999;
}

図7 最初の表示

図8 ドラッグでツマミを移動

Sliderを作成するにきは、この例の<div id="track"><div id="slider">のように2つの要素が必要だ。ツマミが左端から右端までドラッグで移動する間にとりうる値は、デフォルトでは0から1までとなっている。

rangeオプションと$Rで設定すれば、ツマミの位置によってとりうる値を自由に変えられる。負の数でも構わないが、必ず左端より右端のほうが値が大きな数でなくてはならない。$Rについては「いまからはじめるPrototype.js」第1回を参照していただきたい。

【例】上下に動くスライダを作成する

new Control.Slider( 'slider', 'track', { axis : 'vertical' } );

[対象となる要素]
前の例と同じ

[CSS設定]
div#slider  {
  position : relative;   left : -7px;
  width : 30px;  height : 10px;
  background-color : #fc9;
}
div#track  {
  width : 15px;  height : 100px;
  background-color : #999;
}

図9 上下に動くスライダ

上下に動くスライダには axis : 'vertical' を設定する。このとき、当然だが要素全体を縦長のスライダと分かるようにデザインしておかなければならない。

【例】現在のツマミの位置での値を取得する

new Control.Slider( 'slider', 'track', {
  /* ..... その他のオプション設定 ..... */
  onSlide : function( value, slider )  {   // ツマミのドラッグ中
    // value  : 現在のツマミの位置での値
    // slider : Sliderオブジェクト
  },
  onChange : function( value, slider )  {  // ドラッグ終了後
    // 引数はonSlideと同じ
  }
} );

現在のツマミの位置の値を取得する方法として、ツマミのドラッグ中に取得するonSlideと、つまみのドラッグが終了してから取得するonChangeという2つのオプションが用意されている。どちらもコールバック関数として記述し、引数は現在位置での値とSliderオブジェクトである。Sliderオブジェクトは他のオプションの値が必要なときなどに利用できる。

Script.aculo.us自身が持つコンポーネントの数はそれほどでもないが、これをベースにしたPrototype UISpinelzのようなライブラリも既に存在する。あなたも面白いコンポーネントを探していただきたい。