От автора: в этом мы продолжим работу с атрибутом HTML5 contenteditable. При изменении значения редактируемого поля, скрипт будет отправлять асинхронным запросом (средствами AJAX) новое значение, и сохранять его в БД.
Итак, мы остановились на том, что при получении полем со значением фокуса, получаем имеющееся в нем значение и ID данной опции. Следующее событие, с которым мы будем работать, это событие blur, которое наступает при потере полем фокуса. Иными словами, мы будем отслеживать событие, когда пользователь кликнет вне редактируемого поля.

JavaScript. Быстрый старт
Изучите основы JavaScript на практическом примере по созданию веб-приложения
Узнать подробнееПосле этого нам нужно получить новое значение поля и обязательно сравнить его с предыдущим (тем, которое взяли при получении элементом фокуса). Если эти значения будут отличаться, то это значит, что пользователь изменил значение, и мы можем отправлять новое значение на сервер для его сохранения. Если же значения будут идентичны, то никакого запроса отправлять не нужно, поскольку пользователь ничего не изменил в поле.
Итак, обратимся к событию blur, получим новое значение и сравним его с прежним:
1 2 3 4 5 6 7 8 9 | $('.edit').focus(function(){ oldVal = $(this).text(); id = $(this).data('id'); }).blur(function(){ newVal = $(this).text(); if(newVal != oldVal){ console.log("Отправляем запрос"); } }); |
Сейчас при изменении значения в любом из полей после потери фокуса полем, мы должны увидеть в консоли сообщение: Отправляем запрос.
Теперь напишем сам асинхронный запрос, обратившись к методу ajax():
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | blur(function(){ newVal = $(this).text(); if(newVal != oldVal){ $.ajax({ url: 'index.php', type: 'POST', data: {new_val: newVal, id: id}, success: function(res){ console.log(res); }, error: function(){ alert('Error!'); } }); } }); |
Итак, мы отправляем данные асинхронно методом POST в файл index.php. В случае успеха мы готовы принять некий ответ в переменную res и вывести ее содержимое в консоль. Теперь давайте примем эти данные и вернем какой-нибудь ответ, чтобы убедиться, что все работает.
В индексном файле после подключения файла функций добавим пару строк кода:
1 2 3 4 | if( isset($_POST['new_val']) ){ print_r($_POST); exit("Настройка сохранена"); } |
В качестве теста мы просто распечатаем содержимое массива POST. Теперь попробуем изменить значение. Если все сделано верно, то в консоли мы должны в качестве ответа увидеть распечатанный массив POST, в котором будут новое значение и ID изменяемой опции.
Теперь вместо распечатки массива давайте будем вызывать функцию, сохраняющую данные. Если функция будет возвращать ИСТИНУ, тогда вернем в ответе строку об успехе, иначе – сообщение об ошибке сохранения.

JavaScript. Быстрый старт
Изучите основы JavaScript на практическом примере по созданию веб-приложения
Узнать подробнее 1 2 3 4 5 6 7 | if( isset($_POST['new_val']) ){ if( update_option() ){ exit("Настройка сохранена"); }else{ exit("Ошибка сохранения"); } } |
И опишем функцию update_option() в файле functions.php:
1 2 3 4 5 6 7 8 9 10 11 12 | /** * обновление настройки **/ function update_option(){ global $db; $value = mysqli_real_escape_string($db, $_POST['new_val']); $id = (int)$_POST['id']; $query = "UPDATE options SET value = '$value' WHERE id = $id"; $res = mysqli_query($db, $query); if( mysqli_affected_rows($db) ) return true; else return false; } |
Здесь все предельно просто. Запрос UPDATE пытается обновить значение по ID поля. В случае успеха возвращаем TRUE, иначе – FALSE.
Вот практически и все. Если мы нигде не ошиблись, то опция должна сохраняться, а сообщение об успешном сохранении мы должны увидеть в консоли. Конечно же, хотелось бы видеть это сообщение не в консоли, а непосредственно на странице. Давайте это сделаем.
Для этого давайте добавим после таблицы несколько элементов верстки:
1 2 | <div id="loader"><span></span></div> <div id="mes-edit"></div> |
И опишем стили для них:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | #loader{ position:fixed; display:none; top:0; left:0; height:100%; width:100%; background:#f2f2f2; opacity:.9; z-index: 30; } #loader span{ display: block; background: url(../img/loader.gif); width: 128px; height: 15px; position: absolute; left: 50%; top: 50%; margin: -7px 0 0 -56px; } #mes-edit{ display: none; color: #000; font-size: 15px; border: 1px solid #ccc; box-shadow: 0 0 10px #ccc; padding: 10px; text-align: center; width: 400px; position: fixed; left: 50%; top: 50%; margin: -20px 0 0 -200px; font-weight: bold; background: #fff; } |
Новые элементы будут отвечать за показ сообщений с ответом от сервера. По задумке при отправке запроса на сервер мы будем затемнять страницу и показывать анимированную заставку, дающую понять, что идет сохранение данных. После сохранения данных мы вновь покажем страницу и вместе с этим покажем сообщение с ответом. Для этого добавим несколько строк кода внутрь запроса ajax:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | blur(function(){ newVal = $(this).text(); if(newVal != oldVal){ $.ajax({ url: 'index.php', type: 'POST', data: {new_val: newVal, id: id}, beforeSend: function(){ $('#loader').fadeIn(); }, success: function(res){ $('#mes-edit').text(res).delay(500).fadeIn(1000, function(){ $('#mes-edit').delay(1000).fadeOut(); }); }, error: function(){ alert('Error!'); }, complete: function(){ $('#loader').delay(500).fadeOut(); } }); } }); |
Теперь мы должны увидеть вывод сообщений на экран и анимацию всего процесса обновления опции.
Ну и напоследок. Если вы решите обновлять опцию не по событию blur, а по нажатию клавиши Enter (на мой взгляд это гораздо удобнее), то все, что нужно сделать, это описанный код использовать для клавиши Enter (ее код у нас уже есть). В таком случае итоговый код будет таким:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | $(function(){ var oldVal, newVal, id; $('.edit').focus(function(){ oldVal = $(this).text(); id = $(this).data('id'); }); $('.edit').keypress(function(e){ if(e.which == 13){ newVal = $(this).text(); if(newVal != oldVal){ $.ajax({ url: 'index.php', type: 'POST', data: {new_val: newVal, id: id}, beforeSend: function(){ $('#loader').fadeIn(); }, success: function(res){ $('#mes-edit').text(res).delay(500).fadeIn(1000, function(){ $('#mes-edit').delay(1000).fadeOut(); }); }, error: function(){ alert('Error!'); }, complete: function(){ $('#loader').delay(500).fadeOut(); } }); } return false; } }); }); |
На этом мы завершим текущий урок. Удачи и до новых встреч!

