« 2006年10月 | トップページ | 2006年12月 »

2006年11月30日 (木)

[JavaScript]JavaScriptで作るメニュー

ちょっと前回の更新から時間が空いてしまいましたが今回は、JavaScriptでプルダウン形のメニューを作成します。

一番簡単なのは、最初にサブメニューの部分に「display:none;」を指定して隠していおいて、マウスのクリックイベントなどでメニュー部分を表示するタイプで

という風になります。

もう少し高度になるとNiftyのトップページでも行っていますが、メニューの部分にマウスカーソルを持っていくと新たなメニューが表示されてそこから新しい選択肢を選択できるというものです。実際にデモしてみると

メニュー ⇒

という感じになります。

こちらは、マウスがメニューの上に来たときにonmouseoverイベントでメニューを表示して、onmouseoutイベントでタイマーを発生させてある程度の時間メニューからマウスが離れていたらメニューを消すような処理を行っています。

中身を見ていくと

HTMLの内容
<div id="topmenu" class="topmenu" onmouseover="showmenu( this, 'sample2' );"  onmouseout="hiddenmenu( 'sample2' );">メニュー ⇒</div>
 <div id="sample2" class="submenu" style="display:none;" onmouseover="onmousemenu( 'sample2' );" onmouseout="hiddenmenu( 'sample2' );">
  <div class="menuitem"><a class="menuitem" href="" onclick="closeMenu( 'sample2' );return false;">サブメニュー1</a></div>
  <div class="menuitem"><a class="menuitem"  href="" onclick="closeMenu( 'sample2' );return false;">サブメニュー2</a></div>
  <div class="menuitem"><a class="menuitem"  href="" onclick="closeMenu( 'sample2' );return false;">サブメニュー3</a></div>
  <div class="menuitem"><a class="menuitem"  href="" onclick="closeMenu( 'sample2' );return false;">サブメニュー4</a></div>
  <div class="menuitem"><a class="menuitem"  href="" onclick="closeMenu( 'sample2' );return false;">サブメニュー5</a></div>
</div>

読み込んでいるCSSファイルの内容
.topmenu {
 border:solid 1px gray;
}

.submenu {
 width: 10em;
 background-color:white;
 border:solid 1px gray;
 position: absolute;
 z-index:1000;
}
.menuitem {
 width:100%;
 white-space:nowrap;
 border-bottom:solid 1px gray;
 margin:0;
}

a.menuitem:link{
 text-decoration:none;
}
a.menuitem:visited{
 text-decoration:none;
}
a.menuitem:hover{
 text-decoration:none;
 background-color:lightcyan;
}
a.menuitem:active{
 text-decoration:none;
 background-color:lightcyan;
}

JavaScriptの内容
var timer_id = null;
function showmenu( parent, id )
{
  var target = document.getElementById( id );
  var top = 0;
  var left = 0;
  var obj = parent.offsetParent;
  for( ;; )
  {
    if( ! obj )
      break;

    top += obj.offsetTop;
    left += obj.offsetLeft;

    obj = obj.offsetParent;
  }

  target.style.top = top + parent.offsetTop;
  target.style.left = left + parent.offsetLeft + parent.offsetWidth;
  target.style.display = '';
  if( timer_id )
  {
    clearTimeout( timer_id );
    timer_id = null;
  }
}

function onmousemenu()
{
  if( timer_id )
  {
    clearTimeout( timer_id );
    timer_id = null;
  }
}

function hiddenmenu(id)
{
  timer_id = setTimeout( "closeMenu('"+id+"')", 400 );
}

function closeMenu(id)
{
  var submenu = document.getElementById( id );
  submenu.style.display = 'none';
  timer_id = null;
}

となっています。

注意点ですが、setTimeout関数で別の関数を呼び出すときに単純にsetTimeout( "closeMenu("+id+")", 400 )とすると文字列を渡していたidが受け取り側のcloseMenuでは、オブジェクトととして渡されてくるのでうまく動きません。そのためsetTimeout( "closeMenu('"+id+"')", 400 )という風にidを「'(シングルクォート)」でくくる必要があります。

前回と同様に1つにまとめたサンプルになります。

| | コメント (0) | トラックバック (0)

2006年11月16日 (木)

[CSS&JavaScript]CSSでダイアログの作成 パート2

今回は、前回パート1で作成したダイアログをドラッグ&ドロップで画面上を動くようにしたいと思います。

といっても難しいことはなく、JavaScriptのマウスイベントを利用してスタイルシートで指定している位置を動かすということを行っています。

まずは、ダイアログの作成でこれは前回のものを利用します。ダイアログを動かすためにスタイルのpositionabsoluteにすることを忘れないようにしてください。この指定をしないと動きません。

ダイアログの部分
<div class="dlg" id="dlg" style="display: none;position:absolute;">
<div id="dlghead" >
  <div class="dlghead1"></div>
  <div class="dlghead2"></div>
  <div class="dlghead3"></div>
  <div class="dlghead4"><a onclick="close_dialog();return false;" href="#">×</a></div>
