extends base block append head title Users block content div.container h1 Users hr form input[type="text"][placeholder="ie octocat"][data-bind="value: newUserLogin"] button[type="button"][data-bind="click: addUser"] add user hr if len(Users) <= 1 div.alert.alert-info | You should add users table tbody[data-bind="foreachInit: users"] tr[data-template] td[data-bind="text: $data.login"] td[data-bind="text: $data.email"] td[data-bind="text: $data.avatar_url"] td[data-bind="text: $data.active"] td[data-bind="text: $data.admin"] td button.delete[data-bind="click: $parent.removeUser"] delete td button.delete[data-bind="click: $parent.toggleAdmin"] toggle each $user in Users tr[data-init] td[data-bind="init, text: login"] #{$user.Login} td[data-bind="init, text: email"] #{$user.Email} td[data-bind="init, text: avatar_url"] #{$user.Avatar} td[data-bind="init, text: active"] #{$user.Active} td[data-bind="init, text: admin"] #{$user.Admin} td button.delete[data-bind="init, click: $parent.removeUser"] delete td button.delete[data-bind="init, click: $parent.toggleAdmin"] toggle block append scripts script function User(data) { this.login = ko.observable(data.login); this.email = ko.observable(data.email); this.avatar_url = ko.observable(data.avatar_url); this.active = ko.observable(data.active); this.admin = ko.observable(data.admin); } function UserViewModel() { var self = this; self.users = ko.observableArray(); self.newUserLogin = ko.observable(); self.removeUser = function(user) { $.ajax({ url: "/api/users/"+user.login(), type: "DELETE", success: function( data ) { self.users.remove(user); self.users.sort(self.sort); } }); }; self.addUser = function() { $.ajax({ url: "/api/users", type: "POST", data: ko.toJSON({ "login": self.newUserLogin() }), contentType: "application/json", success: function( data ) { self.newUserLogin(""); self.users.push(new User(data)); self.users.sort(self.sort); } }); }; self.toggleAdmin = function(user) { user.admin(!user.admin()); $.ajax({ url: "/api/users/"+user.login(), type: "PATCH", data: ko.toJSON(user), contentType: "application/json" }); }; self.sort = function(a, b) { return a.login().toLowerCase() > b.login().toLowerCase() ? 1 : -1; }; } ko.applyBindings(new UserViewModel());