Frameworks.suFrameworks.su Шпаргалка вебмастера

  • Главная
  • Framework Kohana
  • PHP
  • Javascript
  • CSS
  • Сервисы
    • Генератор паролей
  • Контакты
Главная / PHP / Framework Kohana / Ajax в Kohana 3.3.x: добавление и удаление статьи без перезагрузки страницы

Ajax в Kohana 3.3.x: добавление и удаление статьи без перезагрузки страницы

21.07.2014 1 12017

Ajax в Kohana 3.3.x: добавление и удаление статьи без перезагрузки страницы

Сегодня мы разберем интересную и очень актуальную тему: взаимодействие Kohana 3.3.x и Ajax при помощи jQuery. Мы научимся отправлять данные из формы при помощи Ajax, делать валидацию данных, добавлять запись в БД, выводить обновленную информацию, удалять запись из Базы Данных – и все это будет без перезагрузки страницы.

Итак, сначала определим какие нам для этого понадобятся файлы:

  • Контроллеры
    • Articles - имеет 3 метода:
      • Вывод списка статей
      • Добавление новых статей, при удачном добавлении возвращает список статей (возвращает json обьект)
      • Удаление статьи
  • Виды
    • articles – список статей и форма добавления статьи
    • main – наш базовый шаблон, в который мы будем вставлять все второстепенные виды
  • Модель
    • Articles – имеет 3 метода:
      • Получение всех статей
      • Добавление записи в БД
      • Удалении записи из БД

SQL

Для начала работы нам понадобится таблица articles в БД с данной структурой:

CREATE TABLE IF NOT EXISTS `articles` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `name` varchar(255) NOT NULL,
    `description` text NOT NULL,
    PRIMARY KEY (`id`)
)

Views

Теперь сделаем наш главнй шаблон main.php, в нем бует костяк нашей страницы:

<!DOCTYPE html>
<html lang="ru">
<head>
    <title>Ajax в Kohana 3.3.x</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0;">
    
    <link href="/css/bootstrap.css" rel="stylesheet">
    <link href="/css/bootstrap-responsive.css" rel="stylesheet">
    
    <script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
    <script src="/js/script.js" type="text/javascript"></script>
</head>
    <body>
        <div id="wrap">
            <div class="push"></div>
            <div class="container">
                <div class="page-header">
                  <h1><a href="/">Ajax в Kohana 3.3.x</a></h1>
                </div>                
            </div>
            <div class="container">
                <?php print $content;?>       
            </div>
        </div>
    </body>
</html>

Теперь сделам шаблон для вывода списка новостей и форму добавления статьи articles.php:

<table class="table articles">
    <thead>
        <th>ID</th>
        <th>Заголовок</th>
        <th>Текст</th>    
        <th>Действия</th>    
    </thead>
    <tbody>
        <?php if($data): ?>
        <?php foreach($data as $item): ?>
        <tr>
            <td><?php print $item['id']?></td>
            <td><?php print $item['name']?></td>
            <td><?php print $item['description']?></td>
            <td><a class="delete btn btn-danger" href="/articles/delete/<?php print $item['id']?>">Удалить</a></td>
        </tr>
        <?php endforeach; ?>
        <?php else: ?>
            <td colspan="4"><center>Добавьте статью</center></td>
        <?php endif; ?>
    </tbody>
</table>

<div class="alert alert-error" id="error" style="display:none"></div>

<form action="/articles/add" method="POST" id="form_article">
    <div class="form-item">
        <label>Название</label>
        <input name="name" type="text" class="span5 input-medium " placeholder="Название статьи" />
    </div>
    <div class="form-item">
        <label>Текст</label>
        <textarea name="description" rows="5" class="span5" placeholder="Текст статьи"></textarea>
    </div>
    <div class="form-item">
        <button type="submit" class="btn btn-primary">Добавить статью!</button>
    </div>
</form>

jQuery

Также добавим обработчик на отправку формы, для валидации на стороне клиента и отправку данных посредтсвом ajax на сервер используя jQuery:

