preliminary dashboard ui

master
Steve L. Nyemba 8 years ago
parent ef7136b5a0
commit fd175565bb

@ -0,0 +1,21 @@
body {
font-size:14px;
font-family:sans-serif;
font-weight:lighter;
}
.small {
font-family:verdana;
font-size:12px;
color: gray;
font-weight:lighter;
}
.left {float:left}
.right{float:right}
.caption {
font-size:22px;
margin:4px;
padding:4px;
height:24px;
font-family:sans-serif;
}

@ -0,0 +1,11 @@
<link type="text/css" rel="stylesheet" href="{{ context }}/js/jsgrid/jsgrid.min.css" />
<link type="text/css" rel="stylesheet" href="{{ context }}/js/jsgrid/jsgrid-theme.min.css" />
<script src="{{ context }}/static/js/jsgrid.js"></script>
<script src="{{ context }}/static/js/jquery/jquery.min.js"></script>
<title></title>
<body>
<div class="caption">
<div class="left">Process Monitoring</div>
</div>
</body>

File diff suppressed because it is too large Load Diff

@ -0,0 +1,20 @@
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# editorconfig.org
root = true
[*]
# Change these settings to your own preference
indent_style = space
indent_size = 4
# We recommend you to keep these unchanged
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false

@ -0,0 +1,4 @@
.idea
node_modules
dist
_site

@ -0,0 +1,5 @@
.idea
node_modules
_site
.editorconfig
.travis.yml

@ -0,0 +1,7 @@
language: node_js
node_js:
- '0.10'
before_script:
- 'npm install -g grunt-cli'
script: grunt test --verbose --force

@ -0,0 +1,130 @@
module.exports = function(grunt) {
"use strict"
var banner =
"/*\n" +
" * jsGrid v<%= pkg.version %> (<%= pkg.homepage %>)\n" +
" * (c) <%= grunt.template.today('yyyy') %> <%= pkg.author %>\n" +
" * Licensed under <%= pkg.license.type %> (<%= pkg.license.url %>)\n" +
" */\n";
grunt.initConfig({
pkg: grunt.file.readJSON("package.json"),
copy: {
imgs: {
expand: true,
cwd: "css/",
src: "*.png",
dest: "dist/"
},
i18n: {
expand: true,
cwd: "src/i18n/",
src: "*.js",
dest: "dist/i18n/",
rename: function(dest, src) {
return dest + "jsgrid-" + src;
}
}
},
concat: {
options: {
banner: banner + "\n",
separator: "\n"
},
js: {
src: [
"src/jsgrid.core.js",
"src/jsgrid.load-indicator.js",
"src/jsgrid.load-strategies.js",
"src/jsgrid.sort-strategies.js",
"src/jsgrid.validation.js",
"src/jsgrid.field.js",
"src/fields/jsgrid.field.text.js",
"src/fields/jsgrid.field.number.js",
"src/fields/jsgrid.field.textarea.js",
"src/fields/jsgrid.field.select.js",
"src/fields/jsgrid.field.checkbox.js",
"src/fields/jsgrid.field.control.js"
],
dest: "dist/<%= pkg.name %>.js"
},
css: {
src: "css/jsgrid.css",
dest: "dist/<%= pkg.name %>.css"
},
theme: {
src: "css/theme.css",
dest: "dist/<%= pkg.name %>-theme.css"
}
},
"string-replace": {
version: {
files: [{
src: "<%= concat.js.dest %>",
dest: "<%= concat.js.dest %>"
}],
options: {
replacements: [{
pattern: /"@VERSION"/g,
replacement: "'<%= pkg.version %>'"
}]
}
}
},
imageEmbed: {
options: {
deleteAfterEncoding : true
},
theme: {
src: "<%= concat.theme.dest %>",
dest: "<%= concat.theme.dest %>"
}
},
uglify: {
options : {
banner: banner + "\n"
},
js: {
src: "<%= concat.js.dest %>",
dest: "dist/<%= pkg.name %>.min.js"
}
},
cssmin: {
options : {
banner: banner
},
css: {
src: "<%= concat.css.dest %>",
dest: "dist/<%= pkg.name %>.min.css"
},
theme: {
src: "<%= concat.theme.dest %>",
dest: "dist/<%= pkg.name %>-theme.min.css"
}
},
qunit: {
files: ["tests/index.html"]
}
});
grunt.loadNpmTasks("grunt-contrib-copy");
grunt.loadNpmTasks("grunt-contrib-concat");
grunt.loadNpmTasks("grunt-contrib-uglify");
grunt.loadNpmTasks("grunt-image-embed");
grunt.loadNpmTasks("grunt-contrib-cssmin");
grunt.loadNpmTasks("grunt-contrib-qunit");
grunt.loadNpmTasks('grunt-string-replace');
grunt.registerTask("default", ["copy", "concat", "string-replace", "imageEmbed", "uglify", "cssmin"]);
grunt.registerTask("test", "qunit");
};

@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2014 Artem Tabalin
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

File diff suppressed because it is too large Load Diff

