Подсвечивать кнопку при изменении полей формы (HTML, jQuery)

При разработке web-приложений передо мной периодически встаёт задача узнать, изменились ли данные в полях html-формы с момента их последнего сохранения или нет.

Так как этими web-приложениями я пользуюсь сам, то часто бывает, вносишь что-то в поля, а потом пошёл пуэрчику попить, вернулся и не помнишь, то ли есть изменения в полях ввода, то ли нет.

Если бы кнопка "Обновить" меняла свой цвет при внесении изменений в заданные поля формы, напоминая, что данные нужно сохранить - было бы чудесно.

Предположим, что у нас на странице есть две группы полей, за изменениями в которых нужно следить и подсвечивать свою кнопку "Обновить" для каждой такой группы.

Типы полей в форме, естественно, могут быть разными это и input всех видов, и select, и textarea.

Например, имеем в html две такие группы полей:

<input class="savef1" type="text" id="txt1" value="данные">
<select class="savef1" id="sel">
<option value="1">Один</option>
<option value="2">Два</option>
<option value="3">Три</option>
</select>
<label><input type="radio" value="1" class="savef1" name="vop"/>Зима</label>
<label><input type="radio" value="2" class="savef1" name="vop"/>Лето</label>
<input id="upd1" type="button" value="Обновить" />

<textarea class="savef2" id="txar">еще данные</textarea>
<label><input class="savef2" id="vbr" type="checkbox"/>выбрать</label>
<input id="upd2" type="button" value="Обновить" />

Здесь полям из первой группы задаём class='savef1', для второй группы class='savef2'.

Кнопкам "Обновить", которым мы будем менять цвет фона, задаём атрибут id='upd1' - для первой группы и id='upd2' - для второй группы.

Следующий скрипт на jQuery занимается подсветкой кнопки "Обновить" для каждой группы полей в отдельности. И снимает подсветку, если данные в полях вернуть в исходное значение.

set_red('savef1', 'upd1'); // запомнить изначальные данные
$("body").on("change paste keyup", ".savef1", function () {chk_red('savef1', 'upd1');}); // подсветить кнопку при изменениях

set_red('savef2', 'upd2'); // запомнить изначальные данные
$("body").on("change paste keyup", ".savef2", function () {chk_red('savef2', 'upd2');}); // подсветить кнопку при изменениях

function chk_red(cls, btn) {
 var flg = 0;
 msv = $("#" + cls + '_cl').val();
 ms = JSON.parse(msv);
 $('.' + cls).each(function(i){
  var type = this.type || this.tagName.toLowerCase();
  if (type == 'checkbox') {zn = +$(this).prop('checked');}
  else if (type == 'radio') {zn = +$(this).prop('checked');}
  else {zn = $(this).val();}
  if (ms[i] != zn) {flg = 1; return false;} else {flg = 0;}
 });
 if (flg == 0) {$('#' + btn).css('background','buttonface');} else {$('#' + btn).css('background','#ff8080');}
}

function set_red(cls, btn) {
 $("#" + cls + '_cl').remove();
 let ms = [];
 $('.' + cls).each(function(i){
  var type = this.type || this.tagName.toLowerCase();
  if (type == 'checkbox') {zn = +$(this).prop('checked');}
  else if (type == 'radio') {zn = +$(this).prop('checked');}
  else {zn = $(this).val();}
  ms.push(zn);
 });
 mss = JSON.stringify(ms);
 $("<input>", {id: cls + "_cl", type: "hidden", value: mss}).appendTo("body");
 $('#' + btn).css('background','buttonface');
}

В случае если группы полей создаются динамически, то полям каждой группы нужно автоматически с помощью random задать уникальные class, и id кнопки "Обновить" по которым будет происходить дальнейшая сверка.

// создадим 10 групп полей, за изменениями в которых нужно следить и подсвечивать свою кнопку "Обновить" для каждой такой группы
for(var i = 0; i<=10; i++) {
 let nid = makeid(6); 
 let htm = '<textarea class="txar ' + nid + '">еще данные</textarea>
<label><input class="vbr ' + nid + '" type="checkbox"/>выбрать</label>
<input id="' + nid + '_bt" type="button" value="Обновить" />';
 $('body').append(htm); // запишем группу полей в конец body
 set_red(nid, nid + '_bt'); // запомнить изначальные данные
 $("body").on("change paste keyup", "." + nid, function () {chk_red(nid, nid + '_bt');}); // подсветить кнопку при изменениях
}

// генерирует случайный набор букв на английском
function makeid(length) {
 let result = '';
 const characters = 'abcdefghijklmnopqrstuvwxyz';
 const charactersLength = characters.length;
 let counter = 0;
 while (counter < length) {
  result += characters.charAt(Math.floor(Math.random() * charactersLength));
  counter += 1;
 }
 return result;
}

Если нужно подсвечивать кнопки Сохранить в нескольких новых окнах (попапы), то код будет выглядеть так:

let win = []; // хранит ссылки на попапы
for(var i = 1; i<=10; i++) {
 win_new(i); // создать 10 попапов
}

// создать попап
function win_new(id) {
 let bt = 'butt' + id;
 let sav = 'savv' + id;
 let win = window.open("", "_blank", "toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=500,height=300,top=100,left=200");
win.document.body.innerHTML = '<html><head><style></style><title>Название</title></head><body><div id="lnk"><button id="' + bt + '">Сохранить</button><textarea class="' + sav + '"></textarea></div></body></html>';
 let sav_el = $(win[id].document.body).find('.' + sav);
 let bt_el = $(win[id].document.body).find('#' + bt);
 set_red_win(sav, sav_el, bt_el); // запомнить изначальные данные для попапа

 // вносятся изменения в тело файла в попапе
 $(win[id].document.body).on("change paste keyup", "." + sav, function () {
  chk_red_win(sav, sav_el, bt_el); // подсветить кнопку при изменениях

 });
}

function chk_red_win(cls, sav_el, bt_el) {
 var flg = 0;
 msv = $("#" + cls + '_cl').val();
 ms = JSON.parse(msv);
 sav_el.each(function(i){
  var type = this.type || this.tagName.toLowerCase();
  if (type == 'checkbox') {zn = +$(this).prop('checked');}
  else if (type == 'radio') {zn = +$(this).prop('checked');}
  else {zn = $(this).val();}
  if (ms[i] != zn) {flg = 1; return false;} else {flg = 0;}
 });
 if (flg == 0) {bt_el.css('background','buttonface');} else {bt_el.css('background','#ff8080');}
}

function set_red_win(cls, sav_el, bt_el) {
 $("#" + cls + '_cl').remove();
 let ms = [];
 sav_el.each(function(i){
  var type = this.type || this.tagName.toLowerCase();
  if (type == 'checkbox') {zn = +$(this).prop('checked');}
  else if (type == 'radio') {zn = +$(this).prop('checked');}
  else {zn = $(this).val();}
  ms.push(zn);
 });
 mss = JSON.stringify(ms);
 $("<input>", {id: cls + "_cl", type: "hidden", value: mss}).appendTo("body");
 bt_el.css('background','buttonface');
}

Поделиться статьей:  

Читайте также статьи из ITИнтернет технологии:

Поделитесь своим мнением

Правила сообщений

Для оформления сообщений Вы можете использовать следующие тэги:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Хороший отзыв
Разумно · Дельно · Опытно · Идейно
Яндекс.Метрика
© 2016 - 2024 Хороший отзыв · Разумно · Дельно · Опытно · Идейно