1. Trang chủ
  2. » Công Nghệ Thông Tin

cakephp application development phần 10 pdf

31 310 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 31
Dung lượng 4,05 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Add the following code to search.ctp in /app/views/questions/ to submit the name of the user select, and show the questions of that user: |... In this section, we will use the created

Trang 1

Just like the link() function of the AJAX helper, the autoComplete() function also takes three parameters The first is the name of the field that we are interested to AutoComplete This should have a format like this: Modelname.fieldname In the above code we used User.username as we want it to AutoComplete the user name The next parameter is used to point the controller function to which the AJAX request will be sent to Above, we specified: array('controller' => 'users', 'action'

=> 'show_usernames') We will be creating this action in the next step The third parameter is used to send extra options to the function For example, here we

specified that the class of the input text created should have a class = "fullwidth"

In step 8, we added the action show_usernames to the Users controller In the action, we first defined the layout to be ajax, so that only the content of the view is returned We changed the Debug level to 0, so that no debug messages are returned The AutoComplete code in the previous step also sends the user name (or the partial user name) entered by the user This can be accessed in $this->data['User']['username'] Lastly, we send any user name that is "like" the entered text, and who has confirmed their email address to the view of the action

In step 9, we create the view of the action We put the matching user names into an unordered list and send it back to the browser

Lastly, we add styles for the unordered list that will appear below the user

Trang 2

Quickwall: JavaScript and AJAX

[ 282 ]

Time for Action

1 Add the following code to search.ctp in /app/views/questions/ to submit the name of the user select, and show the questions of that user: <?php e($javascript->link('search', false)); ?>

|<?php e($ajax->link(

'Show Your Questions', array('controller' => 'questions', 'action' =>

'user_questions', $loggedIn), array('update' => 'questionList', 'loading' => "$('loader') show()", 'loaded' => "$('loader').hide()") )); ?>|

<a href='javascript:;' id='showOthersQuestion'>Show Questions of Others</a>| <form id='user_search_form' style="display:none">

<fieldset>

<label for="UserUsername" class="questionlabel"><span> Username</span></label> <?php echo $ajax->autoComplete('User.username',

array('controller' => 'users', 'action' =>

'show_usernames'), array('class' => 'fullwidth'))?>

<?php echo $ajax->submit('Search', array('div' => false, 'class' => 'submitbutton', 'url' => array('controller' => 'questions', 'action' => 'user_questions'), 'update' => 'questionList', 'loading' => "$('loader').show()", 'loaded' => "$('loader').hide()")) ?>

</fieldset>

</form>

<div id="questionList"></div>

2 The code added above will make an AJAX call to /questions/user_

questions The AJAX call will also submit the name of the user selected

To process the user name sent, and return that user's questions, add the following code to Questions controller's user_questions action:

<?php class QuestionsController extends AppController {

function user_questions($user_id = null) { $this->layout = 'ajax';

Configure::write('debug', '0');

if(empty($user_id)) { if($this->data['User']['username']) { $user = $this->Question->User->findByUsername

($this->data['User']['username']); if(isset($user['User']['id'])){

$user_id = $user['User']['id'];

} else { $this->set('nouser', true);

Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com

Trang 3

Chapter 11

[ 283 ]

} } else { $user_id = $this->Auth->user('id');

} }

; $this->set('questions', $this->Question->find('all', array ('conditions' => array('user_id' => $user_id)))); }

} ?>

3 Next, we will need to modify the view of this action Add the following code

to the file user_questions.ctp in the directory /app/views/questions/:

4 To try it out, point the browser to http://localhost/quickwall/

questions/search, log in, click on Show Questions of Others, start typing

in a name, select a user name for the autocomplete list, and click on Search

You should be presented with the questions of that user:

Trang 4

Quickwall: JavaScript and AJAX

[ 284 ]

What Just Happened?

Here we added a submit button to the hidden form in the view of the search page This was done by adding the following code:

