jqwidgets bind Model to Grid - asp.net-mvc-5

I'm using ASP.NET MVC5 and i'm trying to bind my #Model to jqgrid. I already found samples with xml and json, but they're kinda old for me, because i'm using ActionResult to pass data to the view. The problem is that i don't know how to set my model to source of the grid. The #Model is 100% working since it's tested on another view with table.
I wont post any pictures of javascript error, because it's not showing anying that would be helpful. I'm sure that the only problem is mapping the #Model.Employees to the source variable in the View. Here is my code.
Model:
public class EmployeesTownsViewModel
{
public EmployeesTownsViewModel()
{
Towns = new List<SelectListItem>();
}
public List<Employee> Employees { get; set; }
public IList<SelectListItem> Towns { get; set; }
public int Id { get; set; }
public string EmployeeName { get; set; }
public int TownId { get; set; }
public string PhoneNumber { get; set; }
public string Identitycard_num { get; set; }
public string Address { get; set; }
}
Controller:
[HttpGet]
public ActionResult Worker()
{
var employee = new EmployeesTownsViewModel()
{
Employees = this.Data.Employees.All().Where(x => x.IsWorkerDeleted == false).ToList(),
Towns = this.Data.Towns.All().Select(x => new SelectListItem { Text = x.TownName, Value = x.Id.ToString() }).ToList()
};
employee.Towns.Insert(0, new SelectListItem() { Text = "---Choose---", Value = "0" });
return View(employee);
}
View:
#model LogisticsEngineeringLTD.ViewModels.Employees.EmployeesTownsViewModel
#{
ViewBag.Title = "Worker";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<!DOCTYPE html>
<html lang="en">
<head>
<title id='Description'>
This demo illustrates the basic functionality of the Grid plugin. The jQWidgets Grid plugin offers rich support for interacting with data, including paging, grouping and sorting.
</title>
<meta name="description" content="JavaScript Grid with rich support for Data Filtering, Paging, Editing, Sorting and Grouping" />
#*<link rel="stylesheet" href="~/Content/jqx.base.css" type="text/css" />*#
<script type="text/javascript">
$(document).ready(function () {
//How to set this variable 'source' to my Model properties
var source =
{
datatype: "array",
datafields: [
{ name: 'Id', type: 'number' },
{ name: 'EmployeeName', type: 'string' },
{ name: 'PhoneNumber', type: 'string' },
{ name: 'Address', type: 'string' },
{ name: 'TownId', type: 'number' },
{ name: 'Identitycard_num', type: 'string' },
],
localdata: #Model,
};
var dataAdapter = new $.jqx.dataAdapter(source);
var cellsrenderer = function (row, columnfield, value, defaulthtml, columnproperties, rowdata) {
if (value < 20) {
return '<span style="margin: 4px; float: ' + columnproperties.cellsalign + '; color: #ff0000;">' + value + '</span>';
}
else {
return '<span style="margin: 4px; float: ' + columnproperties.cellsalign + '; color: #008000;">' + value + '</span>';
}
}
// initialize jqxGrid
$("#jqxgrid").jqxGrid(
{
width: 850,
source: dataAdapter,
pageable: true,
autoheight: true,
sortable: true,
altrows: true,
enabletooltips: true,
editable: true,
selectionmode: 'multiplecellsadvanced',
columns: [
{ text: "Name", datafield: "EmployeeName" },
{ text: "Number", datafield: "PhoneNumber" },
{ text: "Address", datafield: "Address" },
{ text: "Town", datafield: "TownId" },
{ text: "Id Card Number", datafield: "Identitycard_num" }
],
columngroups: [
{ text: 'Product Details', align: 'center', name: 'ProductDetails' }
]
});
});
</script>
</head>
<body class='default'>
<div id='jqxWidget' style="font-size: 13px; font-family: Verdana; float: left;">
<div id="jqxgrid">
</div>
</div>
</body>
</html>
Thank you in advance ^^

