Динамическая таблица на Javascript

514
10 сентября 2017, 02:57

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

body { 
  font-family: "Helvetica"; 
  font-size: medium; 
} 
 
table { 
  border-collapse: collapse; 
  text-align: center; 
  margin: auto; 
} 
 
table td, 
table th { 
  border: solid 1px #aaa; 
  padding: 10px; 
} 
 
table tbody tr:nth-child(2n) { 
  background: #a8d7ff; 
} 
 
table tbody tr:hover { 
  background: #fffcb6; 
}
<table width="350" border="1" cellspacing="0" cellpadding="5"> 
  <thead> 
    <tr> 
      <th scope="col">Поле 1</th> 
      <th scope="col">Поле 2</th> 
      <th scope="col">Поле 3</th> 
      <th scope="col">Поле 4</th> 
      <th scope="col">Поле 5</th> 
    </tr> 
  </thead> 
  <tbody id="dynamic"> 
    <tr> 
      <td><button type="button" class="add">+</button><button type="button" class="del">-</button></td> 
      <td></td> 
      <td></td> 
      <td></td> 
      <td></td> 
    </tr> 
  </tbody> 
</table> 
 
 
<script> 
  var DynamicTable = (function(GLOB) { 
    var RID = 0; 
    return function(tBody) { 
      /* Если ф-цию вызвали не как конструктор фиксим этот момент: */ 
      if (!(this instanceof arguments.callee)) { 
        return new arguments.callee.apply(arguments); 
      } 
      //Делегируем прослушку событий элементу tbody 
      tBody.onclick = function(e) { 
        var evt = e || GLOB.event, 
          trg = evt.target || evt.srcElement; 
        if (trg.className && trg.className.indexOf("add") !== -1) { 
          _addRow(trg.parentNode.parentNode, tBody); 
        } else if (trg.className && trg.className.indexOf("del") !== -1) { 
          tBody.rows.length > 1 && _delRow(trg.parentNode.parentNode, tBody); 
        } 
      }; 
      var _rowTpl = tBody.rows[0].cloneNode(true); 
      // Корректируем имена элементов формы 
      var _correctNames = function(row) { 
        var elements = row.getElementsByTagName("*"); 
        for (var i = 0; i < elements.length; i += 1) { 
          if (elements.item(i).name) { 
            if (elements.item(i).type && 
              elements.item(i).type === "radio" && 
              elements.item(i).className && 
              elements.item(i).className.indexOf("glob") !== -1) { 
              elements.item(i).value = RID; 
            } else { 
              elements.item(i).name = RID + "[" + elements.item(i).name + "]"; 
            } 
          } 
        } 
        RID++; 
        return row; 
      }; 
      var _addRow = function(before, tBody) { 
        var newNode = _correctNames(_rowTpl.cloneNode(true)); 
        tBody.insertBefore(newNode, before.nextSibling); 
      }; 
      var _delRow = function(row, tBody) { 
        tBody.removeChild(row); 
      }; 
      _correctNames(tBody.rows[0]); 
    }; 
  })(this); 
</script> 
<script> 
  new DynamicTable(document.getElementById("dynamic")); 
</script>

Answer 1

Никогда такого сам не делал, не судите строго :

