Datatables Single Column Filter - datatables

I read api doc and find individual column searching to filter data by column row, great but i just need add one dropdown filter by name on top (beside number filter)
Current setup (use tabletool and bootstrap)
$('table').DataTable({
'aLengthMenu': [[25, 50, 75, -1], [25, 50, 75, 'All']],
'iDisplayLength': 25,
'stateSave': true,
'oLanguage': {
'sLengthMenu': 'Show : _MENU_',
'sSearch': 'Search : _INPUT_',
},
'oTableTools': {
'sSwfPath': 'media/swf/copy_csv_xls_pdf.swf'
},
/*
'order': [[ 1, 'asc' ]],
'aoColumnDefs': [
{
'bSortable': false,
'aTargets': [ -1, 0 ]
}
]
*/
});

If you are using Datatables Version 1.10 and upwards you want to use the DOM option to position a div in the header where you want to add your filter and add your select to it.
var table;
$(document).ready(function () {
table = $('#example').dataTable({
"dom": "l<'#myFilter'>frtip"
});
var myFilter = '<select id="mySelect">'
+ '<option value="1">Searchval 1</option>'
+ '<option value="2">Searchval 2</option>'
+ '<option value="3">Searchval 3</option>'
+ '</select>';
$("#myFilter").html(myFilter);
table.fnDraw();
});
Then add a custom filter function.
$.fn.dataTable.ext.search.push(
function (settings, data) {
//your filter stuff belongs here
return true;
});
And redraw the table everytime you change your filter.
$("body").on("change", "#mySelect", function () {
table.fnDraw();
});
See this JSFiddle for an example of what more or less should fit your requirements.

That idea is implemented in this DataTables plug-in, you may check out working DEMO:
$(document).ready(function () {
//Source data definition
var tableData = [
{item: 'banana', category: 'fruit', color: 'yellow'},
{item: 'pear', category: 'fruit', color: 'green'},
{item: 'cabbage', category: 'vegie', color: 'green'},
{item: 'carrot', category: 'vegie', color: 'red'},
{item: 'apple', category: 'fruit', color: 'red'},
{item: 'kiwi', category: 'fruit', color: 'brown'}
];
//DataTable definition
window.dataTable = $('#mytable').DataTable({
sDom: 'tF',
data: tableData,
columns: [{
data: 'item',
title: 'Item'
}, {
data: 'category',
title: 'Category'
}, {
data: 'color',
title: 'Color'
}]
});
});
<!doctype html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.mfilter.tk/js/mfilter.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.mfilter.tk/css/mfilter.min.css">
</head>
<body>
<table id="mytable"></table>
</body>
</html>

Related

dojox.grid.DataGrid sort order bug on mixed case strings?