$("#form_article").submit(function(){ // при отправке формы проводим валидацию на заполненые поля и отправляем форму
    var form = $(this);
    
    $("[type=submit]",form).attr('disabled','disabled'); // делаем кнопку недоступной, чтобы избежать повторных нажатий
    $("#error").empty().hide(); // Очищаем блок с ошибкой и скрываем его
    
    var name = $('[name=name]',form).val(); // берем имя статьи из формы
    var description = $('[name=description]',form).val(); // берем текст из формы
    /** Если не заполнены поля - то выводим ошибку */
    if(name == '' || description == ''){
        $("#error").html('Ошибка валидации формы!').slideDown();
        $("[type=submit]",form).removeAttr('disabled'); // делаем кнопку снова доступной
        return false;
    }
    $.ajax({ // описываем наш запрос
            type: "POST", // будем передавать данные через POST
            url: form.attr('action'), // берем адрес отправки формы и передаем туда наши данные аяксом
            data: form.serialize(), // серриализируем данные
            dataType: "json", // указываем, что нам вернется JSON
            beforeSend: function(){
                $("#loading").slideDown(); // показываем индикатор загрузки
            },
            success: function(data) { // когда получаем ответ
                if(!data.error){ // Если ошибки нет, то выводим список статей
                    // Если есть статьи - то будем их выводить
                    if(data.content){
                        var html = '';
                        for(var A in data.content){
                            var item = data.content[A];
                            html += '<tr><td>'+item.id+'</td><td>'+item.name+'</td><td>'+item.description+'</td><td><a class="delete btn btn-danger"href="/articles/delete/'+item.id+'">Удалить</a></td></tr>';
                        }
                        $('table.articles tbody').html(html);
                    }
                    form.trigger('reset');
                }else{ // Если сервер вернул ошибку то выводим текст ошибки
                    $("#error").html(data.message).slideDown();
                }
                
                /** Делаем кнопку отправки снова активной и убираем индикатор загрузки */
                $("[type=submit]",form).removeAttr('disabled');
                $("#loading").slideUp();
            },
            error: function(){ // Если сервер вернул ошибку, 4хх, 5хх
                /** Выводим ошибку, делаем кнопку отправки снова активной и убираем индикатор загрузки */
                $("#error").html('Произошла ошибка').slideDown();
                $("[type=submit]",form).removeAttr('disabled');
                $("#loading").slideUp();
            }
    });
    
    return false;
});

Добавим еще один обработчик события для удаления статей:

/** Функция удаления статьи */
$('body').on('click','.delete',function(){
    var link = $(this);
    if(confirm('Вы действительно хотете удалить?')){
        $.ajax({
            type: "POST",
            url: link.attr('href'), // берем адрес из ссылки
            dataType: "json",
            success: function(data) { // когда получаем ответ
                if(!data.error){ // Если ошибки нет, то удаляем строку
                    link.closest('tr').hide(function(){
                        $(this).remove();
                    })
                }else{ // Если сервер вернул ошибку то выводим текст ошибки
                    $("#error").html(data.message).slideDown();
                }
            }
        });
    }
    return false;
});

Model

Создадим модель articles.php для работы с записями в БД:

<?php

class Model_articles extends Model_Database
{
    static $table_articles = "articles";
    
    /** Выбор записей */
    public function findBy() {

        return DB::select()->from(self::$table_articles)->execute()->as_array();
    }
    
    /** Сохранение записи */
    public function save($data){

        if(!$data) return false;
        
        foreach($data as $k=>$v){
            $key[] = $k;
            $value[] = $v;
        }
        
        $id = DB::insert(self::$table_articles, $key)->values($value)->execute();
        
        return $id;
    }
    
    /** Удаление записи */
    public function delete($id){

        if($id){
            return (bool) DB::delete(self::$table_articles)->where('id', '=', $id)->execute();
            
        }
        
        return false;
    }
}

Controller

И на последок создадим контролер, который будет обрабатывать наши запросы:

<?php defined('SYSPATH') or die('No direct script access.');

class Controller_Articles extends Controller_Template {    
    
    public $template = "main";
    
    public function action_index()
    {
        $data = array();
    
        $modelArticles = new Model_articles;
        $data = $modelArticles->findBy();  // выбираем список статей из БД
    
        $this->template->content = View::factory('articles',array('data'=>$data)); // выводим список статей и форму для добавления статей
    }
    
