getting jquery fields from a List - javascript

In the below jsp code the fields are hard code but can i get the fields by using loop from a list which may grow dynamically
List list=[userid,firstname,lastname,email];
for every new request this list may grow or shrink dynamically depends on the columns of the table present in database ,so is there any way to get the field name without hard coding..
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<!-- Include one of jTable styles. -->
<link href="css/metro/crimson/jtable.css" rel="stylesheet" type="text/css" />
<link href="css/jquery-ui-1.10.3.custom.css" rel="stylesheet" type="text/css" />
<!-- Include jTable script file. -->
<script src="js/jquery-1.8.2.js" type="text/javascript"></script>
<script src="js/jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
<script src="js/jquery.jtable.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$('#PersonTableContainer').jtable({
title: 'Table of people',
paging: true, //Enable paging
pageSize: 10, //Set page size (default: 10)
actions: {
listAction: 'CRUDController?action=list',
createAction:'CRUDController?action=create',
updateAction: 'CRUDController?action=update',
deleteAction: 'CRUDController?action=delete'
},
fields: {
userid: {
title:'S.NO',
key: true,
list: true,
create:true
},
firstName: {
title: 'First Name',
width: '30%',
edit:false
},
lastName: {
title: 'Last Name',
width: '30%',
edit:true
},
email: {
title: 'Email',
width: '20%',
edit: true
}
}
});
$('#PersonTableContainer').jtable('load');
});
</script>
</head>
<body>
<div style="width:60%;margin-right:20%;margin-left:20%;text-align:center;">
<div id="PersonTableContainer"></div>
</div>
</body>
</html>

this can be achieved by iterating over a list
<%
HttpSession sec = request.getSession();
List<String> columnsList=(List<String>)sec.getAttribute("columnsList");
%>
<script type="text/javascript">
var jsArray = [<%for (int i = 0; i < columnsList.size(); i++) {%>"<%=columnsList.get(i)%>"<%=i + 1 < columnsList.size() ? ",":""%><%}%>];
var fields={};
var arrayLength = jsArray.length;
for(var i=0;i<arrayLength;i++)
{
fields[jsArray[i]] = {
title: jsArray[i],
width: '40%',
};
}
$(document).ready(function() {
$('#PersonTableContainer').jtable({
title : 'Table of people',
paging : true, //Enable paging
sorting: true, //Enable sorting
defaultSorting: 'Name ASC', //Set default sorting
pageSize : 10, //Set page size (default: 10)
actions : {
listAction : 'DATA?action=list'
},
fields : fields
});
//Load all records when page is first shown
$('#PersonTableContainer').jtable('load');
});
</script>

Related

Kendo grid events not working with delegates