@ -0,0 +1,28 @@
{
"name": "jsgrid",
"version": "1.5.3",
"main": [
"dist/jsgrid.js",
"dist/jsgrid.css",
"dist/jsgrid-theme.css"
],
"ignore": [
"demos",
"external",
"tests",
".editorconfig",
".gitignore",
".travis.yml",
"bower.json",
"Gruntfile.js",
"LICENSE",
"package.json",
"README.md"
],
"dependencies": {
"jquery": ">=1.8.3"
},
"devDependencies": {
"qunit": ">=1.10.0"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

@ -0,0 +1,120 @@
.jsgrid {
position: relative;
overflow: hidden;
font-size: 1em;
}
.jsgrid, .jsgrid *, .jsgrid *:before, .jsgrid *:after {
box-sizing: border-box;
}
.jsgrid input,
.jsgrid textarea,
.jsgrid select {
font-size: 1em;
}
.jsgrid-grid-header {
overflow-x: hidden;
overflow-y: scroll;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
}
.jsgrid-grid-body {
overflow-x: auto;
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
}
.jsgrid-table {
width: 100%;
table-layout: fixed;
border-collapse: collapse;
border-spacing: 0;
}
.jsgrid-cell {
padding: 0.5em 0.5em;
}
.jsgrid-сell,
.jsgrid-header-cell {
box-sizing: border-box;
}
.jsgrid-align-left {
text-align: left;
}
.jsgrid-align-center,
.jsgrid-align-center input,
.jsgrid-align-center textarea,
.jsgrid-align-center select {
text-align: center;
}
.jsgrid-align-right,
.jsgrid-align-right input,
.jsgrid-align-right textarea,
.jsgrid-align-right select {
text-align: right;
}
.jsgrid-header-cell {
padding: .5em .5em;
}
.jsgrid-filter-row input,
.jsgrid-filter-row textarea,
.jsgrid-filter-row select,
.jsgrid-edit-row input,
.jsgrid-edit-row textarea,
.jsgrid-edit-row select,
.jsgrid-insert-row input,
.jsgrid-insert-row textarea,
.jsgrid-insert-row select {
width: 100%;
padding: .3em .5em;
}
.jsgrid-filter-row input[type='checkbox'],
.jsgrid-edit-row input[type='checkbox'],
.jsgrid-insert-row input[type='checkbox'] {
width: auto;
}
.jsgrid-selected-row .jsgrid-cell {
cursor: pointer;
}
.jsgrid-nodata-row .jsgrid-cell {
padding: .5em 0;
text-align: center;
}
.jsgrid-header-sort {
cursor: pointer;
}
.jsgrid-pager {
padding: .5em 0;
}
.jsgrid-pager-nav-button {
padding: .2em .6em;
}
.jsgrid-pager-nav-inactive-button {
display: none;
pointer-events: none;
}
.jsgrid-pager-page {
padding: .2em .6em;
}

@ -0,0 +1,252 @@
.jsgrid-grid-header,
.jsgrid-grid-body,
.jsgrid-header-row > .jsgrid-header-cell,
.jsgrid-filter-row > .jsgrid-cell,
.jsgrid-insert-row > .jsgrid-cell,
.jsgrid-edit-row > .jsgrid-cell {
border: 1px solid #e9e9e9;
}
.jsgrid-header-row > .jsgrid-header-cell {
border-top: 0;
}
.jsgrid-header-row > .jsgrid-header-cell,
.jsgrid-filter-row > .jsgrid-cell,
.jsgrid-insert-row > .jsgrid-cell {
border-bottom: 0;
}
.jsgrid-header-row > .jsgrid-header-cell:first-child,
.jsgrid-filter-row > .jsgrid-cell:first-child,
.jsgrid-insert-row > .jsgrid-cell:first-child {
border-left: none;
}
.jsgrid-header-row > .jsgrid-header-cell:last-child,
.jsgrid-filter-row > .jsgrid-cell:last-child,
.jsgrid-insert-row > .jsgrid-cell:last-child {
border-right: none;
}
.jsgrid-header-row .jsgrid-align-right,
.jsgrid-header-row .jsgrid-align-left {
text-align: center;
}
.jsgrid-grid-header {
background: #f9f9f9;
}
.jsgrid-header-scrollbar {
scrollbar-arrow-color: #f1f1f1;
scrollbar-base-color: #f1f1f1;
scrollbar-3dlight-color: #f1f1f1;
scrollbar-highlight-color: #f1f1f1;
scrollbar-track-color: #f1f1f1;
scrollbar-shadow-color: #f1f1f1;
scrollbar-dark-shadow-color: #f1f1f1;
}
.jsgrid-header-scrollbar::-webkit-scrollbar {
visibility: hidden;
}
.jsgrid-header-scrollbar::-webkit-scrollbar-track {
background: #f1f1f1;
}
.jsgrid-header-sortable:hover {
cursor: pointer;
background: #fcfcfc;
}
.jsgrid-header-row .jsgrid-header-sort {
background: #c4e2ff;
}
.jsgrid-header-sort:before {
content: " ";
display: block;
float: left;
width: 0;
height: 0;
border-style: solid;
}
.jsgrid-header-sort-asc:before {
border-width: 0 5px 5px 5px;
border-color: transparent transparent #009a67 transparent;
}
.jsgrid-header-sort-desc:before {
border-width: 5px 5px 0 5px;
border-color: #009a67 transparent transparent transparent;
}
.jsgrid-grid-body {
border-top: none;
}
.jsgrid-cell {
border: #f3f3f3 1px solid;
}
.jsgrid-grid-body .jsgrid-row:first-child .jsgrid-cell,
.jsgrid-grid-body .jsgrid-alt-row:first-child .jsgrid-cell {
border-top: none;
}
.jsgrid-grid-body .jsgrid-cell:first-child {
border-left: none;
}
.jsgrid-grid-body .jsgrid-cell:last-child {
border-right: none;
}
.jsgrid-row > .jsgrid-cell {
background: #fff;
}
.jsgrid-alt-row > .jsgrid-cell {
background: #fcfcfc;
}
.jsgrid-header-row > .jsgrid-header-cell {
background: #f9f9f9;
}
.jsgrid-filter-row > .jsgrid-cell {
background: #fcfcfc;
}
.jsgrid-insert-row > .jsgrid-cell {
background: #e3ffe5;
}
.jsgrid-edit-row > .jsgrid-cell {
background: #fdffe3;
}
.jsgrid-selected-row > .jsgrid-cell {
background: #c4e2ff;
border-color: #c4e2ff;
}
.jsgrid-nodata-row > .jsgrid-cell {
background: #fff;
}
.jsgrid-invalid input,
.jsgrid-invalid select,
.jsgrid-invalid textarea {
background: #ffe3e5;
border: 1px solid #ff808a;
}
.jsgrid-pager-current-page {
font-weight: bold;
}
.jsgrid-pager-nav-inactive-button a {
color: #d3d3d3;
}
.jsgrid-button + .jsgrid-button {
margin-left: 5px;
}
.jsgrid-button:hover {
opacity: .5;
transition: opacity 200ms linear;
}
.jsgrid .jsgrid-button {
width: 16px;
height: 16px;
border: none;
cursor: pointer;
background-image: url(icons.png);
background-repeat: no-repeat;
background-color: transparent;
}
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-device-pixel-ratio: 2) {
.jsgrid .jsgrid-button {
background-image: url(icons-2x.png);
background-size: 24px 352px;
}
}
.jsgrid .jsgrid-mode-button {
width: 24px;
height: 24px;
}
.jsgrid-mode-on-button {
opacity: .5;
}
.jsgrid-cancel-edit-button { background-position: 0 0; width: 16px; height: 16px; }
.jsgrid-clear-filter-button { background-position: 0 -40px; width: 16px; height: 16px; }
.jsgrid-delete-button { background-position: 0 -80px; width: 16px; height: 16px; }
.jsgrid-edit-button { background-position: 0 -120px; width: 16px; height: 16px; }
.jsgrid-insert-mode-button { background-position: 0 -160px; width: 24px; height: 24px; }
.jsgrid-insert-button { background-position: 0 -208px; width: 16px; height: 16px; }
.jsgrid-search-mode-button { background-position: 0 -248px; width: 24px; height: 24px; }
.jsgrid-search-button { background-position: 0 -296px; width: 16px; height: 16px; }
.jsgrid-update-button { background-position: 0 -336px; width: 16px; height: 16px; }
.jsgrid-load-shader {
background: #ddd;
opacity: .5;
filter: alpha(opacity=50);
}
.jsgrid-load-panel {
width: 15em;
height: 5em;
background: #fff;
border: 1px solid #e9e9e9;
padding-top: 3em;
text-align: center;
}
.jsgrid-load-panel:before {
content: ' ';
position: absolute;
top: .5em;
left: 50%;
margin-left: -1em;
width: 2em;
height: 2em;
border: 2px solid #009a67;
border-right-color: transparent;
border-radius: 50%;
-webkit-animation: indicator 1s linear infinite;
animation: indicator 1s linear infinite;
}
@-webkit-keyframes indicator
{
from { -webkit-transform: rotate(0deg); }
50% { -webkit-transform: rotate(180deg); }
to { -webkit-transform: rotate(360deg); }
}
@keyframes indicator
{
from { transform: rotate(0deg); }
50% { transform: rotate(180deg); }
to { transform: rotate(360deg); }
}
/* old IE */
.jsgrid-load-panel {
padding-top: 1.5em\9;
}
.jsgrid-load-panel:before {
display: none\9;
}

@ -0,0 +1,59 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>jsGrid - Basic Scenario</title>
<link rel="stylesheet" type="text/css" href="demos.css" />
<link href='http://fonts.googleapis.com/css?family=Open+Sans:300,600,400' rel='stylesheet' type='text/css'>
<link rel="stylesheet" type="text/css" href="../css/jsgrid.css" />
<link rel="stylesheet" type="text/css" href="../css/theme.css" />
<script src="../external/jquery/jquery-1.8.3.js"></script>
<script src="db.js"></script>
<script src="../src/jsgrid.core.js"></script>
<script src="../src/jsgrid.load-indicator.js"></script>
<script src="../src/jsgrid.load-strategies.js"></script>
<script src="../src/jsgrid.sort-strategies.js"></script>
<script src="../src/jsgrid.field.js"></script>
<script src="../src/fields/jsgrid.field.text.js"></script>
<script src="../src/fields/jsgrid.field.number.js"></script>
<script src="../src/fields/jsgrid.field.select.js"></script>
<script src="../src/fields/jsgrid.field.checkbox.js"></script>
<script src="../src/fields/jsgrid.field.control.js"></script>
</head>
<body>
<h1>Basic Scenario</h1>
<div id="jsGrid"></div>
<script>
$(function() {
$("#jsGrid").jsGrid({
height: "70%",
width: "100%",
filtering: true,
editing: true,
inserting: true,
sorting: true,
paging: true,
autoload: true,
pageSize: 15,
pageButtonCount: 5,
deleteConfirm: "Do you really want to delete the client?",
controller: db,
fields: [
{ name: "Name", type: "text", width: 150 },
{ name: "Age", type: "number", width: 50 },
{ name: "Address", type: "text", width: 200 },
{ name: "Country", type: "select", items: db.countries, valueField: "Id", textField: "Name" },
{ name: "Married", type: "checkbox", title: "Is Married", sorting: false },
{ type: "control" }
]
});
});
</script>
</body>
</html>

@ -0,0 +1,102 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>jsGrid - Batch Delete</title>
<link rel="stylesheet" type="text/css" href="demos.css" />
<link href='http://fonts.googleapis.com/css?family=Open+Sans:300,600,400' rel='stylesheet' type='text/css'>
<link rel="stylesheet" type="text/css" href="../css/jsgrid.css" />
<link rel="stylesheet" type="text/css" href="../css/theme.css" />
<script src="../external/jquery/jquery-1.8.3.js"></script>
<script src="db.js"></script>
<script src="../src/jsgrid.core.js"></script>
<script src="../src/jsgrid.load-indicator.js"></script>
<script src="../src/jsgrid.load-strategies.js"></script>
<script src="../src/jsgrid.sort-strategies.js"></script>
<script src="../src/jsgrid.field.js"></script>
<script src="../src/fields/jsgrid.field.text.js"></script>
<script src="../src/fields/jsgrid.field.number.js"></script>
<script src="../src/fields/jsgrid.field.control.js"></script>
</head>
<body>
<h1>Batch Delete</h1>
<div id="jsGrid"></div>
<script>
$(function() {
$("#jsGrid").jsGrid({
height: "50%",
width: "100%",
autoload: true,
confirmDeleting: false,
paging: true,
controller: {
loadData: function() {
return db.clients;
}
},
fields: [
{
headerTemplate: function() {
return $("<button>").attr("type", "button").text("Delete")
.on("click", function () {
deleteSelectedItems();
});
},
itemTemplate: function(_, item) {
return $("<input>").attr("type", "checkbox")
.prop("checked", $.inArray(item, selectedItems) > -1)
.on("change", function () {
$(this).is(":checked") ? selectItem(item) : unselectItem(item);
});
},
align: "center",
width: 50
},
{ name: "Name", type: "text", width: 150 },
{ name: "Age", type: "number", width: 50 },
{ name: "Address", type: "text", width: 200 }
]
});
var selectedItems = [];
var selectItem = function(item) {
selectedItems.push(item);
};
var unselectItem = function(item) {
selectedItems = $.grep(selectedItems, function(i) {
return i !== item;
});
};
var deleteSelectedItems = function() {
if(!selectedItems.length || !confirm("Are you sure?"))
return;
deleteClientsFromDb(selectedItems);
var $grid = $("#jsGrid");
$grid.jsGrid("option", "pageIndex", 1);
$grid.jsGrid("loadData");
selectedItems = [];
};
var deleteClientsFromDb = function(deletingClients) {
db.clients = $.map(db.clients, function(client) {
return ($.inArray(client, deletingClients) > -1) ? null : client;
});
};
});
</script>
</body>
</html>

@ -0,0 +1,97 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>jsGrid - Custom Grid Field Scenario</title>
<link rel="stylesheet" type="text/css" href="demos.css" />
<link href='http://fonts.googleapis.com/css?family=Open+Sans:300,600,400' rel='stylesheet' type='text/css' />
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.2/themes/cupertino/jquery-ui.css">
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.11.2/jquery-ui.js"></script>
<link rel="stylesheet" type="text/css" href="../css/jsgrid.css" />
<link rel="stylesheet" type="text/css" href="../css/theme.css" />
<script src="db.js"></script>
<script src="../src/jsgrid.core.js"></script>
<script src="../src/jsgrid.load-indicator.js"></script>
<script src="../src/jsgrid.load-strategies.js"></script>
<script src="../src/jsgrid.sort-strategies.js"></script>
<script src="../src/jsgrid.field.js"></script>
<script src="../src/fields/jsgrid.field.text.js"></script>
<script src="../src/fields/jsgrid.field.control.js"></script>
<style>
.hasDatepicker {
width: 100px;
text-align: center;
}
.ui-datepicker * {
font-family: 'Helvetica Neue Light', 'Open Sans', Helvetica;
font-size: 14px;
font-weight: 300 !important;
}
</style>
</head>
<body>
<h1>Custom Grid DateField</h1>
<div id="jsGrid"></div>
<script>
$(function() {
var MyDateField = function(config) {
jsGrid.Field.call(this, config);
};
MyDateField.prototype = new jsGrid.Field({
sorter: function(date1, date2) {
return new Date(date1) - new Date(date2);
},
itemTemplate: function(value) {
return new Date(value).toDateString();
},
insertTemplate: function(value) {
return this._insertPicker = $("<input>").datepicker({ defaultDate: new Date() });
},
editTemplate: function(value) {
return this._editPicker = $("<input>").datepicker().datepicker("setDate", new Date(value));
},
insertValue: function() {
return this._insertPicker.datepicker("getDate").toISOString();
},
editValue: function() {
return this._editPicker.datepicker("getDate").toISOString();
}
});
jsGrid.fields.myDateField = MyDateField;
$("#jsGrid").jsGrid({
height: "70%",
width: "100%",
inserting: true,
editing: true,
sorting: true,
paging: true,
fields: [
{ name: "Account", width: 150, align: "center" },
{ name: "Name", type: "text" },
{ name: "RegisterDate", type: "myDateField", width: 100, align: "center" },
{ type: "control", editButton: false, modeSwitchButton: false }
],
data: db.users
});
});
</script>
</body>
</html>

@ -0,0 +1,90 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>jsGrid - Custom Load Indicator</title>
<link rel="stylesheet" type="text/css" href="demos.css" />
<link href='http://fonts.googleapis.com/css?family=Open+Sans:300,600,400' rel='stylesheet' type='text/css'>
<link rel="stylesheet" type="text/css" href="../css/jsgrid.css" />
<link rel="stylesheet" type="text/css" href="../css/theme.css" />
<script src="http://cdnjs.cloudflare.com/ajax/libs/spin.js/2.3.1/spin.min.js"></script>
<script src="../external/jquery/jquery-1.8.3.js"></script>
<script src="../src/jsgrid.core.js"></script>
<script src="../src/jsgrid.load-indicator.js"></script>
<script src="../src/jsgrid.load-strategies.js"></script>
<script src="../src/jsgrid.sort-strategies.js"></script>
<script src="../src/jsgrid.field.js"></script>
<script src="../src/fields/jsgrid.field.text.js"></script>
<script src="../src/fields/jsgrid.field.textarea.js"></script>
<script src="../src/fields/jsgrid.field.number.js"></script>
<style>
.rating {
color: #F8CA03;
}
</style>
</head>
<body>
<h1>Custom Load Indicator</h1>
<div id="jsGrid"></div>
<script>
$(function() {
$("#jsGrid").jsGrid({
height: "50%",
width: "100%",
sorting: true,
paging: false,
autoload: true,
controller: {
loadData: function() {
var d = $.Deferred();
$.ajax({
url: "http://services.odata.org/V3/(S(3mnweai3qldmghnzfshavfok))/OData/OData.svc/Products",
dataType: "json"
}).done(function(response) {
setTimeout(function() {
d.resolve(response.value);
}, 2000);
});
return d.promise();
}
},
loadIndicator: function(config) {
var container = config.container[0];
var spinner = new Spinner();
return {
show: function() {
spinner.spin(container);
},
hide: function() {
spinner.stop();
}
};
},
fields: [
{ name: "Name", type: "text" },
{ name: "Description", type: "textarea", width: 150 },
{ name: "Rating", type: "number", width: 50, align: "center",
itemTemplate: function(value) {
return $("<div>").addClass("rating").append(Array(value + 1).join("&#9733;"));
}
},
{ name: "Price", type: "number", width: 50,
itemTemplate: function(value) {
return value.toFixed(2) + "$"; }
}
]
});
});
</script>
</body>
</html>

@ -0,0 +1,79 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>jsGrid - Custom Row Renderer</title>
<link rel="stylesheet" type="text/css" href="demos.css" />
<link href='http://fonts.googleapis.com/css?family=Open+Sans:300,600,400' rel='stylesheet' type='text/css'>
<link rel="stylesheet" type="text/css" href="../css/jsgrid.css" />
<link rel="stylesheet" type="text/css" href="../css/theme.css" />
<script src="../external/jquery/jquery-1.8.3.js"></script>
<script src="../src/jsgrid.core.js"></script>
<script src="../src/jsgrid.load-indicator.js"></script>
<script src="../src/jsgrid.load-strategies.js"></script>
<script src="../src/jsgrid.sort-strategies.js"></script>
<script src="../src/jsgrid.field.js"></script>
<style>
.client-photo { float: left; margin: 0 20px 0 10px; }
.client-photo img { border-radius: 50%; border: 1px solid #ddd; }
.client-info { margin-top: 10px; }
.client-info p { line-height: 25px; }
</style>
</head>
<body>
<h1>Custom Row Renderer</h1>
<div id="jsGrid"></div>
<script>
$(function() {
$("#jsGrid").jsGrid({
height: "80%",
width: "50%",
autoload: true,
paging: true,
controller: {
loadData: function() {
var deferred = $.Deferred();
$.ajax({
url: 'http://api.randomuser.me/?results=40',
dataType: 'jsonp',
success: function(data){
deferred.resolve(data.results);
}
});
return deferred.promise();
}
},
rowRenderer: function(item) {
var user = item;
var $photo = $("<div>").addClass("client-photo").append($("<img>").attr("src", user.picture.large));
var $info = $("<div>").addClass("client-info")
.append($("<p>").append($("<strong>").text(user.name.first.capitalize() + " " + user.name.last.capitalize())))
.append($("<p>").text("Location: " + user.location.city.capitalize() + ", " + user.location.street))
.append($("<p>").text("Email: " + user.email))
.append($("<p>").text("Phone: " + user.phone))
.append($("<p>").text("Cell: " + user.cell));
return $("<tr>").append($("<td>").append($photo).append($info));
},
fields: [
{ title: "Clients" }
]
});
String.prototype.capitalize = function() {
return this.charAt(0).toUpperCase() + this.slice(1);
};
});
</script>
</body>
</html>

@ -0,0 +1,85 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>jsGrid - Custom View Scenario</title>
<link rel="stylesheet" type="text/css" href="demos.css" />
<link href='http://fonts.googleapis.com/css?family=Open+Sans:300,600,400' rel='stylesheet' type='text/css'>
<link rel="stylesheet" type="text/css" href="../css/jsgrid.css" />
<link rel="stylesheet" type="text/css" href="../css/theme.css" />
<script src="../external/jquery/jquery-1.8.3.js"></script>
<script src="db.js"></script>
<script src="../src/jsgrid.core.js"></script>
<script src="../src/jsgrid.load-indicator.js"></script>
<script src="../src/jsgrid.load-strategies.js"></script>
<script src="../src/jsgrid.sort-strategies.js"></script>
<script src="../src/jsgrid.field.js"></script>
<script src="../src/fields/jsgrid.field.text.js"></script>
<script src="../src/fields/jsgrid.field.number.js"></script>
<script src="../src/fields/jsgrid.field.select.js"></script>
<script src="../src/fields/jsgrid.field.checkbox.js"></script>
<script src="../src/fields/jsgrid.field.control.js"></script>
<style>
.config-panel {
padding: 10px;
margin: 10px 0;
background: #fcfcfc;
border: 1px solid #e9e9e9;
display: inline-block;
}
.config-panel label {
margin-right: 10px;
}
</style>
</head>
<body>
<h1>Custom View</h1>
<div class="config-panel">
<label><input id="heading" type="checkbox" checked /> Heading</label>
<label><input id="filtering" type="checkbox" checked /> Filtering</label>
<label><input id="inserting" type="checkbox" /> Inserting</label>
<label><input id="editing" type="checkbox" checked /> Editing</label>
<label><input id="paging" type="checkbox" checked /> Paging</label>
<label><input id="sorting" type="checkbox" checked /> Sorting</label>
<label><input id="selecting" type="checkbox" checked /> Selecting</label>
</div>
<div id="jsGrid"></div>
<script>
$(function() {
$("#jsGrid").jsGrid({
height: "70%",
width: "100%",
filtering: true,
editing: true,
sorting: true,
paging: true,
autoload: true,
pageSize: 15,
pageButtonCount: 5,
controller: db,
fields: [
{ name: "Name", type: "text", width: 150 },
{ name: "Age", type: "number", width: 50 },
{ name: "Address", type: "text", width: 200 },
{ name: "Country", type: "select", items: db.countries, valueField: "Id", textField: "Name" },
{ name: "Married", type: "checkbox", title: "Is Married", sorting: false },
{ type: "control", modeSwitchButton: false, editButton: false }
]
});
$(".config-panel input[type=checkbox]").on("click", function() {
var $cb = $(this);
$("#jsGrid").jsGrid("option", $cb.attr("id"), $cb.is(":checked"));
});
});
</script>
</body>
</html>

@ -0,0 +1,212 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>jsGrid - Data Manipulation</title>
<link rel="stylesheet" type="text/css" href="demos.css" />
<link href='http://fonts.googleapis.com/css?family=Open+Sans:300,600,400' rel='stylesheet' type='text/css'>
<link rel="stylesheet" type="text/css" href="../css/jsgrid.css" />
<link rel="stylesheet" type="text/css" href="../css/theme.css" />
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.2/themes/cupertino/jquery-ui.css">
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.11.2/jquery-ui.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.9/jquery.validate.min.js"></script>
<script src="db.js"></script>
<script src="../src/jsgrid.core.js"></script>
<script src="../src/jsgrid.load-indicator.js"></script>
<script src="../src/jsgrid.load-strategies.js"></script>
<script src="../src/jsgrid.sort-strategies.js"></script>
<script src="../src/jsgrid.field.js"></script>
<script src="../src/fields/jsgrid.field.text.js"></script>
<script src="../src/fields/jsgrid.field.number.js"></script>
<script src="../src/fields/jsgrid.field.select.js"></script>
<script src="../src/fields/jsgrid.field.checkbox.js"></script>
<script src="../src/fields/jsgrid.field.control.js"></script>
<style>
.ui-widget *, .ui-widget input, .ui-widget select, .ui-widget button {
font-family: 'Helvetica Neue Light', 'Open Sans', Helvetica;
font-size: 14px;
font-weight: 300 !important;
}
.details-form-field input,
.details-form-field select {
width: 250px;
float: right;
}
.details-form-field {
margin: 30px 0;
}
.details-form-field:first-child {
margin-top: 10px;
}
.details-form-field:last-child {
margin-bottom: 10px;
}
.details-form-field button {
display: block;
width: 100px;
margin: 0 auto;
}
input.error, select.error {
border: 1px solid #ff9999;
background: #ffeeee;
}
label.error {
float: right;
margin-left: 100px;
font-size: .8em;
color: #ff6666;
}
</style>
</head>
<body>
<h1>Data Manipulation</h1>
<div id="jsGrid"></div>
<div id="detailsDialog">
<form id="detailsForm">
<div class="details-form-field">
<label for="name">Name:</label>
<input id="name" name="name" type="text" />
</div>
<div class="details-form-field">
<label for="age">Age:</label>
<input id="age" name="age" type="number" />
</div>
<div class="details-form-field">
<label for="address">Address:</label>
<input id="address" name="address" type="text" />
</div>
<div class="details-form-field">
<label for="country">Country:</label>
<select id="country" name="country">
<option value="">(Select)</option>
<option value="1">United States</option>
<option value="2">Canada</option>
<option value="3">United Kingdom</option>
<option value="4">France</option>
<option value="5">Brazil</option>
<option value="6">China</option>
<option value="7">Russia</option>
</select>
</div>
<div class="details-form-field">
<label for="married">Is Married</label>
<input id="married" name="married" type="checkbox" />
</div>
<div class="details-form-field">
<button type="submit" id="save">Save</button>
</div>
</form>
</div>
<script>
$(function() {
$("#jsGrid").jsGrid({
height: "70%",
width: "100%",
editing: true,
autoload: true,
paging: true,
deleteConfirm: function(item) {
return "The client \"" + item.Name + "\" will be removed. Are you sure?";
},
rowClick: function(args) {
showDetailsDialog("Edit", args.item);
},
controller: db,
fields: [
{ name: "Name", type: "text", width: 150 },
{ name: "Age", type: "number", width: 50 },
{ name: "Address", type: "text", width: 200 },
{ name: "Country", type: "select", items: db.countries, valueField: "Id", textField: "Name" },
{ name: "Married", type: "checkbox", title: "Is Married", sorting: false },
{
type: "control",
modeSwitchButton: false,
editButton: false,
headerTemplate: function() {
return $("<button>").attr("type", "button").text("Add")
.on("click", function () {
showDetailsDialog("Add", {});
});
}
}
]
});
$("#detailsDialog").dialog({
autoOpen: false,
width: 400,
close: function() {
$("#detailsForm").validate().resetForm();
$("#detailsForm").find(".error").removeClass("error");
}
});
$("#detailsForm").validate({
rules: {
name: "required",
age: { required: true, range: [18, 150] },
address: { required: true, minlength: 10 },
country: "required"
},
messages: {
name: "Please enter name",
age: "Please enter valid age",
address: "Please enter address (more than 10 chars)",
country: "Please select country"
},
submitHandler: function() {
formSubmitHandler();
}
});
var formSubmitHandler = $.noop;
var showDetailsDialog = function(dialogType, client) {
$("#name").val(client.Name);
$("#age").val(client.Age);
$("#address").val(client.Address);
$("#country").val(client.Country);
$("#married").prop("checked", client.Married);
formSubmitHandler = function() {
saveClient(client, dialogType === "Add");
};
$("#detailsDialog").dialog("option", "title", dialogType + " Client")
.dialog("open");
};
var saveClient = function(client, isNew) {
$.extend(client, {
Name: $("#name").val(),
Age: parseInt($("#age").val(), 10),
Address: $("#address").val(),
Country: parseInt($("#country").val(), 10),
Married: $("#married").is(":checked")
});
$("#jsGrid").jsGrid(isNew ? "insertItem" : "updateItem", client);
$("#detailsDialog").dialog("close");
};
});
</script>
</body>
</html>

@ -0,0 +1,884 @@
(function() {
var db = {
loadData: function(filter) {
return $.grep(this.clients, function(client) {
return (!filter.Name || client.Name.indexOf(filter.Name) > -1)
&& (filter.Age === undefined || client.Age === filter.Age)
&& (!filter.Address || client.Address.indexOf(filter.Address) > -1)
&& (!filter.Country || client.Country === filter.Country)
&& (filter.Married === undefined || client.Married === filter.Married);
});
},
insertItem: function(insertingClient) {
this.clients.push(insertingClient);
},
updateItem: function(updatingClient) { },
deleteItem: function(deletingClient) {
var clientIndex = $.inArray(deletingClient, this.clients);
this.clients.splice(clientIndex, 1);
}
};
window.db = db;
db.countries = [
{ Name: "", Id: 0 },
{ Name: "United States", Id: 1 },
{ Name: "Canada", Id: 2 },
{ Name: "United Kingdom", Id: 3 },
{ Name: "France", Id: 4 },
{ Name: "Brazil", Id: 5 },
{ Name: "China", Id: 6 },
{ Name: "Russia", Id: 7 }
];
db.clients = [
{
"Name": "Otto Clay",
"Age": 61,
"Country": 6,
"Address": "Ap #897-1459 Quam Avenue",
"Married": false
},
{
"Name": "Connor Johnston",
"Age": 73,
"Country": 7,
"Address": "Ap #370-4647 Dis Av.",
"Married": false
},
{
"Name": "Lacey Hess",
"Age": 29,
"Country": 7,
"Address": "Ap #365-8835 Integer St.",
"Married": false
},
{
"Name": "Timothy Henson",
"Age": 78,
"Country": 1,
"Address": "911-5143 Luctus Ave",
"Married": false
},
{
"Name": "Ramona Benton",
"Age": 43,
"Country": 5,
"Address": "Ap #614-689 Vehicula Street",
"Married": true
},
{
"Name": "Ezra Tillman",
"Age": 51,
"Country": 1,
"Address": "P.O. Box 738, 7583 Quisque St.",
"Married": true
},
{
"Name": "Dante Carter",
"Age": 59,
"Country": 1,
"Address": "P.O. Box 976, 6316 Lorem, St.",
"Married": false
},
{
"Name": "Christopher Mcclure",
"Age": 58,
"Country": 1,
"Address": "847-4303 Dictum Av.",
"Married": true
},
{
"Name": "Ruby Rocha",
"Age": 62,
"Country": 2,
"Address": "5212 Sagittis Ave",
"Married": false
},
{
"Name": "Imelda Hardin",
"Age": 39,
"Country": 5,
"Address": "719-7009 Auctor Av.",
"Married": false
},
{
"Name": "Jonah Johns",
"Age": 28,
"Country": 5,
"Address": "P.O. Box 939, 9310 A Ave",
"Married": false
},
{
"Name": "Herman Rosa",
"Age": 49,
"Country": 7,
"Address": "718-7162 Molestie Av.",
"Married": true
},
{
"Name": "Arthur Gay",
"Age": 20,
"Country": 7,
"Address": "5497 Neque Street",
"Married": false
},
{
"Name": "Xena Wilkerson",
"Age": 63,
"Country": 1,
"Address": "Ap #303-6974 Proin Street",
"Married": true
},
{
"Name": "Lilah Atkins",
"Age": 33,
"Country": 5,
"Address": "622-8602 Gravida Ave",
"Married": true
},
{
"Name": "Malik Shepard",
"Age": 59,
"Country": 1,
"Address": "967-5176 Tincidunt Av.",
"Married": false
},
{
"Name": "Keely Silva",
"Age": 24,
"Country": 1,
"Address": "P.O. Box 153, 8995 Praesent Ave",
"Married": false
},
{
"Name": "Hunter Pate",
"Age": 73,
"Country": 7,
"Address": "P.O. Box 771, 7599 Ante, Road",
"Married": false
},
{
"Name": "Mikayla Roach",
"Age": 55,
"Country": 5,
"Address": "Ap #438-9886 Donec Rd.",
"Married": true
},
{
"Name": "Upton Joseph",
"Age": 48,
"Country": 4,
"Address": "Ap #896-7592 Habitant St.",
"Married": true
},
{
"Name": "Jeanette Pate",
"Age": 59,
"Country": 2,
"Address": "P.O. Box 177, 7584 Amet, St.",
"Married": false
},
{
"Name": "Kaden Hernandez",
"Age": 79,
"Country": 3,
"Address": "366 Ut St.",
"Married": true
},
{
"Name": "Kenyon Stevens",
"Age": 20,
"Country": 3,
"Address": "P.O. Box 704, 4580 Gravida Rd.",
"Married": false
},
{
"Name": "Jerome Harper",
"Age": 31,
"Country": 5,
"Address": "2464 Porttitor Road",
"Married": false
},
{
"Name": "Jelani Patel",
"Age": 36,
"Country": 2,
"Address": "P.O. Box 541, 5805 Nec Av.",
"Married": true
},
{
"Name": "Keaton Oconnor",
"Age": 21,
"Country": 1,
"Address": "Ap #657-1093 Nec, Street",
"Married": false
},
{
"Name": "Bree Johnston",
"Age": 31,
"Country": 2,
"Address": "372-5942 Vulputate Avenue",
"Married": false
},
{
"Name": "Maisie Hodges",
"Age": 70,
"Country": 7,
"Address": "P.O. Box 445, 3880 Odio, Rd.",
"Married": false
},
{
"Name": "Kuame Calhoun",
"Age": 39,
"Country": 2,
"Address": "P.O. Box 609, 4105 Rutrum St.",
"Married": true
},
{
"Name": "Carlos Cameron",
"Age": 38,
"Country": 5,
"Address": "Ap #215-5386 A, Avenue",
"Married": false
},
{
"Name": "Fulton Parsons",
"Age": 25,
"Country": 7,
"Address": "P.O. Box 523, 3705 Sed Rd.",
"Married": false
},
{
"Name": "Wallace Christian",
"Age": 43,
"Country": 3,
"Address": "416-8816 Mauris Avenue",
"Married": true
},
{
"Name": "Caryn Maldonado",
"Age": 40,
"Country": 1,
"Address": "108-282 Nonummy Ave",
"Married": false
},
{
"Name": "Whilemina Frank",
"Age": 20,
"Country": 7,
"Address": "P.O. Box 681, 3938 Egestas. Av.",
"Married": true
},
{
"Name": "Emery Moon",
"Age": 41,
"Country": 4,
"Address": "Ap #717-8556 Non Road",
"Married": true
},
{
"Name": "Price Watkins",
"Age": 35,
"Country": 4,
"Address": "832-7810 Nunc Rd.",
"Married": false
},
{
"Name": "Lydia Castillo",
"Age": 59,
"Country": 7,
"Address": "5280 Placerat, Ave",
"Married": true
},
{
"Name": "Lawrence Conway",
"Age": 53,
"Country": 1,
"Address": "Ap #452-2808 Imperdiet St.",
"Married": false
},
{
"Name": "Kalia Nicholson",
"Age": 67,
"Country": 5,
"Address": "P.O. Box 871, 3023 Tellus Road",
"Married": true
},
{
"Name": "Brielle Baxter",
"Age": 45,
"Country": 3,
"Address": "Ap #822-9526 Ut, Road",
"Married": true
},
{
"Name": "Valentine Brady",
"Age": 72,
"Country": 7,
"Address": "8014 Enim. Road",
"Married": true
},
{
"Name": "Rebecca Gardner",
"Age": 57,
"Country": 4,
"Address": "8655 Arcu. Road",
"Married": true
},
{
"Name": "Vladimir Tate",
"Age": 26,
"Country": 1,
"Address": "130-1291 Non, Rd.",
"Married": true
},
{
"Name": "Vernon Hays",
"Age": 56,
"Country": 4,
"Address": "964-5552 In Rd.",
"Married": true
},
{
"Name": "Allegra Hull",
"Age": 22,
"Country": 4,
"Address": "245-8891 Donec St.",
"Married": true
},
{
"Name": "Hu Hendrix",
"Age": 65,
"Country": 7,
"Address": "428-5404 Tempus Ave",
"Married": true
},
{
"Name": "Kenyon Battle",
"Age": 32,
"Country": 2,
"Address": "921-6804 Lectus St.",
"Married": false
},
{
"Name": "Gloria Nielsen",
"Age": 24,
"Country": 4,
"Address": "Ap #275-4345 Lorem, Street",
"Married": true
},
{
"Name": "Illiana Kidd",
"Age": 59,
"Country": 2,
"Address": "7618 Lacus. Av.",
"Married": false
},
{
"Name": "Adria Todd",
"Age": 68,
"Country": 6,
"Address": "1889 Tincidunt Road",
"Married": false
},
{
"Name": "Kirsten Mayo",
"Age": 71,
"Country": 1,
"Address": "100-8640 Orci, Avenue",
"Married": false
},
{
"Name": "Willa Hobbs",
"Age": 60,
"Country": 6,
"Address": "P.O. Box 323, 158 Tristique St.",
"Married": false
},
{
"Name": "Alexis Clements",
"Age": 69,
"Country": 5,
"Address": "P.O. Box 176, 5107 Proin Rd.",
"Married": false
},
{
"Name": "Akeem Conrad",
"Age": 60,
"Country": 2,
"Address": "282-495 Sed Ave",
"Married": true
},
{
"Name": "Montana Silva",
"Age": 79,
"Country": 6,
"Address": "P.O. Box 120, 9766 Consectetuer St.",
"Married": false
},
{
"Name": "Kaseem Hensley",
"Age": 77,
"Country": 6,
"Address": "Ap #510-8903 Mauris. Av.",
"Married": true
},
{
"Name": "Christopher Morton",
"Age": 35,
"Country": 5,
"Address": "P.O. Box 234, 3651 Sodales Avenue",
"Married": false
},
{
"Name": "Wade Fernandez",
"Age": 49,
"Country": 6,
"Address": "740-5059 Dolor. Road",
"Married": true
},
{
"Name": "Illiana Kirby",
"Age": 31,
"Country": 2,
"Address": "527-3553 Mi Ave",
"Married": false
},
{
"Name": "Kimberley Hurley",
"Age": 65,
"Country": 5,
"Address": "P.O. Box 637, 9915 Dictum St.",
"Married": false
},
{
"Name": "Arthur Olsen",
"Age": 74,
"Country": 5,
"Address": "887-5080 Eget St.",
"Married": false
},
{
"Name": "Brody Potts",
"Age": 59,
"Country": 2,
"Address": "Ap #577-7690 Sem Road",
"Married": false
},
{
"Name": "Dillon Ford",
"Age": 60,
"Country": 1,
"Address": "Ap #885-9289 A, Av.",
"Married": true
},
{
"Name": "Hannah Juarez",
"Age": 61,
"Country": 2,
"Address": "4744 Sapien, Rd.",
"Married": true
},
{
"Name": "Vincent Shaffer",
"Age": 25,
"Country": 2,
"Address": "9203 Nunc St.",
"Married": true
},
{
"Name": "George Holt",
"Age": 27,
"Country": 6,
"Address": "4162 Cras Rd.",
"Married": false
},
{
"Name": "Tobias Bartlett",
"Age": 74,
"Country": 4,
"Address": "792-6145 Mauris St.",
"Married": true
},
{
"Name": "Xavier Hooper",
"Age": 35,
"Country": 1,
"Address": "879-5026 Interdum. Rd.",
"Married": false
},
{
"Name": "Declan Dorsey",
"Age": 31,
"Country": 2,
"Address": "Ap #926-4171 Aenean Road",
"Married": true
},
{
"Name": "Clementine Tran",
"Age": 43,
"Country": 4,
"Address": "P.O. Box 176, 9865 Eu Rd.",
"Married": true
},
{
"Name": "Pamela Moody",
"Age": 55,
"Country": 6,
"Address": "622-6233 Luctus Rd.",
"Married": true
},
{
"Name": "Julie Leon",
"Age": 43,
"Country": 6,
"Address": "Ap #915-6782 Sem Av.",
"Married": true
},
{
"Name": "Shana Nolan",
"Age": 79,
"Country": 5,
"Address": "P.O. Box 603, 899 Eu St.",
"Married": false
},
{
"Name": "Vaughan Moody",
"Age": 37,
"Country": 5,
"Address": "880 Erat Rd.",
"Married": false
},
{
"Name": "Randall Reeves",
"Age": 44,
"Country": 3,
"Address": "1819 Non Street",
"Married": false
},
{
"Name": "Dominic Raymond",
"Age": 68,
"Country": 1,
"Address": "Ap #689-4874 Nisi Rd.",
"Married": true
},
{
"Name": "Lev Pugh",
"Age": 69,
"Country": 5,
"Address": "Ap #433-6844 Auctor Avenue",
"Married": true
},
{
"Name": "Desiree Hughes",
"Age": 80,
"Country": 4,
"Address": "605-6645 Fermentum Avenue",
"Married": true
},
{
"Name": "Idona Oneill",
"Age": 23,
"Country": 7,
"Address": "751-8148 Aliquam Avenue",
"Married": true
},
{
"Name": "Lani Mayo",
"Age": 76,
"Country": 1,
"Address": "635-2704 Tristique St.",
"Married": true
},
{
"Name": "Cathleen Bonner",
"Age": 40,
"Country": 1,
"Address": "916-2910 Dolor Av.",
"Married": false
},
{
"Name": "Sydney Murray",
"Age": 44,
"Country": 5,
"Address": "835-2330 Fringilla St.",
"Married": false
},
{
"Name": "Brenna Rodriguez",
"Age": 77,
"Country": 6,
"Address": "3687 Imperdiet Av.",
"Married": true
},
{
"Name": "Alfreda Mcdaniel",
"Age": 38,
"Country": 7,
"Address": "745-8221 Aliquet Rd.",
"Married": true
},
{
"Name": "Zachery Atkins",
"Age": 30,
"Country": 1,
"Address": "549-2208 Auctor. Road",
"Married": true
},
{
"Name": "Amelia Rich",
"Age": 56,
"Country": 4,
"Address": "P.O. Box 734, 4717 Nunc Rd.",
"Married": false
},
{
"Name": "Kiayada Witt",
"Age": 62,
"Country": 3,
"Address": "Ap #735-3421 Malesuada Avenue",
"Married": false
},
{
"Name": "Lysandra Pierce",
"Age": 36,
"Country": 1,
"Address": "Ap #146-2835 Curabitur St.",
"Married": true
},
{
"Name": "Cara Rios",
"Age": 58,
"Country": 4,
"Address": "Ap #562-7811 Quam. Ave",
"Married": true
},
{
"Name": "Austin Andrews",
"Age": 55,
"Country": 7,
"Address": "P.O. Box 274, 5505 Sociis Rd.",
"Married": false
},
{
"Name": "Lillian Peterson",
"Age": 39,
"Country": 2,
"Address": "6212 A Avenue",
"Married": false
},
{
"Name": "Adria Beach",
"Age": 29,
"Country": 2,
"Address": "P.O. Box 183, 2717 Nunc Avenue",
"Married": true
},
{
"Name": "Oleg Durham",
"Age": 80,
"Country": 4,
"Address": "931-3208 Nunc Rd.",
"Married": false
},
{
"Name": "Casey Reese",
"Age": 60,
"Country": 4,
"Address": "383-3675 Ultrices, St.",
"Married": false
},
{
"Name": "Kane Burnett",
"Age": 80,
"Country": 1,
"Address": "759-8212 Dolor. Ave",
"Married": false
},
{
"Name": "Stewart Wilson",
"Age": 46,
"Country": 7,
"Address": "718-7845 Sagittis. Av.",
"Married": false
},
{
"Name": "Charity Holcomb",
"Age": 31,
"Country": 6,
"Address": "641-7892 Enim. Ave",
"Married": false
},
{
"Name": "Kyra Cummings",
"Age": 43,
"Country": 4,
"Address": "P.O. Box 702, 6621 Mus. Av.",
"Married": false
},
{
"Name": "Stuart Wallace",
"Age": 25,
"Country": 7,
"Address": "648-4990 Sed Rd.",
"Married": true
},
{
"Name": "Carter Clarke",
"Age": 59,
"Country": 6,
"Address": "Ap #547-2921 A Street",
"Married": false
}
];
db.users = [
{
"ID": "x",
"Account": "A758A693-0302-03D1-AE53-EEFE22855556",
"Name": "Carson Kelley",
"RegisterDate": "2002-04-20T22:55:52-07:00"
},
{
"Account": "D89FF524-1233-0CE7-C9E1-56EFF017A321",
"Name": "Prescott Griffin",
"RegisterDate": "2011-02-22T05:59:55-08:00"
},
{
"Account": "06FAAD9A-5114-08F6-D60C-961B2528B4F0",
"Name": "Amir Saunders",
"RegisterDate": "2014-08-13T09:17:49-07:00"
},
{
"Account": "EED7653D-7DD9-A722-64A8-36A55ECDBE77",
"Name": "Derek Thornton",
"RegisterDate": "2012-02-27T01:31:07-08:00"
},
{
"Account": "2A2E6D40-FEBD-C643-A751-9AB4CAF1E2F6",
"Name": "Fletcher Romero",
"RegisterDate": "2010-06-25T15:49:54-07:00"
},
{
"Account": "3978F8FA-DFF0-DA0E-0A5D-EB9D281A3286",
"Name": "Thaddeus Stein",
"RegisterDate": "2013-11-10T07:29:41-08:00"
},
{
"Account": "658DBF5A-176E-569A-9273-74FB5F69FA42",
"Name": "Nash Knapp",
"RegisterDate": "2005-06-24T09:11:19-07:00"
},
{
"Account": "76D2EE4B-7A73-1212-F6F2-957EF8C1F907",
"Name": "Quamar Vega",
"RegisterDate": "2011-04-13T20:06:29-07:00"
},
{
"Account": "00E46809-A595-CE82-C5B4-D1CAEB7E3E58",
"Name": "Philip Galloway",
"RegisterDate": "2008-08-21T18:59:38-07:00"
},
{
"Account": "C196781C-DDCC-AF83-DDC2-CA3E851A47A0",
"Name": "Mason French",
"RegisterDate": "2000-11-15T00:38:37-08:00"
},
{
"Account": "5911F201-818A-B393-5888-13157CE0D63F",
"Name": "Ross Cortez",
"RegisterDate": "2010-05-27T17:35:32-07:00"
},
{
"Account": "B8BB78F9-E1A1-A956-086F-E12B6FE168B6",
"Name": "Logan King",
"RegisterDate": "2003-07-08T16:58:06-07:00"
},
{
"Account": "06F636C3-9599-1A2D-5FD5-86B24ADDE626",
"Name": "Cedric Leblanc",
"RegisterDate": "2011-06-30T14:30:10-07:00"
},
{
"Account": "FE880CDD-F6E7-75CB-743C-64C6DE192412",
"Name": "Simon Sullivan",
"RegisterDate": "2013-06-11T16:35:07-07:00"
},
{
"Account": "BBEDD673-E2C1-4872-A5D3-C4EBD4BE0A12",
"Name": "Jamal West",
"RegisterDate": "2001-03-16T20:18:29-08:00"
},
{
"Account": "19BC22FA-C52E-0CC6-9552-10365C755FAC",
"Name": "Hector Morales",
"RegisterDate": "2012-11-01T01:56:34-07:00"
},
{
"Account": "A8292214-2C13-5989-3419-6B83DD637D6C",
"Name": "Herrod Hart",
"RegisterDate": "2008-03-13T19:21:04-07:00"
},
{
"Account": "0285564B-F447-0E7F-EAA1-7FB8F9C453C8",
"Name": "Clark Maxwell",
"RegisterDate": "2004-08-05T08:22:24-07:00"
},
{
"Account": "EA78F076-4F6E-4228-268C-1F51272498AE",
"Name": "Reuben Walter",
"RegisterDate": "2011-01-23T01:55:59-08:00"
},
{
"Account": "6A88C194-EA21-426F-4FE2-F2AE33F51793",
"Name": "Ira Ingram",
"RegisterDate": "2008-08-15T05:57:46-07:00"
},
{
"Account": "4275E873-439C-AD26-56B3-8715E336508E",
"Name": "Damian Morrow",
"RegisterDate": "2015-09-13T01:50:55-07:00"
},
{
"Account": "A0D733C4-9070-B8D6-4387-D44F0BA515BE",
"Name": "Macon Farrell",
"RegisterDate": "2011-03-14T05:41:40-07:00"
},
{
"Account": "B3683DE8-C2FA-7CA0-A8A6-8FA7E954F90A",
"Name": "Joel Galloway",
"RegisterDate": "2003-02-03T04:19:01-08:00"
},
{
"Account": "01D95A8E-91BC-2050-F5D0-4437AAFFD11F",
"Name": "Rigel Horton",
"RegisterDate": "2015-06-20T11:53:11-07:00"
},
{
"Account": "F0D12CC0-31AC-A82E-FD73-EEEFDBD21A36",
"Name": "Sylvester Gaines",
"RegisterDate": "2004-03-12T09:57:13-08:00"
},
{
"Account": "874FCC49-9A61-71BC-2F4E-2CE88348AD7B",
"Name": "Abbot Mckay",
"RegisterDate": "2008-12-26T20:42:57-08:00"
},
{
"Account": "B8DA1912-20A0-FB6E-0031-5F88FD63EF90",
"Name": "Solomon Green",
"RegisterDate": "2013-09-04T01:44:47-07:00"
}
];
}());

@ -0,0 +1,82 @@
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
height: 100%;
}
body {
height: 100%;
padding: 10px;
color: #262626;
font-family: 'Helvetica Neue Light', 'Open Sans', Helvetica;
font-size: 14px;
font-weight: 300;
}
h1 {
margin: 0 0 8px 0;
font-size: 24px;
font-family: 'Helvetica Neue Light', 'Open Sans', Helvetica;
font-weight: 300;
}
h2 {
margin: 16px 0 8px 0;
font-size: 18px;
font-family: 'Helvetica Neue Light', 'Open Sans', Helvetica;
font-weight: 300;
}
ul {
list-style: none;
}
a {
color: #2ba6cb;
text-decoration: none;
}
a:hover {
text-decoration: underline;
color: #258faf;
}
input, button, select {
font-family: 'Helvetica Neue Light', 'Open Sans', Helvetica;
font-weight: 300;
font-size: 14px;
padding: 2px;
}
.navigation {
width: 200px;
position: absolute;
top: 0;
bottom: 0;
left: 0;
padding: 10px;
border-right: 1px solid #e9e9e9;
}
.navigation li {
margin: 10px 0;
}
.demo-frame {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 200px;
}
iframe[name='demo'] {
display: block;
width: 100%;
height: 100%;
border: none;
}

@ -0,0 +1,72 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>jsGrid - External Pager Scenario</title>
<link rel="stylesheet" type="text/css" href="demos.css" />
<link href='http://fonts.googleapis.com/css?family=Open+Sans:300,600,400' rel='stylesheet' type='text/css'>
<link rel="stylesheet" type="text/css" href="../css/jsgrid.css" />
<link rel="stylesheet" type="text/css" href="../css/theme.css" />
<script src="../external/jquery/jquery-1.8.3.js"></script>
<script src="db.js"></script>
<script src="../src/jsgrid.core.js"></script>
<script src="../src/jsgrid.load-indicator.js"></script>
<script src="../src/jsgrid.load-strategies.js"></script>
<script src="../src/jsgrid.sort-strategies.js"></script>
<script src="../src/jsgrid.field.js"></script>
<script src="../src/fields/jsgrid.field.text.js"></script>
<script src="../src/fields/jsgrid.field.number.js"></script>
<script src="../src/fields/jsgrid.field.select.js"></script>
<script src="../src/fields/jsgrid.field.checkbox.js"></script>
<style>
.external-pager {
margin: 10px 0;
}
.external-pager .jsgrid-pager-current-page {
background: #c4e2ff;
color: #fff;
}
</style>
</head>
<body>
<h1>External Customized Pager</h1>
<div id="externalPager" class="external-pager"></div>
<div id="jsGrid"></div>
<script>
$(function() {
$("#jsGrid").jsGrid({
height: "70%",
width: "100%",
paging: true,
pageSize: 15,
pageButtonCount: 5,
pagerContainer: "#externalPager",
pagerFormat: "current page: {pageIndex} &nbsp;&nbsp; {first} {prev} {pages} {next} {last} &nbsp;&nbsp; total pages: {pageCount} total items: {itemCount}",
pagePrevText: "<",
pageNextText: ">",
pageFirstText: "<<",
pageLastText: ">>",
pageNavigatorNextText: "&#8230;",
pageNavigatorPrevText: "&#8230;",
fields: [
{ name: "Name", type: "text", width: 150 },
{ name: "Age", type: "number", width: 50 },
{ name: "Address", type: "text", width: 200 },
{ name: "Country", type: "select", items: db.countries, valueField: "Id", textField: "Name" },
{ name: "Married", type: "checkbox", title: "Is Married" }
],
data: db.clients
});
});
</script>
</body>
</html>

@ -0,0 +1,31 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>jsGrid - Simple jQuery DataGrid - Demos</title>
<link rel="stylesheet" type="text/css" href="demos.css" />
<link href='http://fonts.googleapis.com/css?family=Open+Sans:300,600,400' rel='stylesheet' type='text/css'>
</head>
<body>
<div class="navigation">
<h1>jsGrid Demos</h1>
<ul>
<li><a href="basic.html" target="demo">Basic Scenario</a></li>
<li><a href="static-data.html" target="demo">Static Data</a></li>
<li><a href="odata-service.html" target="demo">OData Service</a></li>
<li><a href="data-manipulation.html" target="demo">Data Manipulation</a></li>
<li><a href="validation.html" target="demo">Validation</a></li>
<li><a href="sorting.html" target="demo">Sorting</a></li>
<li><a href="loading-by-page.html" target="demo">Loading by Page</a></li>
<li><a href="custom-view.html" target="demo">Custom View</a></li>
<li><a href="custom-row-renderer.html" target="demo">Custom Row Renderer</a></li>
<li><a href="external-pager.html" target="demo">External Pager</a></li>
<li><a href="custom-grid-field.html" target="demo">Custom Grid Field</a></li>
<li><a href="localization.html" target="demo">Localization</a></li>
</ul>
</div>
<div class="demo-frame">
<iframe name="demo" src="basic.html"></iframe>
</div>
</body>
</html>

@ -0,0 +1,90 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>jsGrid - Loading Data by Page Scenario</title>
<link rel="stylesheet" type="text/css" href="demos.css" />
<link href='http://fonts.googleapis.com/css?family=Open+Sans:300,600,400' rel='stylesheet' type='text/css'>
<link rel="stylesheet" type="text/css" href="../css/jsgrid.css" />
<link rel="stylesheet" type="text/css" href="../css/theme.css" />
<script src="../external/jquery/jquery-1.8.3.js"></script>
<script src="db.js"></script>
<script src="../src/jsgrid.core.js"></script>
<script src="../src/jsgrid.load-indicator.js"></script>
<script src="../src/jsgrid.load-strategies.js"></script>
<script src="../src/jsgrid.sort-strategies.js"></script>
<script src="../src/jsgrid.field.js"></script>
<script src="../src/fields/jsgrid.field.text.js"></script>
<script src="../src/fields/jsgrid.field.number.js"></script>
<script src="../src/fields/jsgrid.field.select.js"></script>
<script src="../src/fields/jsgrid.field.checkbox.js"></script>
<style>
.pager-panel {
padding: 10px;
margin: 10px 0;
background: #fcfcfc;
border: 1px solid #e9e9e9;
display: inline-block;
}
</style>
</head>
<body>
<h1>Loading Data by Page</h1>
<div class="pager-panel">
<label>Page:
<select id="pager">
<option>1</option>
<option selected>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
<option>6</option>
<option>7</option>
</select>
</label>
</div>
<div id="jsGrid"></div>
<script>
$(function() {
$("#jsGrid").jsGrid({
height: "70%",
width: "100%",
autoload: true,
paging: true,
pageLoading: true,
pageSize: 15,
pageIndex: 2,
controller: {
loadData: function(filter) {
var startIndex = (filter.pageIndex - 1) * filter.pageSize;
return {
data: db.clients.slice(startIndex, startIndex + filter.pageSize),
itemsCount: db.clients.length
};
}
},
fields: [
{ name: "Name", type: "text", width: 150 },
{ name: "Age", type: "number", width: 50 },
{ name: "Address", type: "text", width: 200 },
{ name: "Country", type: "select", items: db.countries, valueField: "Id", textField: "Name" },
{ name: "Married", type: "checkbox", title: "Is Married" }
]
});
$("#pager").on("change", function() {
var page = parseInt($(this).val(), 10);
$("#jsGrid").jsGrid("openPage", page);
});
});
</script>
</body>
</html>

@ -0,0 +1,62 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>jsGrid - Localization (FR)</title>
<link rel="stylesheet" type="text/css" href="demos.css" />
<link href='http://fonts.googleapis.com/css?family=Open+Sans:300,600,400' rel='stylesheet' type='text/css'>
<link rel="stylesheet" type="text/css" href="../css/jsgrid.css" />
<link rel="stylesheet" type="text/css" href="../css/theme.css" />
<script src="../external/jquery/jquery-1.8.3.js"></script>
<script src="db.js"></script>
<script src="../src/jsgrid.core.js"></script>
<script src="../src/jsgrid.load-indicator.js"></script>
<script src="../src/jsgrid.load-strategies.js"></script>
<script src="../src/jsgrid.sort-strategies.js"></script>
<script src="../src/jsgrid.validation.js"></script>
<script src="../src/jsgrid.field.js"></script>
<script src="../src/fields/jsgrid.field.text.js"></script>
<script src="../src/fields/jsgrid.field.number.js"></script>
<script src="../src/fields/jsgrid.field.select.js"></script>
<script src="../src/fields/jsgrid.field.checkbox.js"></script>
<script src="../src/fields/jsgrid.field.control.js"></script>
<script src="../src/i18n/fr.js"></script>
</head>
<body>
<h1>Localization (FR)</h1>
<div id="jsGrid"></div>
<script>
$(function() {
jsGrid.locale("fr");
$("#jsGrid").jsGrid({
height: "70%",
width: "100%",
filtering: true,
editing: true,
inserting: true,
sorting: true,
paging: true,
autoload: true,
pageSize: 15,
pageButtonCount: 5,
controller: db,
fields: [
{ name: "Name", title: "Nom", type: "text", width: 150, validate: "required" },
{ name: "Age", title: "Âge", type: "number", width: 50, validate: { validator: "range", param: [18,80] } },
{ name: "Address", title: "Adresse", type: "text", width: 200, validate: { validator: "rangeLength", param: [10, 250] } },
{ name: "Country", title: "Pays", type: "select", items: db.countries, valueField: "Id", textField: "Name" },
{ name: "Married", title: "Marié", type: "checkbox", sorting: false },
{ type: "control" }
]
});
});
</script>
</body>
</html>

@ -0,0 +1,74 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>jsGrid - OData Service Scenario</title>
<link rel="stylesheet" type="text/css" href="demos.css" />
<link href='http://fonts.googleapis.com/css?family=Open+Sans:300,600,400' rel='stylesheet' type='text/css'>
<link rel="stylesheet" type="text/css" href="../css/jsgrid.css" />
<link rel="stylesheet" type="text/css" href="../css/theme.css" />
<script src="../external/jquery/jquery-1.8.3.js"></script>
<script src="../src/jsgrid.core.js"></script>
<script src="../src/jsgrid.load-indicator.js"></script>
<script src="../src/jsgrid.load-strategies.js"></script>
<script src="../src/jsgrid.sort-strategies.js"></script>
<script src="../src/jsgrid.field.js"></script>
<script src="../src/fields/jsgrid.field.text.js"></script>
<script src="../src/fields/jsgrid.field.textarea.js"></script>
<script src="../src/fields/jsgrid.field.number.js"></script>
<style>
.rating {
color: #F8CA03;
}
</style>
</head>
<body>
<h1>OData Service</h1>
<div id="jsGrid"></div>
<script>
$(function() {
$("#jsGrid").jsGrid({
height: "auto",
width: "auto",
sorting: true,
paging: false,
autoload: true,
controller: {
loadData: function() {
var d = $.Deferred();
$.ajax({
url: "http://services.odata.org/V3/(S(3mnweai3qldmghnzfshavfok))/OData/OData.svc/Products",
dataType: "json"
}).done(function(response) {
d.resolve(response.value);
});
return d.promise();
}
},
fields: [
{ name: "Name", type: "text", width: 100 },
{ name: "Description", type: "textarea", width: 200 },
{ name: "Rating", type: "number", width: 150, align: "center",
itemTemplate: function(value) {
return $("<div>").addClass("rating").append(Array(value + 1).join("&#9733;"));
}
},
{ name: "Price", type: "number", width: 100,
itemTemplate: function(value) {
return value.toFixed(2) + "$"; }
}
]
});
});
</script>
</body>
</html>

@ -0,0 +1,83 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>jsGrid - Rows Reordering Scenario</title>
<link rel="stylesheet" type="text/css" href="demos.css" />
<link href='http://fonts.googleapis.com/css?family=Open+Sans:300,600,400' rel='stylesheet' type='text/css'>
<link rel="stylesheet" type="text/css" href="../css/jsgrid.css" />
<link rel="stylesheet" type="text/css" href="../css/theme.css" />
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.2/themes/cupertino/jquery-ui.css">
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.11.2/jquery-ui.js"></script>
<script src="db.js"></script>
<script src="../src/jsgrid.core.js"></script>
<script src="../src/jsgrid.load-indicator.js"></script>
<script src="../src/jsgrid.load-strategies.js"></script>
<script src="../src/jsgrid.sort-strategies.js"></script>
<script src="../src/jsgrid.field.js"></script>
<script src="../src/fields/jsgrid.field.text.js"></script>
<script src="../src/fields/jsgrid.field.number.js"></script>
<script src="../src/fields/jsgrid.field.select.js"></script>
<script src="../src/fields/jsgrid.field.checkbox.js"></script>
<script src="../src/fields/jsgrid.field.control.js"></script>
</head>
<body>
<h1>Rows Reordering Scenario</h1>
<div id="jsGrid"></div>
<script>
$(function() {
$("#jsGrid").jsGrid({
height: "70%",
width: "100%",
autoload: true,
rowClass: function(item, itemIndex) {
return "client-" + itemIndex;
},
controller: {
loadData: function() {
return db.clients.slice(0, 15);
}
},
fields: [
{ name: "Name", type: "text", width: 150 },
{ name: "Age", type: "number", width: 50 },
{ name: "Address", type: "text", width: 200 },
{ name: "Country", type: "select", items: db.countries, valueField: "Id", textField: "Name" },
{ name: "Married", type: "checkbox", title: "Is Married", sorting: false }
],
onRefreshed: function() {
var $gridData = $("#jsGrid .jsgrid-grid-body tbody");
$gridData.sortable({
update: function(e, ui) {
// array of indexes
var clientIndexRegExp = /\s*client-(\d+)\s*/;
var indexes = $.map($gridData.sortable("toArray", { attribute: "class" }), function(classes) {
return clientIndexRegExp.exec(classes)[1];
});
alert("Reordered indexes: " + indexes.join(", "));
// arrays of items
var items = $.map($gridData.find("tr"), function(row) {
return $(row).data("JSGridItem");
});
console && console.log("Reordered items", items);
}
});
}
});
});
</script>
</body>
</html>

@ -0,0 +1,78 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>jsGrid - Sorting Scenario</title>
<link rel="stylesheet" type="text/css" href="demos.css" />
<link href='http://fonts.googleapis.com/css?family=Open+Sans:300,600,400' rel='stylesheet' type='text/css'>
<link rel="stylesheet" type="text/css" href="../css/jsgrid.css" />
<link rel="stylesheet" type="text/css" href="../css/theme.css" />
<script src="../external/jquery/jquery-1.8.3.js"></script>
<script src="db.js"></script>
<script src="../src/jsgrid.core.js"></script>
<script src="../src/jsgrid.load-indicator.js"></script>
<script src="../src/jsgrid.load-strategies.js"></script>
<script src="../src/jsgrid.sort-strategies.js"></script>
<script src="../src/jsgrid.field.js"></script>
<script src="../src/fields/jsgrid.field.text.js"></script>
<script src="../src/fields/jsgrid.field.number.js"></script>
<script src="../src/fields/jsgrid.field.select.js"></script>
<script src="../src/fields/jsgrid.field.checkbox.js"></script>
<style>
.sort-panel {
padding: 10px;
margin: 10px 0;
background: #fcfcfc;
border: 1px solid #e9e9e9;
display: inline-block;
}
</style>
</head>
<body>
<h1>Sorting</h1>
<div class="sort-panel">
<label>Sorting Field:
<select id="sortingField">
<option>Name</option>
<option>Age</option>
<option>Address</option>
<option>Country</option>
<option>Married</option>
</select>
<button type="button" id="sort">Sort</button>
</label>
</div>
<div id="jsGrid"></div>
<script>
$(function() {
$("#jsGrid").jsGrid({
height: "70%",
width: "100%",
autoload: true,
selecting: false,
controller: db,
fields: [
{ name: "Name", type: "text", width: 150 },
{ name: "Age", type: "number", width: 50 },
{ name: "Address", type: "text", width: 200 },
{ name: "Country", type: "select", items: db.countries, valueField: "Id", textField: "Name" },
{ name: "Married", type: "checkbox", title: "Is Married" }
]
});
$("#sort").click(function() {
var field = $("#sortingField").val();
$("#jsGrid").jsGrid("sort", field);
});
});
</script>
</body>
</html>

@ -0,0 +1,50 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>jsGrid - Static Data Scenario</title>
<link rel="stylesheet" type="text/css" href="demos.css" />
<link href='http://fonts.googleapis.com/css?family=Open+Sans:300,600,400' rel='stylesheet' type='text/css'>
<link rel="stylesheet" type="text/css" href="../css/jsgrid.css" />
<link rel="stylesheet" type="text/css" href="../css/theme.css" />
<script src="../external/jquery/jquery-1.8.3.js"></script>
<script src="db.js"></script>
<script src="../src/jsgrid.core.js"></script>
<script src="../src/jsgrid.load-indicator.js"></script>
<script src="../src/jsgrid.load-strategies.js"></script>
<script src="../src/jsgrid.sort-strategies.js"></script>
<script src="../src/jsgrid.field.js"></script>
<script src="../src/fields/jsgrid.field.text.js"></script>
<script src="../src/fields/jsgrid.field.number.js"></script>
<script src="../src/fields/jsgrid.field.select.js"></script>
<script src="../src/fields/jsgrid.field.checkbox.js"></script>
</head>
<body>
<h1>Static Data</h1>
<div id="jsGrid"></div>
<script>
$(function() {
$("#jsGrid").jsGrid({
height: "70%",
width: "100%",
sorting: true,
paging: true,
fields: [
{ name: "Name", type: "text", width: 150 },
{ name: "Age", type: "number", width: 50 },
{ name: "Address", type: "text", width: 200 },
{ name: "Country", type: "select", items: db.countries, valueField: "Id", textField: "Name" },
{ name: "Married", type: "checkbox", title: "Is Married" }
],
data: db.clients
});
});
</script>
</body>
</html>

@ -0,0 +1,61 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>jsGrid - Validation</title>
<link rel="stylesheet" type="text/css" href="demos.css" />
<link href='http://fonts.googleapis.com/css?family=Open+Sans:300,600,400' rel='stylesheet' type='text/css'>
<link rel="stylesheet" type="text/css" href="../css/jsgrid.css" />
<link rel="stylesheet" type="text/css" href="../css/theme.css" />
<script src="../external/jquery/jquery-1.8.3.js"></script>
<script src="db.js"></script>
<script src="../src/jsgrid.core.js"></script>
<script src="../src/jsgrid.load-indicator.js"></script>
<script src="../src/jsgrid.load-strategies.js"></script>
<script src="../src/jsgrid.sort-strategies.js"></script>
<script src="../src/jsgrid.validation.js"></script>
<script src="../src/jsgrid.field.js"></script>
<script src="../src/fields/jsgrid.field.text.js"></script>
<script src="../src/fields/jsgrid.field.number.js"></script>
<script src="../src/fields/jsgrid.field.select.js"></script>
<script src="../src/fields/jsgrid.field.checkbox.js"></script>
<script src="../src/fields/jsgrid.field.control.js"></script>
</head>
<body>
<h1>Validation</h1>
<div id="jsGrid"></div>
<script>
$(function() {
$("#jsGrid").jsGrid({
height: "70%",
width: "100%",
filtering: true,
editing: true,
inserting: true,
sorting: true,
paging: true,
autoload: true,
pageSize: 15,
pageButtonCount: 5,
deleteConfirm: "Do you really want to delete the client?",
controller: db,
fields: [
{ name: "Name", type: "text", width: 150, validate: "required" },
{ name: "Age", type: "number", width: 50, validate: { validator: "range", param: [18,80] } },
{ name: "Address", type: "text", width: 200, validate: { validator: "rangeLength", param: [10, 250] } },
{ name: "Country", type: "select", items: db.countries, valueField: "Id", textField: "Name",
validate: { message: "Country should be specified", validator: function(value) { return value > 0; } } },
{ name: "Married", type: "checkbox", title: "Is Married", sorting: false },
{ type: "control" }
]
});
});
</script>
</body>
</html>

@ -0,0 +1,235 @@
/**
* QUnit v1.10.0 - A JavaScript Unit Testing Framework
*
* http://qunitjs.com
*
* Copyright 2012 jQuery Foundation and other contributors
* Released under the MIT license.
* http://jquery.org/license
*/
/** Font Family and Sizes */
#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
}
#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
#qunit-tests { font-size: smaller; }
/** Resets */
#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter {
margin: 0;
padding: 0;
}
/** Header */
#qunit-header {
padding: 0.5em 0 0.5em 1em;
color: #8699a4;
background-color: #0d3349;
font-size: 1.5em;
line-height: 1em;
font-weight: normal;
border-radius: 5px 5px 0 0;
-moz-border-radius: 5px 5px 0 0;
-webkit-border-top-right-radius: 5px;
-webkit-border-top-left-radius: 5px;
}
#qunit-header a {
text-decoration: none;
color: #c2ccd1;
}
#qunit-header a:hover,
#qunit-header a:focus {
color: #fff;
}
#qunit-testrunner-toolbar label {
display: inline-block;
padding: 0 .5em 0 .1em;
}
#qunit-banner {
height: 5px;
}
#qunit-testrunner-toolbar {
padding: 0.5em 0 0.5em 2em;
color: #5E740B;
background-color: #eee;
overflow: hidden;
}
#qunit-userAgent {
padding: 0.5em 0 0.5em 2.5em;
background-color: #2b81af;
color: #fff;
text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
}
#qunit-modulefilter-container {
float: right;
}
/** Tests: Pass/Fail */
#qunit-tests {
list-style-position: inside;
}
#qunit-tests li {
padding: 0.4em 0.5em 0.4em 2.5em;
border-bottom: 1px solid #fff;
list-style-position: inside;
}
#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running {
display: none;
}
#qunit-tests li strong {
cursor: pointer;
}
#qunit-tests li a {
padding: 0.5em;
color: #c2ccd1;
text-decoration: none;
}
#qunit-tests li a:hover,
#qunit-tests li a:focus {
color: #000;
}
#qunit-tests ol {
margin-top: 0.5em;
padding: 0.5em;
background-color: #fff;
border-radius: 5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
}
#qunit-tests table {
border-collapse: collapse;
margin-top: .2em;
}
#qunit-tests th {
text-align: right;
vertical-align: top;
padding: 0 .5em 0 0;
}
#qunit-tests td {
vertical-align: top;
}
#qunit-tests pre {
margin: 0;
white-space: pre-wrap;
word-wrap: break-word;
}
#qunit-tests del {
background-color: #e0f2be;
color: #374e0c;
text-decoration: none;
}
#qunit-tests ins {
background-color: #ffcaca;
color: #500;
text-decoration: none;
}
/*** Test Counts */
#qunit-tests b.counts { color: black; }
#qunit-tests b.passed { color: #5E740B; }
#qunit-tests b.failed { color: #710909; }
#qunit-tests li li {
padding: 5px;
background-color: #fff;
border-bottom: none;
list-style-position: inside;
}
/*** Passing Styles */
#qunit-tests li li.pass {
color: #3c510c;
background-color: #fff;
border-left: 10px solid #C6E746;
}
#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; }
#qunit-tests .pass .test-name { color: #366097; }
#qunit-tests .pass .test-actual,
#qunit-tests .pass .test-expected { color: #999999; }
#qunit-banner.qunit-pass { background-color: #C6E746; }
/*** Failing Styles */
#qunit-tests li li.fail {
color: #710909;
background-color: #fff;
border-left: 10px solid #EE5757;
white-space: pre;
}
#qunit-tests > li:last-child {
border-radius: 0 0 5px 5px;
-moz-border-radius: 0 0 5px 5px;
-webkit-border-bottom-right-radius: 5px;
-webkit-border-bottom-left-radius: 5px;
}
#qunit-tests .fail { color: #000000; background-color: #EE5757; }
#qunit-tests .fail .test-name,
#qunit-tests .fail .module-name { color: #000000; }
#qunit-tests .fail .test-actual { color: #EE5757; }
#qunit-tests .fail .test-expected { color: green; }
#qunit-banner.qunit-fail { background-color: #EE5757; }
/** Result */
#qunit-testresult {
padding: 0.5em 0.5em 0.5em 2.5em;
color: #2b81af;
background-color: #D2E0E6;
border-bottom: 1px solid white;
}
#qunit-testresult .module-name {
font-weight: bold;
}
/** Fixture */
#qunit-fixture {
position: absolute;
top: -10000px;
left: -10000px;
width: 1000px;
height: 1000px;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,126 @@
/*
* jsGrid v1.5.3 (http://js-grid.com)
* (c) 2016 Artem Tabalin
* Licensed under MIT (https://github.com/tabalinas/jsgrid/blob/master/LICENSE)
*/
.jsgrid {
position: relative;
overflow: hidden;
font-size: 1em;
}
.jsgrid, .jsgrid *, .jsgrid *:before, .jsgrid *:after {
box-sizing: border-box;
}
.jsgrid input,
.jsgrid textarea,
.jsgrid select {
font-size: 1em;
}
.jsgrid-grid-header {
overflow-x: hidden;
overflow-y: scroll;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
}
.jsgrid-grid-body {
overflow-x: auto;
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
}
.jsgrid-table {
width: 100%;
table-layout: fixed;
border-collapse: collapse;
border-spacing: 0;
}
.jsgrid-cell {
padding: 0.5em 0.5em;
}
.jsgrid-сell,
.jsgrid-header-cell {
box-sizing: border-box;
}
.jsgrid-align-left {
text-align: left;
}
.jsgrid-align-center,
.jsgrid-align-center input,
.jsgrid-align-center textarea,
.jsgrid-align-center select {
text-align: center;
}
.jsgrid-align-right,
.jsgrid-align-right input,
.jsgrid-align-right textarea,
.jsgrid-align-right select {
text-align: right;
}
.jsgrid-header-cell {
padding: .5em .5em;
}
.jsgrid-filter-row input,
.jsgrid-filter-row textarea,
.jsgrid-filter-row select,
.jsgrid-edit-row input,
.jsgrid-edit-row textarea,
.jsgrid-edit-row select,
.jsgrid-insert-row input,
.jsgrid-insert-row textarea,
.jsgrid-insert-row select {
width: 100%;
padding: .3em .5em;
}
.jsgrid-filter-row input[type='checkbox'],
.jsgrid-edit-row input[type='checkbox'],
.jsgrid-insert-row input[type='checkbox'] {
width: auto;
}
.jsgrid-selected-row .jsgrid-cell {
cursor: pointer;
}
.jsgrid-nodata-row .jsgrid-cell {
padding: .5em 0;
text-align: center;
}
.jsgrid-header-sort {
cursor: pointer;
}
.jsgrid-pager {
padding: .5em 0;
}
.jsgrid-pager-nav-button {
padding: .2em .6em;
}
.jsgrid-pager-nav-inactive-button {
display: none;
pointer-events: none;
}
.jsgrid-pager-page {
padding: .2em .6em;
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,7 @@
/*
* jsGrid v1.5.3 (http://js-grid.com)
* (c) 2016 Artem Tabalin
* Licensed under MIT (https://github.com/tabalinas/jsgrid/blob/master/LICENSE)
*/
.jsgrid{position:relative;overflow:hidden;font-size:1em}.jsgrid,.jsgrid *,.jsgrid :after,.jsgrid :before{box-sizing:border-box}.jsgrid input,.jsgrid select,.jsgrid textarea{font-size:1em}.jsgrid-grid-header{overflow-x:hidden;overflow-y:scroll;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.jsgrid-grid-body{overflow-x:auto;overflow-y:scroll;-webkit-overflow-scrolling:touch}.jsgrid-table{width:100%;table-layout:fixed;border-collapse:collapse;border-spacing:0}.jsgrid-cell{padding:.5em}.jsgrid-header-cell,.jsgrid-сell{box-sizing:border-box}.jsgrid-align-left{text-align:left}.jsgrid-align-center,.jsgrid-align-center input,.jsgrid-align-center select,.jsgrid-align-center textarea{text-align:center}.jsgrid-align-right,.jsgrid-align-right input,.jsgrid-align-right select,.jsgrid-align-right textarea{text-align:right}.jsgrid-header-cell{padding:.5em}.jsgrid-edit-row input,.jsgrid-edit-row select,.jsgrid-edit-row textarea,.jsgrid-filter-row input,.jsgrid-filter-row select,.jsgrid-filter-row textarea,.jsgrid-insert-row input,.jsgrid-insert-row select,.jsgrid-insert-row textarea{width:100%;padding:.3em .5em}.jsgrid-edit-row input[type=checkbox],.jsgrid-filter-row input[type=checkbox],.jsgrid-insert-row input[type=checkbox]{width:auto}.jsgrid-selected-row .jsgrid-cell{cursor:pointer}.jsgrid-nodata-row .jsgrid-cell{padding:.5em 0;text-align:center}.jsgrid-header-sort{cursor:pointer}.jsgrid-pager{padding:.5em 0}.jsgrid-pager-nav-button{padding:.2em .6em}.jsgrid-pager-nav-inactive-button{display:none;pointer-events:none}.jsgrid-pager-page{padding:.2em .6em}

File diff suppressed because one or more lines are too long

@ -0,0 +1,38 @@
{
"name": "jsgrid",
"version": "1.5.3",
"description": "Lightweight data grid jQuery plugin. It supports basic grid operations like inserting, filtering, editing, deleting, paging, sorting, and validation. jsGrid is tunable and allows to customize appearance and components.",
"keywords": [
"grid",
"jquery",
"plugin"
],
"homepage": "http://js-grid.com",
"author": "Artem Tabalin",
"license": {
"type": "MIT",
"url": "https://github.com/tabalinas/jsgrid/blob/master/LICENSE"
},
"main": "dist/jsgrid.js",
"directories": {
"test": "tests"
},
"repository": {
"type": "git",
"url": "https://github.com/tabalinas/jsgrid"
},
"bugs": {
"url": "https://github.com/tabalinas/jsgrid/issues"
},
"dependencies": {},
"devDependencies": {
"grunt": "^0.4.5",
"grunt-contrib-concat": "~0.3.0",
"grunt-contrib-copy": "^0.7.0",
"grunt-contrib-cssmin": "^0.10.0",
"grunt-contrib-qunit": "^0.5.2",
"grunt-contrib-uglify": "^0.4.0",
"grunt-image-embed": "^0.3.1",
"grunt-string-replace": "^1.2.1"
}
}

@ -0,0 +1,97 @@
(function(jsGrid, $, undefined) {
var Field = jsGrid.Field;
function CheckboxField(config) {
Field.call(this, config);
}
CheckboxField.prototype = new Field({
sorter: "number",
align: "center",
autosearch: true,
itemTemplate: function(value) {
return this._createCheckbox().prop({
checked: value,
disabled: true
});
},
filterTemplate: function() {
if(!this.filtering)
return "";
var grid = this._grid,
$result = this.filterControl = this._createCheckbox();
$result.prop({
readOnly: true,
indeterminate: true
});
$result.on("click", function() {
var $cb = $(this);
if($cb.prop("readOnly")) {
$cb.prop({
checked: false,
readOnly: false
});
}
else if(!$cb.prop("checked")) {
$cb.prop({
readOnly: true,
indeterminate: true
});
}
});
if(this.autosearch) {
$result.on("click", function() {
grid.search();
});
}
return $result;
},
insertTemplate: function() {
if(!this.inserting)
return "";
return this.insertControl = this._createCheckbox();
},
editTemplate: function(value) {
if(!this.editing)
return this.itemTemplate.apply(this, arguments);
var $result = this.editControl = this._createCheckbox();
$result.prop("checked", value);
return $result;
},
filterValue: function() {
return this.filterControl.get(0).indeterminate
? undefined
: this.filterControl.is(":checked");
},
insertValue: function() {
return this.insertControl.is(":checked");
},
editValue: function() {
return this.editControl.is(":checked");
},
_createCheckbox: function() {
return $("<input>").attr("type", "checkbox");
}
});
jsGrid.fields.checkbox = jsGrid.CheckboxField = CheckboxField;
}(jsGrid, jQuery));

@ -0,0 +1,223 @@
(function(jsGrid, $, undefined) {
var Field = jsGrid.Field;
function ControlField(config) {
Field.call(this, config);
this._configInitialized = false;
}
ControlField.prototype = new Field({
css: "jsgrid-control-field",
align: "center",
width: 50,
filtering: false,
inserting: false,
editing: false,
sorting: false,
buttonClass: "jsgrid-button",
modeButtonClass: "jsgrid-mode-button",
modeOnButtonClass: "jsgrid-mode-on-button",
searchModeButtonClass: "jsgrid-search-mode-button",
insertModeButtonClass: "jsgrid-insert-mode-button",
editButtonClass: "jsgrid-edit-button",
deleteButtonClass: "jsgrid-delete-button",
searchButtonClass: "jsgrid-search-button",
clearFilterButtonClass: "jsgrid-clear-filter-button",
insertButtonClass: "jsgrid-insert-button",
updateButtonClass: "jsgrid-update-button",
cancelEditButtonClass: "jsgrid-cancel-edit-button",
searchModeButtonTooltip: "Switch to searching",
insertModeButtonTooltip: "Switch to inserting",
editButtonTooltip: "Edit",
deleteButtonTooltip: "Delete",
searchButtonTooltip: "Search",
clearFilterButtonTooltip: "Clear filter",
insertButtonTooltip: "Insert",
updateButtonTooltip: "Update",
cancelEditButtonTooltip: "Cancel edit",
editButton: true,
deleteButton: true,
clearFilterButton: true,
modeSwitchButton: true,
_initConfig: function() {
this._hasFiltering = this._grid.filtering;
this._hasInserting = this._grid.inserting;
if(this._hasInserting && this.modeSwitchButton) {
this._grid.inserting = false;
}
this._configInitialized = true;
},
headerTemplate: function() {
if(!this._configInitialized) {
this._initConfig();
}
var hasFiltering = this._hasFiltering;
var hasInserting = this._hasInserting;
if(!this.modeSwitchButton || (!hasFiltering && !hasInserting))
return "";
if(hasFiltering && !hasInserting)
return this._createFilterSwitchButton();
if(hasInserting && !hasFiltering)
return this._createInsertSwitchButton();
return this._createModeSwitchButton();
},
itemTemplate: function(value, item) {
var $result = $([]);
if(this.editButton) {
$result = $result.add(this._createEditButton(item));
}
if(this.deleteButton) {
$result = $result.add(this._createDeleteButton(item));
}
return $result;
},
filterTemplate: function() {
var $result = this._createSearchButton();
return this.clearFilterButton ? $result.add(this._createClearFilterButton()) : $result;
},
insertTemplate: function() {
return this._createInsertButton();
},
editTemplate: function() {
return this._createUpdateButton().add(this._createCancelEditButton());
},
_createFilterSwitchButton: function() {
return this._createOnOffSwitchButton("filtering", this.searchModeButtonClass, true);
},
_createInsertSwitchButton: function() {
return this._createOnOffSwitchButton("inserting", this.insertModeButtonClass, false);
},
_createOnOffSwitchButton: function(option, cssClass, isOnInitially) {
var isOn = isOnInitially;
var updateButtonState = $.proxy(function() {
$button.toggleClass(this.modeOnButtonClass, isOn);
}, this);
var $button = this._createGridButton(this.modeButtonClass + " " + cssClass, "", function(grid) {
isOn = !isOn;
grid.option(option, isOn);
updateButtonState();
});
updateButtonState();
return $button;
},
_createModeSwitchButton: function() {
var isInserting = false;
var updateButtonState = $.proxy(function() {
$button.attr("title", isInserting ? this.searchModeButtonTooltip : this.insertModeButtonTooltip)
.toggleClass(this.insertModeButtonClass, !isInserting)
.toggleClass(this.searchModeButtonClass, isInserting);
}, this);
var $button = this._createGridButton(this.modeButtonClass, "", function(grid) {
isInserting = !isInserting;
grid.option("inserting", isInserting);
grid.option("filtering", !isInserting);
updateButtonState();
});
updateButtonState();
return $button;
},
_createEditButton: function(item) {
return this._createGridButton(this.editButtonClass, this.editButtonTooltip, function(grid, e) {
grid.editItem(item);
e.stopPropagation();
});
},
_createDeleteButton: function(item) {
return this._createGridButton(this.deleteButtonClass, this.deleteButtonTooltip, function(grid, e) {
grid.deleteItem(item);
e.stopPropagation();
});
},
_createSearchButton: function() {
return this._createGridButton(this.searchButtonClass, this.searchButtonTooltip, function(grid) {
grid.search();
});
},
_createClearFilterButton: function() {
return this._createGridButton(this.clearFilterButtonClass, this.clearFilterButtonTooltip, function(grid) {
grid.clearFilter();
});
},
_createInsertButton: function() {
return this._createGridButton(this.insertButtonClass, this.insertButtonTooltip, function(grid) {
grid.insertItem().done(function() {
grid.clearInsert();
});
});
},
_createUpdateButton: function() {
return this._createGridButton(this.updateButtonClass, this.updateButtonTooltip, function(grid, e) {
grid.updateItem();
e.stopPropagation();
});
},
_createCancelEditButton: function() {
return this._createGridButton(this.cancelEditButtonClass, this.cancelEditButtonTooltip, function(grid, e) {
grid.cancelEdit();
e.stopPropagation();
});
},
_createGridButton: function(cls, tooltip, clickHandler) {
var grid = this._grid;
return $("<input>").addClass(this.buttonClass)
.addClass(cls)
.attr({
type: "button",
title: tooltip
})
.on("click", function(e) {
clickHandler(grid, e);
});
},
editValue: function() {
return "";
}
});
jsGrid.fields.control = jsGrid.ControlField = ControlField;
}(jsGrid, jQuery));

@ -0,0 +1,41 @@
(function(jsGrid, $, undefined) {
var TextField = jsGrid.TextField;
function NumberField(config) {
TextField.call(this, config);
}
NumberField.prototype = new TextField({
sorter: "number",
align: "right",
readOnly: false,
filterValue: function() {
return this.filterControl.val()
? parseInt(this.filterControl.val() || 0, 10)
: undefined;
},
insertValue: function() {
return this.insertControl.val()
? parseInt(this.insertControl.val() || 0, 10)
: undefined;
},
editValue: function() {
return this.editControl.val()
? parseInt(this.editControl.val() || 0, 10)
: undefined;
},
_createTextBox: function() {
return $("<input>").attr("type", "number")
.prop("readonly", !!this.readOnly);
}
});
jsGrid.fields.number = jsGrid.NumberField = NumberField;
}(jsGrid, jQuery));

@ -0,0 +1,121 @@
(function(jsGrid, $, undefined) {
var NumberField = jsGrid.NumberField;
var numberValueType = "number";
var stringValueType = "string";
function SelectField(config) {
this.items = [];
this.selectedIndex = -1;
this.valueField = "";
this.textField = "";
if(config.valueField && config.items.length) {
var firstItemValue = config.items[0][config.valueField];
this.valueType = (typeof firstItemValue) === numberValueType ? numberValueType : stringValueType;
}
this.sorter = this.valueType;
NumberField.call(this, config);
}
SelectField.prototype = new NumberField({
align: "center",
valueType: numberValueType,
itemTemplate: function(value) {
var items = this.items,
valueField = this.valueField,
textField = this.textField,
resultItem;
if(valueField) {
resultItem = $.grep(items, function(item, index) {
return item[valueField] === value;
})[0] || {};
}
else {
resultItem = items[value];
}
var result = (textField ? resultItem[textField] : resultItem);
return (result === undefined || result === null) ? "" : result;
},
filterTemplate: function() {
if(!this.filtering)
return "";
var grid = this._grid,
$result = this.filterControl = this._createSelect();
if(this.autosearch) {
$result.on("change", function(e) {
grid.search();
});
}
return $result;
},
insertTemplate: function() {
if(!this.inserting)
return "";
return this.insertControl = this._createSelect();
},
editTemplate: function(value) {
if(!this.editing)
return this.itemTemplate.apply(this, arguments);
var $result = this.editControl = this._createSelect();
(value !== undefined) && $result.val(value);
return $result;
},
filterValue: function() {
var val = this.filterControl.val();
return this.valueType === numberValueType ? parseInt(val || 0, 10) : val;
},
insertValue: function() {
var val = this.insertControl.val();
return this.valueType === numberValueType ? parseInt(val || 0, 10) : val;
},
editValue: function() {
var val = this.editControl.val();
return this.valueType === numberValueType ? parseInt(val || 0, 10) : val;
},
_createSelect: function() {
var $result = $("<select>"),
valueField = this.valueField,
textField = this.textField,
selectedIndex = this.selectedIndex;
$.each(this.items, function(index, item) {
var value = valueField ? item[valueField] : index,
text = textField ? item[textField] : item;
var $option = $("<option>")
.attr("value", value)
.text(text)
.appendTo($result);
$option.prop("selected", (selectedIndex === index));
});
$result.prop("disabled", !!this.readOnly);
return $result;
}
});
jsGrid.fields.select = jsGrid.SelectField = SelectField;
}(jsGrid, jQuery));

@ -0,0 +1,69 @@
(function(jsGrid, $, undefined) {
var Field = jsGrid.Field;
function TextField(config) {
Field.call(this, config);
}
TextField.prototype = new Field({
autosearch: true,
readOnly: false,
filterTemplate: function() {
if(!this.filtering)
return "";
var grid = this._grid,
$result = this.filterControl = this._createTextBox();
if(this.autosearch) {
$result.on("keypress", function(e) {
if(e.which === 13) {
grid.search();
e.preventDefault();
}
});
}
return $result;
},
insertTemplate: function() {
if(!this.inserting)
return "";
return this.insertControl = this._createTextBox();
},
editTemplate: function(value) {
if(!this.editing)
return this.itemTemplate.apply(this, arguments);
var $result = this.editControl = this._createTextBox();
$result.val(value);
return $result;
},
filterValue: function() {
return this.filterControl.val();
},
insertValue: function() {
return this.insertControl.val();
},
editValue: function() {
return this.editControl.val();
},
_createTextBox: function() {
return $("<input>").attr("type", "text")
.prop("readonly", !!this.readOnly);
}
});
jsGrid.fields.text = jsGrid.TextField = TextField;
}(jsGrid, jQuery));

@ -0,0 +1,34 @@
(function(jsGrid, $, undefined) {
var TextField = jsGrid.TextField;
function TextAreaField(config) {
TextField.call(this, config);
}
TextAreaField.prototype = new TextField({
insertTemplate: function() {
if(!this.inserting)
return "";
return this.insertControl = this._createTextArea();
},
editTemplate: function(value) {
if(!this.editing)
return this.itemTemplate.apply(this, arguments);
var $result = this.editControl = this._createTextArea();
$result.val(value);
return $result;
},
_createTextArea: function() {
return $("<textarea>").prop("readonly", !!this.readOnly);
}
});
jsGrid.fields.textarea = jsGrid.TextAreaField = TextAreaField;
}(jsGrid, jQuery));

@ -0,0 +1,46 @@
(function(jsGrid) {
jsGrid.locales.de = {
grid: {
noDataContent: "Die Daten konnten nicht gefunden werden",
deleteConfirm: "Möchten Sie die Daten unwiederruflich löschen?",
pagerFormat: "Seiten: {first} {prev} {pages} {next} {last} &nbsp;&nbsp; {pageIndex} von {pageCount}",
pagePrevText: "<",
pageNextText: ">",
pageFirstText: "<<",
pageLastText: ">>",
loadMessage: "Bitte warten...",
invalidMessage: "Ihre Eingabe ist nicht zulässig!"
},
loadIndicator: {
message: "Lädt..."
},
fields: {
control: {
searchModeButtonTooltip: "Suche",
insertModeButtonTooltip: "Eintrag hinzufügen",
editButtonTooltip: "Bearbeiten",
deleteButtonTooltip: "Löschen",
searchButtonTooltip: "Eintrag finden",
clearFilterButtonTooltip: "Filter zurücksetzen",
insertButtonTooltip: "Hinzufügen",
updateButtonTooltip: "Speichern",
cancelEditButtonTooltip: "Abbrechen"
}
},
validators: {
required: { message: "Dies ist ein Pflichtfeld" },
rangeLength: { message: "Die Länge der Eingabe liegt außerhalb des zulässigen Bereichs" },
minLength: { message: "Die Eingabe ist zu kurz" },
maxLength: { message: "Die Eingabe ist zu lang" },
pattern: { message: "Die Eingabe entspricht nicht dem gewünschten Muster" },
range: { message: "Der eingegebene Wert liegt außerhalb des zulässigen Bereichs" },
min: { message: "Der eingegebene Wert ist zu niedrig" },
max: { message: "Der eingegebene Wert ist zu hoch" }
}
};
}(jsGrid, jQuery));

@ -0,0 +1,46 @@
(function(jsGrid) {
jsGrid.locales.es = {
grid: {
noDataContent: "No encontrado",
deleteConfirm: "¿Está seguro?",
pagerFormat: "Paginas: {first} {prev} {pages} {next} {last} &nbsp;&nbsp; {pageIndex} de {pageCount}",
pagePrevText: "Anterior",
pageNextText: "Siguiente",
pageFirstText: "Primero",
pageLastText: "Ultimo",
loadMessage: "Por favor, espere...",
invalidMessage: "¡Datos no válidos!"
},
loadIndicator: {
message: "Cargando..."
},
fields: {
control: {
searchModeButtonTooltip: "Cambiar a búsqueda",
insertModeButtonTooltip: "Cambiar a inserción",
editButtonTooltip: "Editar",
deleteButtonTooltip: "Suprimir",
searchButtonTooltip: "Buscar",
clearFilterButtonTooltip: "Borrar filtro",
insertButtonTooltip: "Insertar",
updateButtonTooltip: "Actualizar",
cancelEditButtonTooltip: "Cancelar edición"
}
},
validators: {
required: { message: "Campo requerido" },
rangeLength: { message: "La longitud del valor está fuera del intervalo definido" },
minLength: { message: "La longitud del valor es demasiado corta" },
maxLength: { message: "La longitud del valor es demasiado larga" },
pattern: { message: "El valor no se ajusta al patrón definido" },
range: { message: "Valor fuera del rango definido" },
min: { message: "Valor demasiado bajo" },
max: { message: "Valor demasiado alto" }
}
};
}(jsGrid, jQuery));

@ -0,0 +1,47 @@
(function(jsGrid) {
jsGrid.locales.fr = {
grid: {
noDataContent: "Pas de données",
deleteConfirm: "Êtes-vous sûr ?",
pagerFormat: "Pages: {first} {prev} {pages} {next} {last} &nbsp;&nbsp; {pageIndex} de {pageCount}",
pagePrevText: "<",
pageNextText: ">",
pageFirstText: "<<",
pageLastText: ">>",
loadMessage: "Chargement en cours...",
invalidMessage: "Des données incorrectes sont entrés !"
},
loadIndicator: {
message: "Chargement en cours..."
},
fields: {
control: {
searchModeButtonTooltip: "Recherche",
insertModeButtonTooltip: "Ajouter une entrée",
editButtonTooltip: "Changer",
deleteButtonTooltip: "Effacer",
searchButtonTooltip: "Trouve",
clearFilterButtonTooltip: "Effacer",
insertButtonTooltip: "Ajouter",
updateButtonTooltip: "Sauvegarder",
cancelEditButtonTooltip: "Annuler"
}
},
validators: {
required: { message: "Champ requis" },
rangeLength: { message: "Longueur de la valeur du champ est hors de la plage définie" },
minLength: { message: "La valeur du champ est trop court" },
maxLength: { message: "La valeur du champ est trop long" },
pattern: { message: "La valeur du champ ne correspond pas à la configuration définie" },
range: { message: "La valeur du champ est hors de la plage définie" },
min: { message: "La valeur du champ est trop petit" },
max: { message: "La valeur du champ est trop grande" }
}
};
}(jsGrid, jQuery));

@ -0,0 +1,46 @@
(function(jsGrid) {
jsGrid.locales.he = {
grid: {
noDataContent: "לא נמצא",
deleteConfirm: "האם אתה בטוח?",
pagerFormat: "עמודים: {first} {prev} {pages} {next} {last} &nbsp;&nbsp; {pageIndex} מתוך {pageCount}",
pagePrevText: "הקודם",
pageNextText: "הבא",
pageFirstText: "ראשון",
pageLastText: "אחרון",
loadMessage: "אנא המתן ...",
invalidMessage: "נתונים לא חוקיים!"
},
loadIndicator: {
message: "טוען..."
},
fields: {
control: {
searchModeButtonTooltip: "ביצוע חיפוש",
insertModeButtonTooltip: "ביצוע עריכת שורה",
editButtonTooltip: "עריכה",
deleteButtonTooltip: "מחיקה",
searchButtonTooltip: "חיפוש",
clearFilterButtonTooltip: "ניקוי מסנן",
insertButtonTooltip: "הכנסה",
updateButtonTooltip: "עדכון",
cancelEditButtonTooltip: "ביטול עריכה"
}
},
validators: {
required: { message: "שדה נדרש" },
rangeLength: { message: "אורכו של הערך הוא מחוץ לטווח המוגדר" },
minLength: { message: "אורכו של הערך קצר מדי" },
maxLength: { message: "אורכו של הערך ארוך מדי" },
pattern: { message: "אורכו של הערך ארוך מדי" },
range: { message: "ערך מחוץ לטווח" },
min: { message: "ערך נמוך מדי" },
max: { message: "גבוה מדי" }
}
};
}(jsGrid, jQuery));

@ -0,0 +1,46 @@
(function(jsGrid) {
jsGrid.locales.ja = {
grid: {
noDataContent: "データが見つかりません。",
deleteConfirm: "削除しますよろしですか。",
pagerFormat: "頁: {first} {prev} {pages} {next} {last} &nbsp;&nbsp; 【{pageIndex}{pageCount}】",
pagePrevText: "前",
pageNextText: "次",
pageFirstText: "最初",
pageLastText: "最後",
loadMessage: "しばらくお待ちください…",
invalidMessage: "入力されたデータが不正です。"
},
loadIndicator: {
message: "処理中…"
},
fields: {
control: {
searchModeButtonTooltip: "検索モードへ",
insertModeButtonTooltip: "登録モードへ",
editButtonTooltip: "編集",
deleteButtonTooltip: "削除",
searchButtonTooltip: "フィルター",
clearFilterButtonTooltip: "クリア",
insertButtonTooltip: "登録",
updateButtonTooltip: "更新",
cancelEditButtonTooltip: "編集戻す"
}
},
validators: {
required: { message: "項目が必要です。" },
rangeLength: { message: "項目の桁数が範囲外です。" },
minLength: { message: "項目の桁数が超過しています。" },
maxLength: { message: "項目の桁数が不足しています。" },
pattern: { message: "項目の値がパターンに一致しません。" },
range: { message: "項目の値が範囲外です。" },
min: { message: "項目の値が超過しています。" },
max: { message: "項目の値が不足しています。" }
}
};
}(jsGrid, jQuery));

@ -0,0 +1,46 @@
(function(jsGrid) {
jsGrid.locales.ka = {
grid: {
noDataContent: "მონაცემები ცარიელია.",
deleteConfirm: "ნამდვილად გსურთ ჩანაწერის წაშლა?",
pagerFormat: "გვერდები: {first} {prev} {pages} {next} {last} &nbsp;&nbsp; {pageIndex} - {pageCount} დან.",
pagePrevText: "<",
pageNextText: ">",
pageFirstText: "<<",
pageLastText: ">>",
loadMessage: "გთხოვთ დაიცადოთ...",
invalidMessage: "შეყვანილია არასწორი მონაცემები!"
},
loadIndicator: {
message: "მიმდინარეობს ჩატვირთვა..."
},
fields: {
control: {
searchModeButtonTooltip: "ძებნა",
insertModeButtonTooltip: "ჩანაწერის დამატება",
editButtonTooltip: "შესწორება",
deleteButtonTooltip: "წაშლა",
searchButtonTooltip: "ძებნა",
clearFilterButtonTooltip: "ფილტრის გასუფთავება",
insertButtonTooltip: "დამატება",
updateButtonTooltip: "შენახვა",
cancelEditButtonTooltip: "გაუქმება"
}
},
validators: {
required: { message: "ველი აუცილებელია შესავსებად." },
rangeLength: { message: "შეყვანილი ჩანაწერის ზომა არ ექვემდებარება დიაპაზონს." },
minLength: { message: "შეყვანილი ჩანაწერის ზომა საკმაოდ პატარა არის." },
maxLength: { message: "შეყვანილი ჩანაწერის ზომა საკმაოდ დიდი არის." },
pattern: { message: "შეყვანილი მნიშვნელობა არ ემთხვევა მითითებულ შაბლონს." },
range: { message: "შეყვანილი ინფორმაცია არ ჯდება დიაპაზონში." },
min: { message: "შეყვანილი ინფორმაციის ზომა საკმაოდ პატარა არის." },
max: { message: "შეყვანილი ინფორმაციის ზომა საკმაოდ დიდი არის." }
}
};
}(jsGrid, jQuery));

@ -0,0 +1,62 @@
(function(jsGrid) {
jsGrid.locales.pl = {
grid: {
noDataContent: "Nie znaleziono",
deleteConfirm: "Czy jesteś pewien?",
pagerFormat: "Strony: {first} {prev} {pages} {next} {last} &nbsp;&nbsp; {pageIndex} z {pageCount}",
pagePrevText: "Poprzednia",
pageNextText: "Następna",
pageFirstText: "Pierwsza",
pageLastText: "Ostatnia",
loadMessage: "Proszę czekać...",
invalidMessage: "Wprowadzono nieprawidłowe dane!"
},
loadIndicator: {
message: "Ładowanie..."
},
fields: {
control: {
searchModeButtonTooltip: "Wyszukiwanie",
insertModeButtonTooltip: "Dodawanie",
editButtonTooltip: "Edytuj",
deleteButtonTooltip: "Usuń",
searchButtonTooltip: "Szukaj",
clearFilterButtonTooltip: "Wyczyść filtr",
insertButtonTooltip: "Dodaj",
updateButtonTooltip: "Aktualizuj",
cancelEditButtonTooltip: "Anuluj edytowanie"
}
},
validators: {
required: {
message: "Pole jest wymagane"
},
rangeLength: {
message: "Długość wartości pola znajduje się poza zdefiniowanym zakresem"
},
minLength: {
message: "Wartość pola jest zbyt krótka"
},
maxLength: {
message: "Wartość pola jest zbyt długa"
},
pattern: {
message: "Wartość pola nie zgadza się ze zdefiniowanym wzorem"
},
range: {
message: "Wartość pola znajduje się poza zdefiniowanym zakresem"
},
min: {
message: "Wartość pola jest zbyt mała"
},
max: {
message: "Wartość pola jest zbyt duża"
}
}
};
}(jsGrid, jQuery));

@ -0,0 +1,46 @@
(function(jsGrid) {
jsGrid.locales["pt-br"] = {
grid: {
noDataContent: "Não encontrado",
deleteConfirm: "Você tem certeza que deseja remover este item?",
pagerFormat: "Páginas: {first} {prev} {pages} {next} {last} &nbsp;&nbsp; {pageIndex} de {pageCount}",
pagePrevText: "Anterior",
pageNextText: "Seguinte",
pageFirstText: "Primeira",
pageLastText: "Última",
loadMessage: "Por favor, espere...",
invalidMessage: "Dados inválidos!"
},
loadIndicator: {
message: "Carregando..."
},
fields: {
control: {
searchModeButtonTooltip: "Mudar para busca",
insertModeButtonTooltip: "Mudar para inserção",
editButtonTooltip: "Editar",
deleteButtonTooltip: "Remover",
searchButtonTooltip: "Buscar",
clearFilterButtonTooltip: "Remover filtro",
insertButtonTooltip: "Adicionar",
updateButtonTooltip: "Atualizar",
cancelEditButtonTooltip: "Cancelar Edição"
}
},
validators: {
required: { message: "Campo obrigatório" },
rangeLength: { message: "O valor esta fora do intervaldo definido" },
minLength: { message: "O comprimento do valor é muito curto" },
maxLength: { message: "O comprimento valor é muito longo" },
pattern: { message: "O valor informado não é compatível com o padrão" },
range: { message: "O valor informado esta fora do limite definido" },
min: { message: "O valor é muito curto" },
max: { message: "O valor é muito longo" }
}
};
}(jsGrid, jQuery));

@ -0,0 +1,46 @@
(function(jsGrid) {
jsGrid.locales.pt = {
grid: {
noDataContent: "Não encontrado",
deleteConfirm: "Você tem certeza que deseja remover este item?",
pagerFormat: "Páginas: {first} {prev} {pages} {next} {last} &nbsp;&nbsp; {pageIndex} de {pageCount}",
pagePrevText: "Anterior",
pageNextText: "Seguinte",
pageFirstText: "Primeira",
pageLastText: "Última",
loadMessage: "Por favor, espere...",
invalidMessage: "Dados inválidos!"
},
loadIndicator: {
message: "Carregando..."
},
fields: {
control: {
searchModeButtonTooltip: "Mudar para busca",
insertModeButtonTooltip: "Mudar para inserção",
editButtonTooltip: "Editar",
deleteButtonTooltip: "Remover",
searchButtonTooltip: "Buscar",
clearFilterButtonTooltip: "Remover filtro",
insertButtonTooltip: "Adicionar",
updateButtonTooltip: "Atualizar",
cancelEditButtonTooltip: "Cancelar Edição"
}
},
validators: {
required: { message: "Campo obrigatório" },
rangeLength: { message: "O valor esta fora do intervaldo definido" },
minLength: { message: "O comprimento do valor é muito curto" },
maxLength: { message: "O comprimento valor é muito longo" },
pattern: { message: "O valor informado não é compatível com o padrão" },
range: { message: "O valor informado esta fora do limite definido" },
min: { message: "O valor é muito curto" },
max: { message: "O valor é muito longo" }
}
};
}(jsGrid, jQuery));

@ -0,0 +1,47 @@
(function(jsGrid) {
jsGrid.locales.ru = {
grid: {
noDataContent: "Данных не найдено",
deleteConfirm: "Вы действительно хотите удалить запись?",
pagerFormat: "Страницы: {first} {prev} {pages} {next} {last} &nbsp;&nbsp; {pageIndex} из {pageCount}",
pagePrevText: "<",
pageNextText: ">",
pageFirstText: "<<",
pageLastText: ">>",
loadMessage: "Пожалуйста, подождите...",
invalidMessage: "Введены неверные данные!"
},
loadIndicator: {
message: "Загрузка..."
},
fields: {
control: {
searchModeButtonTooltip: "Поиск",
insertModeButtonTooltip: "Добавить запись",
editButtonTooltip: "Изменить",
deleteButtonTooltip: "Удалить",
searchButtonTooltip: "Найти",
clearFilterButtonTooltip: "Очистить фильтр",
insertButtonTooltip: "Добавить",
updateButtonTooltip: "Сохранить",
cancelEditButtonTooltip: "Отменить"
}
},
validators: {
required: { message: "Поле обязательно для заполения" },
rangeLength: { message: "Длинна введенного значения вне допустимого диапазона" },
minLength: { message: "Введенное значение слишком короткое" },
maxLength: { message: "Введенное значение слишком длинное" },
pattern: { message: "Введенное значение не соответствует заданному шаблону" },
range: { message: "Введенное значение вне допустимого диапазона" },
min: { message: "Введенное значение слишком маленькое" },
max: { message: "Введенное значение слишком большое" }
}
};
}(jsGrid, jQuery));

@ -0,0 +1,47 @@
(function(jsGrid) {
jsGrid.locales.tr = {
grid: {
noDataContent: "Kayıt Bulunamadı",
deleteConfirm: "Emin misiniz ?",
pagerFormat: "Sayfalar: {first} {prev} {pages} {next} {last} &nbsp;&nbsp; {pageIndex} / {pageCount}",
pagePrevText: "<",
pageNextText: ">",
pageFirstText: "<<",
pageLastText: ">>",
loadMessage: "Lütfen bekleyiniz...",
invalidMessage: "Geçersiz veri girişi !"
},
loadIndicator: {
message: "Yükleniyor..."
},
fields: {
control: {
searchModeButtonTooltip: "Arama moduna geç",
insertModeButtonTooltip: "Yeni kayıt moduna geç",
editButtonTooltip: "Değiştir",
deleteButtonTooltip: "Sil",
searchButtonTooltip: "Bul",
clearFilterButtonTooltip: "Filtreyi temizle",
insertButtonTooltip: "Ekle",
updateButtonTooltip: "Güncelle",
cancelEditButtonTooltip: "Güncelleme iptali"
}
},
validators: {
required: { message: "Gerekli alandır" },
rangeLength: { message: "Alan değerinin uzunluğu tanımlanan aralık dışındadır" },
minLength: { message: "Alan değeri çok kısadır" },
maxLength: { message: "Alan değeri çok uzundur" },
pattern: { message: "Alan değeri tanımlanan şablon ile eşleşmiyor" },
range: { message: "Alan değeri tanımlı aralığın dışındadır" },
min: { message: "Alan değeri çok küçüktür" },
max: { message: "Alan değeri çok büyüktür" }
}
};
}(jsGrid, jQuery));

@ -0,0 +1,46 @@
(function(jsGrid) {
jsGrid.locales["zh-cn"] = {
grid: {
noDataContent: "暂无数据",
deleteConfirm: "确认删除?",
pagerFormat: "页码: {first} {prev} {pages} {next} {last} &nbsp;&nbsp; {pageIndex} / {pageCount}",
pagePrevText: "上一页",
pageNextText: "下一页",
pageFirstText: "第一页",
pageLastText: "最后页",
loadMessage: "请稍后...",
invalidMessage: "数据有误!"
},
loadIndicator: {
message: "载入中..."
},
fields: {
control: {
searchModeButtonTooltip: "切换为搜索",
insertModeButtonTooltip: "切换为新增",
editButtonTooltip: "编辑",
deleteButtonTooltip: "删除",
searchButtonTooltip: "搜索",
clearFilterButtonTooltip: "清空过滤",
insertButtonTooltip: "插入",
updateButtonTooltip: "更新",
cancelEditButtonTooltip: "取消编辑"
}
},
validators: {
required: { message: "字段必填" },
rangeLength: { message: "字段值长度超过定义范围" },
minLength: { message: "字段长度过短" },
maxLength: { message: "字段长度过长" },
pattern: { message: "字段值不符合定义规则" },
range: { message: "字段值超过定义范围" },
min: { message: "字段值太小" },
max: { message: "字段值太大" }
}
};
}(jsGrid, jQuery));

@ -0,0 +1,46 @@
(function(jsGrid) {
jsGrid.locales["zh-tw"] = {
grid: {
noDataContent: "暫無資料",
deleteConfirm: "確認刪除?",
pagerFormat: "頁碼: {first} {prev} {pages} {next} {last} &nbsp;&nbsp; {pageIndex} / {pageCount}",
pagePrevText: "上一頁",
pageNextText: "下一頁",
pageFirstText: "第一頁",
pageLastText: "最後一頁",
loadMessage: "請稍候...",
invalidMessage: "輸入資料不正確"
},
loadIndicator: {
message: "載入中..."
},
fields: {
control: {
searchModeButtonTooltip: "切換為搜尋",
insertModeButtonTooltip: "切換為新增",
editButtonTooltip: "編輯",
deleteButtonTooltip: "刪除",
searchButtonTooltip: "搜尋",
clearFilterButtonTooltip: "清除搜尋條件",
insertButtonTooltip: "新增",
updateButtonTooltip: "修改",
cancelEditButtonTooltip: "取消編輯"
}
},
validators: {
required: { message: "欄位必填" },
rangeLength: { message: "欄位字串長度超出範圍" },
minLength: { message: "欄位字串長度太短" },
maxLength: { message: "欄位字串長度太長" },
pattern: { message: "欄位字串不符合規則" },
range: { message: "欄位數值超出範圍" },
min: { message: "欄位數值太小" },
max: { message: "欄位數值太大" }
}
};
}(jsGrid, jQuery));

File diff suppressed because it is too large Load Diff

@ -0,0 +1,72 @@
(function(jsGrid, $, undefined) {
function Field(config) {
$.extend(true, this, config);
this.sortingFunc = this._getSortingFunc();
}
Field.prototype = {
name: "",
title: null,
css: "",
align: "",
width: 100,
visible: true,
filtering: true,
inserting: true,
editing: true,
sorting: true,
sorter: "string", // name of SortStrategy or function to compare elements
headerTemplate: function() {
return (this.title === undefined || this.title === null) ? this.name : this.title;
},
itemTemplate: function(value, item) {
return value;
},
filterTemplate: function() {
return "";
},
insertTemplate: function() {
return "";
},
editTemplate: function(value, item) {
this._value = value;
return this.itemTemplate(value, item);
},
filterValue: function() {
return "";
},
insertValue: function() {
return "";
},
editValue: function() {
return this._value;
},
_getSortingFunc: function() {
var sorter = this.sorter;
if($.isFunction(sorter)) {
return sorter;
}
if(typeof sorter === "string") {
return jsGrid.sortStrategies[sorter];
}
throw Error("wrong sorter for the field \"" + this.name + "\"!");
}
};
jsGrid.Field = Field;
}(jsGrid, jQuery));

@ -0,0 +1,82 @@
(function(jsGrid, $, undefined) {
function LoadIndicator(config) {
this._init(config);
}
LoadIndicator.prototype = {
container: "body",
message: "Loading...",
shading: true,
zIndex: 1000,
shaderClass: "jsgrid-load-shader",
loadPanelClass: "jsgrid-load-panel",
_init: function(config) {
$.extend(true, this, config);
this._initContainer();
this._initShader();
this._initLoadPanel();
},
_initContainer: function() {
this._container = $(this.container);
},
_initShader: function() {
if(!this.shading)
return;
this._shader = $("<div>").addClass(this.shaderClass)
.hide()
.css({
position: "absolute",
top: 0,
right: 0,
bottom: 0,
left: 0,
zIndex: this.zIndex
})
.appendTo(this._container);
},
_initLoadPanel: function() {
this._loadPanel = $("<div>").addClass(this.loadPanelClass)
.text(this.message)
.hide()
.css({
position: "absolute",
top: "50%",
left: "50%",
zIndex: this.zIndex
})
.appendTo(this._container);
},
show: function() {
var $loadPanel = this._loadPanel.show();
var actualWidth = $loadPanel.outerWidth();
var actualHeight = $loadPanel.outerHeight();
$loadPanel.css({
marginTop: -actualHeight / 2,
marginLeft: -actualWidth / 2
});
this._shader.show();
},
hide: function() {
this._loadPanel.hide();
this._shader.hide();
}
};
jsGrid.LoadIndicator = LoadIndicator;
}(jsGrid, jQuery));

@ -0,0 +1,122 @@
(function(jsGrid, $, undefined) {
function DirectLoadingStrategy(grid) {
this._grid = grid;
}
DirectLoadingStrategy.prototype = {
firstDisplayIndex: function() {
var grid = this._grid;
return grid.option("paging") ? (grid.option("pageIndex") - 1) * grid.option("pageSize") : 0;
},
lastDisplayIndex: function() {
var grid = this._grid;
var itemsCount = grid.option("data").length;
return grid.option("paging")
? Math.min(grid.option("pageIndex") * grid.option("pageSize"), itemsCount)
: itemsCount;
},
itemsCount: function() {
return this._grid.option("data").length;
},
openPage: function(index) {
this._grid.refresh();
},
loadParams: function() {
return {};
},
sort: function() {
this._grid._sortData();
this._grid.refresh();
return $.Deferred().resolve().promise();
},
reset: function() {
this._grid.refresh();
return $.Deferred().resolve().promise();
},
finishLoad: function(loadedData) {
this._grid.option("data", loadedData);
},
finishInsert: function(insertedItem) {
var grid = this._grid;
grid.option("data").push(insertedItem);
grid.refresh();
},
finishDelete: function(deletedItem, deletedItemIndex) {
var grid = this._grid;
grid.option("data").splice(deletedItemIndex, 1);
grid.reset();
}
};
function PageLoadingStrategy(grid) {
this._grid = grid;
this._itemsCount = 0;
}
PageLoadingStrategy.prototype = {
firstDisplayIndex: function() {
return 0;
},
lastDisplayIndex: function() {
return this._grid.option("data").length;
},
itemsCount: function() {
return this._itemsCount;
},
openPage: function(index) {
this._grid.loadData();
},
loadParams: function() {
var grid = this._grid;
return {
pageIndex: grid.option("pageIndex"),
pageSize: grid.option("pageSize")
};
},
reset: function() {
return this._grid.loadData();
},
sort: function() {
return this._grid.loadData();
},
finishLoad: function(loadedData) {
this._itemsCount = loadedData.itemsCount;
this._grid.option("data", loadedData.data);
},
finishInsert: function(insertedItem) {
this._grid.search();
},
finishDelete: function(deletedItem, deletedItemIndex) {
this._grid.search();
}
};
jsGrid.loadStrategies = {
DirectLoadingStrategy: DirectLoadingStrategy,
PageLoadingStrategy: PageLoadingStrategy
};
}(jsGrid, jQuery));

@ -0,0 +1,36 @@
(function(jsGrid, $, undefined) {
var isDefined = function(val) {
return typeof(val) !== "undefined" && val !== null;
};
var sortStrategies = {
string: function(str1, str2) {
if(!isDefined(str1) && !isDefined(str2))
return 0;
if(!isDefined(str1))
return -1;
if(!isDefined(str2))
return 1;
return ("" + str1).localeCompare("" + str2);
},
number: function(n1, n2) {
return n1 - n2;
},
date: function(dt1, dt2) {
return dt1 - dt2;
},
numberAsString: function(n1, n2) {
return parseFloat(n1) - parseFloat(n2);
}
};
jsGrid.sortStrategies = sortStrategies;
}(jsGrid, jQuery));

@ -0,0 +1,135 @@
(function(jsGrid, $, undefined) {
function Validation(config) {
this._init(config);
}
Validation.prototype = {
_init: function(config) {
$.extend(true, this, config);
},
validate: function(args) {
var errors = [];
$.each(this._normalizeRules(args.rules), function(_, rule) {
if(rule.validator(args.value, args.item, rule.param))
return;
var errorMessage = $.isFunction(rule.message) ? rule.message(args.value, args.item) : rule.message;
errors.push(errorMessage);
});
return errors;
},
_normalizeRules: function(rules) {
if(!$.isArray(rules))
rules = [rules];
return $.map(rules, $.proxy(function(rule) {
return this._normalizeRule(rule);
}, this));
},
_normalizeRule: function(rule) {
if(typeof rule === "string")
rule = { validator: rule };
if($.isFunction(rule))
rule = { validator: rule };
if($.isPlainObject(rule))
rule = $.extend({}, rule);
else
throw Error("wrong validation config specified");
if($.isFunction(rule.validator))
return rule;
return this._applyNamedValidator(rule, rule.validator);
},
_applyNamedValidator: function(rule, validatorName) {
delete rule.validator;
var validator = validators[validatorName];
if(!validator)
throw Error("unknown validator \"" + validatorName + "\"");
if($.isFunction(validator)) {
validator = { validator: validator };
}
return $.extend({}, validator, rule);
}
};
jsGrid.Validation = Validation;
var validators = {
required: {
message: "Field is required",
validator: function(value) {
return value !== undefined && value !== null && value !== "";
}
},
rangeLength: {
message: "Field value length is out of the defined range",
validator: function(value, _, param) {
return value.length >= param[0] && value.length <= param[1];
}
},
minLength: {
message: "Field value is too short",
validator: function(value, _, param) {
return value.length >= param;
}
},
maxLength: {
message: "Field value is too long",
validator: function(value, _, param) {
return value.length <= param;
}
},
pattern: {
message: "Field value is not matching the defined pattern",
validator: function(value, _, param) {
if(typeof param === "string") {
param = new RegExp("^(?:" + param + ")$");
}
return param.test(value);
}
},
range: {
message: "Field value is out of the defined range",
validator: function(value, _, param) {
return value >= param[0] && value <= param[1];
}
},
min: {
message: "Field value is too small",
validator: function(value, _, param) {
return value >= param;
}
},
max: {
message: "Field value is too large",
validator: function(value, _, param) {
return value <= param;
}
}
};
jsGrid.validators = validators;
}(jsGrid, jQuery));

@ -0,0 +1,37 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JSGrid QUnit Tests</title>
<link rel="stylesheet" href="../external/qunit/qunit-1.10.0.css">
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture">
<div id="jsGrid"></div>
</div>
<script src="../external/qunit/qunit-1.10.0.js"></script>
<script src="../external/jquery/jquery-1.8.3.js"></script>
<script src="../src/jsgrid.core.js"></script>
<script src="../src/jsgrid.load-indicator.js"></script>
<script src="../src/jsgrid.load-strategies.js"></script>
<script src="../src/jsgrid.sort-strategies.js"></script>
<script src="../src/jsgrid.validation.js"></script>
<script src="../src/jsgrid.field.js"></script>
<script src="../src/fields/jsgrid.field.text.js"></script>
<script src="../src/fields/jsgrid.field.number.js"></script>
<script src="../src/fields/jsgrid.field.textarea.js"></script>
<script src="../src/fields/jsgrid.field.checkbox.js"></script>
<script src="../src/fields/jsgrid.field.select.js"></script>
<script src="../src/fields/jsgrid.field.control.js"></script>
<script src="jsgrid.tests.js"></script>
<script src="jsgrid.field.tests.js"></script>
<script src="jsgrid.sort-strategies.tests.js"></script>
<script src="jsgrid.validation.tests.js"></script>
</body>
</html>

@ -0,0 +1,461 @@
$(function() {
var Grid = jsGrid.Grid;
module("common field config", {
setup: function() {
this.isFieldExcluded = function(FieldClass) {
return FieldClass === jsGrid.ControlField;
};
}
});
test("filtering=false prevents rendering filter template", function() {
var isFieldExcluded = this.isFieldExcluded;
$.each(jsGrid.fields, function(name, FieldClass) {
if(isFieldExcluded(FieldClass))
return;
var field = new FieldClass({ filtering: false });
equal(field.filterTemplate(), "", "empty filter template for field " + name);
});
});
test("inserting=false prevents rendering insert template", function() {
var isFieldExcluded = this.isFieldExcluded;
$.each(jsGrid.fields, function(name, FieldClass) {
if(isFieldExcluded(FieldClass))
return;
var field = new FieldClass({ inserting: false });
equal(field.insertTemplate(), "", "empty insert template for field " + name);
});
});
test("editing=false renders itemTemplate", function() {
var isFieldExcluded = this.isFieldExcluded;
$.each(jsGrid.fields, function(name, FieldClass) {
if(isFieldExcluded(FieldClass))
return;
var item = {
field: "test"
};
var args;
var field = new FieldClass({
editing: false,
itemTemplate: function() {
args = arguments;
FieldClass.prototype.itemTemplate.apply(this, arguments);
}
});
var itemTemplate = field.itemTemplate("test", item);
var editTemplate = field.editTemplate("test", item);
var editTemplateContent = editTemplate instanceof jQuery ? editTemplate[0].outerHTML : editTemplate;
var itemTemplateContent = itemTemplate instanceof jQuery ? itemTemplate[0].outerHTML : itemTemplate;
equal(editTemplateContent, itemTemplateContent, "item template is rendered instead of edit template for " + name);
equal(args.length, 2, "passed both arguments for " + name);
equal(args[0], "test", "field value passed as a first argument for " + name);
equal(args[1], item, "item passed as a second argument for " + name);
});
});
module("jsGrid.field");
test("basic", function() {
var customSortingFunc = function() {
return 1;
},
field = new jsGrid.Field({
name: "testField",
title: "testTitle",
sorter: customSortingFunc
});
equal(field.headerTemplate(), "testTitle");
equal(field.itemTemplate("testValue"), "testValue");
equal(field.filterTemplate(), "");
equal(field.insertTemplate(), "");
equal(field.editTemplate("testValue"), "testValue");
strictEqual(field.filterValue(), "");
strictEqual(field.insertValue(), "");
strictEqual(field.editValue(), "testValue");
strictEqual(field.sortingFunc, customSortingFunc);
});
module("jsGrid.field.text");
test("basic", function() {
var field = new jsGrid.TextField({ name: "testField" });
equal(field.itemTemplate("testValue"), "testValue");
equal(field.filterTemplate()[0].tagName.toLowerCase(), "input");
equal(field.insertTemplate()[0].tagName.toLowerCase(), "input");
equal(field.editTemplate("testEditValue")[0].tagName.toLowerCase(), "input");
strictEqual(field.filterValue(), "");
strictEqual(field.insertValue(), "");
strictEqual(field.editValue(), "testEditValue");
});
test("set default field options with setDefaults", function() {
jsGrid.setDefaults("text", {
defaultOption: "test"
});
var $element = $("#jsGrid").jsGrid({
fields: [{ type: "text" }]
});
equal($element.jsGrid("option", "fields")[0].defaultOption, "test", "default field option set");
});
module("jsGrid.field.number");
test("basic", function() {
var field = new jsGrid.NumberField({ name: "testField" });
equal(field.itemTemplate(5), "5");
equal(field.filterTemplate()[0].tagName.toLowerCase(), "input");
equal(field.insertTemplate()[0].tagName.toLowerCase(), "input");
equal(field.editTemplate(6)[0].tagName.toLowerCase(), "input");
strictEqual(field.filterValue(), undefined);
strictEqual(field.insertValue(), undefined);
strictEqual(field.editValue(), 6);
});
module("jsGrid.field.textArea");
test("basic", function() {
var field = new jsGrid.TextAreaField({ name: "testField" });
equal(field.itemTemplate("testValue"), "testValue");
equal(field.filterTemplate()[0].tagName.toLowerCase(), "input");
equal(field.insertTemplate()[0].tagName.toLowerCase(), "textarea");
equal(field.editTemplate("testEditValue")[0].tagName.toLowerCase(), "textarea");
strictEqual(field.insertValue(), "");
strictEqual(field.editValue(), "testEditValue");
});
module("jsGrid.field.checkbox");
test("basic", function() {
var field = new jsGrid.CheckboxField({ name: "testField" }),
itemTemplate,
filterTemplate,
insertTemplate,
editTemplate;
itemTemplate = field.itemTemplate("testValue");
equal(itemTemplate[0].tagName.toLowerCase(), "input");
equal(itemTemplate.attr("type"), "checkbox");
equal(itemTemplate.attr("disabled"), "disabled");
filterTemplate = field.filterTemplate();
equal(filterTemplate[0].tagName.toLowerCase(), "input");
equal(filterTemplate.attr("type"), "checkbox");
equal(filterTemplate.prop("indeterminate"), true);
insertTemplate = field.insertTemplate();
equal(insertTemplate[0].tagName.toLowerCase(), "input");
equal(insertTemplate.attr("type"), "checkbox");
editTemplate = field.editTemplate(true);
equal(editTemplate[0].tagName.toLowerCase(), "input");
equal(editTemplate.attr("type"), "checkbox");
equal(editTemplate.is(":checked"), true);
strictEqual(field.filterValue(), undefined);
strictEqual(field.insertValue(), false);
strictEqual(field.editValue(), true);
});
module("jsGrid.field.select");
test("basic", function() {
var field,
filterTemplate,
insertTemplate,
editTemplate;
field = new jsGrid.SelectField({
name: "testField",
items: ["test1", "test2", "test3"],
selectedIndex: 1
});
equal(field.itemTemplate(1), "test2");
filterTemplate = field.filterTemplate();
equal(filterTemplate[0].tagName.toLowerCase(), "select");
equal(filterTemplate.children().length, 3);
insertTemplate = field.insertTemplate();
equal(insertTemplate[0].tagName.toLowerCase(), "select");
equal(insertTemplate.children().length, 3);
editTemplate = field.editTemplate(2);
equal(editTemplate[0].tagName.toLowerCase(), "select");
equal(editTemplate.find("option:selected").length, 1);
ok(editTemplate.children().eq(2).is(":selected"));
strictEqual(field.filterValue(), 1);
strictEqual(field.insertValue(), 1);
strictEqual(field.editValue(), 2);
});
test("items as array of integers", function() {
var field,
filterTemplate,
insertTemplate,
editTemplate;
field = new jsGrid.SelectField({
name: "testField",
items: [0, 10, 20],
selectedIndex: 0
});
strictEqual(field.itemTemplate(0), 0);
filterTemplate = field.filterTemplate();
equal(filterTemplate[0].tagName.toLowerCase(), "select");
equal(filterTemplate.children().length, 3);
insertTemplate = field.insertTemplate();
equal(insertTemplate[0].tagName.toLowerCase(), "select");
equal(insertTemplate.children().length, 3);
editTemplate = field.editTemplate(1);
equal(editTemplate[0].tagName.toLowerCase(), "select");
equal(editTemplate.find("option:selected").length, 1);
ok(editTemplate.children().eq(1).is(":selected"));
strictEqual(field.filterValue(), 0);
strictEqual(field.insertValue(), 0);
strictEqual(field.editValue(), 1);
});
test("string value type", function() {
var field = new jsGrid.SelectField({
name: "testField",
items: [
{ text: "test1", value: "1" },
{ text: "test2", value: "2" },
{ text: "test3", value: "3" }
],
textField: "text",
valueField: "value",
valueType: "string",
selectedIndex: 1
});
field.filterTemplate();
strictEqual(field.filterValue(), "2");
field.editTemplate("2");
strictEqual(field.editValue(), "2");
field.insertTemplate();
strictEqual(field.insertValue(), "2");
});
test("value type auto-defined", function() {
var field = new jsGrid.SelectField({
name: "testField",
items: [
{ text: "test1", value: "1" },
{ text: "test2", value: "2" },
{ text: "test3", value: "3" }
],
textField: "text",
valueField: "value",
selectedIndex: 1
});
strictEqual(field.sorter, "string", "sorter set according to value type");
field.filterTemplate();
strictEqual(field.filterValue(), "2");
field.editTemplate("2");
strictEqual(field.editValue(), "2");
field.insertTemplate();
strictEqual(field.insertValue(), "2");
});
test("value type defaulted to string", function() {
var field = new jsGrid.SelectField({
name: "testField",
items: [
{ text: "test1" },
{ text: "test2", value: "2" }
],
textField: "text",
valueField: "value"
});
strictEqual(field.sorter, "string", "sorter set to string if first item has no value field");
});
test("object items", function() {
var field = new jsGrid.SelectField({
name: "testField",
items: [
{ text: "test1", value: 1 },
{ text: "test2", value: 2 },
{ text: "test3", value: 3 }
]
});
strictEqual(field.itemTemplate(1), field.items[1]);
field.textField = "text";
strictEqual(field.itemTemplate(1), "test2");
field.textField = "";
field.valueField = "value";
strictEqual(field.itemTemplate(1), field.items[0]);
ok(field.editTemplate(2));
strictEqual(field.editValue(), 2);
field.textField = "text";
strictEqual(field.itemTemplate(1), "test1");
});
module("jsGrid.field.control");
test("basic", function() {
var field,
itemTemplate,
headerTemplate,
filterTemplate,
insertTemplate,
editTemplate;
field = new jsGrid.ControlField();
field._grid = {
filtering: true,
inserting: true,
option: $.noop
};
itemTemplate = field.itemTemplate("any_value");
equal(itemTemplate.filter("." + field.editButtonClass).length, 1);
equal(itemTemplate.filter("." + field.deleteButtonClass).length, 1);
headerTemplate = field.headerTemplate();
equal(headerTemplate.filter("." + field.insertModeButtonClass).length, 1);
var $modeSwitchButton = headerTemplate.filter("." + field.modeButtonClass);
$modeSwitchButton.trigger("click");
equal(headerTemplate.filter("." + field.searchModeButtonClass).length, 1);
filterTemplate = field.filterTemplate();
equal(filterTemplate.filter("." + field.searchButtonClass).length, 1);
equal(filterTemplate.filter("." + field.clearFilterButtonClass).length, 1);
insertTemplate = field.insertTemplate();
equal(insertTemplate.filter("." + field.insertButtonClass).length, 1);
editTemplate = field.editTemplate("any_value");
equal(editTemplate.filter("." + field.updateButtonClass).length, 1);
equal(editTemplate.filter("." + field.cancelEditButtonClass).length, 1);
strictEqual(field.filterValue(), "");
strictEqual(field.insertValue(), "");
strictEqual(field.editValue(), "");
});
test("switchMode button should consider filtering=false", function() {
var optionArgs = {};
var field = new jsGrid.ControlField();
field._grid = {
filtering: false,
inserting: true,
option: function(name, value) {
optionArgs = {
name: name,
value: value
};
}
};
var headerTemplate = field.headerTemplate();
equal(headerTemplate.filter("." + field.insertModeButtonClass).length, 1, "inserting switch button rendered");
var $modeSwitchButton = headerTemplate.filter("." + field.modeButtonClass);
$modeSwitchButton.trigger("click");
ok($modeSwitchButton.hasClass(field.modeOnButtonClass), "on class is attached");
equal(headerTemplate.filter("." + field.insertModeButtonClass).length, 1, "insert button rendered");
equal(headerTemplate.filter("." + field.searchModeButtonClass).length, 0, "search button not rendered");
deepEqual(optionArgs, { name: "inserting", value: true }, "turn on grid inserting mode");
$modeSwitchButton.trigger("click");
ok(!$modeSwitchButton.hasClass(field.modeOnButtonClass), "on class is detached");
deepEqual(optionArgs, { name: "inserting", value: false }, "turn off grid inserting mode");
});
test("switchMode button should consider inserting=false", function() {
var optionArgs = {};
var field = new jsGrid.ControlField();
field._grid = {
filtering: true,
inserting: false,
option: function(name, value) {
optionArgs = {
name: name,
value: value
};
}
};
var headerTemplate = field.headerTemplate();
equal(headerTemplate.filter("." + field.searchModeButtonClass).length, 1, "filtering switch button rendered");
var $modeSwitchButton = headerTemplate.filter("." + field.modeButtonClass);
$modeSwitchButton.trigger("click");
ok(!$modeSwitchButton.hasClass(field.modeOnButtonClass), "on class is detached");
equal(headerTemplate.filter("." + field.searchModeButtonClass).length, 1, "search button rendered");
equal(headerTemplate.filter("." + field.insertModeButtonClass).length, 0, "insert button not rendered");
deepEqual(optionArgs, { name: "filtering", value: false }, "turn off grid filtering mode");
$modeSwitchButton.trigger("click");
ok($modeSwitchButton.hasClass(field.modeOnButtonClass), "on class is attached");
deepEqual(optionArgs, { name: "filtering", value: true }, "turn on grid filtering mode");
});
test("switchMode is not rendered if inserting=false and filtering=false", function() {
var optionArgs = {};
var field = new jsGrid.ControlField();
field._grid = {
filtering: false,
inserting: false
};
var headerTemplate = field.headerTemplate();
strictEqual(headerTemplate, "", "empty header");
});
});

@ -0,0 +1,51 @@
$(function() {
var sortStrategies = jsGrid.sortStrategies;
module("sortStrategies");
test("string sorting", function() {
var data = ["c", "a", "d", "b"];
data.sort(sortStrategies["string"]);
deepEqual(data, ["a", "b", "c", "d"]);
});
test("string sorting should be robust", function() {
var data = ["a", 1, true, "b"];
data.sort(sortStrategies["string"]);
deepEqual(data, [1, "a", "b", true]);
});
test("number sorting", function() {
var data = [5, 3.2, 1e2, 4];
data.sort(sortStrategies["number"]);
deepEqual(data, [3.2, 4, 5, 100]);
});
test("date sorting", function() {
var date1 = new Date(2010, 0, 1),
date2 = new Date(2011, 0, 1),
date3 = new Date(2012, 0, 1);
var data = [date2, date3, date1];
data.sort(sortStrategies["date"]);
deepEqual(data, [date1, date2, date3]);
});
test("numberAsString sorting", function() {
var data = [".1", "2.1", "4e5", "2"];
data.sort(sortStrategies["numberAsString"]);
deepEqual(data, [".1", "2", "2.1", "4e5"]);
});
});

File diff suppressed because it is too large Load Diff

@ -0,0 +1,279 @@
$(function() {
var validators = jsGrid.validators;
module("validation.validate", {
setup: function() {
this.validation = new jsGrid.Validation();
}
});
test("as function", function() {
var validateFunction = function(value) {
return value === "test";
};
deepEqual(this.validation.validate({
value: "not_test",
rules: validateFunction
}), [undefined]);
deepEqual(this.validation.validate({
value: "test",
rules: validateFunction
}), []);
});
test("as rule config", function() {
var validateRule = {
validator: function(value) {
return value === "test";
},
message: "Error"
};
deepEqual(this.validation.validate({
value: "not_test",
rules: validateRule
}), ["Error"]);
deepEqual(this.validation.validate({
value: "test",
rules: validateRule
}), []);
});
test("as rule config with param", function() {
var validateRule = {
validator: function(value, item, param) {
return value === param;
},
param: "test",
message: "Error"
};
deepEqual(this.validation.validate({
value: "not_test",
rules: validateRule
}), ["Error"]);
deepEqual(this.validation.validate({
value: "test",
rules: validateRule
}), []);
});
test("as array of rules", function() {
var validateRules = [{
message: "Error",
validator: function(value) {
return value !== "";
}
}, {
validator: function(value) {
return value === "test";
}
}];
deepEqual(this.validation.validate({
value: "",
rules: validateRules
}), ["Error", undefined]);
deepEqual(this.validation.validate({
value: "test",
rules: validateRules
}), []);
});
test("as string", function() {
validators.test_validator = function(value) {
return value === "test";
};
deepEqual(this.validation.validate({
value: "not_test",
rules: "test_validator"
}), [undefined]);
deepEqual(this.validation.validate({
value: "test",
rules: "test_validator"
}), []);
delete validators.test_validator;
});
test("as rule config with validator as string", function() {
validators.test_validator = function(value) {
return value === "test";
};
var validateRule = {
validator: "test_validator",
message: "Error"
};
deepEqual(this.validation.validate({
value: "not_test",
rules: validateRule
}), ["Error"]);
deepEqual(this.validation.validate({
value: "test",
rules: validateRule
}), []);
delete validators.test_validator;
});
test("as array of mixed rules", function() {
validators.test_validator = function(value) {
return value === "test";
};
var validationRules = [
"test_validator",
function(value) {
return value !== "";
}, {
validator: function(value) {
return value === "test";
},
message: "Error"
}
];
deepEqual(this.validation.validate({
value: "",
rules: validationRules
}), [undefined, undefined, "Error"]);
deepEqual(this.validation.validate({
value: "not_test",
rules: validationRules
}), [undefined, "Error"]);
deepEqual(this.validation.validate({
value: "test",
rules: validationRules
}), []);
delete validators.test_validator;
});
test("as string validator with default error message", function() {
validators.test_validator = {
message: function(value) {
return "Error: " + value;
},
validator: function(value) {
return value === "test";
}
};
var validateRule = {
validator: "test_validator"
};
deepEqual(this.validation.validate({
value: "not_test",
rules: validateRule
}), ["Error: not_test"]);
deepEqual(this.validation.validate({
value: "test",
rules: validateRule
}), []);
delete validators.test_validator;
});
test("throws exception for unknown validator", function() {
var validateRule = {
validator: "unknown_validator"
};
var validation = this.validation;
throws(function() {
validation.validate({
value: "test",
rules: validateRule
});
}, /unknown validator "unknown_validator"/, "exception for unknown validator");
});
module("validators", {
setup: function() {
var validation = new jsGrid.Validation();
this.testValidator = function(validator, value, param) {
var result = validation.validate({
value: value,
rules: { validator: validator, param: param }
});
return !result.length;
}
}
});
test("required", function() {
equal(this.testValidator("required", ""), false);
equal(this.testValidator("required", undefined), false);
equal(this.testValidator("required", null), false);
equal(this.testValidator("required", 0), true);
equal(this.testValidator("required", "test"), true);
});
test("rangeLength", function() {
equal(this.testValidator("rangeLength", "123456", [0, 5]), false);
equal(this.testValidator("rangeLength", "", [1, 5]), false);
equal(this.testValidator("rangeLength", "123", [0, 5]), true);
equal(this.testValidator("rangeLength", "", [0, 5]), true);
equal(this.testValidator("rangeLength", "12345", [0, 5]), true);
});
test("minLength", function() {
equal(this.testValidator("minLength", "123", 5), false);
equal(this.testValidator("minLength", "12345", 5), true);
equal(this.testValidator("minLength", "123456", 5), true);
});
test("maxLength", function() {
equal(this.testValidator("maxLength", "123456", 5), false);
equal(this.testValidator("maxLength", "12345", 5), true);
equal(this.testValidator("maxLength", "123", 5), true);
});
test("pattern", function() {
equal(this.testValidator("pattern", "_13_", "1?3"), false);
equal(this.testValidator("pattern", "13", "1?3"), true);
equal(this.testValidator("pattern", "3", "1?3"), true);
equal(this.testValidator("pattern", "_13_", /1?3/), true);
});
test("range", function() {
equal(this.testValidator("range", 6, [0, 5]), false);
equal(this.testValidator("range", 0, [1, 5]), false);
equal(this.testValidator("range", 3, [0, 5]), true);
equal(this.testValidator("range", 0, [0, 5]), true);
equal(this.testValidator("range", 5, [0, 5]), true);
});
test("min", function() {
equal(this.testValidator("min", 3, 5), false);
equal(this.testValidator("min", 5, 5), true);
equal(this.testValidator("min", 6, 5), true);
});
test("max", function() {
equal(this.testValidator("max", 6, 5), false);
equal(this.testValidator("max", 5, 5), true);
equal(this.testValidator("max", 3, 5), true);
});
});

@ -0,0 +1,15 @@
<link type="text/css" rel="stylesheet" href="{{ context }}/static/js/jsgrid/jsgrid.min.css" >
<link type="text/css" rel="stylesheet" href="{{ context }}/static/js/jsgrid/jsgrid-theme.min.css" >
<link href="{{ context }}/static/css/default.css" rel="stylesheet">
<script src="{{ context }}/static/js/jquery/jquery.min.js"></script>
<script src="{{ context }}/static/js/jsgrid/jsgrid.js"></script>
<title></title>
<body>
<div class="caption">
<div class="left" align="center">Process Monitoring
<div class="small">Latest Process Logs</div>
</div>
</div>
</body>
Loading…
Cancel
Save