Related

ag grid does not react to scroll in infinite scrolling pagination

I have server side pagination. I've created a simple back-end service to mimic it. See https://gitlab.com/sunnyatticsoftware/sasw-community/sasw-pagination-tester
The back-end can be run as a docker container on port 5000 (or any other) with
docker run -p 5000:8080 registry.gitlab.com/sunnyatticsoftware/sasw-community/sasw-pagination-tester:latest
This is gonna allow to query items (i.e: tickets in this case) with pagination filtering. See its swagger http://localhost:5000/swagger for more info and/or to interact with the sample.
It works in a pretty standard way.
To retrieve the first page with pagination size of 5 items per page:
GET http://localhost:5000/api/tickets?Page=1&Count=5
To retrieve the second page with pagination size of 5 items per page:
GET http://localhost:5000/api/tickets?Page=2&Count=10
etcetera.
The result would have enough information to be able to draw any table on a UI with pagination links and info about total items and total pages:
{
"items": [
{
"id": "00000001-0000-0000-0000-000000000000",
"channel": "chat",
"subject": "one"
},
{
"id": "00000002-0000-0000-0000-000000000000",
"channel": "email",
"subject": "two"
},
{
"id": "00000003-0000-0000-0000-000000000000",
"channel": "email",
"subject": "three"
},
{
"id": "00000004-0000-0000-0000-000000000000",
"channel": "phone",
"subject": "four"
},
{
"id": "00000005-0000-0000-0000-000000000000",
"channel": "chat",
"subject": "five"
}
],
"pageNumber": 1,
"pageSize": 5,
"totalPages": 7,
"totalCount": 32
}
THE PROBLEM
I want to use agGrid for the UI, with infinite scrolling, but I am struggling with the examples, as they all seem to have a previous fetch of a json that later is sliced to show results while scrolling. It would've been useful to have a sample with real integration, but in theory that shouldn't be a problem.
I cannot have the infinite scroll working. For whatever reason, it loads the first items but then the agGrid does not trigger the getRows anymore, and I don't know what am I missing.
I would like to have a simple infinite scrolling example working with the server-side pagination already in place. The following html/js won't send a second request to the server after scrolling.
The index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>JavaScript example</title>
<meta charSet="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<style media="only screen">
html, body {
height: 100%;
width: 100%;
margin: 0;
box-sizing: border-box;
-webkit-overflow-scrolling: touch;
}
html {
position: absolute;
top: 0;
left: 0;
padding: 0;
overflow: auto;
}
body {
padding: 1rem;
overflow: auto;
}
</style>
</head>
<body>
<div id="myGrid" style="height: 100%" class="ag-theme-alpine-dark">
</div>
<script>var __basePath = './';</script>
<script src="https://unpkg.com/ag-grid-enterprise#28.1.3/dist/ag-grid-enterprise.min.js">
</script>
<script src="main.js">
</script>
</body>
</html>
and the main.js
(() => {
const gridOptions = {
columnDefs: [
{ valueGetter: 'node.rowIndex', maxWidth: 100 },
{ field: 'id', minWidth: 150 },
{ field: 'channel', minWidth: 150 },
{ field: 'subject', minWidth: 400 }
],
defaultColDef: {
flex: 1,
minWidth: 80,
},
rowModelType: 'serverSide',
serverSideInfiniteScroll: true,
cacheBlockSize: 10,
maxBlocksInCache: 2,
rowBuffer: 0,
//blockLoadDebounceMillis: 1000,
debug: true,
};
document.addEventListener('DOMContentLoaded', function () {
var gridDiv = document.querySelector('#myGrid');
new agGrid.Grid(gridDiv, gridOptions);
var datasource = createDataSource();
gridOptions.api.setServerSideDatasource(datasource);
});
function createDataSource() {
return {
//rowCount: undefined,
getRows: (params) => {
console.log(`params start row:${params.startRow}, params end row: ${params.endRow}`);
var pagination = getPagination(params.startRow, params.endRow);
console.log(`asking for page ${pagination.page} and count ${pagination.count}`);
// send new request
fetch(`http://localhost:5000/api/tickets?page=${pagination.page}&count=${pagination.count}`)
.then((response) => response.json())
.then(data => {
console.log("data received");
console.log(data);
console.log(params);
params.success({
rowData: data.items,
rowCount: pagination.page * pagination.count,
});
//gridOptions.api.setRowCount(data.totalCount);
});
},
};
}
function getPagination(startRow, endRow){
let pagination = {
page: 1,
count: 10
};
if(startRow && endRow){
let size = endRow - startRow;
let page = Math.ceil(startRow / size);
pagination = {
page: page,
count: size
};
}
return pagination;
}
})();
I figured it out. The problem was in the row count itself (probably) as it needs to be set to the total existing count of items that exist in back-end, so that the grid knows that needs more.
Here's a possible solution.
For ag-grid Enterprise
(() => {
const gridOptions = {
columnDefs: [
{ valueGetter: 'node.rowIndex', maxWidth: 100 },
{ field: 'id', minWidth: 150 },
{ field: 'channel', minWidth: 150 },
{ field: 'subject', minWidth: 400 }
],
defaultColDef: {
flex: 1,
minWidth: 80,
},
rowModelType: 'serverSide',
serverSideInfiniteScroll: true,
cacheBlockSize: 10, //this is the count (page size)
maxBlocksInCache: 2,
rowBuffer: 0,
debug: false
};
document.addEventListener('DOMContentLoaded', function () {
var gridDiv = document.querySelector('#myGrid');
new agGrid.Grid(gridDiv, gridOptions);
var datasource = createDataSource();
gridOptions.api.setServerSideDatasource(datasource);
});
function createDataSource() {
return {
getRows: (params) => {
let count = params.request.endRow - params.request.startRow; // or the cacheBlockSize
let page = Math.ceil(params.request.endRow / count);
console.log(`asking for page ${page} and count ${count}`);
fetch(`http://localhost:5000/api/tickets?page=${page}&count=${count}`)
.then((response) => response.json())
.then(data => {
params.success({
rowData: data.items,
rowCount: data.totalCount,
});
});
},
};
}
})();
For ag-grid Community
A few things are different,
obviously the ag-grid library is a different one.
the row model type is infinite
the grid options api method to set datasource is called setDatasource
there is no object response within the injected getRows parameter, so the startRow and endRow are retrieved directly from the params object.
at index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>JavaScript example</title>
<meta charSet="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<style media="only screen">
html, body {
height: 100%;
width: 100%;
margin: 0;
box-sizing: border-box;
-webkit-overflow-scrolling: touch;
}
html {
position: absolute;
top: 0;
left: 0;
padding: 0;
overflow: auto;
}
body {
padding: 1rem;
overflow: auto;
}
</style>
</head>
<body>
<div id="myGrid" style="height: 100%" class="ag-theme-alpine-dark">
</div>
<script>var __basePath = './';</script>
<script src="https://unpkg.com/ag-grid-community/dist/ag-grid-community.min.js">
</script>
<script src="main.js">
</script>
</body>
</html>
at main.js
(() => {
const gridOptions = {
columnDefs: [
{ valueGetter: 'node.rowIndex', maxWidth: 100 },
{ field: 'id', minWidth: 150 },
{ field: 'channel', minWidth: 150 },
{ field: 'subject', minWidth: 400 }
],
defaultColDef: {
flex: 1,
minWidth: 80,
},
rowModelType: 'infinite',
cacheBlockSize: 10, //this is the count (page size)
maxBlocksInCache: 2,
rowBuffer: 0,
debug: false
};
document.addEventListener('DOMContentLoaded', function () {
var gridDiv = document.querySelector('#myGrid');
new agGrid.Grid(gridDiv, gridOptions);
var datasource = createDataSource();
gridOptions.api.setDatasource(datasource);
});
function createDataSource() {
return {
getRows: (params) => {
console.log(params);
let count = params.endRow - params.startRow; // or the cacheBlockSize
let page = Math.ceil(params.endRow / count);
console.log(`asking for page ${page} and count ${count}`);
fetch(`http://localhost:5000/api/tickets?page=${page}&count=${count}`) // any additional filter must be set on that url as query params
.then((response) => response.json())
.then(data => {
params.successCallback(data.items, data.totalCount);
});
},
};
}
})();