    public function action_add()
    {
        $error = true;
        $id= null;
        $modelArticles = new Model_articles;
        if($post = $this->request->post())
        {
            $data = array(
                'name' => $post['name'],
                'description' => $post['description'],
            );
            $validate = Validation::factory($data); // готовимся к проведению валидации
            $validate -> rule(TRUE, 'not_empty'); // Проверяем на наличие пустых строк
            if($validate -> check()) // проводим валидацию
            {
                
                $id = $modelArticles->save($data); //добавляем в БД запись
                if ($id){
                    $error = false;
                }
            }
        }
        
        if (Request::initial()->is_ajax()){ // выполняем только если запрос был через Ajax
            if($error){
                $result = array('error'=>true,'message'=>'Ошибка валидации формы!'); // по умолчанию возвращаем код с ошибкой
            }else{
                // если валидация прошла успешно и запись в БД новой статьи прошла успешно
                $result['error'] = false; // возвращаем код успеха!
                
                $data = $modelArticles->findBy();  // выбираем список статей из БД и формируем масив
                if($data){
                    foreach($data as $v){
                        $result['content'][] = array(
                            'id' => $v['id'],
                            'name' => $v['name'],
                            'description' => $v['description']
                        );
                    }
                }
            }
            header('Content-Type: text/json; charset=utf-8');  // Устанавоиваем правильный заголовок
            echo json_encode($result);  // на выходе отдаем код в формате JSON
            exit;
        }else{
            $this->redirect('/articles'); // если запрос был не Аяксом, то редиректим на страницу списка статей
        }
    }
    public function action_delete()
    {
        $error = true;
        $modelArticles = new Model_articles;
        $id = (int) $this->request->param('id');
        if($id)
        {
            $error = !$modelArticles->delete($id); //Удаляем статью
        }
        
        if (Request::initial()->is_ajax()){ // выполняем только если запрос был через Ajax
            if($error){
                $result = array('error'=>true,'message'=>'Ошибка при удалении'); // по умолчанию возвращаем код с ошибкой
            }else{
                $result['error'] = false; // возвращаем код успеха!
            }
            header('Content-Type: text/json; charset=utf-8');  // Устанавоиваем правильный заголовок
            echo json_encode($result);  // на выходе отдаем код в формате JSON
            exit;
        }else{
            $this->redirect('/articles'); // если запрос был не Аяксом, то редиректим на страницу списка статей
        }
    }
}

Тут стоит отметить, что благодаря проверке Request::initial()->is_ajax() мы проверяем как нам передали данные, если передача была обычным методом - то мы просто редиректим на страницу со списком статей, если запросы был Аяксом, то выдаем список статей в JSON.

Готово, пробуем запустить http://localhost/articles/.  Только в рабочем приложении не забудьте добавить дополнительные проверки входных данных, а также – авторизованный доступ.

Скачать рабочий пример

Теги:
  • Framework Kohana
  • jQuery
  • Пример

Комментарии

  1. Денис
    Денис
    29.09.2015 00:32

    Благодарю Вас за труды!
    Очень помогло в освоении kohana.
    Особенно версии 3.3 в русскоязычном пространстве.
    Было бы здорово если бы Вы добавили в пример функцию редактирования статьи и запись ее в БД.
    И еще хотелось бы увидеть реализацию этого примера через ORM.
    Надеюсь, что мою просьбу не оставите без внимания.

    Ответить

Оставить комментарий Отмена

*

*

*

*

Категории

  • PHP
    • Framework Kohana
  • Javascript
  • CSS
  • Администрирование

Теги

Framework Kohana Пример jQuery Уроки CRON Установка и настройка Backup CSS3 Валидация API Bash Cache Captcha i18n Linux

Авторизация

  • Забыли пароль?
  • Регистрация

Популярные статьи

  • Находим расстояние до ближайших станций метро

    Находим расстояние до ближайших станций метро

    17.02.2017 102828
  • Регистрация и авторизация пользователей. Модуль Auth в Kohana 3.3.x

    Регистрация и авторизация пользователей. Модуль Auth в Kohana 3.3.x

    02.07.2014 44444
  • Собственная система лайков на PHP и JQuery

    Собственная система лайков на PHP и JQuery

    06.04.2015 33128
  • Javascript — сумма прописью

    Javascript — сумма прописью

    07.07.2014 22967
  • Cross-domain ajax с помощью jQuery

    Cross-domain ajax с помощью jQuery

    24.04.2015 19840
Copyright © 2014-2025 Frameworks.su. Все права защищены.