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

29 мая, 2009
notes widget

В этой статье мы продолжаем разработку виджета для работы с короткими заметками. Если вы не читали предыдущую часть, то очень советую бегло её просмотреть. В ней мы подробно описаны постановка задачи и реализована серверная часть виджета, т.е. весь PHP код.

Для того, чтобы виджет заработал нам осталось написать клиентскую часть.

Думаю, очевидно, что для виджета отправка и получение данных должна выполняться с помощью AJAX запросов. Ведь вряд ли кому-то понравиться, если каждая операция с виджетом будет приводить к перезагрузке всей страницы.

Поэтому основную часть клиентской части у нас будет занимать JavaScript код. А чтобы его сократить мы используем библиотеку jQuery с несколькими плагинами.

Кстати, есть демонстрационная страничка с этим виджетом.

демонстрационный пример

И, как и обещал, выкладываю архив с исходниками.

архив с исходным кодом

Прежде всего, рассмотрим разметку страницы (index.html).

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  4. <head>
  5.     <title>Notes Widget</title>
  6.  
  7.     <meta http-equiv="content-type" content="text/html;charset=utf-8" />
  8.     <meta http-equiv="Content-Style-Type" content="text/css" />
  9.    
  10.     <link rel="stylesheet" type="text/css" href="pagestyles.css" />
  11.     <link rel="stylesheet" type="text/css" href="widgetstyles.css" />
  12. </head>
  13. <body>
  14.     <div id="content">
  15. …. Содержимое страницы…
  16.     </div>
  17.  
  18.     <div id="notesWidget">
  19.         <div id="notesHeader">Мои заметки</div>
  20.         <div id="notes">
  21.         </div>
  22.         <form id="fAddNote" action="savenote.php" method="post">
  23.             <input type="text" id="addNote" name="addNote" value="" />
  24.             <input type="submit" name="bAddNote" id="bAddNote" value="" />
  25.         </form>
  26.     </div>
  27.  
  28.     <script type="text/javascript" src="js/jquery-1.3.2.min.js"></script>
  29.     <script type="text/javascript" src="js/jquery-ui-1.7.1.custom.min.js"></script>
  30.     <script type="text/javascript" src="js/jquery.jeditable.mini.js"></script>
  31.     <script type="text/javascript" src="js/custom.js"></script>
  32. </body>
  33. </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 стили минимально необходимые для работы плагина. Полный файл со стилями вы можете посмотреть в архиве с исходниками. К тому же при использовании виджета его оформление наверняка придется подстраивать под дизайн страницы.

  1. #notesWidget {
  2.     position: absolute;
  3.     top: 200px;
  4.     left: 0;
  5.     width: 200px;
  6.     height: 300px;
  7.     ….
  8. }
  9.  
  10. #notesHeader {
  11.     cursor: move;
  12.     ….
  13. }
  14.  
  15. #notes {
  16.     overflow: scroll;
  17.     ….
  18. }

Для того, чтобы виджет можно было перемещать по странице, он должен иметь абсолютное позиционирование. При этом необходимо задать его размеры и положение.

Чтобы пользователь без наших подсказок мог догадаться, что это перемещаемый блок, мы изменим вид курсора для заголовка виджета.

И, т.к. заметок может быть много, добавим прокрутку в блок notes.