How do I create a multi-select header filter in tabulator?

This question has been asked several times in various forms over the years in the Tabulator GitHub repository. Here are a few instances:
https://github.com/olifolkerd/tabulator/issues/527, https://github.com/olifolkerd/tabulator/issues/1759
I'm looking for an example of how to achieve this using a dropdown menu of some form --- ideally as described in #1759 (dropdown with checkboxes) but another solution that would work for us is a "select" editor that adds/removes CSVs in the header filter when a value is selected/deselected (extending on the example provided in #527).
Hopefully someone with experience working with custom header filters / editors in tabulator can provide an example of a multi-select header filter dropdown, but if not, then I will post a JSFiddle link myself once I've got something that works.
Checkout: https://github.com/olifolkerd/tabulator/issues/527#issuecomment-850900451
Simple Answer by AkshayaBrianTauro
{
field: "book_name",
title: "Book Name",
headerFilterPlaceholder: " ",
headerFilter: 'select',
headerFilterFunc:"in",
headerFilterParams: {values:true, sortValuesList:"asc", multiselect:true}
},
Here is an example of a custom header filter for tabulator of 'select multiple' type. It can be converted to a dropdown style if desired using external sources such as Chosen or multiselect.js
(I recommend running the below Code Snippet in Full Page view).
const speciesTypes = ['Human', 'Android', 'Betazoid', 'Klingon', 'Ferengi', 'Tamarian'];
function multiSelectHeaderFilter(cell) {
var values = speciesTypes;
const filterFunc = (rowData) => {
return values.includes(rowData['species']);
}
const getSelectedValues = (multiSelect) => {
var result = [];
var options = multiSelect && multiSelect.options;
var opt;
for (var i = 0, iLen = options.length; i < iLen; i++) {
opt = options[i];
if (opt.selected) {
result.push(opt.value || opt.text);
}
}
return result;
}
const onChange = () => {
var editor = document.getElementById('speciesSelector');
values = getSelectedValues(editor);
console.log("values: " + values);
cell.getColumn().getTable().removeFilter(filterFunc);
cell.getColumn().getTable().addFilter(filterFunc);
}
var select = document.createElement("select");
select.multiple = "multiple";
select.id = 'speciesSelector';
select.class = "chosen-select";
select.style = 'width: 100%';
speciesTypes.forEach(species => {
select.innerHTML += "<option id='" + species + "' value='" + species + "' selected='selected'>" + species + "</option>";
});
cell.getColumn().getTable().addFilter(filterFunc);
select.addEventListener('change', onChange);
return select;
}
var table = new Tabulator("#tabulator", {
layout: "fitColumns",
data: [{
name: 'Geordi La Forge',
species: 'Human'
}, {
name: 'Dathon',
species: 'Tamarian'
}, {
name: 'Jean-Luc Picard',
species: 'Human'
}, {
name: 'Worf, son of Mogh',
species: 'Klingon'
}, {
name: 'Tasha Yarr',
species: 'Human'
}, {
name: 'Data',
species: 'Android'
}, {
name: 'Wesley Crusher',
species: 'Human'
}, {
name: 'Jalad',
species: 'Tamarian'
}, {
name: 'Lwaxana Troi',
species: 'Betazoid'
}, {
name: 'Temba',
species: 'Tamarian'
}, {
name: 'T\'Kuvma',
species: 'Klingon'
}, {
name: 'Lore',
species: 'Android'
}, {
name: 'Noonian Soongh',
species: 'Human'
}, {
name: 'Darmok',
species: 'Tamarian'
}, {
name: 'Reittan Grax',
species: 'Betazoid'
}, {
name: 'Quark',
species: 'Ferengi'
}],
headerSort: true,
columns: [{
title: 'Name',
field: 'name',
sorter: 'string'
}, {
title: 'Species',
field: 'species',
sorter: 'string',
headerFilter: multiSelectHeaderFilter,
headerFilterLiveFilter: false
}, ],
});
<html>
<head>
<link href="https://unpkg.com/tabulator-tables#4.5.3/dist/css/tabulator.min.css" rel="stylesheet">
<script type="text/javascript" src="https://unpkg.com/tabulator-tables#4.5.3/dist/js/tabulator.min.js"></script>
</head>
<body>
<div id="tabulator"></div>
</body>
</html>
JSFiddle: https://jsfiddle.net/jjech/3th28pv0/
See my answer to Tabulator Multiple Filter in the same Column (show dropbox)
Extend as you see fit...
I dont think <select> support checkboxes as <option>'s, but it would be trivial to replace the <select> with a different style of "pulldown" that does.

