Одноэлементная таблица встроенного редактирования Angular

Я пытаюсь создать встроенное редактирование для таблицы (аналогично angular-xeditable ), но я хочу разрешить редактирование только одной строки за раз. В настоящее время вы можете любое количество строк быть в режиме редактирования.

Параметры

  1. Держите список строк в режиме редактирования, и как только новая строка будет выбрана для редактирования, выполните цикл по списку и принудительно выйдите из режима редактирования, поместите строку запроса в режим редактирования и добавьте ее в список. По сути, это позволит содержать не более 1 строки в списке, что приведет к возможности редактирования одной строки за раз. Но я не показываю, как вывести строки из режима редактирования.

  2. Есть кнопка отмены, которая выходит из режима редактирования. Так что, возможно, используйте jquery (или angular.element), чтобы получить список всех кнопок отмены и прагматично щелкнуть их - опять же, принудительно выйдя из строк в режиме редактирования, но это может замедлить работу для большой таблицы, поскольку она будет нажимать кнопку отмены на строки, которые даже не находятся в режиме редактирования.

<table class="table table-striped">
<thead>
  <tr>
    <th id="th-name">Name</th>
    <th id="th-age">Age</th>
    <th id="th-actions">Actions</th>
  </tr>
</thead>
<tr ng-repeat="contact in model.contacts">
  <td>
    <span ng-show="edit != true">{{contact.name}}</span>
    <input ng-show="edit" type="text" ng-model="model.selected.name" class="form-control" placeholder="Name">
  </td>
  <td>
    <span ng-show="edit != true">{{contact.age}}</span>
    <input ng-show="edit" type="text" ng-model="model.selected.age" class="form-control" placeholder="Name"></td>
  <td>
    <button ng-show="edit != true" id="table-edit" ng-click="edit = true; editContact(contact)" uib-tooltip="Delete" tooltip-trigger="mouseenter" tooltip-placement="bottom"><i class="fa fa-fw fa-pencil"></i></button>
    <button ng-show="edit" id="table-save" ng-click="edit = false; saveContact($index)" uib-tooltip="Delete" tooltip-trigger="mouseenter" tooltip-placement="bottom"><i class="fa fa-fw fa-floppy-o"></i></button>
    <button ng-show="edit" id="table-cancel" ng-click="edit = false; reset()" uib-tooltip="Delete" tooltip-trigger="mouseenter" tooltip-placement="bottom"><i class="fa fa-fw fa-trash"></i></button>
  </td>
</tr>
</table>

Вот демонстрация plunker (позволяет всем строкам быть в режиме редактирования): Plnkr Demo`

Вот рабочая демонстрация того, чего я хочу достичь, но она использует шаблоны. На мой взгляд, он вызывает getTemplate слишком много раз (вызывает его каждый раз, когда запускается дайджест — нажатие кнопок, ввод текста, отображение всплывающей подсказки). Рабочая демонстрация (с использованием шаблонов)


person Mohammad Ali    schedule 06.09.2016    source источник


Ответы (2)


Я смог получить желаемый результат, обновив функции editContact и reset до следующего:

$scope.editContact = function(contact, event) {
  // Nothing first time, but will have an element second time
  $timeout(function() {
    // Click the element and remove the class since it is not in edit mode anymore
    angular.element('.row-edit-mode').triggerHandler('click');
    angular.element('.row-edit-mode').removeClass('row-edit-mode');

    // If it is not a button, then it is the fa-icon, so get its parent, which is a button
    var eventElement = angular.element(event.target).is('button') ? event.target : event.target.parentNode;
    // Find it's sibling with given id, and add a class to it
    angular.element(eventElement).siblings("#table-cancel").addClass('row-edit-mode')

    $scope.model.selected = angular.copy(contact);
  });
};

$scope.reset = function() {
  // Remove class on cancel
  angular.element('.row-edit-mode').removeClass('row-edit-mode');
  $scope.model.selected = {};
};

http://plnkr.co/edit/vAACyxv2bE0li5muefsQ?p=preview

Я все еще вижу небольшое мерцание между переключателями, поэтому, если у кого-то есть предложения сделать его более плавным, я буду очень признателен.

Если я не увижу других ответов, которые приведут к желаемому результату в течение нескольких дней, я отмечу этот ответ как принятый. Спасибо всем, кто предложил помощь!

person Mohammad Ali    schedule 07.09.2016

Вы можете передать индекс операции ng-repeat вашей функции editContact следующим образом, используя переменную $index (уже встроенную в операцию ng-repeat):

 <button class="edit-btn" ng-show="edit != true" id="table-edit" ng-click="edit = true; editContact(contact, $index);" uib-tooltip="Delete" tooltip-trigger="mouseenter" tooltip-placement="bottom"><i class="fa fa-fw fa-pencil"></i></button>

Обратите внимание, что я также дал кнопке имя класса!!

Затем в вашем файле app.js вы можете установить отображение других кнопок на none, когда одна кнопка срабатывает для редактирования. Затем, когда редактирование будет сохранено, установите отображение на блокировку:

var eles = document.getElementsByClassName('edit-btn');

$scope.editContact = function (contact, ind) {

    $scope.model.selected = angular.copy(contact);

    //remove display of other buttons
    for(var i = 0; i < eles.length; i++){
      if(i != ind){
        eles[i].style.display = "none";
      }
    }

};

$scope.saveContact = function (idx) {
    console.log("Saving contact");
    $scope.model.contacts[idx] = angular.copy($scope.model.selected);

    //redo display of all buttons
    for(var i = 0; i < eles.length; i++){
        eles[i].style.display = "block";
    }

    $scope.reset();
};

Вы можете видеть, что внутри кнопки editContact переменная ind является индексом текущей нажатой кнопки редактирования.

Вот плункер: http://plnkr.co/edit/N9EKErLJkFR5TwEzImNP?p=preview

person A.Sharma    schedule 06.09.2016
comment
Хороший обходной путь. Я переместил ваш цикл «повторить отображение» в функцию сброса, поскольку при отмене редактирования также должны отображаться все кнопки (plnkr .co/edit/mTa8EPmuwEOw1DBHLAHN?p=preview). Но, как вы можете видеть из демонстрации с использованием шаблонов, идеальным ожиданием было бы отображение всех кнопок и возможность редактирования других строк без необходимости сохранения/отмены. - person Mohammad Ali; 06.09.2016
comment
Просто измените элемент, чтобы показать и скрыть (eles), чтобы он был текстовым полем ввода. Кроме того, вам нужно будет добавить имя класса для промежутков, содержащих контент. Хотя логика должна быть такой же. - person A.Sharma; 06.09.2016
comment
Это все еще не дает желаемого результата (отображения всех данных и кнопок и возможности щелкнуть любую кнопку редактирования, чтобы войти в режим редактирования для соответствующей строки). Пожалуйста, смотрите мой ответ, и если у вас есть какие-либо отзывы, это очень приветствуется и ценится! Спасибо за вашу помощь! - person Mohammad Ali; 07.09.2016