I have a page that may create several grids at any time. I am trying to set a single event handler for all of them by adding a delegate for the groupor dataBoundevent but it never triggers.
I am trying this
$(document).on('dataBound', 'div.k-grid', onGridDataBound);
Is it possible to do this without hooking on to each individual grid's settings when it is being created or without having to bind the event per grid?
I can suggest you two alternatives:
Override the Grid prototype (before creating any Grids) and inject the event handler(s) directly there:
function onGridDataBound(e) {
alert(e.sender.wrapper.attr("id") + " was databound");
}
kendo.ui.Grid.fn.options.dataBound = onGridDataBound;
Here is a full example:
<!DOCTYPE html>
<html>
<head>
<base href="http://demos.telerik.com/kendo-ui/grid/remote-data-binding">
<style>html { font-size: 14px; font-family: Arial, Helvetica, sans-serif; }</style>
<title></title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2017.2.621/styles/kendo.common.min.css" />
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2017.2.621/styles/kendo.default.min.css" />
<script src="https://kendo.cdn.telerik.com/2017.2.621/js/jquery.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2017.2.621/js/kendo.all.min.js"></script>
</head>
<body>
<p>Grid 1</p>
<div id="grid1"></div>
<p>Grid 2</p>
<div id="grid2"></div>
<script>
function onGridDataBound(e) {
alert(e.sender.wrapper.attr("id") + " was databound");
}
$(function() {
kendo.ui.Grid.fn.options.dataBound = onGridDataBound;
var gridOptions = {
dataSource: {
type: "odata",
transport: {
read: "https://demos.telerik.com/kendo-ui/service/Northwind.svc/Orders"
},
pageSize: 5,
serverPaging: true,
serverFiltering: true,
serverSorting: true
},
height: 200,
pageable: true,
columns: [{
field:"OrderID",
filterable: false
}, {
field: "ShipName",
title: "Ship Name"
}, {
field: "ShipCity",
title: "Ship City"
}]
};
$("#grid1").kendoGrid(gridOptions);
$("#grid2").kendoGrid(gridOptions);
});
</script>
</body>
</html>
Create a custom Kendo UI widget that has the desired event handlers attached initially.
(function($) {
var kendo = window.kendo,
ui = kendo.ui,
Grid = ui.Grid
var MyGrid = Grid.extend({
init: function(element, options) {
Grid.fn.init.call(this, element, options);
this.bind("dataBound", onGridDataBound);
},
options: {
name: "MyGrid"
}
});
ui.plugin(MyGrid);
})(jQuery);
function onGridDataBound(e) {
alert(e.sender.wrapper.attr("id") + " was databound");
}
Here is a full example:
<!DOCTYPE html>
<html>
<head>
<base href="http://demos.telerik.com/kendo-ui/grid/remote-data-binding">
<style>html { font-size: 14px; font-family: Arial, Helvetica, sans-serif; }</style>
<title>Kendo UI default event handlers via prototype</title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2017.2.621/styles/kendo.common.min.css" />
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2017.2.621/styles/kendo.default.min.css" />
<script src="https://kendo.cdn.telerik.com/2017.2.621/js/jquery.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2017.2.621/js/kendo.all.min.js"></script>
</head>
<body>
<p>Grid 1</p>
<div id="grid1"></div>
<p>Grid 2</p>
<div id="grid2"></div>
<script>
(function($) {
var kendo = window.kendo,
ui = kendo.ui,
Grid = ui.Grid
var MyGrid = Grid.extend({
init: function(element, options) {
Grid.fn.init.call(this, element, options);
this.bind("dataBound", onGridDataBound);
},
options: {
name: "MyGrid"
}
});
ui.plugin(MyGrid);
})(jQuery);
function onGridDataBound(e) {
alert(e.sender.wrapper.attr("id") + " was databound");
}
$(function() {
var gridOptions = {
dataSource: {
type: "odata",
transport: {
read: "https://demos.telerik.com/kendo-ui/service/Northwind.svc/Orders"
},
pageSize: 5,
serverPaging: true,
serverFiltering: true,
serverSorting: true
},
height: 200,
pageable: true,
columns: [{
field:"OrderID",
filterable: false
}, {
field: "ShipName",
title: "Ship Name"
}, {
field: "ShipCity",
title: "Ship City"
}]
};
$("#grid1").kendoMyGrid(gridOptions);
$("#grid2").kendoMyGrid(gridOptions);
});
</script>
</body>
</html>
So I ended up doing something really inefficient to get this done. Since only the default browser events seem to be delegated, I ended up adding a binder for mousedown on any of the grid headers. The handler for that would then bind to the group event for that grid since then it is guaranteed to be on the page.
var boundGrids = [];
function onGridGroup(e) {
//Grid group code
};
function onGridHeaderClick(e) {
var grid = $(this).closest('.k-grid').data('kendoGrid');
if (!grid._attachedGroup) {
grid._attachedGroup = true;
boundGrids.push(grid);
grid.bind('group', onGridGroup);
}
};
$(document).on('mousedown', '.k-grid th a.k-link', onGridHeaderClick);
Check this thread. Only difference is that in your case you got multiple grids. Due that I would do something like:
var grids = $('div.k-grid');
grids.each(function(e) {
var grid = $(this).data('kendoGrid');
grid.bind("dataBound", function () {
alert('Databounded');
});
});

Kendo Grid Row Selection Client-side Persistence Issue