var DynamicTable = (function(GLOB) { 
  var RID = 0; 
  return function(tBody) { 
    /* Если ф-цию вызвали не как конструктор фиксим этот момент: */ 
    if (!(this instanceof arguments.callee)) { 
      return new arguments.callee.apply(arguments); 
    } 
    //Делегируем прослушку событий элементу tbody 
    tBody.onclick = function(e) { 
      var evt = e || GLOB.event, 
        trg = evt.target || evt.srcElement; 
      if (trg.className && trg.className.indexOf("add") !== -1) { 
        _addRow(trg.parentNode.parentNode, tBody); 
      } else if (trg.className && trg.className.indexOf("del") !== -1) { 
        tBody.rows.length > 1 && _delRow(trg.parentNode.parentNode, tBody); 
      } 
      // то что я добавил 
      if (trg.className && trg.className.indexOf("edit") !== -1) { 
        var tds = trg.closest('tr').children; 
        for (var i = 0; i < tds.length; i++) { 
          if (tds[i].className.indexOf("buttons") == -1) { 
            var input = tds[i].getElementsByTagName('input')[0]; 
            var lbl = tds[i].getElementsByTagName('label')[0]; 
            input.value = lbl.textContent; 
            input.classList.remove("invisible"); 
            lbl.classList.add("invisible"); 
          } else { 
            var buttons = tds[i].children; 
            for (var j = 0; j < buttons.length; j++) { 
              if (buttons[j].className.indexOf("save") !== -1) { 
                buttons[j].disabled = false; 
                break; 
              } 
            } 
          } 
        } 
      } 
 
      if (trg.className && trg.className.indexOf("save") !== -1) { 
        var tds = trg.closest('tr').children; 
        for (var i = 0; i < tds.length; i++) { 
          if (tds[i].className.indexOf("buttons") == -1) { 
            var input = tds[i].getElementsByTagName('input')[0]; 
            var lbl = tds[i].getElementsByTagName('label')[0]; 
            lbl.textContent = input.value; 
            input.classList.add("invisible"); 
            lbl.classList.remove("invisible"); 
          } else { 
            var buttons = tds[i].children; 
            for (var j = 0; j < buttons.length; j++) { 
              if (buttons[j].className.indexOf("save") !== -1) { 
                buttons[j].disabled = true; 
                break; 
              } 
            } 
          } 
        } 
      } 
    }; 
    // тут конец того что я добавил  
 
    var _rowTpl = tBody.rows[0].cloneNode(true); 
    // Корректируем имена элементов формы 
    var _correctNames = function(row) { 
      var elements = row.getElementsByTagName("*"); 
      for (var i = 0; i < elements.length; i += 1) { 
        if (elements.item(i).name) { 
          if (elements.item(i).type && 
            elements.item(i).type === "radio" && 
            elements.item(i).className && 
            elements.item(i).className.indexOf("glob") !== -1) { 
            elements.item(i).value = RID; 
          } else { 
            elements.item(i).name = RID + "[" + elements.item(i).name + "]"; 
          } 
        } 
      } 
      RID++; 
      return row; 
    }; 
    var _addRow = function(before, tBody) { 
      var newNode = _correctNames(_rowTpl.cloneNode(true)); 
      tBody.insertBefore(newNode, before.nextSibling); 
    }; 
    var _delRow = function(row, tBody) { 
      tBody.removeChild(row); 
    }; 
    _correctNames(tBody.rows[0]); 
  }; 
})(this); 
 
document.addEventListener('DOMContentLoaded', function() { 
  new DynamicTable(document.getElementById("dynamic")); 
});
body { 
  font-family: "Helvetica"; 
  font-size: medium; 
} 
 
table { 
  border-collapse: collapse; 
  text-align: center; 
  margin: auto; 
} 
 
table td { 
  padding: 0px; 
  height: 30px; 
  width: 140px; 
} 
 
table td input, 
table td label { 
  width: 100%; 
  height: 100%; 
  border: none; 
  text-align: center; 
  font-size: 16px; 
} 
 
table tbody tr:nth-child(2n), 
table tbody tr:nth-child(2n) input { 
  background: #a8d7ff; 
} 
 
table tbody tr:hover { 
  background: #fffcb6; 
} 
 
table tbody tr:hover input { 
  background: #fffcb6; 
} 
 
table tbody input:hover { 
  background: #ffd3b6 !important; 
} 
 
table tbody input:active { 
  background: #c27949 !important; 
} 
 
.tblBtn { 
  width: auto; 
  height: 20px; 
} 
 
.buttons { 
  width: 150px; 
} 
 
.invisible { 
  display: none; 
}
<table border="1" cellspacing="0" cellpadding="5"> 
  <thead> 
    <tr> 
      <th class="buttons" scope="col">Buttons</th> 
      <th scope="col">Поле 2</th> 
      <th scope="col">Поле 3</th> 
      <th scope="col">Поле 4</th> 
      <th scope="col">Поле 5</th> 
    </tr> 
  </thead> 
  <tbody id="dynamic"> 
    <tr> 
      <td class="buttons"> 
        <button type="button" class="tblBtn add">+</button><button type="button" class="tblBtn del">-</button> 
        <button type="button" class="tblBtn edit">Edit</button><button type="button" class="tblBtn save" disabled="disabled">Save</button> 
      </td> 
      <td><input type="text" class="invisible" /><label>1</label></td> 
      <td><input type="text" class="invisible" /><label>12</label></td> 
      <td><input type="text" class="invisible" /><label>123</label></td> 
      <td><input type="text" class="invisible" /><label>1234</label></td> 
    </tr> 
  </tbody> 
</table>

Опишу вкратце что я сделал, в каждый td в таблице я добавил input(для редактирования) label(для хранения результата). Соответственно при клике на кнопку edit значение с лейбола пишем в инпут, лейбл скрываем, инпут показываем, при сохранении наоборот.

READ ALSO
Разница в поведении между let и var в цикле for

Разница в поведении между let и var в цикле for

Разница в объявлении счетчика цикла через let и var в том что через var переменная-счетчик видна за пределами цикла в функции, через let - только...

326
Иконка аватара без потери качества

Иконка аватара без потери качества

Добрый День! Столкнулся с проблемойСуществуют ли способы сохранения качества аватара без потери качества изображения? Проблема заключается...

315
memcached не принимает большие данные

memcached не принимает большие данные

Есть большой json-файл(примерно, 7,5 мегабайт), который подгружается с диска и декодируется примерно 3 секундыЯ захотел это исправить и положить...

306