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,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"
 | 
				
			||||
    }
 | 
				
			||||
}
 | 
				
			||||
| 
		 After Width: | Height: | Size: 15 KiB  | 
| 
		 After Width: | Height: | Size: 6.5 KiB  | 
@ -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,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,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,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,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
												
											
										
									
								
											
												
													File diff suppressed because it is too large
													Load Diff
												
											
										
									
								
											
												
													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}    {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}    {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}    {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}    {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}    {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}    {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}    {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}    {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}    {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-cn"] = {
 | 
				
			||||
        grid: {
 | 
				
			||||
            noDataContent: "暂无数据",
 | 
				
			||||
            deleteConfirm: "确认删除?",
 | 
				
			||||
            pagerFormat: "页码: {first} {prev} {pages} {next} {last}    {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}    {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…
					
					
				
		Reference in new issue