We have selections persisting, maybe just a bit too much. :D
For example, if you have a multipage kendo grid with client side data, do this with a client side kendo grid:
Select a row on Page 1
Go to Page 2
Select a row on Page 2 THEN deselect it and select another row
Go back to Page 1 (row selection persists)
Go back to Page 2
Row selection persists, but also the row that was previously deselected is also selected.
Is there a solution to this? Something we can use in the change event:
http://dojo.telerik.com/#crunchfactory/uhEZe/7
Thank you,
j
Please try with the below code snippet.
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2015.2.902/styles/kendo.common-material.min.css" />
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2015.2.902/styles/kendo.material.min.css" />
<script src="https://kendo.cdn.telerik.com/2015.2.902/js/jquery.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2015.2.902/js/kendo.all.min.js"></script>
</head>
<body>
<script src="http://demos.telerik.com/kendo-ui/content/shared/js/products.js"></script>
<div id="example">
<div id="grid"></div>
<script>
$(document).ready(function () {
var selectedOrders = [];
var idField = "ProductID";
$("#grid").kendoGrid({
dataSource: {
data: products,
schema: {
model: {
fields: {
ProductName: { type: "string" },
UnitPrice: { type: "number" },
UnitsInStock: { type: "number" },
Discontinued: { type: "boolean" }
}
}
},
pageSize: 20
},
height: 550,
scrollable: true,
sortable: true,
selectable: "multiple, row",
pageable: {
input: true,
numeric: false
},
columns: [
"ProductName",
{ field: "UnitPrice", title: "Unit Price", format: "{0:c}", width: "130px" },
{ field: "UnitsInStock", title: "Units In Stock", width: "130px" },
{ field: "Discontinued", width: "130px" }
],
change: function (e, args) {
var grid = e.sender;
var items = grid.items();
items.each(function (idx, row) {
var idValue = grid.dataItem(row).get(idField);
if (row.className.indexOf("k-state-selected") >= 0) {
selectedOrders[idValue] = true;
} else if (selectedOrders[idValue]) {
delete selectedOrders[idValue];
}
});
},
dataBound: function (e) {
var grid = e.sender;
var items = grid.items();
var itemsToSelect = [];
items.each(function (idx, row) {
var dataItem = grid.dataItem(row);
if (selectedOrders[dataItem[idField]]) {
itemsToSelect.push(row);
}
});
e.sender.select(itemsToSelect);
}
});
});
</script>
</div>
</body>
</html>
Let me know if any concern.

How do determine when DataSource is no longer used

I have a page with a Kendo Grid. When the user selects a row in the Grid I update a template and another grid with dependent information. I'm doing this by creating two new DataSources and binding them (see the code below).
To support live updates I want to attach, in the init() of the DataSource, an event handler to a websocket to detect changes in the backend for this DataSource (basically a subscription model). My problem is that in this page since every time the user selects an item I would get two more DataSources and so I would end up with lots of event handlers triggering for DataSources that are no longer used. I would like to clean them up somehow.
I can see a number of ways to handle this:
Have some event that triggers when the DataSource is no longer used so I can unregister the handler and unsubscribe.
Instead of creating a new DataSource each time just change the url in the transport each time. But then I'd like some event that triggers when the transport is changed so the event handler knows the subscription needs to be changed.
What I currently do: add a custom method to the DataSource called nuke() which I call just before creating the new DataSource. Error prone, but functional.
Or am I going about this completely the wrong way? Perhaps there is some general way to trigger on changes in Kendo objects?
Below is code that demonstrates the naive approach that causes the problem. It's also available here: http://dojo.telerik.com/OKaDu
Note the example code uses filters but in my actual code it's the URL that changes. Though if there is a way to trigger on changing filters that would be cool too.
<html>
<head>
<meta charset="utf-8">
<title>Kendo UI Snippet</title>
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.2.624/styles/kendo.common.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.2.624/styles/kendo.rtl.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.2.624/styles/kendo.default.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.2.624/styles/kendo.dataviz.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.2.624/styles/kendo.dataviz.default.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.2.624/styles/kendo.mobile.all.min.css">
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2015.2.624/js/kendo.all.min.js"></script>
</head>
<body>
<div id="grid"></div>
<div id="detail">
Employee ID: <span data-bind="text: EmployeeID"></span><br>
FirstName: <span data-bind="text: FirstName"></span><br>
LastName: <span data-bind="text: LastName"></span><br>
</div>
<div id="orders"></div>
<script>
var element = $("#grid").kendoGrid({
dataSource: {
type: "odata",
transport: {
read: "http://demos.kendoui.com/service/Northwind.svc/Employees"
},
pageSize: 6,
serverPaging: true,
serverSorting: true
},
height: 450,
selectable: "row",
sortable: true,
pageable: true,
columns: [
{
field: "FirstName",
title: "First Name"
},
{
field: "LastName",
title: "Last Name"
},
{
field: "Country"
},
{
field: "City"
},
{
field: "Title"
}
],
change: function(e) {
var selectedRows = this.select();
var dataItem = this.dataItem(selectedRows[0]);
var remoteDataSource = new kendo.data.DataSource({
type: "odata",
transport: {
read: "http://demos.kendoui.com/service/Northwind.svc/Employees"
},
serverPaging: true,
serverSorting: true,
serverFiltering: true,
pageSize:6,
filter: { field: "EmployeeID", operator: "eq", value: dataItem.EmployeeID }
});
remoteDataSource.fetch(function(){
kendo.bind("#detail", remoteDataSource.view()[0]);
});
$("#orders").kendoGrid({
dataSource: {
type: "odata",
transport: {
read: "http://demos.kendoui.com/service/Northwind.svc/Orders"
},
serverPaging: true,
serverSorting: true,
serverFiltering: true,
pageSize:6,
filter: { field: "EmployeeID", operator: "eq", value: dataItem.EmployeeID }
},
scrollable: false,
sortable: true,
pageable: true,
columns: [
{ field: "OrderID", width: 70 },
{ field: "ShipCountry", title:"Ship Country", width: 100 },
{ field: "ShipAddress", title:"Ship Address" },
{ field: "ShipName", title: "Ship Name", width: 200 }
]
});
}
});
</script>
</body>
</html>