</div>
  <div class="dlgbody">
   <table style="margin:0px 5px;padding:2px 5px;">
    <tr>
     <th style="text-align:left;">名前</th>
     <td><input type="text" size="30"></td>
    </tr>
    <tr>
     <th style="text-align:left;">パスワード</th>
     <td><input type="password" size="30"></td>
    </tr>
   </table>
   <input type="button" value="登録する" onclick="close_dialog();return false;" style="margin-left:5px">
</div>
</div>

続いては、これを動かすためのJavaScriptを作成します。

JavaScriptの部分
var target;var offsetX;var offsetY; ①

function mouseDown( e ) ②
{
  target = document.getElementById( 'dlg' );
  target.style.cursor = 'move';
  
  if( e )
  {
    offsetX = e.layerX;offsetY = e.layerY;
  }
  else if( event )
  {
    offsetX = event.offsetX;offsetY = event.offsetY;
  }
  
  return false;
}

function mouseMove( e ) ③
{
  if( ! target ) return false;
  
  var x;var y;
  if( e )
  {
    x = e.pageX;y = e.pageY;
  }
  else if( event )
  {
    x = event.clientX + document.body.scrollLeft;
    y = event.clientY + document.body.scrollTop;
  }
  x -= offsetX;y-=offsetY;
  target.style.left = x; target.style.top = y;
  return false;
}

function mouseUp( e ) ④
{
  if( ! target ) return false;
  target.style.cursor = 'auto';
  target = null;
}

function init_page() ⑤
{
  var dialogHead = document.getElementById( 'dlghead' );
  dialogHead.onmousedown= mouseDown;
  document.onmouseup= mouseUp;
  document.onmousemove= mouseMove;
}

window.onload = init_page; ⑥

解説していきます。

は、ダイアログとその位置を保存するための変数です。これがないと動かしているときの位置などがわからなくなってしまいます。

は、ダイアログのタイトルバーの部分をクリックしたときに発生するイベントです。これ以降マウスボタンをあげるまで動かすことができるようになります。中身は、マウスカーソルの形を変更して動かせるようにユーザーにわかってもらえるようにして、クリックされたダイアログのオブジェクトを①で用意した変数に代入しています。同様にイベントの位置も変数に代入しています。

は、実際にダイアログを動かしている部分でスタイルの位置指定をマウスを動かした分量だけ変化させています。if( e )else if( event )は、ブラウザごとに位置の算出方法を変えているということになります。

は、マウスボタンを離してダイアログの移動を終了させるときに呼び出されます。中身は、マウスカーソルを通常の状態に戻して、覚えていたダイアログのオブジェクトをクリアしています。

は、この画面が表示されたときに呼び出される関数で、標準のイベントハンドラを定義している関数に置き換えています。最初の2つは、ダイアログのタイトル部分でマウスが押されたときのイベントを置き換えています。

は、実際にこの画面が表示されたときに⑤を呼び出すための関数になります。

前回と同様に1つにまとめたサンプルになります。

という感じで、スタイルシートとJavaScriptでウインドウを画面内に作成してそれを動かすということができるようになりました。 中身を知らないと難しい気がしますが実際にやってみるとそんなには難しいことは行っていません。あとは、いろいろ試してみてください。

| | コメント (0) | トラックバック (0)

2006年11月 8日 (水)

[PHP]PDOではまったこと

PHPのPDOで開発を行っていますが、基本的にWindows環境で試験などを行っています。それでたまにLinux上で試験を実行してみととたんに動かなくなることがあります。今日は、ちょっとした思い込みで動かないことになってしまっていたのでそのことを書いておきます。

データベースからデータを取り込むときにPDOを使用している場合、

$db = new PDO( 'pgsql:host=localhost port=5432 dbname=testdb user=bruce password=mypass' );
$stmt = $db->prepare( 'SELECT * FROM testtable WHERE id = :id' );
$stmt->execute( array( ':id'=>$id ) );
$result = $stmt->fetch( PDO::FETCH_ASSOC );

というような一度、「prepare」をしてクエリーの発行準備をおこなってそれから「execute」にパラメータを渡して実際の実行を行うといった書き方をします。

ここまでは、別に何ということもないのですが、複数のパラメータを「execute」に渡すときに落とし穴がありました。

たとえば

