Z poprzedniego wpisu mamy formularz, który jest połączony z listą z danymi. Dane są automatycznie przepisywane. Teraz chcielibyśmy, aby nie było ograniczenia co do wierszy. Zróbmy więc tak, żebyśmy mogli dodawać je dynamicznie, podczas działania aplikacji.
Dodawanie wiersza przyciskiem
Pod tabelą dodajmy przycisk:
1 |
<button ng-click="addItem()">Add</button> |
Skorzystaliśmy z dyrektywy ng-click
, której parametrem jest przypisana funkcja addItem()
(działa to bardzo podobnie do zwykłej metody onclick
w czystym JavaScript).
Przejdźmy zatem do definicji funkcji:
1 2 3 |
$scope.addItem = function(){ $scope.list.push({title: "", name: "", surname: ""}); }; |
Nie ma tu nic zaskakującego (jeśli ktoś czytał poprzedni wpis). Po prostu na listę dodajemy kolejny obiekt (z wypełnionymi pustymi danymi). Dzięki temu pojawi się kolejny wiersz z polami do wpisywania. Mało pracy, a dobry efekt.
Usuwanie wiersza przyciskiem
Dodajmy kolejną kolumnę w tabeli (czyli komórkę <td>
powtarzaną w wierszach <tr>
), a w niej przycisk z teksem minus:
1 |
<button ng-click="list.splice($index, 1)">-</button> |
Tak samo korzystamy tu z dyrektywy ng-click
. Jednak tym razem nie wywołujemy funkcji z kontrolera, tak jak to było w przypadku dodawania wiersza. Jeśli fragment kodu jest mały, możemy go od razu umieścić w tym samym miejscu. Z listy usuwamy ten element, w którym został kliknięty przycisk. Do usuwania z listy w JavaScript służy metoda splice
. Pierwszym parametrem jest od którego elementu mają być usuwane, a drugim, ile elementów ma być usuniętych (w tym wypadku jeden). Aby otrzymać numer elementu, w którym jest przycisk, wystarczy skorzystać z $index (jest to dostępne dzięki temu, że ng-repeat
tworzy swój własny, „lokalny” scope).
Automatyczne dodawanie wiersza, gdy jest ostatni
Dodajmy jeszcze jedną funkcjonalność, która poprawi komfort z korzystania z aplikacji. AngularJS sam do tego zachęca, gdyż często dobre efekty można uzyskać stosunkowo małym kosztem.
Niech nowy wiersz dodaje się automatycznie, gdy klikniemy ostatni (wtedy będzie wiadomo, że użytkownikowi zaczyna brakować miejsca).
W wierszu tabeli <tr>
dodajmy kolejną dyrektywę (po za istniejącą już ng-repeat
): ng-click="$last && addItem()"
. Po kliknięciu wiersza wykona się to co w niej jest umieszczone. Najpierw jest umieszczona właściwość $last
(dostępna z lokalnego $scope
). Przyjmuje wartość true
, jeśli aktualnym (klikniętym) elementem jest ostatni. Wtedy wykonuje się również to co jest po operatorze and oznaczonym podwójnym ampersandem czyli funkcja addItem()
(ta sama co po kliknięciu przycisku Add).
Wynik
index.html
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 |
<!DOCTYPE html> <html ng-app="agendaEditor"> <head> <meta charset="UTF-8"> <title>Form AgendaEditor</title> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js"></script> <script src="controller.js"></script> </head> <body ng-controller="formCtrl"> <h2>Form AgendaEditor</h2> <table> <tr> <td>Title</td> <td>Name</td> <td>Surname</td> <td></td> </tr> <tr ng-repeat="item in list" ng-click="$last && addItem()"> <td><input type="text" ng-model="item.title"></td> <td><input type="text" ng-model="item.name"></td> <td><input type="text" ng-model="item.surname"></td> <td ng-if="!$first"><button ng-click="list.splice($index, 1)">-</button></td> </tr> </table> <button ng-click="addItem()">Add</button><br /> Wynik: <div ng-repeat="item in myResult() track by $index">{{item}}<br /></div> </body> </html> |
controlller.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
var app = angular.module('agendaEditor', []); app.controller('formCtrl', function($scope) { $scope.list = []; $scope.list.push({title: "", name: "", surname: ""}); $scope.myResult = function () { var result = []; for (var i = 0; i < $scope.list.length; i++) { var concat = $scope.list[i].title + "” – " + $scope.list[i].name + " " + $scope.list[i].surname; if($scope.list[i].title !== ""){ result.push(concat); } } return result; }; $scope.addItem = function(){ $scope.list.push({title: "", name: "", surname: ""}); }; }); |
Wynik działania:
Kod na GitHub
Kod tej części aplikacji umieściłem na GitHubie w repozytorium agenda-editor
w branchu form-angularjs
:
https://github.com/mkczyk/agenda-editor/tree/form-angularjs
Pingback: Podpięcie Bootstrapa do AngularJS | Marcin Kowalczyk – Blog IT
Pingback: Podsumowanie projektu AgendaEditor 2016 – Marcin Kowalczyk – Blog IT
Witam, jak wyświetlić konkretny element z listy w wynikach? Np. wartość pola Name znajdującego się w drugim wierszu?