Динамічне меню на Ajax

22

Від автора: у даному уроці ми розглянемо створення динамічного меню, за допомогою технології AJAX. Якщо Ви працювали з CMS WordPress, то, напевно, знайомі з такою штукою, як віджети WordPress. В даному випадку віджети — це блоки, які можна переміщати в режимі Drag and Drop («тягни і кидай»). При цьому, після переміщення блоку, він зберігає свою позицію, тобто, наприклад, в сайдбарі сайту у нас є блок пошуку, під яким розміщений блок з довільним текстом… ми захотіли поміняти їх позиції… немає нічого простіше — перетягли блок з пошуком під блок з текстом і… вуаля — на сайті ці зміни розташування блоків набрали чинності. Погодьтеся, динамічне меню — це швидко, зручно і ефектно.

Динамічне меню на AjaxДинамічне меню на Ajax

1. Постановка завдань. Створення БД

Для початку сформулюємо задачу. Замість блоків у нас буде меню, пункти якого у нас і будуть перетаскиваемыми блоками. Для чого взагалі це потрібно? Припустимо, ми хочемо змінити сортування пунктів меню, тобто зробити так, щоб з БД пункти меню виводилися не відсортованими за ідентифікатор пункту меню, а, приміром, полю position. Для цього, звичайно ж, можна написати нескладний скрипт, який буде відображати поточну позицію кожного з пунктів меню в числовому вигляді (1, 2, 3 і т. д.). Далі ми зможемо для конкретного пункту задати нову числову позицію і зберегти зміни в БД. Але набагато швидше і гарніше буде виглядати реалізація, коли ми просто візьмемо пункт меню і перетягнемо його на нове місце… все — він збереже свою позицію.

Отже, ми створюємо меню і через адміністративну частину сайту зможемо змінювати позицію його пунктів. Давайте тепер визначимося з тим, що нам знадобиться. Насамперед, нам знадобляться 2 бібліотеки jQuery:

власне сама бібліотека jQuery;

бібліотека jQuery User Inteface.

Взяти їх можна на офф сайті jQuery. Також Ви знайдете ці скрипти в исходниках до уроку. Також нам знадобиться файл стилів для оформлення пунктів меню, який Ви можете згенерувати на сайті jQuery в розділі jQueryUI або знайти в исходниках до уроку (або написати стилі для пунктів меню самостійно в залежності від дизайну Вашого сайту).

У нас буде 2 файлу. Перший файл (index.php) — це сторінка сайту для загального доступу. Другий файл (admin.php) — це сторінка адмінки, на якій ми зможемо змінювати позицію пунктів меню. Звичайно ж, доступ до адмінки повинен бути обмежений (як це зробити, Ви можете дізнатися з попередніх уроків). Основна відмінність файлу admin.php полягає в тому, що ми підключили нього 2 зазначених скрипта:

В файл index.php ці бібліотеки підключати не потрібно.

Також в обидва файлу ми підключимо файл стилів:

І напишемо кілька правил стилях на сторінці index.php:

#sortable { list-style-type: none; margin: 0; padding: 0; width: 200px; }
#sortable li { margin: 0 3px 3px 3px; padding: 0.4 em; padding-left: 1.5 em; font-size: 1.4 em; height: 15px; cursor: pointer;}
#sortable li span { position: absolute; margin-left: -1.3 em; }

І на сторінці admin.php:

#sortable { list-style-type: none; margin: 0; padding: 15px 40px 15px 0; width: 200px; }
#sortable li { margin: 0 3px 3px 3px; padding: 0.4 em; padding-left: 1.5 em; font-size: 1.4 em; height: 15px; cursor:move}
#sortable li span { position: absolute; margin-left: -1.3 em; }
.block{/*border:1px solid #ccc;*/ width:200px;}

Наступне, що нам знадобиться — це БД, в якій будуть зберігатися назви кожного з пунктів меню і їх поточна позиція на сайті. Щоб не створювати БД вручну, Ви можете імпортувати дамп БД з исходников (файл test.sql).

БД я назву test і створю в ній таблицю sortable, для якої знадобиться всього 3 поля:

id тип INT, первинний ключ, автоинкремент;

name, тип VARCHAR, довжина 255 символів;

position, тип INT.

Тепер занесемо в створену таблицю 3 тестових пункту меню:

Пункт 1 із позицією 1;

Пункт 2 із позицією 2;

Пункт 3 із позицією 3;

Відмінно! БД готова.

2. Виводимо меню з БД

