87941631 2014-11-06
Front End Start(4)knockoutjs Paged List and Creation
knockoutjs CRUD
http://sillycat.iteye.com/blog/2152090
http://sillycat.iteye.com/blog/2152092
1. Paged List
http://tech.pro/tutorial/1235/handling-paged-datasets-in-knockoutjs
http://jsfiddle.net/rniemeyer/5Xr2X/
Here is the Key features for Pager
function Metro(data) {
this.name = ko.observable(data.name);
this.path = ko.observable(data.path);
this.latitude = ko.observable(data.latitude);
this.longitude = ko.observable(data.longitude);
}
function MetroListViewModel() {
// Data
var self = this;
self.items = ko.observableArray([]);
//Loading
Auth.request({
type: 'GET',
url: "/data/metros.json",
success: function(allData) {
var mappedItems = $.map(allData, function(item) {
return new Metro(item)
});
self.items(mappedItems);
}
});
// pager related stuff
// ---------------------------------------------
this.currentPage = ko.observable(1);
this.perPage = 2;
this.pagedItems = ko.computed(function(){
var pg = this.currentPage(),
start = this.perPage * (pg-1),
end = start + this.perPage;
return this.items().slice(start,end);
}, this);
this.nextPage = function(){
if(this.nextPageEnabled())
this.currentPage(this.currentPage()+1);
};
this.nextPageEnabled = ko.computed(function(){
return this.items().length > this.perPage * this.currentPage();
},this);
this.previousPage = function(){
if(this.previousPageEnabled())
this.currentPage(this.currentPage()-1);
};
this.previousPageEnabled = ko.computed(function(){
return this.currentPage() > 1;
},this);
}
ko.applyBindings(new MetroListViewModel());
The HTML using bootstrap
<h1>Metros list
<a href="#" class="btn btn-primary pull-right">
Create
</a>
</h1>
<ul class="pager">
<li data-bind="css: {'disabled': !previousPageEnabled()}" class="previous">
<a data-bind="click: previousPage" href="#">← Previous</a>
</li>
<li data-bind="css: {'disabled': !nextPageEnabled()}" class="next">
<a data-bind="click: nextPage" href="#">Next →</a>
</li>
</ul>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Name</th>
<th>Path</th>
<th>Latitude</th>
<th>Longitude</th>
<th>Actions</th>
</tr>
</thead>
<tbody data-bind="foreach: pagedItems, visible: items().length > 0">
<tr>
<td class="col-md-3">
<a href="#" data-bind="click: $parent.viewItem">
<span data-bind="text: name" />
</a>
</td>
<td class="col-md-3"><span data-bind="text: path" /></td>
<td class="col-md-2"><span data-bind="text: latitude" /></td>
<td class="col-md-2"><span data-bind="text: longitude" /></td>
<td class="col-md-6">
<div class="btn-group">
<a class="btn btn-primary" href="#" data-bind="click: $parent.editItem"> Edit
</a>
<button class="btn btn-primary dropdown-toggle" data-toggle="dropdown">
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li><a href="#"
data-bind="click: $parent.delItem">
Delete
</a>
</li>
</ul>
</div>
</td>
</tr>
</tbody>
</table>
<ul class="pager">
<li data-bind="css: {'disabled': !previousPageEnabled()}" class="previous">
<a data-bind="click: previousPage" href="#">← Previous</a>
</li>
<li data-bind="css: {'disabled': !nextPageEnabled()}" class="next">
<a data-bind="click: nextPage" href="#">Next →</a>
</li>
</ul>
2. Other CRUD Operation
Binding
http://knockoutjs.com/documentation/foreach-binding.html
http://knockoutjs.com/documentation/with-binding.html
Confirm and Popup Window
http://jsfiddle.net/J4UWX/
http://jsfiddle.net/rniemeyer/CLxsV/
http://stackoverflow.com/questions/25034120/knockout-js-implementing-delete-confirmation-box-on-delete-click
Edit and Popup Window
http://jsfiddle.net/rniemeyer/WpnTU/
http://cgeers.com/2012/10/06/single-page-application-with-knockout-js-part-1/
For Create
<a data-bind="click: $parent.editItem" href="#" class="btn btn-primary pull-right">
Create
</a>
<div data-bind="with: itemCreateView">
<form data-bind="submit: $parent.itemSave" class="form-horizontal" role="form">
<div class="form-group">
<label for="input1" class="col-sm-1 control-label"> </label>
<h1 class="text-left">Metro Creation</h1>
</div>
<div class="form-group">
<label for="input2" class="col-sm-1 control-label">Name</label>
<div class="col-sm-5">
<input data-bind="value: name, enable: actionType != 'view'"
class="form-control" id="input2" placeholder="name">
<input data-bind="value: id" type="hidden"/>
</div>
</div>
<div class="form-group">
<label for="input3" class="col-sm-1 control-label">Path</label>
<div class="col-sm-5">
<input data-bind="value : path,enable: actionType != 'view'"
class="form-control" id="input3" placeholder="path">
</div>
</div>
<div class="form-group">
<label for="input4" class="col-sm-1 control-label">Latitude</label>
<div class="col-sm-5">
<input data-bind="value : latitude, enable: actionType != 'view'"
class="form-control" id="input4" placeholder="latitude">
</div>
</div>
<div class="form-group">
<label for="input5" class="col-sm-1 control-label">Longitude</label>
<div class="col-sm-5">
<input data-bind="value : longitude, enable: actionType != 'view'"
class="form-control" id="input5" placeholder="longitude">
</div>
</div>
<div class="form-group">
<div data-bind="ifnot: actionType == 'view'" class="col-sm-offset-1 col-sm-1">
<button type="submit" class="btn btn-primary btn-lg active">
<span data-bind="if: actionType == 'create'">
Create
</span>
<span data-bind="if: actionType == 'update'">
Update
</span>
</button>
</div>
<div class="col-sm-offset-1 col-sm-1">
<button data-bind="click: $parent.itemList"type="button" class="btn btn-default btn-sm active">Back</button>
</div>
</div>
</form>
</div>
function MetroListViewModel() {
var self = this;
…snip...
self.id = ko.observable();
self.name = ko.observable();
self.path = ko.observable();
self.latitude = ko.observable();
self.longitude = ko.observable();
self.actionType = 'create';
self.editItem = function(data) {
self.itemListView(null);
if(data.id() == undefined){
data.actionType = 'create';
}else{
data.actionType = 'update';
}
self.itemCreateView(data);
};
self.itemSave = function() {
var id = this.id();
if(id == undefined){
$.ajax({
type: 'POST',
url: parameters.api.host + "/api/v1/metros.json",
data: {
"campeasy_campeasyshared_metrotype[name]": this.name(),
"campeasy_campeasyshared_metrotype[path]": this.path(),
"campeasy_campeasyshared_metrotype[latitude]": this.latitude(),
"campeasy_campeasyshared_metrotype[longitude]": this.longitude()
},
success: function() {
self.itemList();
}
});
}else{
…for UPDATE...
}
};
3. Sammy.js
http://learn.knockoutjs.com/#/?tutorial=webmail
http://sammyjs.org/
TODO...
4. jquery-deparam
https://github.com/AceMetrix/jquery-deparam
TODO...
5. momentjs
http://momentjs.com/
TODO...
References:
https://github.com/AceMetrix/jquery-deparam
http://momentjs.com/