--------------- <> -----------------
--- KHOA HỌC - CÔNG NGHỆ - GIÁO DỤC - VIỆC LÀM ---
--- Học để đi cùng bà con trên thế giới ---

Tìm kiếm trong Blog

Ngu ngơ học làm web (x18) - CakePHP2 - Gọi và gửi biến giữa các action

Tiếp theo của: Ngu ngơ học làm web (x17) - CakePHP2 – Search trên hai table, paginate, validate
-----

Phần x18. CakePHP2 – Gọi và gửi biến giữa các action


Xem (clip số 22c – chickenrainshop):

- Lấy keyword của form tìm kiếm (3":18)

- Lấy giá trị của một biến gửi từ các function khác nhau trong cùng controller (7":32)

- request->params hoặc request->passedArgs

- Gửi lại từ khóa tìm kiếm lên form (14":40)

Ý tưởng của phần này là:

- Khi người dùng submit, dữ liệu của form được gửi về action get_keyword

- Action get_keyword sẽ kiểm tra dữ liệu, lưu lại lỗi của việc kiểm tra dữ liệu (nếu nó)

- Trong action get_keyword, gọi action search và gửi biến keyword cho action search, sử dụng câu lệnh sau: $this->redirect(['action' => 'search', 'keyword' => $keyword]);  

- Trong action search, sử dụng $this->request->params hoặc $this->passedArgs để lấy giá trị của biến keyword do action get_keyword gửi tới.

Lưu lại đoạn mã để tham khảo:

[action get_keyword() trong BooksController.php]

public function get_keyword() {
                        if ($this->request->is('post')) {
                                    $this->Book->set($this->request->data);
                                    if ($this->Book->validates()) {
                                                $keyword = $this->request->data['Book']['keyword'];
                                    } else {
                                                $errors = $this->Book->validationErrors;
                                                $this->Session->write('search_validation', $errors);
                                    }
                                    $this->redirect(['action' => 'search', 'keyword' => $keyword]);                  
                        }
            }

[action search() trong BooksController.php]

public function search() {
                        $notFound = false;
                        if ($this->Session->check('search_validation')) {
                                    $this->set('errors', $this->Session->read('search_validation'));
                                    $this->Session->delete('search_validation');
                        }
                        if (!empty($this->params['named']['keyword'])) {
                                    $keyword = $this->params['named']['keyword'];
                                    $this->paginate = [
                                                            'fields' => ['title', 'image', 'sale_price', 'slug'],
                                                            // 'contain' => ['Writer.name', 'Writer.slug'],
                                                            'contain' => ['Writer' => ['name', 'slug']],
                                                            'order' => ['Book.created' => 'desc'],
                                                            'limit' => 2,
                                                            'conditions' => [
                                                                        'published' => 1,
                                                                        'or' => [
                                                                                    'title like' => '%'.$keyword.'%',
                                                                                    'w.name like' => '%'.$keyword.'%'
                                                                                    ]
                                                                        ],
                                                            'joins' => [
                                                                        [
                                                                                    'table' => 'books_writers',
                                                                                    'alias' => 'bw',
                                                                                    'conditions' => 'bw.book_id = Book.id'
                                                                        ],
                                                                        [
                                                                                    'table' => 'writers',
                                                                                    'alias' => 'w',
                                                                                    'conditions' => 'bw.writer_id = w.id'
                                                                        ]
                                                            ]
                                                ];
                                    $books = $this->paginate('Book');
                                    if (!empty($books)) {
                                                $this->set('results', $books);
                                    } else {
                                                $notFound = true;
                                    }
                                    $this->set('keyword', $keyword);
                        }          
                        $this->set('notFound', $notFound);
            }

[search.ctp]

<?php echo $this->Form->create('Book', ['url' => ['action' => 'get_keyword'],'novalidate' => true]) ?>
            <?php if (isset($keyword)): ?>
                        <?php echo $this->Form->input('keyword',
                        [
                                    'label' => '',
                                    'placeholder' => 'Nhập từ khóa tìm kiếm...',
                                    'error' => false,
                                    'required' => false,
                                    'value' => $keyword
                        ]);
                        ?>      
            <?php else: ?>
                        <?php echo $this->Form->input('keyword',
                        [
                                    'label' => '',
                                    'placeholder' => 'Nhập từ khóa tìm kiếm...',
                                    'error' => false,
                                    'required' => false
                        ]);
            ?>
            <?php endif ?>
           
            <?php if (isset($errors)): ?>
                        <?php foreach ($errors as $error): ?>
                                    <?php echo $error[0]; ?>
                        <?php endforeach ?>
            <?php endif ?>
            <?php if (isset($results) && $notFound == false): ?>
                        Kết quả tìm kiếm của từ khóa <strong><?php echo $keyword; ?></strong> <br>
                        <?php echo $this->element('book', ['books' => $results]); ?>
                        <?php echo $this->element('pagination', ['object' => 'quyển sách']); ?>
            <?php elseif($notFound == true): ?>
                        Không tìm thấy quyển sách này!
            <?php endif ?>

<?php echo $this->Form->end('Search'); ?>

-----------
Cập nhật 18/5/2017
-----------
Xem thêm:
- Tổng hợp các bài viết về Ngu ngơ học làm web

Ngu ngơ học làm web (j2) - JS - Biến, alert, confirm, prompt

Tiếp theo của: Ngu ngơ học làm web (j1) - JS - Chương trình đầu tiên, cách debug Javascript
-----

Phần j2. JS – Biến, alert, confirm, prompt


Bài 2: Biến và khai báo biến

- Dùng từ khóa var để khai báo biến

- Biến không được định kiểu trước, mà tùy vào giá trị gán cho nó là gì, thì nó sẽ có kiểu tương ứng.

- Để xuất biến hay chuỗi ra màn hình trình duyệt, dùng hàm document.write(value).

Bài 3: alert, prompt, confirm

- alert(value): để xuất một nội dung ra màn hình, dạng một cửa sổ (popup)

- confirm(value): giống alert(), tuy nhiên có thêm lựa chọn Yes, No. Người dùng bấm Yes hàm này sẽ trả về TRUE, bấm No trả về FALSE.

Ví dụ,

[vidu.js]

            var bt = document.getElementById('click-me');
            bt.addEventListener('click', function() {
                        var content = document.getElementById('text').value;
                        if (confirm(content)) {
                                    alert('Đồng ý');
                        } else {
                                    alert('Không đồng ý');
                        }
            });

- prompt(param1, param2): dùng để lấy thông tin người dùng nhập vào, param1: nội dung thông báo, param2, giá trị khởi tạo. Nếu người dùng nhập nội dung và bấm OK, hàm sẽ trả về nội dung mà người dùng vừa nhập, nếu bấm Cancel, hàm sẽ trả về NULL.

Ví dụ,

[vidu.js]

            var bt = document.getElementById('click-me');
            bt.addEventListener('click', function() {
                        var input = document.getElementById('text');
                        var noiDung = prompt('Nhập vào nội dung:','');
                        input.value = noiDung;
            });

Ví dụ,

Viết đoạn mã Javascript để nhập: Họ, Tên Lót, Tên, Năm Sinh, Email, Giới Tính. Xuất ra màn hình các thông tin vừa nhập theo định dạng:

Họ và Tên:

Tuổi:

Email:

Giới Tính:

[js.html]

<!DOCTYPE html>
<html lang="en">
<head>
            <meta charset="UTF-8">
            <title>Document</title>
</head>
<body>
            <script>
                        var ho, tenLot, ten, namSinh, email, gioiTinh, tuoi, ketQua;

                        ho = prompt('Họ:','');
                        tenLot = prompt('Tên lót:','');
                        ten = prompt('Tên:','');
                        namSinh = prompt('Năm sinh:','');
                        email = prompt('Email:','');
                        gioiTinh = prompt('Giới tính:','');

                        tuoi = new Date().getFullYear() - namSinh;

                        ketQua = 'Họ và Tên: ' + ho + ' '+ tenLot + ' ' + ten;
                        ketQua += '<br>' + 'Tuổi: ' + tuoi;
                        ketQua += '<br>' + 'Email: ' + email;
                        ketQua += '<br>' + 'Giới tính: ' + gioiTinh;

                        document.write(ketQua);

            </script>
</body>
</html>


Lưu ý: dấu + được sử dụng để nối chuỗi. Để lấy năm hiện tại, sử dụng đoạn mã: new Date().getFullYear()
-----------
Cập nhật 18/5/2017
-----------
Xem thêm:
- Tổng hợp các bài viết về Ngu ngơ học làm web
- Ngu ngơ học làm web (j3) - JS - Toán tử, lệnh If  

Ngu ngơ học làm web (j1) - JS - Chương trình đầu tiên, cách debug Javascript

Tiếp theo của: Ngu ngơ học làm web (j) -
-----

Phần j1. JS – Chương trình đầu tiên, cách debug Javascript


Sẵn dịp học Ajax, học lại luôn kiến thức nền tảng về Javascript, học bài bản một tí để khi đi làm đỡ phải mất thời gian đọc lại.

Đọc và làm theo hướng dẫn của tác giả Thehalfheart (freetuts.net).


Bài 1: Javascript là gì? Viết ứng dụng Javascript đầu tiên


Để ý làm các bài tập ở cuối mỗi bài viết.

Ghi lại một số ý:

- Trình duyệt web sẽ biên dịch và thực thi mã của Javascript

- Mã của Javascript được trình duyệt nhận ra bởi thẻ <script></script>

- Mã của Javascript sẽ nằm lẫn lộn với mã HTML và CSS, khi xử lý tập tin .html (trong tập tin này sẽ có HTML, CSS và Javascript), trình duyệt sẽ xử lý mã theo thứ tự từ trên xuống dưới, từ trái qua phải, gặp cái gì xử lý cái đó. Với các hàm Javascript thì sẽ được biên dịch rồi để đó, chờ có lệnh gọi hàm thì các đoạn mã ở trong hàm sẽ được thực thi.

- Có ba chỗ để đặt mã Javascript khi làm web: internal (đặt trong trang .html, bất kì chỗ nào), external (đặt ngoài trang .html, trong tập tin có đuôi .js, sau đó gọi tập tin này ở trong trang .html), inline (đặt trong thẻ HTML).

Ví dụ một chương trình Javascript:

<!DOCTYPE html>
<html lang="en">
<head>
            <meta charset="UTF-8">
            <title>Document</title>
</head>
<body>
            Nhập nội dung: <input type="text" id="text"><br>
            <button id="click-me">Xuất thông báo</button>

            <script>
                        var bt = document.getElementById('click-me');
                        bt.addEventListener('click', function() {
                        var content = document.getElementById('text').value;
                                    alert(content);
                        });
            </script>

</body>
</html>

Học thêm về cách debug Javascript tại đây:


Xem từ phút thứ 16:45 đến hết.

Ghi lại một số ý liên quan đến debug:

- Mở trang web cần debug

- Mở cửa sổ Developer tools (hoặc F12)

- Tại cửa sổ Developer tools, chọn tab Console để xem thông báo lỗi liên quan đến Javascript (nếu có)

- Tại cửa sổ Developer tools, chọn tab Sources

- Tại khung cửa sổ bên trái (Sources), tìm và mở tập tin chứa mã Javascript

- Tại khung cửa sổ ở giữa (chứa mã Javascript), bấm vào chỉ số hàng để đánh dấu một hoặc nhiều điểm dừng (breakpoint) để xem quá trình chạy của đoạn mã. Hàng nào được đánh dấu sẽ có màu xanh tại chỉ số dòng, và sẽ xuất hiện ở khung cửa sổ bên phải, mục Breakpoints.

- Refesh trang web và chạy các thao tác trên trang web để kích hoạt các đoạn mã Javascript.

- Sử dụng các nút Resume, Step over, Step into, Step out. Tại mục Watch, bấm vào dấu +, nhập tên biến để quan sát nội dung, các thuộc tính của biến.

- Học thêm các chức năng khác liên quan đến debug Javascript.

Ví dụ, về viết Javascript trong thẻ HTML:

<button id="click-me" onclick="alert('hi')">Xuất thông báo</button>

Ví dụ, về gọi Javascript từ tập tin bên ngoài:

[vidu.js]

var bt = document.getElementById('click-me');
                        bt.addEventListener('click', function() {
                                    var content = document.getElementById('text').value;
                                    alert(content);
                        });

[index.html]

<!DOCTYPE html>
<html lang="en">
<head>
            <meta charset="UTF-8">
            <title>Document</title>
</head>
<body>
            Nhập nội dung: <input type="text" id="text"><br>
            <button id="click-me">Xuất thông báo</button>
            <script src="vidu.js"></script>
</body>

</html>
-----------
Cập nhật 17/5/2017
-----------
Xem thêm:
- Tổng hợp các bài viết về Ngu ngơ học làm web

Ngu ngơ học làm web (x17) - CakePHP2 - Search trên hai table, paginate, validate

Tiếp theo của: Ngu ngơ học làm web (x16) - CakePHP2 – Search trên một table
-----

Phần x17. CakePHP2 – Search trên hai table, paginate, validate


Xem (clip số 22b – chickenrainshop):

Phần này sẽ thực hiện tìm kiếm mở rộng, nghĩa là cho phép người dùng nhập vào một từ khóa, từ khóa này có thể là (một phần) tên một cuốn sách hoặc (một phần) tên của tác giả, và kết quả trả về là cuốn sách có tên hoặc tác giả liên quan.

Câu lệnh truy vấn được thực hiện trên model Book, tuy nhiên cần phải truy vấn đến tên tác giả, nên phải kết nối tới model Writer, việc kết nối giữa Book và Writer được thực hiện thông qua bảng trung gian books_writers, sử dụng từ khóa joins.


[hàm search() trong BooksController.php] thay đổi như sau:

public function search() {
                        $notFound = false;
                        if ($this->request->is('post')) {
                                    $keyword = $this->request->data['Book']['keyword'];
                                    $books = $this->Book->find('all',
                                                [
                                                            'fields' => ['title', 'image', 'sale_price', 'slug'],
                                                            // 'contain' => ['Writer.name', 'Writer.slug'],
                                                            'contain' => ['Writer' => ['name', 'slug']],
                                                            'order' => ['Book.created' => 'desc'],
                                                            'conditions' => [
                                                                        'published' => 1,
                                                                        'or' => [
                                                                                    'title like' => '%'.$keyword.'%',
                                                                                    'w.name like' => '%'.$keyword.'%'
                                                                                    ]
                                                                        ],
                                                            'joins' => [
                                                                        [
                                                                                    'table' => 'books_writers',
                                                                                    'alias' => 'bw',
                                                                                    'conditions' => 'bw.book_id = Book.id'
                                                                        ],
                                                                        [
                                                                                    'table' => 'writers',
                                                                                    'alias' => 'w',
                                                                                    'conditions' => 'bw.writer_id = w.id'
                                                                        ]
                                                            ]
                                                ]);
                                    if (!empty($books)) {
                                                $this->set('results', $books);
                                    } else {
                                                $notFound = true;
                                    }
                        }
                        $this->set('notFound', $notFound);
            }

Phân trang dữ liệu tìm kiếm được.

[hàm search() trong BooksController.php] thay đổi như sau:

public function search() {
                        $notFound = false;
                        if ($this->request->is('post')) {
                                    $keyword = $this->request->data['Book']['keyword'];
                                    $this->paginate = [
                                                            'fields' => ['title', 'image', 'sale_price', 'slug'],
                                                            // 'contain' => ['Writer.name', 'Writer.slug'],
                                                            'contain' => ['Writer' => ['name', 'slug']],
                                                            'order' => ['Book.created' => 'desc'],
                                                            'conditions' => [
                                                                        'published' => 1,
                                                                        'or' => [
                                                                                    'title like' => '%'.$keyword.'%',
                                                                                    'w.name like' => '%'.$keyword.'%'
                                                                                    ]
                                                                        ],
                                                            'joins' => [
                                                                        [
                                                                                    'table' => 'books_writers',
                                                                                    'alias' => 'bw',
                                                                                    'conditions' => 'bw.book_id = Book.id'
                                                                        ],
                                                                        [
                                                                                    'table' => 'writers',
                                                                                    'alias' => 'w',
                                                                                    'conditions' => 'bw.writer_id = w.id'
                                                                        ]
                                                            ]
                                                ];
                                    $books = $this->paginate('Book');
                                    if (!empty($books)) {
                                                $this->set('results', $books);
                                    } else {
                                                $notFound = true;
                                    }
                        }
                        $this->set('notFound', $notFound);
            }

Trong search.ctp thêm dòng mã sau:

<?php if(isset($results) && $notFound == false): ?>
                        <?php echo $this->element('book', ['books' => $results]); ?>
                        <?php echo $this->element('pagination', ['object' => 'quyển sách']); ?>

Thiết lập kiểm tra dữ liệu cho trường ‘keyword’:

[Model\Book.php]

public $validate = array(
                        'keyword' => array(
                                    'rule' => 'notBlank',
                                    'message' => 'Bạn phải nhập từ khóa để tìm kiếm!'
                        ),
                        'title' => array(
                                    'notBlank' => array(

[View\Books\search.ctp]

<?php echo $this->Form->create('Book', ['novalidate' => true]) ?>
            <?php echo $this->Form->input('keyword',
                        [
                                    'label' => '',
                                    'placeholder' => 'Nhập từ khóa tìm kiếm...',
                                    'error' => false,
                                    'required' => false
                        ]);
            ?>
            <?php if (isset($errors)): ?>
                        <?php foreach ($errors as $error): ?>
                                    <?php echo $error[0]; ?>
                        <?php endforeach ?>
            <?php endif ?>
            <?php if (isset($results) && $notFound == false): ?>
                        <?php echo $this->element('book', ['books' => $results]); ?>
                        <?php echo $this->element('pagination', ['object' => 'quyển sách']); ?>
            <?php elseif($notFound == true): ?>
                        Không tìm thấy quyển sách này!
            <?php endif ?>
<?php echo $this->Form->end('Search'); ?>

[Controller\BooksController.php search()]

public function search() {
                        $notFound = false;
                        if ($this->request->is('post')) {
                                    $this->Book->set($this->request->data);
                                    if ($this->Book->validates()) {
                                                $keyword = $this->request->data['Book']['keyword'];
                                                $this->paginate = [
                                                                        'fields' => ['title', 'image', 'sale_price', 'slug'],
                                                                        // 'contain' => ['Writer.name', 'Writer.slug'],
                                                                        'contain' => ['Writer' => ['name', 'slug']],
                                                                        'order' => ['Book.created' => 'desc'],
                                                                        'conditions' => [
                                                                                    'published' => 1,
                                                                                    'or' => [
                                                                                                'title like' => '%'.$keyword.'%',
                                                                                                'w.name like' => '%'.$keyword.'%'
                                                                                                ]
                                                                                    ],
                                                                        'joins' => [
                                                                                    [
                                                                                                'table' => 'books_writers',
                                                                                                'alias' => 'bw',
                                                                                                'conditions' => 'bw.book_id = Book.id'
                                                                                    ],
                                                                                    [
                                                                                                'table' => 'writers',
                                                                                                'alias' => 'w',
                                                                                                'conditions' => 'bw.writer_id = w.id'
                                                                                    ]
                                                                        ]
                                                            ];
                                                $books = $this->paginate('Book');
                                                if (!empty($books)) {
                                                            $this->set('results', $books);
                                                } else {
                                                            $notFound = true;
                                                }
                                    } else {
                                                $errors = $this->Book->validationErrors;
                                                $this->set('errors', $errors);
                                    }
                        }
                        $this->set('notFound', $notFound);
            }

Để không hiển thị thông báo lỗi validate mặc định ngay dưới một input, thêm thuộc tính 'error' => false, ví dụ:

<?php echo $this->Form->input('keyword',
                        [
                                    'label' => '',
                                    'placeholder' => 'Nhập từ khóa tìm kiếm...',
                                    'error' => false
                        ]);

            ?>
-----------
Cập nhật 15/5/2017
-----------
Xem thêm:
- Tổng hợp các bài viết về Ngu ngơ học làm web