БД створена і тепер можна вивести меню на сайт. Перш, ніж зробити це створимо файл з підключенням до БД. Цей файл ми будемо включати на індексну і адмін сторінки сайту. Я назву файл db.php. Як підключатися до сервера БД і вибирати необхідну для роботи БД ми вже знаємо, оскільки це неодноразово робили:

Тепер підключимо цей файл в самому верху індексного та адмінської сторінки:

Відмінно! Тепер виведемо пункти меню на сайт. Для цього створимо заяву (запит), якою виберемо з таблиці sortable все, що там є, і відсортуємо обраний по полю position в порядку зростання (таким чином, пункти меню будуть виведені традиційно — 1, 2, 3). З запитами ми вже працювали, тому нічого нового тут не повинно бути для Вас.

Відкриваємо конструкцію PHP в тому місці, де має бути виведено меню і пишемо код:

\r\n»;
while($row = mysql_fetch_assoc($res)){
echo «

  • {$row[‘name’]}
  • \r\n»;
    }
    echo «

    «;
    ?>

    Тут ми виводимо пункти меню списком. При цьому варто звернути увагу на те, що кожен з пунктів має свій ідентифікатор, значенням якого є ідентифікатор конкретного поля в БД. Цей ідентифікатор нам знадобиться для того, щоб уникализировать кожен з пунктів меню.

    Відмінно!

    Пункти меню вибрані з БД і з’явилися на сайті.

    3. Реалізуємо сортування без збереження

    З файло index.php ми закінчили і тепер можна перейти до адмінці. Для початку просто скопіювати код виведення меню з індексного файлу. Тепер, якщо подивитися в браузері сторінку admin.php, то побачимо аналогічне меню за одним винятком — при наведенні на пункти меню курсор набуває крестовідную форму, що говорить про те, що ці пункти можна перетягувати. Реалізується така форма курсору правилом в стилях:

    cursor:move

    Це правило ми прописали раніше. Курсор змінює свою форму, але пункти меню поки що неможливо перетягувати. Для того, щоб це було можливо зробити, пропишемо простий скрипт в блоці head:

    $(document).ready(function(){
    $(‘#sortable’).sortable({
    });
    });

    Всі…

    Тепер ми вже можемо перетягувати пункти меню. Це реалізовано завдяки роботі тих двох бібліотек, які ми підключили раніше. Тут же ми просто взяли в набір jQuery елемент з ідентифікатором sortable і викликали для нього метод sortable. Якщо Ви не знайомі з основами jQuery, то рекомендую Вам звернутися до попередніх уроків на сайті, де ми знайомилися з основами роботи jQuery. Сам метод sortable, до якого ми звернулися, описаний в бібліотеці jQuery UI. Він має безліч параметрів, подій і методів, деякі з яких ми зараз і скористуємося. Перш за все, давайте обмежимо переміщення блоків тільки віссю Y (тільки по вертикалі). Для цього звернемося до опції axis:

    $(document).ready(function(){
    $(‘#sortable’).sortable({
    axis: ‘y’
    });
    });

    Тепер давайте зменшимо непрозорість перетягуваного елемента до 50%:

    $(document).ready(function(){
    $(‘#sortable’).sortable({
    axis: ‘y’,
    opacity: 0.5
    });
    });

    Відмінно!

    Тепер треба зробити так, щоб ми могли отримати поточну позицію кожного з елементів після того, як ми завершимо переміщення. Для цього звернемося до події stop і методом (функції) toArray:

    $(document).ready(function(){
    $(‘#sortable’).sortable({
    axis: ‘y’,
    opacity: 0.5,
    stop: function(){
    var arr = $(‘#sortable’).sortable(«toArray»);
    alert(arr);
    }
    });
    });

    Отже, що ми тут зробили? Після настання події stop (коли завершено перетягування елемента) ми звертаємося до елементу з id sortable (це наше меню) і викликаємо функцію toArray. Дана функція отримує id кожного з відсортованих елементів і вміщує його в масив у вигляді рядка, де значення розділені комою. Результат поміщаємо в змінну arr. Таким чином, якщо ми змінимо початкову позицію пунктів 1 і 2, то змінної arr буде міститися ось такий рядок — 2, 1, 3. Для наочності можна вивести методом alert значення змінної arr після кожного з перетаскиваний.

    4. Звертаємося до методу ajax

    Ми виконали частину завдання — пункти меню можна перетягувати. Але вони не зберігають своєї позиції в БД і після оновлення сторінки, все стає на круги своя. Для того, щоб оновлення були внесені у БД, необхідно передати значення змінної arr в скрипт PHP, який би заніс оновлені дані в БД. Зробити це, звернувшись до методу jQuery під назвою ajax(). Отже, пропишемо його з усіма необхідними нам параметрами:

    $(document).ready(function(){
    $(‘#sortable’).sortable({
    axis: ‘y’,
    opacity: 0.5,
    stop: function(){
    var arr = $(‘#sortable’).sortable(«toArray»);
    //alert(arr);
    $.ajax({
    url: ‘save.php’,
    type: ‘POST’,
    data: {masiv:arr},
    error: function(){
    $(‘#res’).text(«Помилка!»);
    },
    success: function(){
    $(‘#res’).text(«Збережено!»);
    }
    });
    }
    });
    });

    Пройдемося по параметрам:

    url: вказуємо ім’я файлу, який прийме дані з скрипта (аналог атрибут action у формі);

    type: тип переданих даних (аналог атрибут method у формі);

    data: передавані дані у форматі {змінна:значення};

    error і success: події помилки і успіху запиту відповідно.

    Таким чином, ми передаємо значення змінної masiv методом POST у файл save.php. У разі успіху в блок з ідентифікатором res буде додано текст «Збережено!», у випадку помилки — «Помилка!».

    Все просто…

    5. Реалізуємо збереження сортування

    Залишилося написати скрипт для файлу save.php, який би брав дані. Створимо файл save.php і запишемо в нього наступний код:

    Тепер давайте спробуємо розібратися в роботі того, що ми написали тільки що.

    6. Логіка роботи скрипта

    Оскільки ми приймаємо масив даних — використовуємо цикл foreach для того, щоб пройтися по кожному з елементів масиву. До початку циклу створимо змінну $pos_new зі значенням 1, яка буде новим значенням позиції для кожного з пунктів меню. У тілі циклу ми будемо з кожним кроком циклу збільшувати значення змінної на одиницю. Таким чином, її значення послідовно буде змінюватися від 1 до 3. Також у тілі циклу вказуємо запит, яким встановлюємо поточне значення змінної $pos_new значенням поля position. Але робимо ми це для того поля, в якому значення поля id буде дорівнює поточному значенню перебираемого елемента масиву, який ми отримали. Тут важливо зрозуміти саму логіку роботи запиту. Оскільки ми передаємо в масиві ідентифікатор кожного з пунктів меню, то логічно, що вони будуть відповідати ідентифікаторів пунктів меню в БД. Саме тому для отриманого ідентифікатора ми встановимо поточне значення змінної $pos_new в БД.

    Вам простіше буде усвідомити роботу скрипта, якщо Ви за допомогою методу alert будете бачити що відсилається і спостерігати зміни в БД.

    7. Додаємо юзабельности

    Залишилося додати деякі поліпшення, які зроблять приємною роботу зі скриптом. Наприклад, ми можемо після кожного збереження тільки на час показувати текст «Збережено!», а потім зробити так, щоб він зникав. Також зробимо так, щоб місце блоку, який ми захопили, подсвечивалось:

    $(document).ready(function(){
    $(‘#sortable’).sortable({
    axis: ‘y’,
    opacity: 0.5,
    placeholder: ‘ui-state-default’,
    containment: ‘.block’,
    stop: function(){
    var arr = $(‘#sortable’).sortable(«toArray»);
    //alert(arr);
    $.ajax({
    url: ‘save.php’,
    type: ‘POST’,
    data: {masiv:arr},
    error: function(){
    $(‘#res’).text(«Помилка!»);
    },
    success: function(){
    $(‘#res’).show().text(«Збережено!»).fadeOut(1000);
    }
    });
    }
    });
    });

    Тепер набагато краще. От і все. Наша задача реалізована.

    Висновок уроку по створенню динамічного меню для сайту

    Пункти динамічного меню після перетягування зберігають свою позицію в БД. Варто тільки нагадати про безпеку. В принципі, про це я вже неодноразово говорив в попередніх уроках, але нагадаю основне правило безпеки: усі дані, що приймаються від користувача, повинні відповідним чином бути оброблені. Тут, звичайно, в цьому особливого сенсу немає, оскільки робота з БД здійснюється на рівні адмінки, але якщо б ми брали дані користувача частини, то кожен з елементів масиву необхідно було б привести до явного целочисленному функцією типу (int) або intval(), щоб запит гарантовано потрапляло число.

    На цьому наш урок по створенню динамічного меню завершений. Ваші запитання, відгуки завжди будемо раді бачити в коментарях. Удачі у Ваших розробках і до нових зустрічей!