JavaScript. Быстрый старт
Изучите основы JavaScript на практическом примере по созданию веб-приложения
Узнать подробнее
Разработка веб-приложения на PHP
Скачайте видеокурс и узнайте, как создать веб-приложение на PHP
Скачать
тема — супер, подача материала — супер, но, к сожалению, сама идея без авторизации не прокатит (imho)
С уважением…
Ну да, конечно же, это только момент, который можно реализовать, скажем, в админке)
Доброго дня!
Андрей, может подскажите, я вот решил дальше пойти, и как раз тэг textarea не срабатывает на .blur(function()
то есть, когда вот ставишь <textarea data-id="» class=»description» contenteditable>
как только заменяешь textarea на div все ок. Но мне как раз нужно что бы был что бы видит html код.
Спасибо за помощь!
Здравствуйте, Анатолий.
У меня сразу же возник вопрос: зачем использовать атрибут contenteditable для текстовой области формы, если она итак доступна для редактирования? Относительно вопроса, то здесь нужно только смотреть код, возможно неверно обращаетесь к текстовой области или есть ошибки в верстке или скрипте. Посмотрите нет ли ошибок в консоли. Если не получится разобраться, тогда создайте тему на нашем форуме, прикрепите в архиве ваш код, попробую посмотреть.
Доброго дня!
Андрей, может подскажите, я вместо div поставил input type=»text» и ajax не срабатывает вобше не пойму почему !
Здравствуйте.отладку кода , по другому никак.
Нужно только смотреть консоль на предмет ошибок и производить
бееда в том сто в консоль вобше не че не приходит
В консоли проверяется не только то, что приходит, но и то, что отправляется. Если ничего не приходит, значит запрос AJAX не отправляется и, опять-таки, приходим к необходимости отладки кода.
здравствуйте
а как связаться автором?
Здравствуйте.
Для вопросов по урокам у нас есть форум.
Андрей здравствуйте статья пригодилась, а как быть если я не одно поле хочу редактировать а несколько, где указать какой столбец изменять? Запрос update.. переделать можно, не соображу, как передать имя поля для редактирования.
Здравствуйте, Екатерина.
Как вариант, можно использовать title (или ID) опции. Получаете его, передаете вместе с прочими данными на сервер и обновляете ту опцию, title (или ID) которой передан.
Никак не получается:(
Вот так обращаюсь к переменной, POST передает пустое pole
if ($(this).title = «Emes») {pole = «message»}
C web-программированием знакома совсем мало, может что то не так делаю…
Если с программированием знакомы мало, то реализовать задачу, к сожалению, будет довольно проблематично. Имя поля можно поместить, скажем, в атрибут data-name (как это делаем с ID) и получать его оттуда. Соответственно, в запросе update это поле будет подставлено в качестве имени поля таблицы. Также нужно не забывать о безопасности.
Все получилось, спасибо!!!
Пожалуйста)
Здравствуйте Андрей. В уроке Вы применили данный метод только для одного столбца. А как это можно реализовать для нескольких столбцов? Попробовал осуществить изменение столбца с заголовком(тот, что в Вашем примере), но когда я изменяю значение в первом столбце, стирается значение во втором. И наоборот. Не могли Вы показать на практике какие изменения нужно внести чтоб получить данный результат. Надеюсь на Вашу помощь. Спасибо.
Здравствуйте, Александр. Чуть выше в комментариях аналогичный вопрос задавала Екатерина, и я давал советы, как можно реализовать такую возможность. Возможно в дальнейшем запишу продолжение и покажу реализацию в уроке.
Андрей, спасибо Вам за очень полезный урок! Скажите, а возможно ли таким способом редактировать комментарии, которые Вы добавляете аяксом в курсе Создание каталога. Имею в виду комментарии, которые выведены без перезагрузки страницы. Можно ли их тут же отредактировать? Я пробую, но не получается пока. Редактируются только если обновить страницу.
Нужно пробовать, но, думаю, возможно. Не получается редактировать сразу, поскольку изначально данного элемента не было в DOM. Чтобы попробовать решить проблему, нужно смотреть в сторону делегирования событий. Вотурок по теме.
Спасибо, Андрей, но к сожалению не получается. Написала на форум.