Создаём виджет для хранения заметок. Часть 2.

В этой статье мы продолжаем разработку виджета для работы с короткими заметками. Если вы не читали предыдущую часть, то очень советую бегло её просмотреть. В ней мы подробно описаны постановка задачи и реализована серверная часть виджета, т.е. весь PHP код.
Для того, чтобы виджет заработал нам осталось написать клиентскую часть.
Думаю, очевидно, что для виджета отправка и получение данных должна выполняться с помощью AJAX запросов. Ведь вряд ли кому-то понравиться, если каждая операция с виджетом будет приводить к перезагрузке всей страницы.
Поэтому основную часть клиентской части у нас будет занимать JavaScript код. А чтобы его сократить мы используем библиотеку jQuery с несколькими плагинами.
Кстати, есть демонстрационная страничка с этим виджетом.
И, как и обещал, выкладываю архив с исходниками.
Прежде всего, рассмотрим разметку страницы (index.html).
-
<?xml version="1.0" encoding="UTF-8"?>
-
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-
<head>
-
<title>Notes Widget</title>
-
-
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
-
<meta http-equiv="Content-Style-Type" content="text/css" />
-
-
<link rel="stylesheet" type="text/css" href="pagestyles.css" />
-
<link rel="stylesheet" type="text/css" href="widgetstyles.css" />
-
</head>
-
<body>
-
<div id="content">
-
…. Содержимое страницы…
-
</div>
-
-
<div id="notesWidget">
-
<div id="notesHeader">Мои заметки</div>
-
<div id="notes">
-
</div>
-
<form id="fAddNote" action="savenote.php" method="post">
-
<input type="text" id="addNote" name="addNote" value="" />
-
<input type="submit" name="bAddNote" id="bAddNote" value="" />
-
</form>
-
</div>
-
-
<script type="text/javascript" src="js/jquery-1.3.2.min.js"></script>
-
<script type="text/javascript" src="js/jquery-ui-1.7.1.custom.min.js"></script>
-
<script type="text/javascript" src="js/jquery.jeditable.mini.js"></script>
-
<script type="text/javascript" src="js/custom.js"></script>
-
</body>
-
</html>
В заголовке страницы мы подключаем файлы с CSS стилями (строки 13 и 14). Я вынес все стили, которые относятся к виджету в отдельный файл (widgetstyles.css), чтобы они не путались со стилями основной страницы.
Внутри страницы у нас находится 2 блока: основное содержимое (<div id="content">) и виджет (<div id="notesWidget">).
Первый блок нас не интересует, а вот на втором остановимся подробнее. Он состоит из трёх частей:
- заголовок (<div id="notesHeader">);
- блок заметок (<div id="notes">);
- блок с формой добавления заметки (<form id="fAddNote").
Обратите внимание, что блок заметок не заполнен. Внутрь него мы будем вставлять список заметок, полученный от сервера.
И в конце страницы мы подключаем jQuery, плагины и файл с нашими скриптами.
Сразу же рассмотрим используемые плагины.
1) jQuery UI. Это скорее не плагин, а целая библиотека. На её сайте вы можете выбрать необходимые компоненты и скачать архив с ними. Для нашего виджета нужны Core UI и Draggable. С их помощью мы сможем свободно перемещать виджет по странице.
2) Jeditable. С помощью этого плагина мы будем создавать in-line редакторы. Т.е. сделаем список с нашими заметками редактируемым. При клике по тексту заметки будет появляться поле ввода с помощью которого пользователь сможет изменить текст.
Теперь рассмотрим CSS стили минимально необходимые для работы плагина. Полный файл со стилями вы можете посмотреть в архиве с исходниками. К тому же при использовании виджета его оформление наверняка придется подстраивать под дизайн страницы.
-
#notesWidget {
-
position: absolute;
-
top: 200px;
-
left: 0;
-
width: 200px;
-
height: 300px;
-
….
-
}
-
-
#notesHeader {
-
cursor: move;
-
….
-
}
-
-
#notes {
-
overflow: scroll;
-
….
-
}
Для того, чтобы виджет можно было перемещать по странице, он должен иметь абсолютное позиционирование. При этом необходимо задать его размеры и положение.
Чтобы пользователь без наших подсказок мог догадаться, что это перемещаемый блок, мы изменим вид курсора для заголовка виджета.
И, т.к. заметок может быть много, добавим прокрутку в блок notes.
Теперь переходим к самой интересной части – нашему JavaScript файлу (custom.js).
-
$(function() {
-
//делаем виджет перемещаемым
-
$('#notesWidget').draggable({
-
handle: '#notesHeader'
-
, containment: 'parent'
-
});
-
//обработчик нажатия на кнопку добавления новой записи
-
$('#bAddNote').click(function() {
-
if ($('#addNote').val() != ") {
-
//сохраняем запись
-
$.post('savenote.php', {value:$('#addNote').val(), bAddNote:true},
-
function(noteid) {
-
//добавляем запись в список
-
var curDate = new Date();
-
var noteData = {id:noteid, note_text:$('#addNote').val(),
-
note_date:curDate.toString()};
-
var note = $(createListElement(noteData));
-
$('#notes ul').prepend(note);
-
$('.edit').editable('savenote.php');
-
note.children('.remove').click(function() {addRemove(this);});
-
-
refreshClasses();
-
});
-
}
-
else {
-
alert('Вы ничего не написали');
-
}
-
-
return false;
-
});
-
//загружаем список записей
-
$.getJSON('getnotes.php', {}, function(data, status) {
-
if (data.status == 'OK') {
-
-
//формируем список
-
var notesList = '<ul>';
-
$.each(data.notes, function(i, note) {
-
notesList += createListElement(note);
-
});
-
notesList += '</ul>';
-
-
$('#notes').html(notesList);
-
-
//делаем записи редактируемыми
-
$('.edit').editable('savenote.php');
-
-
//добавляем обработчики нажатия на кнопку удаления записи
-
$('.remove').click(function() {addRemove(this);});
-
-
refreshClasses();
-
}
-
else {
-
//вывод сообщения об ошибке
-
$('#notes').html('<p>Не могу загрузить список записей</p>');
-
}
-
});
-
});
-
-
function createListElement(note) {
-
return '<li>'
-
+ '<img src="images/removenote.gif" alt="Удалить" class="remove" />'
-
+ '<div class="edit" id="note_' + note.id + '">'
-
+ note.note_text + '</div>'
-
+ '<div class="notedate">' + note.note_date + '</div>'
-
+ '</li>';
-
}
-
-
function addRemove(element) {
-
var noteid = $(element).next().attr('id');
-
-
//удаляем запись
-
$.post('removenote.php', {id:noteid}, function() {
-
//убираем данную запись из списка
-
$(element).parent().slideUp("slow", function() {
-
$(this).remove();
-
refreshClasses();
-
});
-
});
-
}
-
-
function refreshClasses() {
-
var odds = $('#notes ul li:odd');
-
odds.removeClass('even');
-
odds.addClass('odd');
-
var evens = $('#notes ul li:even');
-
evens.removeClass('odd');
-
evens.addClass('even');
-
}
Рассмотрим его подробнее.
Прежде всего, сделаем виджет перемещаемым (строки 3-6). Параметр handle указывает, что блок можно будет перемещать только за заголовок, а containment – запрещает выводить блок за пределы страницы.
Затем, мы создаем обработчик нажатия на кнопку «Добавить» (строки 8-30). В нём мы проверяем, ввел ли пользователь текст новой заметки и отправляем AJAX запрос.
После получения ответа будет вызвана анонимная функция (строки 12-23), которая:
1) создает элемент списка с новой записью (с помощью функции createListElement, её мы рассмотрим чуть ниже);
2) вставляет его в начало общего списка;
3) делает редактируемым (с помощью метода editable);
4) добавляет обработчик нажатия на кнопку «Удалить» (вызывает функцию addRemove);
5) и обновляет цвет фона записей (с помощью функции refreshClasses).
Теперь рассмотрим функцию createListElement (строки 59-66). Её основная задача – создать разметку новой записи.
Запись состоит из текста, кнопки «Удалить» (точнее это обычный рисунок, которому назначается обработчик события click), и даты. Оформление записи выполняется с помощью CSS стилей, но на них я останавливаться не буду, в них ничего примечательного нет, к тому же они в любом случае должны сочетаться с конкретной страницей (если интересно, качайте архив с виджетом).
В разметке записи стоит обратить внимание на два момента.
1) Тексту записи присваивается класс edit (<div class="edit"…). С его помощью мы выбираем элементы для которых создаются in-line редакторы.
2) Этому же элементу мы присваиваем атрибут id в формате (note_№), его значение используется при изменении и удалении заметок.
Следующая функция addRemove (строки 68-79).
Здесь выполняется AJAX запрос на удаление заметки (строка 72) и после этого заметка удаляется из списка. При этом используется эффект slideUp.
Теперь рассмотрим функцию refreshClasses (строки 81-88).
Она работает следующим образом.
1) Находим все нечетные элементы в списке заметок.
2) Устанавливаем для них класс odd и убираем even (если он был установлен).
3) Находим все четные элементы списка и устанавливаем для них класс even.
Стили для классов odd и even указаны в CSS файле (widgetstyles.css). Т.е. с помощью этой функции мы всегда можем обновить расцветку списка после добавления или удаления элементов.
Теперь рассмотрим загрузку полного списка записей (строки 32-56). Она выполняется сразу после загрузки страницы.
Мы отправляем AJAX запрос (с помощью метода getJSON) и после получения ответа формируем HTML список с заметками. Точно также как и при добавлении заметки устанавливаем обработчики нажатия на кнопку «Удалить», делаем записи редактируемыми и обновляем стили.
На этом можно остановиться. Общий принцип работы виджета мы рассмотрели, а если есть вопросы или замечания, пишите в комментариях, постараюсь ответить.
P.S. В архиве с исходниками есть файл notes.sql с помощью которого можно создать таблицу в базе данных.
Интересно почитать:
Понравилась статья? Подписывайтесь на продолжение
!
Опубликовано в Ajax, CSS, HTML, JavaScript, Web разработка Комментарии (5) »
Комментарии (5)
Вы можете отслеживать обсуждение записи с помощью RSS 2.0 ![]()
Вы также можете оставить комментарий, или трекбек с Вашего сайта.











В продолжении темы удобства к виджету (по сути любому), неплохо бы прикрутить кнопку для сворачивания вплоть до размеров копеечной монетки. А в остальном все выглядит законченным
Согласен. Нужно будет доделать. Может кроме сворачивания добавить перемещение свернутого виджета к краю экрана?
Не думаю, что это будет удобно, ибо пользователь изначально расположит виджет так, как ему удобно. Возможно будет лучше, если, наравне с содержимым, виджет будет запоминать свое местоположение + position:fixed (опционально) для сохранения позиции при прокрутке.
Спасибо за советы! Я поэкспериментирую.
Спасибо автору за статью, очень классный виджет