how to handle multiple request keys with the same value?

For this project, I'm building out models and passing in values from the body of a POST request. I want to understand how I should be declaring the models.
Sample of JSON which I want to be posted to MongoDB.
{
"signageId": "5cd857c4965f863b7c88d24a",
"parameters": {
"imageURL": "url.com",
"page": {
"pageHeight": "100", //want to change to "height"
"pageWidth": "100" //want to change to "width"
},
"density": {
"height": "300",
"width": "300"
}
}
}
I want to name pageHeight and pageWidth just "height" and "width" within the JSON, like I have done for the density segment, but I'm having difficulties knowing how to declare the models and grab the values from the request.
Model I'm using:
const ObjectSchema = new Schema({
signageId: {
type: String,
require: true
}
parameters: {
imageURL: {
type: String,
require: true
}
},
page: {
pageHeight: {
type: String
},
pageWidth: {
type: String
}
},
density: {
height: {
type: String
},
width: {
type: String
}
}
}
});
Post router
router.post('/', (req, res) =>{
const object = new Objects({
signageId: req.body.signageId,
imageURL: req.body.imageURL,
page: req.body.page,
pageHeight: req.body.pageHeight,
pageWidth: req.body.pageWidth,
density: req.body.density,
height: req.body.height,
width: req.body.width
});
try {
object.save();
res.json({object});
}
catch (err) {
res.json({message: err});
}
});
Your new object should be something like this.
const newObject = new Objects({
signageId: req.body.signageId,
parameters: {
imageURL: req.body.imageURL,
page: {
height: req.body.pageHeight,
width: req.body.pageWidth,
},
density: {
height: req.body.height,
width: req.body.width,
}
}
});
Notes:
1. Give your mongoose schema another name, in order to avoid javascript conflicts.
2. You can use height and width properties for different objects.
page: {
height: {
type: String
},
width: {
type: String
}
},
density: {
height: {
type: String
},
width: {
type: String
}
}
3. the model properties should be required, not require