Dojo chart: zoom in values disappear

I am having an issue in Dojox charts wherein the zooming in operation is making the data points at the end of the series disappear for some reason. The more I zoom in the more data values I lose. Is there a workaround for this. I am using the MouseZoomAndPan module with a line chart.
Attaching code.
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# page import="atk.graph.*" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script>
var c;
<% String data = "[{value: 1, text: \"X\"}, {value: 2, text: \"Z\"}]"; %> // Some test labels
<% String labels = new LabelMaker().makeLabels(10);%> // Generating labels in java class
</script>
<style type="text/css">
#import
url("http://archive.dojotoolkit.org/nightly/dojotoolkit/dijit/themes/claro/claro.css") ;
</style>
<script>dojoConfig = {parseOnLoad: true}</script>
<script src='//ajax.googleapis.com/ajax/libs/dojo/1.8.0/dojo/dojo.js'></script>
<script>
require(["dojox/charting/Chart", "dojox/charting/axis2d/Default", "dojox/charting/plot2d/StackedLines"
, "dojo/ready", "dojox/charting/action2d/Tooltip",
"dojox/charting/action2d/Highlight","dojox/charting/themes/PlotKit/blue","dojox/charting/action2d/MouseZoomAndPan"],
function(Chart, _axis, StackedLines,ready, Tooltip,Highlight,theme_green, MouseZoomAndPan){
ready(function(){
c = new Chart("chartOne");
c.setTheme(theme_green);
c.addPlot("default", {type: StackedLines, markers: true, tension:3, enable\Cache: true})
.addAxis("x", {fixLower: "major", fixUpper: "major", enableCache: true, majorTickStep:1, natural:false, fixed: true, minorTicks: false, labels: <% out.println(labels); %>})
.addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", min: 0, enableCache: true})
.addSeries("Series A", [ 1, 2, 5, 0, 8,7, 20]);
var anim2b = new Highlight(c, "default");
var animc = new Tooltip(c, "default");
new MouseZoomAndPan(c, "default", {axis:"x"});
c.render();
});
});
</script>
</head>
<body class="claro">
<div id="chartOne"
style="width: 800px; height: 540px; align:center";></div>
</body>
</html>
Seemed to be a version issue, fixed when switched to 1.10.1.

Is there a way to show an attractive "empty state" message using Flexigrid?