I know Dojo is getting quite old now but we still have apps that are using it.
One thing that was pointed out was the sort facility on the dojox.grid.DataGrid table of users. Our users table has grown over time so it's useful to order by the name column. However, we find that, while most names were entered with a Capital first letter, some names were entered all in lowercase and when I click on the name column header for sorting, I find that the Capitalised names appear in alphabetical order BUT followed by lowercase name in the same order at the bottom.
e.g. The raw data:
Tom
Dick
harry
After "sorting" displays as :
Dick
Tom
harry
Code example, using Dojo 1.8.3, as follows:
require(["dojox/grid/EnhancedGrid",
"dojo/data/ItemFileWriteStore",
"dojo/parser",
"dojo/on",
'dojo/domReady!'
],
function(EnhancedGrid, ItemFileWriteStore, Filter, parser, on) {
var data = {
items: [
{ name: 'Tom', age: 29 },
{ name: 'Dick', age: 9 },
{ name: 'harry', age: 19 }
]
};
var gridStore = new ItemFileWriteStore({
data: data
});
var gridStructure = [
[
{ 'name': 'Name', 'field': 'name' },
{ 'name': 'Age' , 'field': 'age' }
]
];
var mygrid = new EnhancedGrid({
id: "grid",
store: gridStore,
structure: gridStructure,
autoHeight: true,
autoWidth: true
}, "mydatagrid");
mygrid.startup();
}
);
<link href="https://ajax.googleapis.com/ajax/libs/dojo/1.8.3/dojox/grid/enhanced/resources/claro/EnhancedGrid.css" rel="stylesheet" />
<link href="https://ajax.googleapis.com/ajax/libs/dojo/1.8.3/dijit/themes/claro/claro.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/dojo/1.8.3/dojo/dojo.js"></script>
<div id="container" class="claro">
<div id="mydatagrid"></div>
</div>
How do I sort a column of mixed case names correctly?
i.e. to display sorted grid as:
Dick
harry
Tom
Thanks
I managed to get a solution through a suggestion on a related DataGrid post: dojox.grid.DataGrid custom sort method?
Basically, you can use the "comparatorMap" of the ItemFileWriteStore (or ItemFileReadStore)
require(["dojox/grid/EnhancedGrid",
"dojo/data/ItemFileWriteStore",
"dojo/parser",
"dojo/on",
'dojo/domReady!'
],
function(EnhancedGrid, ItemFileWriteStore, Filter, parser, on) {
var data = {
items: [
{ name: 'Tom', age: 29 },
{ name: 'Dick', age: 9 },
{ name: 'harry', age: 19 }
]
};
var gridStore = new ItemFileWriteStore({
data: data
});
var gridStructure = [
[
{ 'name': 'Name', 'field': 'name' },
{ 'name': 'Age' , 'field': 'age' }
]
];
//====================================================================================
//= Define the comparator function for "Name" ========================================
//====================================================================================
gridStore.comparatorMap = {};
gridStore.comparatorMap["name"] = function(a,b) {
var nameA = a.toLowerCase().trim(), nameB = b.toLowerCase().trim();
if (nameA < nameB) //sort string ascending
return -1;
if (nameA > nameB)
return 1;
return 0; //default return value (no sorting)
}
//====================================================================================
//====================================================================================
//====================================================================================
var mygrid = new EnhancedGrid({
id: "grid",
store: gridStore,
structure: gridStructure,
autoHeight: true,
autoWidth: true
}, "mydatagrid");
mygrid.startup();
}
);
<link href="https://ajax.googleapis.com/ajax/libs/dojo/1.8.3/dojox/grid/enhanced/resources/claro/EnhancedGrid.css" rel="stylesheet" />
<link href="https://ajax.googleapis.com/ajax/libs/dojo/1.8.3/dijit/themes/claro/claro.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/dojo/1.8.3/dojo/dojo.js"></script>
<div id="container" class="claro">
<div id="mydatagrid"></div>
</div>

How to filter a dgrid on multiple columns

I am using dgrid 0.4.0 (latest) and dstore 1.1.0. Now I have a filtering on my dgrid like
myDgrid.set('collection', myStore.filter(new myStore.Filter({includeInUI: true}).or( {fruit: /apple|banana|orange/i}, {forceSell: true} )) );
myStore has 20 rows in which forceSell is not true for any row. fruit field has different values in it but few rows meet the above condition. All of the rows have 'includeInUI' set to true. I expect only the rows that are apple or banana or orange should be displayed but when I apply above filter all 20 rows get displayed.
Is the logical OR is not functioning? Or Am I doing something wrong? Also I add rows to the grid when I receive data from web socket. (using dgrid.put).
I would appreciate any help. Thanks!.
IncludeInUI was already set in my code. So the following statement works.
myDgrid.set('collection', myStore.filter(new myStore.Filter().or(new myStore.Filter().eq('fruit','apple'), new myStore.Filter().eq('forceSell', true))));
Note: looks like RegExp is not accepted in Filter operators. So the multiple values case may go
grid.set('collection', store.filter(new store.Filter().or(new store.Filter().in('fruit', ['apple', 'grape']),
new store.Filter().eq('forceSell', true))));
complete code is:
<head>
<meta charset="utf-8">
<title>Test Simple Grid Creation</title>
<meta name="viewport" content="width=570">
<style>
#import "dojo/dojo/resources/dojo.css";
#import "dojo/dijit/themes/claro/claro.css";
.heading {
font-weight: bold;
padding-bottom: 0.25em;
}
.dgrid {
margin: 10px;
}
/* add styles to size this grid appropriately */
#grid {
height: 20em;
}
#grid .field-order {
width: 7%;
}
#grid .field-name {
width: 18%;
}
</style>
<script src="dojo/dojo/dojo.js"
data-dojo-config="async: true"></script>
<script>
var columns = {
id: "ID",
fruit: "Fruit",
includeInUI: "includeInUI",
forceSell: "forceSell"
};
require(["dgrid/OnDemandGrid", "dstore/Memory", "dojo/domReady!"], function(Grid, Memory){
var data1 = [
{id: 1, fruit:"apple", includeInUI:true, forceSell: false},
{id: 2, fruit:"banana", includeInUI:true, forceSell: false},
{id: 3, fruit:"grape", includeInUI:true, forceSell: false},
{id: 4, fruit:"apple", includeInUI:true, forceSell: false},
{id: 5, fruit:"banana", includeInUI:true, forceSell: false},
{id: 6, fruit:"apple", includeInUI:false, forceSell: false},
{id: 7, fruit:"banana", includeInUI:true, forceSell: false},
{id: 8, fruit:"grape", includeInUI:true, forceSell: false},
{id: 9, fruit:"apple", includeInUI:true, forceSell: false},
{id: 10, fruit:"banana", includeInUI:true, forceSell: false}
];
var store = new Memory({data: data1});
window.grid = new Grid({
columns: columns,
collection: store.filter({includeInUI: true}),
idProperty: "id",
id: "myGrid"
}, "grid");
});
</script>
<script>
function filterData() {
require(["dgrid/Grid", "dijit/registry", "dojo/domReady!"], function(Grid, registry){
//var grid = registry.byId('myGrid');
console.log('filterData: ', grid);
var store = grid.collection;
grid.set('collection', store.filter(new store.Filter().or(new store.Filter().eq('fruit','apple'), new store.Filter().eq('forceSell', true))));
});
}
</script>
</head>
<body class="claro">
<h2>A basic grid rendered from an array</h2>
<div id="grid"></div>
<div>Buttons to test filter:
<button onClick="filterData();">Filter</button>
</div>
</body>
</html>
Hope this helps someone.

