symfony askeet Day 8

AJAX

  • レイアウトにインジケータを追加する
  • Ajaxインタラクションを追加する
  • 結果領域を作る
  • リンクをクリックするとぬっと出てくるログインフォームを追加する

レイアウトにインジケータを追加する

インジケータって何?と思ったのですが、よくAjaxが使われているサイトにある
Now loading...的なモノだそうです。
ということで早速実装。
まずはlayout.phpに追加。
場所はaskeet/apps/frontend/templates/layout.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
 
<?php echo include_http_metas() ?>
<?php echo include_metas() ?>
 
<?php echo include_title() ?>
 
<link rel="shortcut icon" href="/favicon.ico" />
 
</head>
<div id="indicator" style="display: none"></div>
<body>

こんな感じにbodyタグの前に

<div id="indicator" style="display: none"></div>

を追加。
お次はCSS
場所はaskeet/web/css/main.css

div#indicator
{
  position: absolute;
  width: 100px;
  height: 40px;
  left: 10px;
  top: 10px;
  z-index: 900;
  background: url(/images/indicator.gif) no-repeat 0 0;
}

これでHTMLとCSSの設定は完了。後は呼び出し側の設定だけ。

Ajaxインタラクションを追加する

このアプリケーションはユーザーの興味を表すことができるらしい。
そこのリンクにAjaxを使いたい。ということで実装。
まずは_interested_user.phpを編集。

<?php use_helper('User') ?>

<div class="interested_mark" id="mark_<?php echo $question->getId() ?>">
   <?php echo $question->getInterestedUsers() ?>
</div>

<?php echo link_to_user_interested($sf_user, $question) ?>

次はヘルパーの設定。
このリンクには

  • すでに興味がある
  • 興味ある?

の2パターンが考えられる。
なので、それを実現するためにヘルパーを作る。
askeet/apps/frontend/lib/helper/UserHelper.php

<?php

use_helper('Javascript');

function link_to_user_interested($user, $question)
{

  if($user->isAuthenticated())
    {
      $interested = InterestPeer::retrieveByPk($question->getId(),$user->getSubscriberId());
      if($interested)
        {
          // already interested (興味を持っている)
          return 'interested!';
        }
      else
        {
          // didn't declare interest yet (興味があることをまだ宣言していない)
          return link_to_remote('interested?',array(
                                                    'url' => 'user/interested?id='.$question->getId(),
                                                    'update' => array('success' => 'block_'.$question->getId()),
                                                    'loading' => "Element.show('indicator')",
                                                    'complete' => "Element.hide('indicator');"
                                                    .visual_effect('hightlight','mark_'.$question->getId()),
                                                    ));
        }

    }
  else
    {
      return link_to('interested?','user/login');
    }
}

あとは、_list.phpを弄る。

  <div class="question">
    <div class="interested_block" id="block_<?php echo $question->getId() ?>">
      <?php include_partial('interested_user', array('question' => $question)) ?>
    </div>

これで、キャッシュをクリアして確認。

結果領域を作る

リンクはできても中身がないので中身を作る
まずはサーバ上で行うことを書く。
書く場所はaskeet/apps/frontend/modules/user/actions/actions.class.php

  public function executeInterested()
  {
    $this->question = QuestionPeer::retrieveByPk($this->getRequestParameter('id'));
    $this->forward404Unless($this->question);

    $user = $this->getUser()->getSubscriber();

    $interest = new Interest();
    $interest->setQuestion($this->question);
    $interest->setUser($user);
    $interest->save();
  }

後はview.ymlに追加する。

  interestedSuccess:
    has_layout:   off

リンクをクリックするとぬっと出てくるログインフォームを追加する。

よくありますね、これも。
ということでまずはlayout.phpに出てくるHTMLを書く。
場所はaskeet/apps/frontend/templates/layout.php
書く場所はheaderとcontentの間

 <?php use_helper('Javascript') ?>
 
<div id="login" style="display: none">
  <h2>Please signin first♪</h2>
 
  <?php echo link_to_function('cancel', visual_effect('blind_up', 'login', array('duration' => 0.5))) ?>
 
  <?php echo form_tag('user/login', 'id=loginform') ?>
    nickname: <?php echo input_tag('nickname') ?><br />
    password: <?php echo input_password_tag('password') ?><br />
    <?php echo input_hidden_tag('referer', $sf_params->get('referer') ? $sf_params->get('referer') : $sf_request->getUri()) ?>
    <?php echo submit_tag('login') ?>
  </form>
</div>

あとはログインしていない状態でinterested?をクリックすればフォームが出ればいい。
なので、リンクを書き換える。
interested?リンクのジャンプ処理などはUserHelper.phpに書いているのでそこを直す。
場所はaskeet/lib/helper/UserHelper.php

return link_to_function('interested?',visual_effect('blind_down','login',array('duration' => 0.5)));

で、確認。