As a designer, I am a big fan of the notion of a beautiful "empty-state" message when there is no data to dislplay, which encourages the user to take action. (In fact, there is a whole tumblr blog dedicated to this: http://emptystat.es/)
As a happy and devoted user of Flexigrid, I'd love to be able to substitute an empty-state message when the system I'm building doesn't have any search results to display in the grid (e.g. "You have no pending requests! Click New to start."). Ideally, such an empty-state message would be graphic and larger than an individual row and would replace the entire contents of the grid. Can anyone provide some advice on how I might go about replacing the content of the flexigrid with a graphic empty-state message when there are no rows returned?
Thanks!
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Flexigrid</title>
<link rel="stylesheet" type="text/css" href="../css/flexigrid.css">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript" src="../js/flexigrid.js"></script>
</head>
<body>
<p>This is a sample implementation attached to a form, to add additional parameters.</p>
<form id="sform">
<p>
The values you entered will be place in name column for demo's sake.<br />
Value 1 : <input type="text" name="val1" value="" autocomplete="off" /><br />
Value 2 : Is a hidden input with value 3<input type="hidden" name="val2" value="3" /><br />
Value 3 :
<select name="val3">
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
<option value="4">Four</option>
<option value="5">Five</option>
</select><br />
Value 4 : <input type="checkbox" name="val4" id="val4" value="4" /><label for="val4">This will pass a value 4 if checked</label>
</p>
<p>
<input type="submit" value="Submit" />
</p>
</form>
<button onclick=hide()>HIDE</button>
<button onclick=show()>SHOW</button>
<table id="empty1" style="display:none">
<tr><td><b>Please</b> <u>fill some</u> data</td></tr>
</table>
<table id="flex1" style="display:block">
<tr><td>1</td></tr>
<tr><td>2</td></tr>
<tr><td>3</td></tr>
</table>
<script type="text/javascript">
var old = undefined
function hide() {
if (old == undefined) {
old = flex1.innerHTML
flex1.innerHTML = empty1.innerHTML
}
}
function show() {
if (old != undefined) {
flex1.innerHTML = old
old = undefined
}
}
$("#flex1").flexigrid({
url: 'post2.php',
dataType: 'json',
colModel : [
{display: 'ISO', name : 'iso', width : 40, sortable : true, align: 'center'},
{display: 'Name', name : 'name', width : 180, sortable : true, align: 'left'},
{display: 'Printable Name', name : 'printable_name', width : 120, sortable : true, align: 'left'},
{display: 'ISO3', name : 'iso3', width : 130, sortable : true, align: 'left', hide: true},
{display: 'Number Code', name : 'numcode', width : 80, sortable : true, align: 'right'}
],
searchitems : [
{display: 'ISO', name : 'iso'},
{display: 'Name', name : 'name', isdefault: true}
],
sortname: "iso",
sortorder: "asc",
usepager: true,
title: 'Countries',
useRp: true,
rp: 15,
showTableToggleBtn: true,
width: 700,
onSubmit: addFormData,
height: 200
});
//This function adds paramaters to the post of flexigrid. You can add a verification as well by return to false if you don't want flexigrid to submit
function addFormData(){
//passing a form object to serializeArray will get the valid data from all the objects, but, if the you pass a non-form object, you have to specify the input elements that the data will come from
var dt = $('#sform').serializeArray();
$("#flex1").flexOptions({params: dt});
return true;
}
$('#sform').submit(function (){
$('#flex1').flexOptions({newp: 1}).flexReload();
return false;
});
</script>
</body>
</html>
I solved this using dojo, as we were already using this framework in our site. I'm sure there are similar solutions in different libraries. Essentially I created a new class which, after creating the flexigrid, notices if there is no data in the flexigrid and puts in a background-image to the table if one is specified:
dojo.provide("app.components.EmptyStateFlexigrid");
dojo.require("dijit._Widget");
// Provides a custom Flexigrid with an empty-state
dojo.declare("app.components.EmptyStateFlexigrid", [dijit._Widget], {
emptyStateUrl: null,
id: null,
url: null,
colModel: null,
buttons: null,
sortField: null,
sortOrder: null,
height: null,
usePager: null,
resizable: null,
// Create the flexigrid object
makeGrid: function() {
var gridObj = $('#' + this.id + "_flexigrid");
gridObj.flexigrid({
url: this.url,
dataType : 'json',
colModel : this.colModel,
buttons : this.buttons,
sortname : this.sortField,
sortorder : this.sortOrder,
height: this.height,
usepager : this.usePager,
resizable: this.resizable,
onSuccess: this.checkEmptyState,
useRp : true,
rpOptions: [2, 10, 15, 20, 30, 50],
rp : 15,
showTableToggleBtn : false
});
}
},
// EMPTY-STATE: make a nice graphic here if there is no data
// Note that "this" is a flexigrid object
checkEmptyState: function() {
var self = dijit.byId(this.id);
var gridObj = $('#' + this.id + "_flexigrid");
if (gridObj[0].id === this.id + '_flexigrid') {
var gridChildren = gridObj.children();
if (gridChildren.length === 0) {
var gblocks = $(".gBlock");
for (var i = 0; i < gblocks.length; i++) {
var styleObj = gblocks[i].style;
// The only way I could find to identify "our" flexigrid (if there is
// more than one on the page) is to test to see if the height is the
// same as our height. Kind of a lousy hack, but the best I could figure
// out. -pbanka
if (styleObj.height == self.height + 'px') {
styleObj.backgroundSize = "450px";
styleObj.backgroundRepeat = "no-repeat";
styleObj.backgroundImage = "url('" + self.emptyStateUrl + "')";
}
}
}
}
},

Categories