slickgrid vertical scrolling while column reorder - javascript

I am using SlickGrid in my project and when i try to reorder columns , web page scrolls vertically and column headers become invisible .I found that in SlickGrid.js , in function setupColumnReorder, start function is called when user begins to drag column. I changed the start and stop functions in setupColumnReorder as below. This time , first time when user begins to drag column header , web page scrolls automatically. When the user drags second time it works as intended and no vertical scrolling occurs . How to prevent vertical scrolling in the first drag operation ?
function setupColumnReorder() {
$headers.filter(":ui-sortable").sortable("destroy");
$headers.sortable({
containment: "parent",
distance: 3,
axis: "x",
cursor: "default",
tolerance: "intersection",
helper: "clone",
placeholder: "slick-sortable-placeholder ui-state-default slick-header-column",
start: function (e, ui) {
/********************I added this part******************************************************/
$("body").css("overflow", "hidden");
$(this.parentNode).css("overflow", "hidden");
// window.scrollTo(0, 0) ;
/********************I added this part******************************************************/
ui.placeholder.width(ui.helper.outerWidth() - headerColumnWidthDiff);
$(ui.helper).addClass("slick-header-column-active");
},
beforeStop: function (e, ui) {
$(ui.helper).removeClass("slick-header-column-active");
},
stop: function (e) {
/********************I added this part******************************************************/
$("body").css("overflow", "auto");
$(this.parentNode).css("overflow", "auto");
/********************I added this part******************************************************/
Edit : I am adding an example that vertical scrolling occurs .
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="shortcut icon" type="image/ico" href="favicon.ico" />
<title>SlickGrid example 2: Formatters</title>
<link rel="stylesheet" href="../slick.grid.css" type="text/css"/>
<link rel="stylesheet" href="../css/smoothness/jquery-ui-1.11.3.custom.css" type="text/css"/>
<link rel="stylesheet" href="examples.css" type="text/css"/>
<style>
.cell-title {
font-weight: bold;
}
.cell-effort-driven {
text-align: center;
}
.green {
background-color: green;
}
.red {
background-color: red;
}
.orange {
background-color: orange;
}
</style>
<script src="../lib/firebugx.js"></script>
<script src="../lib/jquery-1.11.2.min.js"></script>
<script src="../lib/jquery-ui-1.11.3.min.js"></script>
<script src="../lib/jquery.event.drag-2.3.0.js"></script>
<script src="../slick.core.js"></script>
<script src="../slick.formatters.js"></script>
<script src="../slick.grid.js"></script>
<script>
// a standard formatter returns a string
function formatter(row, cell, value, columnDef, dataContext) {
return value;
}
// an extended formatter returns an object { text , removeClasses, addClasses }
// the classes are removed and then added during an update, or just added on cell creation
function statusFormatter(row, cell, value, columnDef, dataContext) {
var rtn = { text: value, removeClasses: 'red orange green' };
if (value !== null || value !== "") {
if (value < 33) {
rtn.addClasses = "red";
} else if (value < 66) {
rtn.addClasses = "orange";
} else {
rtn.addClasses = "green";
}
}
return rtn;
}
var grid;
var data = [];
var columns = [
{id: "title", name: "Title", field: "title", width: 120, cssClass: "cell-title", formatter: formatter},
{id: "duration", name: "Duration", field: "duration"},
{id: "%", name: "% Complete", field: "percentComplete", width: 80, resizable: false, formatter: Slick.Formatters.PercentCompleteBar},
{id: "status", name: "Status", field: "percentComplete", width: 50, resizable: false, formatter: statusFormatter},
{id: "start", name: "Start", field: "start", minWidth: 60},
{id: "finish", name: "Finish", field: "finish", minWidth: 60},
{id: "effort-driven", name: "Effort Driven", sortable: false, width: 80, minWidth: 20, maxWidth: 80, cssClass: "cell-effort-driven", field: "effortDriven", formatter: Slick.Formatters.Checkmark}
];
var options = {
editable: false,
enableAddRow: false,
enableCellNavigation: true
};
$(function () {
for (var i = 0; i < 5; i++) {
var d = (data[i] = {});
d["title"] = "<a href='#' tabindex='0'>Task</a> " + i;
d["duration"] = "5 days";
d["percentComplete"] = Math.min(100, Math.round(Math.random() * 110));
d["start"] = "01/01/2009";
d["finish"] = "01/05/2009";
d["effortDriven"] = (i % 5 == 0);
}
grid = new Slick.Grid("#myGrid", data, columns, options);
})
</script>
</head>
<body>
<table width="100%">
<tr>
<td valign="top" width="50%">
<div id="myGrid" style="position:absolute;top:300px;width:700px;height:500px;"></div>
</td>
<td valign="top">
<h2>Demonstrates:</h2>
<ul>
<li>width, minWidth, maxWidth, resizable, cssClass column attributes</li>
<li>custom column formatters</li>
<li>an extended formatter returning an object { text , removeClasses, addClasses } rather than a string, allowing adding and removing css classes from the cell</li>
</ul>
<h2>View Source:</h2>
<ul>
<li> View the source for this example on Github</li>
</ul>
</td>
</tr>
</table>
</body>
</html>
Edit : The problem seems to be related to Mozilla Firefox. I tested the above code with Google Chrome and no vertical scrolling occurs .

Have you replicated the bug in the basic examples?
You can drag columns in http://6pac.github.io/SlickGrid/examples/example2-formatters.html
Does the problem occur there?
I'm not getting any issues, so if you are please specify the browser and OS you are using.

Related

Implementing complex TreeList structure

I'll need to use correct component to implement this https://imgur.com/a/P2VHX2i . I'm currently looking at TreeList Examples ( https://demos.telerik.com/kendo-ui/treelist/remote-data-binding ) using json data from server. Can you give some advice on creating this treelist?
I did a PoC once for a similar scenario like yours. I've simulated a TreeList with a Grid, and it worked:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled</title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.3.917/styles/kendo.common.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.3.917/styles/kendo.rtl.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.3.917/styles/kendo.default.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.3.917/styles/kendo.mobile.all.min.css">
<style type="text/css">
.item-level {
display: inline-block;
width: 10px;
}
.level-arrow-expanded:before {
content: "\00bb"
}
.level-arrow-collapsed:before {
content: "\00ab"
}
.item-cell {
cursor: pointer
}
td[role="gridcell"] {
padding: 0;
}
.cell-container {
display: inline-block;
padding-bottom: 6.4px;
padding-left: 9.6px;
padding-right: 9.6px;
padding-top: 6.4px;
box-sizing: border-box;
width: 100%;
}
.header-container {
padding: 0
}
.header-editable-cell {
color: #9cc3e5;
font-weight: bold
}
.k-grid tr:hover td .cell-container {
background-color: #bdb4af !important
}
</style>
<script src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2019.3.917/js/angular.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2019.3.917/js/jszip.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2019.3.917/js/kendo.all.min.js"></script>
<script id="line-template" type="text/x-kendo-template">
<div class='cell-container'>
<div class='item-level #= (data.Level < 4 ? "level-arrow-" + (data.Collapsed ? "collapsed" : "expanded") : "") #'></div>
# for (let i = -1; i < (data.Level - 1); i++) { #
<div class='item-level level-space'></div>
# } #
#= data.Line #
</div>
</script>
<script>
$(function() {
const lineTemplate = $("#line-template").html();
let data = [];
let cols = [{
title: " ",
field: "Line",
locked: true,
width: 200,
template: lineTemplate,
attributes: { "class": "item-cell" }
}, {
title: "Customer Type",
field: "CustomerType",
width: 300
}];
for (var n = 0; n < 50000; n++) {
let level = (n % 5),
dataItem = {
Line: n,
CustomerType: (n % 2 == 0 ? "All" : "3rd Party"),
Level: level,
Show: true,
Index: n,
Collapsed: false
};
data.push(dataItem);
}
let grid = $("#grid").kendoGrid({
dataSource: {
data: data,
pageSize: 20,
filter: { field: "Show", operator: "eq", value: true }
},
height: 500,
columns: cols,
scrollable: {
virtual: true
}
}).data("kendoGrid");
grid.lockedTable.on("click", "td.item-cell", function() {
let data = grid.dataSource.data(),
dataItem = grid.dataItem($(this).closest("tr")),
item;
for (let i = 0, count = data.length; i < count; i++) {
item = data[i];
if (item.Index == dataItem.Index) {
dataItem.Collapsed = !dataItem.Collapsed;
}
else if (item.Index > dataItem.Index) {
if (dataItem.Index != i && item.Level == 0) {
break;
}
item.Show = !dataItem.Collapsed;
}
}
grid.dataSource.fetch();
});
});
</script>
</head>
<body>
<div id="grid"></div>
</body>
</html>
Demo in Dojo
Why I did that? To work with huge datasets which I don't know if is your case tho. As you can see, the above TreeList is displaying 50k rows, virtualized. The problem is that TreeList does not virtualizes(check out it's docs), but Grid does.
How that works:
Lock the first column to be the collpase/expand column. You can also lock more columns;
In your dataItems(row's data), you have to use some control properties, which are: Collapsed, Level, Show and Index. They control the collpase/expand behaviour and the hierarchical display. Add a console.log(data) before Grid's initialization to checkout how it's been filled;
The Show property handles the collpase/expand displaying status. Once a row is Show = false, it will be hidden. That works because of a filter in the dataSource: filter: { field: "Show", operator: "eq", value: true };
A click event on the item-cell class manages the row's children display status. That class is added in the first column as: attributes: { "class": "item-cell" }. The event changes the Show property for the children rows;
The template line-template will display the right level indetation and the arrows for the collpase/expand column;

Uncaught TypeError: Cannot read property 'addPoint' of undefined ( Highstock live data)

As I posted a previous question, I am using Highcharts to consume a REST API (Spring app) (http://85614a50.ngrok.io/api/devices) with 2 series (axes)
The first series is memory vs time, so the object contains (Memory usage, timestamp).
The second series is CPU vs time, so the object contains (CPU Usage, timestamp).
This data is static right now, but I want it to be dynamic.
I created a function which does a call to the REST API every 5 seconds and an event function inside the Chart refreshing every 5 seconds.
I tried to declare variables inside the event function with series, but it gives me this error:
Uncaught TypeError: Cannot read property 'addPoint' of undefined
Code Pen example: https://codepen.io/anon/pen/eLEyGb
Home.blade.php
#extends('index.app')
#section('main')
<style type="text/css">
#container{
width: 100%;
margin: 0 auto;
}
.col-lg-4 {
margin-bottom: 10%;
min-width: 40%;
max-width: 100%;
margin: 1em auto;
height: 400px;
}
.modal {
display: none; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 1; /* Sit on top */
padding-top: 10%; /* Location of the box */
padding-right: 10%;
padding-left: 10%;
left: 0;
top: 0;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgb(0,0,0); /* Fallback color */
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
}
#container.modal{
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.5);
display:block;
}
</style>
<h2 class="text-center" >{{$user->first_name}} Charts </h2>
<div id="container">
<div class="row"></div>
</div>
<script type="text/javascript">
$(function () {
setInterval(getHighChart, 10000); //30 seconds onload="getHighChart()"
});
function getHighChart() {
$.getJSON( "http://localhost:8000/api/devices", function( data ) {
console.log(data);
var mappedClientsAllias = _.map(_.uniqBy(data, "clientName"), "clientAllias");
var mappedClients = _.map(_.uniqBy(data, "Id_client"), "Id_client");
var devices= [];
_.forEach(mappedClients, function(Id_client, clientName) {
var tempClient = {
Allias: mappedClientsAllias[clientName],
name: Id_client,
data: [],
memory:[]
};
tempClient2=tempClient;
_.forEach(data, function(tempData) {
if (clientId === tempData.clientId) {
_.forEach(tempData.clientData, function(clientData) {
tempClient.data.push([
clientData.timestamp,
clientData.cpuUsage,
]);
tempClient.memory.push([
clientData.timestamp,
clientData.memoryUsage,
]);
});
}
});
devices.push(tempClient);
});
console.log("devices", devices);
var chart = _.forEach(devices, function(device) {
$('<div class="col-lg-4">')
.css("position", "relative")
.appendTo("#container")
.highcharts("StockChart", {
marker: {
states: {
enabled: true
}
},
time: {
timezoneOffset: -5 * 60
},
exporting: {
buttons: {
customButton3: {
text: 'Zooming',
//make fullscreen of chart with size change
onclick: function(b) {
var w = $(window).width();
var h = $(window).height();
$(b.target).closest('#container').toggleClass('modal');
if($(b.target).closest('#container').hasClass('modal')) {
$('.col-lg-4').hide();
$(b.target).closest('.col-lg-4').show();
$('.col-lg-4').css({
'width': w * .9,
'height': h * .9
});
} else {
$('.col-lg-4').show();
$('.col-lg-4').css({
'width': '',
'height': ''
});
}
$(b.target).closest('.col-lg-4').highcharts().reflow();
}
}
}
},
rangeSelector: {
y: 15,
buttons: [
{
count: 1,
type: "minute",
text: "Sec"
},
{
count: 1,
type: "hour",
text: "Min"
},
{
count: 1,
type: "day",
text: "Hours"
},
{
type: "all",
text: "All"
}
],
title: "hours",
inputEnabled: true,
_selected: 1
},
title: {
text: device.Allias
},
yAxis: [{
labels: {
enabled: true,
align: 'right',
x: -3
},
title: {
text: 'CPU'
},
height: '50%',
lineWidth: 2,
color: 'red'
}, {
labels: {
align: 'right',
x: -3
},
title: {
text: 'Memory'
},
top: '70%',
height: '50%',
offset: 0,
lineWidth: 2,
}],
xAxis: {
tickInterval: 1,
title: {
enabled: true,
text: "Client usage"
},
top: '20%',
type: "datetime",
dateTimeLabelFormats: {
second: "%H:%M:%S",
minute: "%H:%M",
hour: "%H:%M",
day: "%e. %b",
week: "%e. %b",
day: "%Y.%b-%d"
}
},
plotOptions: {
series: {
marker: {
enabled: false,
}
}
},
series: [{
name: "Memory USAGE",
data: device.memory.sort()
}, // Add a new series
{
name: "Cpu USAGE",
yAxis: 1,
color: 'red',
data: device.data.sort()
}],
chart: {
renderTo: "container",
height:400,
events: {
load: function () {
// set up the updating of the chart each second
var series = this.series[0];
setInterval(function () {
var x = (new Date()).getTime(), // current time
y = Math.round(Math.random() * 100);
series.addPoint([x, y], false, true);
}, 1000);
}
}
},
});
});
});
}
</script>
#endsection
Layouts.app
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>Master thesis application</title>
<!-- Jquery -->
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<link rel="stylesheet" type="text/css" href="https://getbootstrap.com/docs/3.3/examples/jumbotron-narrow/">
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css">
<!-- Import css file-->
<link href="{{asset('css/app.css')}}" rel="stylesheet" type="text/css"/>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://code.highcharts.com/stock/highstock.js"></script>
<script src="https://code.highcharts.com/stock/modules/exporting.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
</head>
<body>
#include('file.hed')
#include('file.bar')
<script>
window.onscroll = function() {myFunction()};
var navbar = document.getElementById("navbar");
var sticky = navbar.offsetTop;
function myFunction() {
if (window.pageYOffset >= sticky) {
navbar.classList.add("sticky")
} else {
navbar.classList.remove("sticky");
}
}
</script>
<div class="container">
#include('file.info')
#yield('main')
</div> <!-- /container -->
#include('file.down')
</body>
</html>
You've got the error because of this part of code:
events: {
load: function (series) {
var memory=client.memory.sort();
setInterval(function () {
var x = memory;
series[0].addPoint([x], true, true);
}, 5000);
}
}
There you are passing the series argument to event function, which actually isn't the series. It's just the event. If you want to refer to the series array, please do it like below:
events: {
load: function () {
var memory = client.memory.sort(),
series = this.series;
setInterval(function () {
var x = memory;
series[0].addPoint([x], true, true);
}, 5000);
}
}
BTW. I don't quite understand why you are adding the new chart every 5 seconds, instead of updating old ones.
Live example: https://codepen.io/anon/pen/oPGYoZ

Click on label - Pie chart jQuery Flot

I'm using jQuery flot pie chart, I used embedded labels in interactive pie chart. When I click on one of the sectors in pie chart it shows alert but when I click on label that is embedded in the sector it doesn't respond to the click action. Is there is any solution for this?
My source code
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="http://static.pureexample.com/js/flot/excanvas.min.js"></script>
<script src="http://static.pureexample.com/js/flot/jquery.flot.min.js"></script>
<script src="http://static.pureexample.com/js/flot/jquery.flot.pie.min.js"></script>
<!-- CSS -->
<style type="text/css">
#flotcontainer {
width: 600px;
height: 400px;
text-align: left;
}
</style>
<!-- Javascript -->
<script type="text/javascript">
$(function () {
var data = [
{label: "data1", data:10},
{label: "data2", data: 20},
{label: "data3", data: 30},
{label: "data4", data: 40},
{label: "data5", data: 50},
{label: "data6", data: 60},
{label: "data7", data: 70}
];
var options = {
series: {
pie: {
show: true,
radius: 1,
tilt: 0.5,
label:{
radius: 3/4,
formatter: function (label, series) {
return '<div style="border:1px solid gray;font-size:8pt;text-align:center;padding:5px;color:white;">' + label + '<br/>' +
Math.round(series.percent) + '%</div>';
},
background: {
opacity: 0.5,
color: '#000'
}
}
}
},
legend: {
show: false
},
grid: {
hoverable: true,
clickable: true
}
};
$.plot($("#flotcontainer"), data, options);
$("#flotcontainer").bind("plothover", function(event, pos, obj){
if (!obj){return;}
percent = parseFloat(obj.series.percent).toFixed(2);
var html = [];
html.push("<div style=\"flot:left;width:105px;height:20px;text-align:center;border:1px solid black;background-color:", obj.series.color, "\">",
"<span style=\"font-weight:bold;color:white\">", obj.series.label, " (", percent, "%)</span>",
"</div>");
$("#showInteractive").html(html.join(''));
});
$("#flotcontainer").bind("plotclick", function(event, pos, obj){
if (!obj){return;}
percent = parseFloat(obj.series.percent).toFixed(2);
alert(obj.series.label + " ("+ percent+ "%)");
});
});
</script>
<!-- HTML -->
<div>
Hover percent : <span id="showInteractive"></span>
</div>
<div id="flotcontainer"></div>
If you want to try it, you can use this editor
http://plnkr.co/edit/LvUuMYIYUAi3RZRYGSjV?p=preview
Another option here is to manually pass the event down:
$('.pieLabel').bind('click',function(e){
$("#flotcontainer .flot-overlay").trigger(e);
});
Any click on a pie label will now manually call a click event on flot's overlay canvas. This will in turn call into the plotclick event.
Updated plunkr
You can add $(".pieLabel").click(function() { alert("clicked"); }); to get the clicks on the pie labels
Sample:
$("#flotcontainer").bind("plotclick", function(event, pos, obj){
if (!obj){return;}
alert('hello');
});
$(".pieLabel").click(function() { alert("clicked"); });
Other solution to use your series info: add a call to a custom function when you define the legend (onclick on the div), and pass the right parameters:
series: {
pie: {
show: true,
radius: 1,
tilt: 0.5,
label:{
radius: 3/4,
formatter: function (label, series) {
return '<div onclick="legendClicker(' + series.percent + ');" style="border:1px solid gray;font-size:8pt;text-align:center;padding:5px;color:white;">' + label + '<br/>' +
Math.round(series.percent) + '%</div>';
},
background: {
opacity: 0.5,
color: '#000'
}
}
}
},
And the function:
function legendClicker(info) {
// Do what you want
alert("legend click / " + info);
}

How to set up jqxListBox of jqxGrid programmatically

I have a jqxGrid with jqxListBox inputs as cells. How can I set the cells' values programmatically by selecting their jqxListBox index?
See a demo here:
http://www.jqwidgets.com/jquery-widgets-demo/demos/jqxgrid/index.htm?%28web%29#demos/jqxgrid/customrowcelledit.htm
For a standalone jqxListbox, it can be simply done as
$("#jqxListBox").jqxListBox('selectIndex', 0 );
But how can I do it if it is part of the grid? I need to change cell values after the grid is initialized. Overwriting cell values instead of changing the selected index is not a good solution.
You need to use the "initeditor" callback function of the Column. The same demo is below, but with the jQWidgets ListBox instead of the jQWidgets DropDownList as an editor.
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="../../jqwidgets/styles/jqx.base.css" type="text/css" />
<script type="text/javascript" src="../../scripts/jquery-1.10.2.min.js"></script>
<script type="text/javascript" src="../../jqwidgets/jqxcore.js"></script>
<script type="text/javascript" src="../../jqwidgets/jqxdata.js"></script>
<script type="text/javascript" src="../../jqwidgets/jqxbuttons.js"></script>
<script type="text/javascript" src="../../jqwidgets/jqxscrollbar.js"></script>
<script type="text/javascript" src="../../jqwidgets/jqxmenu.js"></script>
<script type="text/javascript" src="../../jqwidgets/jqxgrid.js"></script>
<script type="text/javascript" src="../../jqwidgets/jqxgrid.edit.js"></script>
<script type="text/javascript" src="../../jqwidgets/jqxgrid.selection.js"></script>
<script type="text/javascript" src="../../jqwidgets/jqxlistbox.js"></script>
<script type="text/javascript" src="../../jqwidgets/jqxdropdownlist.js"></script>
<script type="text/javascript" src="../../jqwidgets/jqxcheckbox.js"></script>
<script type="text/javascript" src="../../jqwidgets/jqxnumberinput.js"></script>
<script type="text/javascript" src="../../jqwidgets/jqxslider.js"></script>
<script type="text/javascript" src="../../scripts/gettheme.js"></script>
<script type="text/javascript" src="generatedata.js"></script>
<script type="text/javascript">
$(document).ready(function () {
var theme = getDemoTheme();
// prepare the data
var data = new Array();
data.push({ "Name": "Population", "Berlin": "3560154", "Boston": "3406829", "London": "8174100" });
data.push({ "Name": "Country", "Berlin": "Germany", "Boston": "United States", "London": "United Kingdom" });
data.push({ "Name": "Capital", "Berlin": "true", "Boston": "false", "London": "true" });
var source =
{
localdata: data,
datatype: "array",
updaterow: function (rowid, rowdata, commit) {
// synchronize with the server - send update command
// call commit with parameter true if the synchronization with the server is successful
// and with parameter false if the synchronization failder.
commit(true);
},
datafields:
[
{ name: 'Name', type: 'string' },
{ name: 'Berlin', type: 'string' },
{ name: 'Boston', type: 'string' },
{ name: 'London', type: 'string' }
]
};
var dataAdapter = new $.jqx.dataAdapter(source);
var createGridEditor = function(row, cellValue, editor, cellText, width, height)
{
// construct the editor.
if (row == 0) {
editor.jqxNumberInput({ decimalDigits: 0, inputMode: 'simple', theme: theme, width: width, height: height, spinButtons: true });
}
else if (row == 1) {
editor.jqxListBox({theme: theme, width: width, height: height, source: ['United States', 'Germany', 'United Kingdom']});
}
else if (row == 2) {
var element = $('<div tabIndex=0 style="position: absolute; top: 50%; left: 50%; margin-top: -7px; margin-left: -10px;"></div>');
editor.append(element);
element.jqxCheckBox({ animationShowDelay: 0, animationHideDelay: 0, width: 16, height: 16, theme: theme });
}
}
var initGridEditor = function (row, cellValue, editor, cellText, width, height) {
// set the editor's current value. The callback is called each time the editor is displayed.
if (row == 0) {
editor.jqxNumberInput({ decimal: parseInt(cellValue)});
}
else if (row == 1) {
editor.jqxListBox('selectItem', cellValue);
}
else if (row == 2) {
var checkBoxHTMLElement = editor.find('div:first');
checkBoxHTMLElement.jqxCheckBox({ checked: cellValue.toString() == "true" });
}
}
var gridEditorValue = function (row, cellValue, editor) {
if (row == 2) {
var checkBoxHTMLElement = editor.find('div:first');
return checkBoxHTMLElement.val();
}
return editor.val();
}
// initialize jqxGrid
$("#jqxgrid").jqxGrid(
{
width: 600,
rowsheight: 60,
autoheight: true,
source: dataAdapter,
editable: true,
theme: theme,
selectionmode: 'singlecell',
columns: [
{
text: 'Name', pinned: true, editable: false, datafield: 'Name', width: 150
},
{
text: 'Boston', columntype: 'custom', datafield: 'Boston', width: 150,
createeditor: createGridEditor, initeditor: initGridEditor, geteditorvalue: gridEditorValue
},
{
text: 'Berlin', columntype: 'custom', datafield: 'Berlin', width: 150,
createeditor: createGridEditor, initeditor: initGridEditor, geteditorvalue: gridEditorValue
},
{
text: 'London', columntype: 'custom', datafield: 'London',
createeditor: createGridEditor, initeditor: initGridEditor, geteditorvalue: gridEditorValue
}
]
});
});
</script>
</head>
<body class='default'>
<div id="jqxgrid"></div>
</body>
</html>
Hope this helps you.

dojo enhanced grid filter - programatically set column A greater than some number

I'm trying to set a filter on a dojo grid programatically so that some column be greater than some number.
I have a quantity column and I wish to set a filter so that quantity be greater (or different) than zero.
Thanks!
So the code would look like this:
dojo.require("dojox.grid.EnhancedGrid");
var storage = new dojo.data.ItemFileWriteStore({data: data});
var layout = [ { field: 'id', name: '# ID', width: '60px' },
{ field: 'name', name: 'Nume produs', width: '200px' },
{ field: 'qty', name: 'QTY', alwaysEditing: true, editable: true }
];
var grid = new dojox.grid.EnhancedGrid({
store: storage,
structure: layout,
plugins: { filter : true },
}, 'grid');
grid.startup();
I'm guessing I should do a filter or a query but I really don't know how to compare two things, the only thing I found out is that I can use a query with RegEx but.. that's all
Doing
var grid = new dojox.grid.EnhancedGrid({
query: { 'qty' : new RegExp('^[1-9]+[0-9]*$') },
store: storage,
structure: layout,
plugins: { filter : true },
}, 'grid');
works but I believe it's rather inefficient and I hoped for a nicer, cleaner, faster solution.
Here's how I ended up doing something similar:
The basic idea is to add an invisible column. When the value you want to test meets your criteria (greater than some value, or in my case within some range) then set the invisible column to 'Y', otherwise set it to 'N'. Then the filter is easy: invisibleColumn: 'Y'.
The following displays a grid with Column_B values between 100-500. Click the button to activate a filter to display only values between 150-350. It is a complete working example in three parts (javascript, HTML, CSS):
The JavaScript (script.js)
dojo.require("dijit.layout.ContentPane");
dojo.require("dijit.form.Button");
dojo.require("dojox.grid.DataGrid");
dojo.require("dojo.data.ItemFileReadStore");
dojo.ready(function(){
var appLayout = new dijit.layout.ContentPane({
id: "appLayout"
}, "appLayout");
var data = {
'items': [
{'Column_A': 'alpha', 'Column_B': 100},
{'Column_A': 'beta', 'Column_B': 200},
{'Column_A': 'gamma', 'Column_B': 300},
{'Column_A': 'delta', 'Column_B': 400},
{'Column_A': 'epsilon', 'Column_B': 500}
]
};
var store = new dojo.data.ItemFileReadStore({
data: data
});
var layout = [[
{name : 'A', field : 'Column_A', width : '125px'},
{name : 'B', field : 'Column_B', width : '125px%'}
]];
var grid = new dojox.grid.DataGrid({
structure : layout,
store: store,
queryOptions: {ignoreCase: true}
});
var filterButton = new dijit.form.Button({
label: "Filter",
onClick: function () {
var determineRange = function (items, request) {
for (var i = 0; i < items.length; ++i) {
items[i].invisibleColumn = (items[i].Column_B > 150 && items[i].Column_B < 350) ? 'Y' : 'N';
}
grid.filter({invisibleColumn: 'Y'});
};
store.fetch({onComplete: determineRange});
}
});
filterButton.placeAt(appLayout.domNode);
grid.placeAt(appLayout.domNode);
appLayout.startup();
});
The html (index.html)
<html lang="en">
<head>
<meta charset="utf-8">
<title>Filter by range</title>
<link rel="stylesheet" href="style.css" media="screen"/>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.7.1/dijit/themes/claro/claro.css" />
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.7.1/dijit/themes/claro/document.css" />
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.7.1/dojox/layout/resources/ExpandoPane.css" />
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.7.1/dojox/grid/resources/claroGrid.css">
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.7.1/dojox/grid/enhanced/resources/claro/EnhancedGrid.css">
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.7.1/dojo/dojo.js" type="text/javascript"></script>
<script src="script.js" type="text/javascript"></script>
</head>
<body class="claro">
<div id="appLayout"></div>
</body>
</html>
And finally the CSS (style.css)
html, body {
width: 100%; height: 100%;
margin: 0; padding: 0;
overflow: hidden;
}
#appLayout {
width 100%; height: 100%;
}

Categories

Resources