$stmt = $db->prepare( 'SELECT * FORM shouhin WHERE price > :min AND price < :max';
$stmt->execute( array( ':min'=>10000, ':max'=>50000 );
$result = $stmt->fetchAll( PDO::FETCH_ASSOC );

というような別の値をとるような変数がある場合は問題ないのですが、同じ値を使う場合、何も考えないで

$stmt = $db->prepare( 'SELECT * FORM seiseki WHERE kokugo = :tensu AND sansu = :tensu';
$stmt->execute( array( ':tensu'=>100 );
$result = $stmt->fetchAll( PDO::FETCH_ASSOC );

という感じに「tensu」を使いまわしてクエリーを発行しようとしました。これは、Windows版で実行すると問題なく国語と算数の点数が100点のデータを取得できるのですが、Linux版に持っていくとクエリーエラーが発生して落ちてしまいます。

よくよくドキュメントを見てみるときちんと「prepare」の中にも書かれていましたし、オンラインのドキュメントの囲みの中で書かれていますがこちらにも同じようにはまった人がいたようです。

つまりは、

$stmt = $db->prepare( 'SELECT * FORM seiseki WHERE kokugo = :kokugo AND sansu = :sansu';
$stmt->execute( array( ':kokugo'=>100, ':sansu'=>100 );
$result = $stmt->fetchAll( PDO::FETCH_ASSOC );

といった感じに同じ値を使うのでもそれぞれ別の名前として使用しろということらしいです。

まあ、いろいろとありましたが結論としてはきちんとドキュメントに目を通せということなんでしょうけど、どう考えても「prepare」に名前をつけれるのであれば使い回しができてもよさそうな気がします。

| | コメント (0) | トラックバック (0)

2006年11月 1日 (水)

[CSS&JavaScript]CSSでダイアログの作成 パート1

今回は、ポップアップするUIの作成です。divタグにスタイルを適用することで、簡単にポップアップするようなUIを作成することができます。

あとはこれの応用でうまいことレイアウトを作っていくと

という感じでダイアログのようなUIを画面上に表示することができます。

やっている内容は、前回のタブの応用でダイアログ的なUIを作成していて、最初にHTMLが表示されたときのスタイルに「display:none」を指定して表示されないようにしています。それでボタンが押されたタイミングでそのスタイルをはずしているだけです。あと、その場で表示するために「position:absolute」を指定して画面の指定した位置にダイアログを表示するようにしています。

HTMLの内容
<div class="dlg" id="dlg" style="display: none;position:absolute;">
 <div id="dlghead" >
  <div class="dlghead1"></div>
  <div class="dlghead2"></div>
  <div class="dlghead3"></div>
  <div class="dlghead4"><a onclick="close_dialog();return false;" href="#">×</a></div>
 </div>
  <div class="dlgbody">
   <table style="margin:0px 5px;padding:2px 5px;">
    <tr>
     <th style="text-align:left;">名前</th>
     <td><input type="text" size="30"></td>
    </tr>
    <tr>
     <th style="text-align:left;">パスワード</th>
     <td><input type="password" size="30"></td>
    </tr>
   </table>
   <input type="button" value="登録する" onclick="close_dialog();return false;" style="margin-left:5px">
 </div>
</div>

読み込んでいるCSSファイルの内容
div.dlg a:link{
color:white;
}
div.dlg a:visited{
color:white;
}
div.dlg a:hover{
color:white;
} div.dlg a:active{
color:white;
}
div.dlghead1{ BORDER-RIGHT: gray 1px solid; MARGIN: 0px 3px; OVERFLOW: hidden; BORDER-LEFT: gray 1px solid; HEIGHT: 1px; BACKGROUND-COLOR: blue; }
div.dlghead2{ BORDER-RIGHT: gray 1px solid; MARGIN: 0px 2px; OVERFLOW: hidden; BORDER-LEFT: gray 1px solid; HEIGHT: 1px; BACKGROUND-COLOR: blue; }
div.dlghead3{ BORDER-RIGHT: gray 1px solid; MARGIN: 0px 1px; OVERFLOW: hidden; BORDER-LEFT: gray 1px solid; HEIGHT: 2px; BACKGROUND-COLOR: blue; }
div.dlghead4{ BORDER-RIGHT: gray 1px solid;BORDER-LEFT: gray 1px solid;margin:0px 0px;padding:0px 0px;TEXT-ALIGN: right;font-size:0.8em;BACKGROUND-COLOR: blue;}
div.dlgbody {BORDER-RIGHT: gray 1px solid;BORDER-LEFT: gray 1px solid;BORDER-RIGHT: gray 1px solid;BORDER-bottom: gray 1px solid;background-color:white; }

JavaScriptの内容
function pop_show()
{
  var menu = document.getElementById( 'menu' );
  if( menu )
  {
    menu.style.display = '';
  }
}

function pop_close()
{
  var menu = document.getElementById( 'menu' );
  if( menu )
  {
    menu.style.display = 'none';
  }
}

function show_dialog( x, y, width )
{
  document.getElementById( 'dlg' ).style.display = '';
  document.getElementById( 'dlg' ).style.width = width ;
}

function close_dialog()
{
  document.getElementById( 'dlg' ).style.display = 'none';
}

ココログでは、スタイルシートやJavaScriptタグが使えないみたいなので外部ファイルとしてこれらの内容を読み込んでいますがこれらを同一ファイル内に正しく書くけばうまく表示されます。

次回は、このダイアログを動かしたいと思います。

| | コメント (0) | トラックバック (0)

« 2006年10月 | トップページ | 2006年12月 »