Grid with filtering, editing, inserting, deleting, sorting and paging. Data provided by controller. Read about controller interface in the docs.
Simple grid with static data. Provide an array to option data in config.
Controller loadData method requests data from OData service with ajax. Any asynchronous source could be used instead. Just return jQuery.promise from controller method. Field option itemTemplate allows to render any custom cell content, just return your markup as string, DOM Node or jQuery Element.
The API methods updateItem, insertItem and deleteItem allow editing from outside of the grid with ease. This demo shows how to implement editing and inserting data to the grid with external details dialog. Here for popup we use jQuery UI dialog plugin. The jQuery Validation Plugin is used for form validation.
Sorting can be done not only with column header interaction, but also with sort method.
Grid supports field values validation for inserting and editing. There are plenty of built-in validators available. Furthermore custom validators can be easily added.
Grid supports localization. Find how to set locale and register custom locale in the Localization section.
Grid allows to load data by pages. It helps to reduce data loading time and of course necessary for large data sources.
All components of the grid can be easily configured. Heading, filtering, inserting, editing, sorting, paging and row selection could be switched with a single corresponding boolean option.
Grid rows can be completely customized. There are special row renderer functions. To customize data row use rowRenderer.
Cell content of every column can be customized with itemTemplate, headerTemplate, filterTemplate and insertTemplate functions specified in field config. This example shows how to implement batch deleting with custom field for selecting items.
Rows reordering is a popular use case of a grid. This example shows how to implement it using jQuery UI Sortable plugin.
The pager could be placed anywhere outside of the grid. Just specify pagerContainer option.
All existing grid fields (columns) can be easily customized and new field types could be added. Here we create custom date column with jQuery UI datepicker.
$(function() { $("#jsGrid").jsGrid({ height: "90%", width: "100%", filtering: true, editing: true, sorting: true, paging: true, autoload: true, pageSize: 15, pageButtonCount: 5, deleteConfirm: "Do you really want to delete the client?", controller: db, fields: [ { name: "Name", type: "text", width: 150 }, { name: "Age", type: "number", width: 50 }, { name: "Address", type: "text", width: 200 }, { name: "Country", type: "select", items: db.countries, valueField: "Id", textField: "Name" }, { name: "Married", type: "checkbox", title: "Is Married", sorting: false }, { type: "control" } ] }); });
$(function() { $("#jsGrid").jsGrid({ height: "90%", width: "100%", sorting: true, paging: true, data: db.clients, 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" } ] }); });
$(function() { $("#jsGrid").jsGrid({ height: "auto", width: "100%", sorting: true, paging: false, autoload: true, controller: { loadData: function() { var d = $.Deferred(); $.ajax({ url: "http://services.odata.org/V3/(S(3mnweai3qldmghnzfshavfok))/OData/OData.svc/Products", dataType: "json" }).done(function(response) { d.resolve(response.value); }); return d.promise(); } }, fields: [ { name: "Name", type: "text" }, { name: "Description", type: "textarea", width: 150 }, { name: "Rating", type: "number", width: 50, align: "center", itemTemplate: function(value) { return $("<div>").addClass("rating").append(Array(value + 1).join("★")); } }, { name: "Price", type: "number", width: 50, itemTemplate: function(value) { return value.toFixed(2) + "$"; } } ] }); });
$(function() { $("#jsGrid").jsGrid({ height: "70%", width: "100%", editing: true, autoload: true, paging: true, deleteConfirm: function(item) { return "The client \"" + item.Name + "\" will be removed. Are you sure?"; }, rowClick: function(args) { showDetailsDialog("Edit", args.item); }, controller: db, fields: [ { name: "Name", type: "text", width: 150 }, { name: "Age", type: "number", width: 50 }, { name: "Address", type: "text", width: 200 }, { name: "Country", type: "select", items: db.countries, valueField: "Id", textField: "Name" }, { name: "Married", type: "checkbox", title: "Is Married", sorting: false }, { type: "control", modeSwitchButton: false, editButton: false, headerTemplate: function() { return $("<button>").attr("type", "button").text("Add") .on("click", function () { showDetailsDialog("Add", {}); }); } } ] }); $("#detailsDialog").dialog({ autoOpen: false, width: 400, close: function() { $("#detailsForm").validate().resetForm(); $("#detailsForm").find(".error").removeClass("error"); } }); $("#detailsForm").validate({ rules: { name: "required", age: { required: true, range: [18, 150] }, address: { required: true, minlength: 10 }, country: "required" }, messages: { name: "Please enter name", age: "Please enter valid age", address: "Please enter address (more than 10 chars)", country: "Please select country" }, submitHandler: function() { formSubmitHandler(); } }); var formSubmitHandler = $.noop; var showDetailsDialog = function(dialogType, client) { $("#name").val(client.Name); $("#age").val(client.Age); $("#address").val(client.Address); $("#country").val(client.Country); $("#married").prop("checked", client.Married); formSubmitHandler = function() { saveClient(client, dialogType === "Add"); }; $("#detailsDialog").dialog("option", "title", dialogType + " Client") .dialog("open"); }; var saveClient = function(client, isNew) { $.extend(client, { Name: $("#name").val(), Age: parseInt($("#age").val(), 10), Address: $("#address").val(), Country: parseInt($("#country").val(), 10), Married: $("#married").is(":checked") }); $("#jsGrid").jsGrid(isNew ? "insertItem" : "updateItem", client); $("#detailsDialog").dialog("close"); }; });
$(function() { $("#jsGrid").jsGrid({ height: "80%", width: "100%", autoload: true, selecting: false, controller: db, fields: [ { name: "Name", type: "text", width: 150 }, { name: "Age", type: "number", width: 50 }, { name: "Address", type: "text", width: 200 }, { name: "Country", type: "select", items: db.countries, valueField: "Id", textField: "Name" }, { name: "Married", type: "checkbox", title: "Is Married" } ] }); $("#sort").click(function() { var field = $("#sortingField").val(); $("#jsGrid").jsGrid("sort", field); }); });
$(function() { $("#jsGrid").jsGrid({ height: "70%", width: "100%", filtering: true, editing: true, inserting: true, sorting: true, paging: true, autoload: true, pageSize: 15, pageButtonCount: 5, deleteConfirm: "Do you really want to delete the client?", controller: db, fields: [ { name: "Name", type: "text", width: 150, validate: "required" }, { name: "Age", type: "number", width: 50, validate: { validator: "range", param: [18, 80] } }, { name: "Address", type: "text", width: 200, validate: { validator: "rangeLength", param: [10, 250] } }, { name: "Country", type: "select", items: db.countries, valueField: "Id", textField: "Name", validate: { message: "Country should be specified", validator: function(value) { return value > 0; } } }, { name: "Married", type: "checkbox", title: "Is Married", sorting: false }, { type: "control" } ] }); });
$(function() { jsGrid.locale("fr"); $("#jsGrid").jsGrid({ height: "70%", width: "100%", filtering: true, editing: true, inserting: true, sorting: true, paging: true, autoload: true, pageSize: 15, pageButtonCount: 5, controller: db, fields: [ { name: "Name", title: "Nom", type: "text", width: 150, validate: "required" }, { name: "Age", title: "Âge", type: "number", width: 50, validate: { validator: "range", param: [18,80] } }, { name: "Address", title: "Adresse", type: "text", width: 200, validate: { validator: "rangeLength", param: [10, 250] } }, { name: "Country", title: "Pays", type: "select", items: db.countries, valueField: "Id", textField: "Name" }, { name: "Married", title: "Marié", type: "checkbox", sorting: false }, { type: "control" } ] }); });
$(function() { $("#jsGrid").jsGrid({ height: "80%", width: "100%", autoload: true, paging: true, pageLoading: true, pageSize: 15, pageIndex: 2, controller: { loadData: function(filter) { var startIndex = (filter.pageIndex - 1) * filter.pageSize; return { data: db.clients.slice(startIndex, startIndex + filter.pageSize), itemsCount: db.clients.length }; } }, fields: [ { name: "Name", type: "text", width: 150 }, { name: "Age", type: "number", width: 50 }, { name: "Address", type: "text", width: 200 }, { name: "Country", type: "select", items: db.countries, valueField: "Id", textField: "Name" }, { name: "Married", type: "checkbox", title: "Is Married" } ] }); $("#pager").on("change", function() { var page = parseInt($(this).val(), 10); $("#jsGrid").jsGrid("openPage", page); }); });
$(function() { $("#jsGrid").jsGrid({ height: "80%", width: "100%", filtering: true, editing: true, sorting: true, paging: true, autoload: true, pageSize: 15, pageButtonCount: 5, controller: db, fields: [ { name: "Name", type: "text", width: 150 }, { name: "Age", type: "number", width: 50 }, { name: "Address", type: "text", width: 200 }, { name: "Country", type: "select", items: db.countries, valueField: "Id", textField: "Name" }, { name: "Married", type: "checkbox", title: "Is Married", sorting: false }, { type: "control", modeSwitchButton: false, editButton: false } ] }); $(".config-panel input[type=checkbox]").on("click", function() { var $cb = $(this); $("#jsGrid").jsGrid("option", $cb.attr("id"), $cb.is(":checked")); }); });
$(function() { $("#jsGrid").jsGrid({ height: "90%", width: "100%", autoload: true, paging: true, controller: { loadData: function() { var deferred = $.Deferred(); $.ajax({ url: 'http://api.randomuser.me/?results=40', dataType: 'jsonp', success: function(data){ deferred.resolve(data.results); } }); return deferred.promise(); } }, rowRenderer: function(item) { var user = item; var $photo = $("<div>").addClass("client-photo").append($("<img>").attr("src", user.picture.large)); var $info = $("<div>").addClass("client-info") .append($("<p>").append($("<strong>").text(user.name.first.capitalize() + " " + user.name.last.capitalize()))) .append($("<p>").text("Location: " + user.location.city.capitalize() + ", " + user.location.street)) .append($("<p>").text("Email: " + user.email)) .append($("<p>").text("Phone: " + user.phone)) .append($("<p>").text("Cell: " + user.cell)); return $("<tr>").append($("<td>").append($photo).append($info)); }, fields: [ { title: "Clients" } ] }); String.prototype.capitalize = function() { return this.charAt(0).toUpperCase() + this.slice(1); }; });
$(function() { $("#jsGrid").jsGrid({ height: "50%", width: "100%", autoload: true, confirmDeleting: false, paging: true, controller: { loadData: function() { return db.clients; } }, fields: [ { headerTemplate: function() { return $("<button>").attr("type", "button").text("Delete") .on("click", function () { deleteSelectedItems(); }); }, itemTemplate: function(_, item) { return $("<input>").attr("type", "checkbox") .prop("checked", $.inArray(item, selectedItems) > -1) .on("change", function () { $(this).is(":checked") ? selectItem(item) : unselectItem(item); }); }, align: "center", width: 50 }, { name: "Name", type: "text", width: 150 }, { name: "Age", type: "number", width: 50 }, { name: "Address", type: "text", width: 200 } ] }); var selectedItems = []; var selectItem = function(item) { selectedItems.push(item); }; var unselectItem = function(item) { selectedItems = $.grep(selectedItems, function(i) { return i !== item; }); }; var deleteSelectedItems = function() { if(!selectedItems.length || !confirm("Are you sure?")) return; deleteClientsFromDb(selectedItems); var $grid = $("#jsGrid"); $grid.jsGrid("option", "pageIndex", 1); $grid.jsGrid("loadData"); selectedItems = []; }; var deleteClientsFromDb = function(deletingClients) { db.clients = $.map(db.clients, function(client) { return ($.inArray(client, deletingClients) > -1) ? null : client; }); }; });
$(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); } }); } }); });
$(function() { $("#jsGrid").jsGrid({ height: "85%", width: "100%", paging: true, pageSize: 15, pageButtonCount: 5, pagerContainer: "#externalPager", pagerFormat: "current page: {pageIndex} {first} {prev} {pages} {next} {last} total pages: {pageCount}", pagePrevText: "<", pageNextText: ">", pageFirstText: "<<", pageLastText: ">>", pageNavigatorNextText: "…", pageNavigatorPrevText: "…", data: db.clients, 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" } ] }); });
$(function() { var MyDateField = function(config) { jsGrid.Field.call(this, config); }; MyDateField.prototype = new jsGrid.Field({ sorter: function(date1, date2) { return new Date(date1) - new Date(date2); }, itemTemplate: function(value) { return new Date(value).toDateString(); }, insertTemplate: function(value) { return this._insertPicker = $("<input>").datepicker({ defaultDate: new Date() }); }, editTemplate: function(value) { return this._editPicker = $("<input>").datepicker().datepicker("setDate", new Date(value)); }, insertValue: function() { return this._insertPicker.datepicker("getDate").toISOString(); }, editValue: function() { return this._editPicker.datepicker("getDate").toISOString(); } }); jsGrid.fields.myDateField = MyDateField; $("#jsGrid").jsGrid({ height: "90%", width: "100%", inserting: true, editing: true, sorting: true, paging: true, data: db.users, fields: [ { name: "Account", width: 150, align: "center" }, { name: "Name", type: "text" }, { name: "RegisterDate", type: "myDateField", width: 100, align: "center" }, { type: "control", editButton: false, modeSwitchButton: false } ] }); });