Dojo: Trigger child widget resize on wipein/fadein when parent is not visible by default

to convey what I'm running into I mashed together Dojo examples in the HTML below. The issue is that the table does not render if its parent is not displayed on page load. How can I get the child table to resize when its parent becomes visible?
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.9.1/dijit/themes/claro/claro.css">
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.9.1/dojo/resources/dojo.css">
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.9.1/dojox/grid/enhanced/resources/claro/EnhancedGrid.css">
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.9.1/dojox/grid/enhanced/resources/EnhancedGrid_rtl.css">
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.9.1/dojo/dojo.js"></script>
<script>dojoConfig = {parseOnLoad: true}</script>
<style>
#grid {
width: 500px;
height: 500px;
}
</style>
<script>
require(["dojo/fx", "dojo/dom", "dojo/dom-style", "dojo/on", "dojo/domReady!","dojox/grid/EnhancedGrid","dojo/data/ItemFileWriteStore"],
function(coreFx, dom, style, on,egrid,ifws){
/*set up data store*/
var data = {
identifier: 'id',
items: []
};
var data_list = [
{ col1: "normal", col2: false, col3: 'But are not followed by two hexadecimal', col4: 29.91},
{ col1: "important", col2: false, col3: 'Because a % sign always indicates', col4: 9.33},
{ col1: "important", col2: false, col3: 'Signs can be selectively', col4: 19.34}
];
var rows = 60;
for(var i=0, l=data_list.length; i<rows; i++){
data.items.push(dojo.mixin({ id: i+1 }, data_list[i%l]));
}
var store = new dojo.data.ItemFileWriteStore({data: data});
/*set up layout*/
var layout = [[
{'name': 'Column 1', 'field': 'id'},
{'name': 'Column 2', 'field': 'col2'},
{'name': 'Column 3', 'field': 'col3', 'width': '230px'},
{'name': 'Column 4', 'field': 'col4', 'width': '230px'}
]];
/*create a new grid:*/
var grid = new dojox.grid.EnhancedGrid({
id: 'grid',
store: store,
structure: layout,
rowSelector: '20px'},
document.createElement('div'));
/*append the new grid to the div*/
dojo.byId("gridDiv").appendChild(grid.domNode);
/*Call startup() to render the grid*/
grid.startup();
on(dom.byId("basicWipeButton"), "click", function(){
style.set("basicWipeNode", "display", "none");
coreFx.wipeIn({
node: "basicWipeNode"
}).play();
});
});
</script>
</head>
<body class="claro">
<button type="button" id="basicWipeButton">Wipe It In!</button>
<div id="basicWipeNode" style=" background-color: #EEE; display: none;">
<p><b>This is a container of random content to wipe in!</b></p>
<div id="gridDiv"></div>
</div>
</body>
</html>
Its a hack but you can try
on(dom.byId("basicWipeButton"), "click", function(){
style.set("basicWipeNode", "display", "none");
coreFx.wipeIn({
node: "basicWipeNode",
onEnd:function(){
grid.domNode.style.height="500px";
grid.resize();
}
}).play();
Update::
This is a much cleaner way. set the attribute autoHeight:true when creating the grid::
var grid = new dojox.grid.EnhancedGrid({
id: 'grid',
store: store,
structure: layout,
rowSelector: '20px',
autoHeight:true});
Then onEnd of the wipeIn you just do the resize by itself.:
on(dom.byId("basicWipeButton"), "click", function(){
style.set("basicWipeNode", "display", "none");
coreFx.wipeIn({
node: "basicWipeNode",
onEnd:function(){
grid.resize();
}
}).play();

Returning JSON Data to JQGrid is prompting to save a file

I'm new to ASP.Net MVC. I'm trying a sample program to bind a JQGrid with data. When I return the JSON data from the Controller , the system is prompting me with a pop up "Do you want to Save the file ..".I beleive my browser is not able to understand JSON data. I went through the other post in StackOverFlow and none of them seem to help me. I'm running this on IE8 set to Compatibility mode. Please see the code below:
Index.cshtml
#{
ViewBag.Title = "Home Page";
}
<link href="~/Content/Site.css" rel="stylesheet" type="text/css" />
<link href="~/Content/jquery.jqGrid/ui.jqgrid.css" rel="stylesheet" type="text/css" />
<link href="~/Content/themes/base/jquery.ui.all.css" rel="stylesheet" type="text/css" />
<script src="~/Scripts/jquery-1.9.1.min.js" type="text/javascript"></script>
<script src="~/Scripts/i18n/grid.locale-en.js" type="text/javascript"></script>
<script src="~/Scripts/jquery.jqGrid.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#myGrid").jqGrid({
url: '../../Home/About/GetJQGridData',
datatype: 'json',
contentType: 'application/json',
myType: 'GET',
colNames: ['Id', 'Name'],
colModel: [
{ name: 'Id', index: 'Id' },
{ name: 'Name', index: 'Name' }
],
jsonReader: {
root: 'Data',
id: 'id',
repeatitems: false
},
pager: $('#myPager'),
rowNum: 5,
rowList: [2, 5, 10],
width: 600,
viewrecords: true,
caption: 'Jqgrid MVC Tutorial'
});
});
</script>
<table id="myGrid"></table>
<div id="myPager"></div>`
My Controller code is as follows:
HomeController.cs
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult GetJQGridData()
{
var jqGridData = new JQGridObject()
{
Data = GetSomeSampleData(),
Page = "1",
PageSize = 3, // u can change this !
SortColumn = "Name",
SortOrder = "asc"
};
return Json(jqGridData, JsonRequestBehavior.AllowGet);
}
public List<Fruit> GetSomeSampleData()
{
return new List<Fruit>
{
new Fruit{Id = 1, Name = "Apple" },
new Fruit{Id = 2, Name = "Melon" },
new Fruit{Id = 3, Name = "Orange" },
new Fruit{Id = 4, Name = "Grapes" },
new Fruit{Id = 5, Name = "Pineapple" },
new Fruit{Id = 6, Name = "Mango" },
new Fruit{Id = 7, Name = "Bannana" },
new Fruit{Id = 8, Name = "Cherry" }
};
}
Any help would be highly appreciated.
Thanks
First thing that jumps out at me is that your Controller/View is being referenced incorrectly
url: '../../Home/About/GetJQGridData',
should be
url: '/Home/GetJQGridData',
You shouldn't need to set a jsonReader as well on the client.

My extjs grid is not showing in new archictecture

I am using the architecture for my extjs app is from this blog post
http://blog.extjs.eu/know-how/writing-a-big-application-in-ext/
So here is my index.html Please read the whole question for complete answer.
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Reseller DashBoard</title>
<!-- ** CSS ** -->
<!-- base library -->
<link rel="stylesheet" type="text/css" href="./ext/resources/css/ext-all.css" />
<link rel="stylesheet" type="text/css" href="./ext/resources/css/xtheme-gray.css" />
<!-- overrides to base library -->
<!-- ** Javascript ** -->
<!-- ExtJS library: base/adapter -->
<script type="text/javascript" src="./ext/adapter/ext/ext-base-debug.js"></script>
<!-- ExtJS library: all widgets -->
<script type="text/javascript" src="./ext/ext-all-debug.js"></script>
<!-- overrides to base library -->
<!-- page specific -->
<script type="text/javascript" src="application.js"></script>
<script type="text/javascript" src="js/Application.dashboard.js"></script>
<script type="text/javascript" src="js/jsfunction.js"></script>
<script type="text/javascript" src="js/reseller.js"></script>
</head>
<body>
<div id="dashboard">
</div>
</body>
</html>
Here is my application.js I am intialising here my dashboard grid, is it the right place to initialise ?
/*global Ext, Application */
Ext.BLANK_IMAGE_URL = './ext/resources/images/default/s.gif';
Ext.ns('Application');
// application main entry point
Ext.onReady(function() {
Ext.QuickTips.init();
var pg = new Application.DashBoardGrid();
// or using it's xtype
var win = new Ext.Window({
items:{xtype:'DashBoardGrid'}
});
// code here
}); // eo function onReady
// eof
Here is my Application.DashBoardGrid.js
My request to the api is going two times right now Why ?
I have a linkrenderer function for a column for rendering where should i put this function?
And Suggest Why My Grid is not Coming ?
Application.DashBoardGrid = Ext.extend(Ext.grid.GridPanel, {
border:false
,initComponent:function() {
var config = {
store:new Ext.data.JsonStore({
// store configs
autoDestroy: true,
autoLoad :true,
url: 'api/index.php?_command=getresellerscount',
storeId: 'getresellerscount',
// reader configs
root: 'cityarray',
idProperty: 'cityname',
fields: [
{name: 'cityname'},
{name: 'totfollowup'},
{name: 'totcallback'},
{name: 'totnotintrested'},
{name: 'totdealsclosed'},
{name: 'totcallsreceived'},
{name: 'totcallsentered'},
{name: 'totresellerregistered'},
{name: 'countiro'},
{name: 'irotransferred'},
{name: 'irodeferred'}
]
})
,columns: [
{
id :'cityname',
header : 'City Name',
width : 120,
sortable : true,
dataIndex: 'cityname'
},
{
id :'countiro',
header : ' Total Prospect',
width : 100,
sortable : true,
dataIndex: 'countiro'
},
{
id :'irotransferred',
header : 'Calls Transfered By IRO',
height : 50,
width : 100,
sortable : true,
dataIndex: 'irotransferred'
},
{
id :'irodeferred',
header : ' Calls Deferred By IRO',
width : 100,
sortable : true,
dataIndex: 'irodeferred'
},
{
id :'totcallsentered',
header : ' Total Calls Entered',
width : 100,
sortable : true,
dataIndex : 'totcallsentered'//,
//renderer : linkRenderer
},
{
id :'totfollowup',
header : ' Follow Up',
width : 100,
sortable : true,
dataIndex: 'totfollowup'
},
{
id :'totcallback',
header : ' Call Backs',
width : 100,
sortable : true,
dataIndex: 'totcallback'
},
{
id :'totnotintrested',
header : ' Not Interested',
width : 100,
sortable : true,
dataIndex: 'totnotintrested'
},
{
id :'totdealsclosed',
header : ' Deals Closed',
width : 100,
sortable : true,
dataIndex: 'totdealsclosed'
},
{
id :'totresellerregistered',
header : ' Reseller Registered',
width : 100,
sortable : true,
dataIndex: 'totresellerregistered'
}
]
,plugins:[]
,viewConfig:{forceFit:true}
,tbar:[]
,bbar:[]
,render:'dashboard'
,height: 350
,width: 1060
,title: 'Reseller Dashboard'
}; // eo config object
// apply config
Ext.apply(this, Ext.apply(this.initialConfig, config));
Application.DashBoardGrid.superclass.initComponent.apply(this, arguments);
} // eo function initComponent
,onRender:function() {
// this.store.load();
Application.DashBoardGrid.superclass.onRender.apply(this, arguments);
} // eo function onRender
});
Ext.reg('DashBoardGrid', Application.DashBoardGrid);
Json Response
{
"countothercities": "0",
"directreseller": "14",
"totalresellersregisteredfor8cities": 33,
"cityarray": [{
"cityname": "bangalore",
"totfollowup": "3",
"totcallback": "4",
"totnotintrested": "2",
"totdealsclosed": "0",
"totcallsreceived": "0",
"totcallsentered": "68",
"totresellerregistered": "6",
"countiro": "109",
"irotransferred": "83",
"irodeferred": "26"
}]
}
Please show your JSON response, or server code. So that we can answer better.
My request to the api is going two times right now Why ?
Obvious. Inside Ext.onReady()
You are creating instance of DashboardGrid. Call 1
You are asking Ext to create instance of DashboardGrid by passing xtype. Call 2
You are creating the grid twice. Do this instead.
Ext.onReady(function() {
Ext.QuickTips.init();
var win = new Ext.Window({
items:{xtype:'DashBoardGrid'}
});
// code here
}); // eo function onReady