<?php echo $ajax->submit('Search', array('div' => false, 'class' => 'submitbutton', 'url' => array('controller' =>

'questions', 'action' => 'user_questions'), 'update' =>

'questionList', 'loading' => "$('loader').show()", 'loaded' =>

"$('loader').hide()")) ?>

The submit() function of the AJAX helper submits the form using an AJAX call

to the controller action specified It takes two parameters here The first is the label

of the submit button created The second parameter is an array that can take many different options We pass the following options into the array: div, class, url,

update, loading, and "loaded" By specifying div to false, it does not create a wrapping <div> element for the submit button

class specifies the class name for the submit button

url is used to point to the controller action to which the AJAX call should be made The update option is used to specify the DOM element that will be filled with the returned text

loading and loaded has the same functions as discussed previously

In the next step, we modify the users_question action in the Questions controller This is the same action that returns the questions of the logged in user Previously, the id of the logged in user was sent, so it was easy to find all the questions with that user_id But this time, we are supplied with the user name So, we need to use the user name to get the id of that user To do so, we need to access the User model Since the User model is related to the Question model, we can access the User mode through the Question model As a result, we do not have to explicitly load User

model We use this to find the id of the user name, and then send the questions with that particular user_id

Lastly, we modify the view of this action to accommodate the changes

In-Line Editing to Edit Own Answers

This is the last section of the chapter We will end this chapter by showing another eye catching functionality We would like our users of Quickwall to edit the answers that they have given But to do so, we would like to do so in the same position where the answer in shown When a user will click on the answer, it will be replaced by input field, where our beloved user can edit it This is called in-line editing Thanks

to the CakePHP AJAX helper and Scriptaculous, doing this will be very easy

Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com

Trang 5

Chapter 11

[ 285 ]

Time for Action

1 Modify the file /app/views/questions/show.ctp, as shown below:

<h2><?php e($question['Question']['question']) ?>?</h2>

<div id="questioner"><div><span><?php e($question['User']

['username']) ?></span></div></div> <?php if($loggedIn): ?>

== $loggedIn): ?> <?php e($ajax->editor('answer_'.$answer['id'], array('controller' => 'questions', 'action' =>

'edit_answer', $answer['id']), array('callback' => "return 'data[Answer][answer]=' + escape(value)"))); ?> <?php endif; ?>

<?php class QuestionsController extends AppController { var $name = 'Questions';

var $uses = array('Question', 'Answer');

function home() { .

} function show( $id = null) {

} function search() { }

Trang 6

Quickwall: JavaScript and AJAX

$answer['Answer']['user_id'] == $this->Auth->user('id')) { $this->Question->Answer->id = $answer_id;

$this->Question->Answer->saveField('answer', $this->data['Answer']['answer']);

$this->set('answer', $this->data['Answer']['answer']); } else {

$this->set('answer', $answer['Answer']['answer']);

} }

} ?>

3 LaLastly, add the view file for the edit_answer action In /app/views/

questions, add a new file named edit_answer.ctp Just add this single line

to it, and save:

<?php e($answer) ?>

4 Now from the browser, log into Quickwall, and go to the page of a question that has your answers Hover the mouse over any one of your answer and click You will be presented with a input to edit the answer:

Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com

Trang 7

Chapter 11

[ 287 ]

What Just Happened?

Inline editor is created by adding the following code to the view of the show action:

<?php e($ajax->editor('answer_'.$answer['id'], array('controller' => 'questions', 'action' => 'edit_answer',

$answer['id']), array('callback' => "return 'data[Answer]

[answer]=' + escape(value)"))); ?>

This code will only work if the answer belongs to the currently logged in user The

editor() function of the AJAX helper is passed two parameters The first is the id of the DOM element that will be replaced by the inline editor You will notice we added

a unique id attribute to each <dd> tag that holds an answer This id is passed as the first parameter The second parameter is an array that contains the controller action that will save the edited data The third parameter is used to pass extra options

We pass only one option named callback This points to JavaScript code that will

be executed before data is sent via the AJAX call Normally, the editor() function sends the edited data in a variable named value But this is not included in

$this->data variable once in the server side POST data is only included in

$this->data if the name of the variable passed is in this format: data[ModeName][fieldname] We use the callback option to change the name of the variable passed

to data[Answer] [answer], so that it is included in $this->data

Next, we create the edit_answer action in the Questions controller It accepts the AJAX request made by the AJAX helper function in the previous step What this does

is that it saves the edited data into the database, and sends it back to browser

Summary

In this chapter, we saw the usage of the JavaScript and the AJAX helpers We started this chapter by showing how to add JavaScript to Cake views and layouts We saw the use of <?php e($scripts_for_layout); ?> to add JavaScript links to the layout We also saw the use $javascript->link()) to link JavaScript files in the views

We then moved into the usage of the AJAX helper We found out that the

AJAX helper in CakePHP depends on the Prototype and Scriptaculous Javascript Libraries We first created an AJAX link, using $ajax->link(), that retrieved data from the server and populated a DOM element We saw how easy it is to add AJAX AutoComplete($ajax->autocomplete()) that retrieved matching data from the database Next, we saw how to submit a form through an AJAX call

($ajax->submit()) We ended the chapter by creating an AJAX Inline Editor using

$ajax->editor()

Trang 9

Quickwall: Making It Better

During the last three chapters, we have slowly developed Quickwall into a small but working web application In chapter 9, we built the basics of the application In chapter 10, we saw how to integrate authentication to it And in chapter 11, we saw the use of the AJAX helper to make our application more interactive

In this last chapter, we will continue the evolution of Quickwall, and yet again add more features to it And in the process, we will see many more features of CakePHP that can make the life of web developers much easier

In this chapter, we will see how to do the following stuff with CakePHP:

Making dates more human readableMake a user page in QuickwallIntegrating the user page with the search pageAdding pagination using CakePHP

Adding RSS Feeds to our application

Making Dates More Readable

If you remember, we have fields in our database tables called created and

modified CakePHP automatically saves the time when a row has been inserted to

created Similarly, it saves the time when a row has been changed in the modified

field But, we have not really used these two fields In this section, we will use the

created field to show the time, so that the users know when a question or answer has been posted We will also show the use of the Time Helper that is a default helper present in CakePHP The Time Helper has many different functions that help

to show the time in a nicely presented format

Trang 10

Quickwall: Making It Better

[ 290 ]

Time for Action

1 Add the Time helper to the App controller:

<?php class AppController extends Controller {

.

var $helpers = array('Html', 'Form', 'Javascript', 'Ajax', 'Time');

function beforeFilter(){

.

}

function isAuthorized() { return true;

} } ?>

2 In the element question_list.ctp, add the following lines to show a well formatted date:

<?php e($time->niceShort($question['Question']

['created'])) ?>

<?php if(!$question['Question']['answer_count']) .

Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com

Trang 11

Chapter 12

[ 291 ]

<div id="questioner"><div><span><?php e($question['User']

['username']) ?></span></div></div> <?php if($loggedIn): ?>

<?php endif; ?>

<?php endforeach; ?>

</dl>

<?php endif; ?>

4 To make sure that the questions are shown in order, add the following lines

in the home() action of the questions controller:

<?php class QuestionsController extends AppController {

function home() { .

this->Question->unbindModel(

array('hasMany' => array('Answer')) );

$this->set('questions', $this->Question->find('all', array('order' => 'Question.created DESC')));

}

} ?>

Trang 12

Quickwall: Making It Better

[ 292 ]

5 Do the same for the user questions, add the following code to the

user_questions() action of the Question controller:

<?php class QuestionsController extends AppController {

.

function user_questions($user_id = null) {

$this->layout = 'ajax';

Configure::write('debug', '0');

.

$this->Question->unbindModel(

array('hasMany' => array('Answer')) );

$this->set('questions', $this->Question->find('all', array('conditions' => array('Question.user_id' => $user_id), 'order' => 'Question.created DESC')));

}

.

} ?>

6 Now, if you point your browser to the homepage (http://localhost/quickwall/), we should be able to see the data and time when the questions were asked, in a nice format:

Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com

Trang 13

Chapter 12

[ 293 ]

What Just Happened?

We just saw a simple usage of the Time Helper Like most things in CakePHP, formatting time in a human readable format is not really very hard to do Now, let us

understand in more details what have we accomplished in the above Time for Action.

We started by adding the Time Helper to our App controller Adding the Time Helper here has the advantage that we can use it in all the views of our application Though we will not be using it in all the views, adding it in the App Controller is a good idea, since the Time Helper is used very frequently

In the next step, we changed the element question_list.ctp This element is used

to show the lists of questions To show the time when a question has been posted, we use the function $time->niceShort() of the Time Helper This function takes the raw time as a parameter and formats the time in a human readable format There are some more functions in the Time Helper that can be used to format time in different formats To check out the other functions in the Time Helper, we can check the source of the helper which can be found in /cake/libs/view/helpers/time.php.Next, we do the same thing for the answers of the questions In the view file of the

show() action of the Questions controller, we again use the $time->niceShort()

function of the Time Helper, to format the time when an answer has been

last modified

In Step 4 and 5, we made sure that the questions are shown in a descending order depending on the time they have been posted We achieved this by mentioning the order in the find() method of the Question model, which is used to get

the questions from the database The code $this->Question->find('all',

array('order' => 'Question.created DESC')) tells the find() method to return an array of questions that are ordered in descending order in respect to the created field

Creating a User Page

In this section, we will create a user page that will be showing the questions posted

by a particular user In addition to that, the page will also contain information about the user such as the number of questions posted by the user, the number of answers given, and the user's joining date Lastly, we will be adding a link so that the user can easily check their own page

Trang 14

Quickwall: Making It Better

[ 294 ]

Time for Action

1 First, lets add an action to the Users controller, named show(), for the user page Add the following code to it:

<?php class UsersController extends AppController { var $name = 'Users';

var $components = array('Email');

function signup(){

}

function show($id = null) {

if (!$id) { $this->Session->setFlash('Invalid User.');

$this->redirect(array('controller' => 'questions', 'action'=>'home'));

} $this->User->recursive = 2;

$this->set('user', $this->User->find(array('User.id' => $id), array('id', 'username', 'created'))); $this->User->Answer->recursive = -1;

$this->set('answer_count', $this->User->

Answer->find('count', array('conditions' => array('Answer.user_id' => $id))));

}

} ?>

2 Next, let's add the view file for the new action In the directory /views/users, create a new file named show.ctp Add the following code to it: <h2><?php e($user['User']['username']) ?></h2>

<div id="questioner"><div><span>Name</span></div></div>

<dl>

<dt><span>Joined On</span></dt>

<dd><?php e($time->niceShort($user['User']['created'])) ?></dd> <dt><span>Asked</span></dt>

Trang 15

<?php e($time->niceShort($question['created'])) ?>

<?php $answer_count = count($question['Answer']);

if(!$answer_count) e("(no answers yet)");

else if($answer_count == 1) e("(1 answer)");

else e("(".$answer_count." answers)");

<?php e($html->link('Search', array('controller' => 'questions', 'action' => 'search'))); ?>|

<?php e($html->link('Logout', array('controller' => 'users', 'action' => 'logout'))); ?>|

<?php else: ?>

<?php e($html->link('Sign Up', array('controller' => 'users', 'action' => 'signup'))); ?>|

<?php e($html->link('Login', array('controller' => 'users', 'action' => 'login'))); ?>|

Ngày đăng: 12/08/2014, 10:22

TỪ KHÓA LIÊN QUAN