От автора: в этом мы продолжим работу с атрибутом HTML5 contenteditable. При изменении значения редактируемого поля, скрипт будет отправлять асинхронным запросом (средствами AJAX) новое значение, и сохранять его в БД.
Итак, мы остановились на том, что при получении полем со значением фокуса, получаем имеющееся в нем значение и ID данной опции. Следующее событие, с которым мы будем работать, это событие blur, которое наступает при потере полем фокуса. Иными словами, мы будем отслеживать событие, когда пользователь кликнет вне редактируемого поля.
После этого нам нужно получить новое значение поля и обязательно сравнить его с предыдущим (тем, которое взяли при получении элементом фокуса). Если эти значения будут отличаться, то это значит, что пользователь изменил значение, и мы можем отправлять новое значение на сервер для его сохранения. Если же значения будут идентичны, то никакого запроса отправлять не нужно, поскольку пользователь ничего не изменил в поле.
Итак, обратимся к событию 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 изменяемой опции.
Теперь вместо распечатки массива давайте будем вызывать функцию, сохраняющую данные. Если функция будет возвращать ИСТИНУ, тогда вернем в ответе строку об успехе, иначе – сообщение об ошибке сохранения.
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; } }); }); |
На этом мы завершим текущий урок. Удачи и до новых встреч!
Комментарии (21)