ajax tests
testing ko.toJS and $.ajax
by Jorgelig
HTML
<link rel="stylesheet" href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css">
<script src="http://twitter.github.com/bootstrap/assets/js/bootstrap-tooltip.js"></script>
<script src="http://github.com/downloads/SteveSanderson/knockout/knockout-2.1.0.debug.js"></script>
<script src="https://github.com/downloads/rniemeyer/knockout-sortable/knockout-sortable.js"></script>
<div class="widget">
<div class="person_editor">
<div class="header" data-bind="with:person">
<h1>Edit Person</h1>
<span data-bind="text: id"></span>:
<span data-bind="text: name"></span>
<span class="spinner" data-bind="visible:$root.isSearching">Running AJAX...</span>
</div>
<div class="body">
<form data-bind="submit:savePerson, with:person">
<div class="field control-group" data-bind="dirty:name">
<label>Name</label>
<div><input type="text" data-bind="value:name, valueUpdate:'afterkeydown'" placeholder="Enter person name" /></div>
</div>
<div class="field control-group" data-bind="dirty:pushStatus">
<label>Push Status</label>
<div>
<select data-bind="
optionsCaption: 'Choose...',
options: push_status_values,
optionsValue: 'id',
optionsText: 'name',
value: pushStatus"></select>
</div>
</div>
<div class="field control-group" data-bind="dirty:hasHeadshot">
<label>Has Headshot</label>
<div>
<input type="checkbox" data-bind="checked: hasHeadshot" value="Y"/>
</div>
</div>
<div class="field control-group" data-bind="dirty:biography">
...
CSS
body {
padding: 5px;
margin: 5px;
font-family: "helvetica", sans-serif
}
.spinner {
XXXdisplay:none;
margin-left:3px;
}
.widget {
border: 5px solid lightblue;
border-radius: 1em;
-moz-box-shadow: 3px 3px 5px black;
-webkit-box-shadow: 3px 3px 5px black;
box-shadow: 3px 3px 5px black;
--width:20em;
min-height:100px;
}
.widget .header {
display:block;
padding:5px;
border-top-left-radius:0.7em;
border-top-right-radius:0.7em;
border-bottom: 1px solid lightblue;
background: -moz-linear-gradient(top, #f2f6f8 0%, #d8e1e7 50%, #b5c6d0 51%, #e0eff9 100%); /* FF3.6+ */
}
.widget .header h1 {
display:inline;
marin-right: 2em;
font-weight:bold;
font-size:150%;
}
.widget .header form {
display:inline;
}
.widget .header .searchStatus {
font-size: 75%
}
.widget .body {
display:block;
}
.widget textarea {
Xborder-radius: 3px 3px 3px 3px;
padding: 0.3em;
width: 100%;
height: 100%;
}
.widget .field {
width: 100%;
}
.widget .field:before, .widget .field:after {
display: table;
content: "";
}
.widget .field:after {
clear: both;
}
.widget .field label, .widget .field div {
display: block;
float: left;
height: 100%;
Xwidth: 10em;
Xpadding: 0.3em;
padding-left: 0.3em;
padding-right: 0.3em;
Xmargin-bottom: 0.5em;
}
.widget .field label {
text-align: right;
border-right: 2px solid lightgrey;
width: 5em;
}
.widget .field label:after {
Xcontent: ':';
}
.widget .field div {
text-align: left;
border-left: 2px solid lightgrey;
margin-left:-2px;
width: 25em;
}
.widget .sortable {
padding: 0px;
margin: 0px;
list-style-type: none;
}
.widget .sortable-placeholder {
border: 2px dotted grey;
background-color: lightgrey;
}
.widget .sortable-item {
border: 2px solid transparent;
}
.widget .sortable-item .handle {
cursor: move;
border: 2px dotted grey;
...
JavaScript
function ajaxGateway (watcher) {
var self = this;
var isRunning = watcher;
// JSON method wrapper
self.postAjaxData = function(validationCallback, url, data) {
if (watcher) isRunning(true);
//alert("firing json");
// jQuery
// $.post(url,data,validationCallback);
console.log("Preparing AJAX data=",data);
if(ko.isObservable(data)) data = ko.toJS(data);
console.log("Sending AJAX data=",data);
$.ajax({
type: "POST",
url: url,
data: ko.toJS(data),
contentType: "application/json",
success: function(data, status) {
// execute this code once the asynch JSON call completes
if (watcher) isRunning(false);
validationCallback(data, status);
},
error: self.handleJsonError
});
};
self.handleJsonError = function (jqXHR, textStatus, errorThrown){
if (watcher) isRunning(false);
var msg = textStatus + (errorThrown) ? ": " + errorThrown : "";
alert("Failure due to " + msg)
};
};
function Person(data) {
var self = this;
ConvertMapToObservables(data, this); // use ko Mapping ext instead ?
/*
this.id = ko.observable(data.id);
this.name = ko.observable(data.name);
this.pushStatus = ko.observable(data.pushStatus);
this.hasHeadshot = ko.observable(data.pushStatus);
*/
self.addAlias = function(alias) {
alias = $.trim(alias);
self.aliases.push( { id:0, name:alias } );
}
}
function PersonEditorViewModel(init_data) {
// Data
var self = this;
self.person = ko.observable(new Person(init_data));
self.push_status_values = ko.observableArray(push_status_values);
self.alias = ko.observable("");
self.isSearching = ko.observable(false);
var slide_triggered_by_add = false; // flag to enable alias animations
// custom Heavy Meta ajax object
...