Теперь переходим к самой интересной части – нашему JavaScript файлу (custom.js).

  1. $(function() {
  2.     //делаем виджет перемещаемым
  3.     $('#notesWidget').draggable({
  4.         handle: '#notesHeader'
  5.         , containment: 'parent'
  6.     });
  7.     //обработчик нажатия на кнопку добавления новой записи
  8.     $('#bAddNote').click(function() {
  9.         if ($('#addNote').val() != ") {
  10.             //сохраняем запись
  11.             $.post('savenote.php', {value:$('#addNote').val(), bAddNote:true},
  12.                     function(noteid) {
  13.                 //добавляем запись в список
  14.                 var curDate = new Date();
  15.                 var noteData = {id:noteid, note_text:$('#addNote').val(),
  16.                     note_date:curDate.toString()};
  17.                 var note = $(createListElement(noteData));
  18.                 $('#notes ul').prepend(note);
  19.                 $('.edit').editable('savenote.php');
  20.                 note.children('.remove').click(function() {addRemove(this);});
  21.                
  22.                 refreshClasses();
  23.             });
  24.         }
  25.         else {
  26.             alert('Вы ничего не написали');
  27.         }
  28.        
  29.         return false;
  30.     });
  31.     //загружаем список записей
  32.     $.getJSON('getnotes.php', {}, function(data, status) {
  33.         if (data.status == 'OK') {
  34.  
  35.             //формируем список
  36.             var notesList = '<ul>';
  37.             $.each(data.notes, function(i, note) {
  38.                 notesList += createListElement(note);
  39.             });
  40.             notesList += '</ul>';
  41.  
  42.             $('#notes').html(notesList);
  43.            
  44.             //делаем записи редактируемыми
  45.             $('.edit').editable('savenote.php');
  46.            
  47.             //добавляем обработчики нажатия на кнопку удаления записи
  48.             $('.remove').click(function() {addRemove(this);});
  49.            
  50.             refreshClasses();
  51.         }
  52.         else {
  53.             //вывод сообщения об ошибке
  54.             $('#notes').html('<p>Не могу загрузить список записей</p>');
  55.         }
  56.     });
  57. });
  58.  
  59. function createListElement(note) {
  60.     return '<li>'
  61.         + '<img src="images/removenote.gif" alt="Удалить" class="remove" />'
  62.         + '<div class="edit" id="note_' + note.id + '">'
  63.         + note.note_text + '</div>'
  64.         + '<div class="notedate">' + note.note_date + '</div>'
  65.         + '</li>';
  66. }
  67.  
  68. function addRemove(element) {
  69.     var noteid = $(element).next().attr('id');
  70.    
  71.     //удаляем запись
  72.     $.post('removenote.php', {id:noteid}, function() {
  73.         //убираем данную запись из списка
  74.         $(element).parent().slideUp("slow", function() {
  75.             $(this).remove();
  76.             refreshClasses();
  77.         });
  78.     });
  79. }
  80.  
  81. function refreshClasses() {
  82.     var odds = $('#notes ul li:odd');
  83.     odds.removeClass('even');
  84.     odds.addClass('odd');
  85.     var evens = $('#notes ul li:even');
  86.     evens.removeClass('odd');
  87.     evens.addClass('even');
  88. }

Рассмотрим его подробнее.

Прежде всего, сделаем виджет перемещаемым (строки 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 с помощью которого можно создать таблицу в базе данных.

Интересно почитать:

Закат Веба?

Понравилась статья? Подписывайтесь на продолжение rss link !

Или на мой твиттер twitter link

]]>

Добавьте эту страницу в google.com bobrdobr.ru del.icio.us technorati.com linkstore.ru news2.ru rumarkz.ru memori.ru moemesto.ru

]]>

Опубликовано в Ajax, CSS, HTML, JavaScript, Web разработка Комментарии (5) »

]]>

Комментарии (5)

Вы можете отслеживать обсуждение записи с помощью RSS 2.0 rss link

Вы также можете оставить комментарий, или трекбек с Вашего сайта.

]]>
  1. Serator

    В продолжении темы удобства к виджету (по сути любому), неплохо бы прикрутить кнопку для сворачивания вплоть до размеров копеечной монетки. А в остальном все выглядит законченным :)

    • Согласен. Нужно будет доделать. Может кроме сворачивания добавить перемещение свернутого виджета к краю экрана?

      • Serator

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

  2. Спасибо автору за статью, очень классный виджет

]]>

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

* - обязательные для заполнения поля

]]>