Vuetify treeview search behavior

Hello and Happy new Year guys,
Again I ask about v-treeview search. When I do my filter, the behavior do not satisfy me.
I updated my version of vuetify to 1.4.0. And I'm using vue 2.5.15
https://codepen.io/anon/pen/PXeMmy?&editors=101
HTML
<div id="app">
<v-container grid-list-md>
<v-layout wrap>
<v-flex xs6>
<!-- Search Field -->
<v-text-field label="search" v-model="search" box>
</v-text-field>
<!-- Treeview -->
<v-treeview :items="filteredTree"
v-model="selected"
active-class="grey lighten-4 indigo--text"
item-key="name"
selected-color="blue"
selectable
hoverable>
</v-treeview>
</v-flex>
<v-flex xs6>
<v-chip v-for="(s , i) in selected" :key="i">
{{s}}
</v-chip>
</v-flex>
</v-layout>
</v-container>
</div>
JS :
new Vue({
el: '#app',
data(){
return{
search: '',
tree: [
{
id: 1,
name: 'Applications',
children: [
{ id: 2, name: 'Calendar' },
{ id: 3, name: 'Chrome' },
{ id: 4, name: 'Webstorm' }
]
},
{
id: 5,
name: 'Languages',
children: [
{ id: 6, name: 'English' },
{ id: 7, name: 'French' },
{ id: 8, name: 'Spannish' }
]
}
],
selected: []
}
},
computed:{
filteredTree: {
get: function() {
let regexp = new RegExp(this.search, "i")
return this.filterTree(this.tree, regexp) || []
},
},
},
methods: {
filterTree: function(tree, filter) {
if (!Array.isArray(tree)) return null
return JSON.parse(JSON.stringify(tree)).filter(function matchName(o) {
let temp;
if (o.name.match(filter)) {
return true;
}
if (!Array.isArray(o.children)) {
return false;
}
temp = o.children.filter(matchName);
if (temp.length) {
o.children = temp;
return true;
}
});
}
}
})
In this exemple when I search "Calen", only "Application -> Calendar" is visible. Until now, it's what I want.
But when I select Calendar, "Application" is also selected; and when I clear the filter, all the children of "Application" are selected too. And I'd like to select "Calendar" and when I clear I don't want its siblings to be selected.
Thank you for reading

js grid and autocomplete

I am able to create a custom field with jsGrid and jquery autocomplete. All ajax CRUD calls are working for all other fields. The below code activates autocomplete and shows the available options in the input field as expected.
var tags = ["tag1", "tag2", "tag3"];
MyDescriptionField.prototype = new jsGrid.Field({
insertTemplate: function(value) {
return this._editPicker = $("<input>").autocomplete({source : tags});
},
editTemplate: function(value) {
return this._editPicker = $("<input>").autocomplete({source : tags});
},
........... (more code)
So far so good. However to actually capture the value so it can be inserted into the db, I also need to define insertValue and editValue.
The code below is NOT working
insertValue: function(){
return this._insertPicker = $("<input>").val();
},
...........(more code)
this one is not working eiter:
insertValue: function(){
return this._insertPicker.autocomplete({
select: function(event, ui) {
$("<input>").val(ui.item.value);
}
});
},
reference: jsGrid. http://js-grid.com/demos/
autocomplete: https://jqueryui.com/autocomplete/
Try this snippet:
$(function() {
var myTagField = function(config) {
jsGrid.Field.call(this, config);
};
myTagField.prototype = new jsGrid.Field({
sorter: function(tag1, tag2) {
return tag1.localeCompare(tag2);
},
itemTemplate: function(value) {
return value;
},
insertTemplate: function(value) {
return this._insertAuto = $("<input>").autocomplete({source : tags});
},
editTemplate: function(value) {
return this._editAuto = $("<input>").autocomplete({source : tags}).val(value);
},
insertValue: function() {
return this._insertAuto.val();
},
editValue: function() {
return this._editAuto.val();
}
});
jsGrid.fields.myTagField = myTagField;
$("#jsGrid").jsGrid({
width: "100%",
inserting: true,
editing: true,
sorting: true,
paging: true,
fields: [
{ name: "Name", type: "text" },
{ name: "Tag", type: "myTagField", width: 100, align: "center" },
{ type: "control", editButton: false, modeSwitchButton: false }
],
data: db.users
});
});
var tags = ["tag1", "tag2", "tag3"];
var db = {};
db.users = [
{
"Name": "Carson Kelley",
"Tag": ""
},
{
"Name": "Prescott Griffin",
"Tag": "tag1"
},
{
"Name": "Amir Saunders",
"Tag": "tag3"
},
{
"Name": "Derek Thornton",
"Tag": "tag2"
},
{
"Name": "Fletcher Romero",
"Tag": ""
}];
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script><script src="//code.jquery.com/ui/1.11.2/jquery-ui.js"></script>
<script src="//rawgit.com/tabalinas/jsgrid/master/dist/jsgrid.min.js"></script>
<link href="//code.jquery.com/ui/1.11.2/themes/cupertino/jquery-ui.css" rel="stylesheet"/>
<link href="//rawgit.com/tabalinas/jsgrid/master/dist/jsgrid.min.css" rel="stylesheet"/>
<link href="//rawgit.com/tabalinas/jsgrid/master/dist/jsgrid-theme.css" rel="stylesheet"/>
<div id="jsGrid"></div>
or this codepen: https://codepen.io/beaver71/pen/rpaLEo
Thanks #beaver. Your pen helped my understand custom fields better. I extended it a bit to add filtering with autocomplete. https://codepen.io/obrienje/pen/aQKNry
$(function() {
var myTagField = function(config) {
jsGrid.Field.call(this, config);
};
myTagField.prototype = new jsGrid.Field({
autosearch: true,
sorter: function(tag1, tag2) {
return tag1.localeCompare(tag2);
},
itemTemplate: function(value) {
return '<span class="label label-primary">' + value + '</span>';
},
insertTemplate: function(value) {
return this._insertAuto = $("<input>").autocomplete({
source: tags
});
},
filterTemplate: function(value) {
if (!this.filtering)
return "";
var grid = this._grid,
$result = this._filterAuto = $("<input>").autocomplete({
source: tags
});
if (this.autosearch) {
$result.on("change", function(e) {
grid.search();
});
}
return $result;
},
editTemplate: function(value) {
return this._editAuto = $("<input>").autocomplete({
source: tags
}).val(value);
},
insertValue: function() {
return this._insertAuto.val();
},
filterValue: function() {
return this._filterAuto.val();
},
editValue: function() {
return this._editAuto.val();
}
});
jsGrid.fields.myTagField = myTagField;
$("#jsGrid").jsGrid({
width: "100%",
filtering: true,
inserting: true,
editing: true,
sorting: true,
paging: true,
fields: [{
name: "Name",
type: "text"
},
{
name: "Tag",
type: "myTagField",
width: 100,
align: "center"
},
{
type: "control",
editButton: false,
modeSwitchButton: false
}
],
data: db.users,
controller: {
loadData: function(filter) {
return $.grep(db.users, function(item) {
return (!filter.Tag || item.Tag.toLowerCase().indexOf(filter.Tag.toLowerCase()) > -1);
});
}
}
});
});
var tags = ["tag1", "tag2", "tag3"];
var db = {};
db.users = [{
"Name": "Carson Kelley",
"Tag": ""
},
{
"Name": "Prescott Griffin",
"Tag": "tag1"
},
{
"Name": "Amir Saunders",
"Tag": "tag3"
},
{
"Name": "Derek Thornton",
"Tag": "tag2"
},
{
"Name": "Fletcher Romero",
"Tag": ""
}
];
<html>
<head>
<link href="https://rawgit.com/tabalinas/jsgrid/master/dist/jsgrid.min.css" rel="stylesheet"/>
<link href="https://rawgit.com/tabalinas/jsgrid/master/dist/jsgrid-theme.css" rel="stylesheet"/>
<link href="//code.jquery.com/ui/1.11.2/themes/cupertino/jquery-ui.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css"/>
</head>
<body>
<h1>Custom Grid DateField filtering with autocomplete</h1>
<div id="jsGrid"></div>
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.2/jquery-ui.js"></script>
<script src="https://rawgit.com/tabalinas/jsgrid/master/dist/jsgrid.min.js"></script>
</body>
</html>
Thanks #beaver. Your pen helped my understand custom fields better. I extended it a bit to add filtering with autocomplete. https://codepen.io/obrienje/pen/aQKNry

Resources