Handsontable RuleJS missing recursive resolution - javascript

I use RuleJS plugin for Handsontable (see it on GitHub) which works great for basic formulas but seems to lack recursive resolution.
I've made a code snippet containing two detailed examples, please check it out :
$(document).ready(function () {
var container1 = $('#example1');
var container2 = $('#example2');
container1.handsontable({
data: [[1, '=A2'], ['=B2', '=5 * 2']],
colHeaders: true,
rowHeaders: true,
formulas: true,
minSpareRows: 1
});
container2.handsontable({
data: [[1, '=A2', 3], ['=C1 * B2', '=5 + 1', 3]],
colHeaders: true,
rowHeaders: true,
formulas: true,
minSpareRows: 1
});
});
<!DOCTYPE html>
<html>
<head>
<script src="http://handsontable.github.io/handsontable-ruleJS/lib/jquery/jquery-1.10.2.js"></script>
<script src="http://handsontable.github.io/handsontable-ruleJS/lib/handsontable/handsontable.full.js"></script>
<link rel="stylesheet" media="screen" href="http://handsontable.github.io/handsontable-ruleJS/lib/handsontable/handsontable.full.css">
<script src="http://handsontable.github.io/handsontable-ruleJS/lib/RuleJS/lib/lodash/lodash.js"></script>
<script src="http://handsontable.github.io/handsontable-ruleJS/lib/RuleJS/lib/underscore.string/underscore.string.js"></script>
<script src="http://handsontable.github.io/handsontable-ruleJS/lib/RuleJS/lib/moment/moment.js"></script>
<script src="http://handsontable.github.io/handsontable-ruleJS/lib/RuleJS/lib/numeral/numeral.js"></script>
<script src="http://handsontable.github.io/handsontable-ruleJS/lib/RuleJS/lib/numericjs/numeric.js"></script>
<script src="http://handsontable.github.io/handsontable-ruleJS/lib/RuleJS/lib/js-md5/md5.js"></script>
<script src="http://handsontable.github.io/handsontable-ruleJS/lib/RuleJS/lib/jstat/jstat.js"></script>
<script src="http://handsontable.github.io/handsontable-ruleJS/lib/RuleJS/lib/formulajs/formula.js"></script>
<script src="http://handsontable.github.io/handsontable-ruleJS/lib/RuleJS/js/parser.js"></script>
<script src="http://handsontable.github.io/handsontable-ruleJS/lib/RuleJS/js/ruleJS.js"></script>
<script src="http://handsontable.github.io/handsontable-ruleJS/lib/handsontable/handsontable.formula.js"></script>
<link rel="stylesheet" media="screen" href="http://handsontable.github.io/handsontable-ruleJS/css/samples.css">
<style type="text/css">
body {background: white; margin: 20px;}
h2 {margin: 20px 0;}
</style>
</head>
<body>
<h2>Bugs in handsontable-ruleJS</h2>
<p>Both cases seem to come from the same problem, but they both worth seeing.</p>
<p>Here B1 displays the value of B2 <b>before</b> its interpretation where it should display "<b>10</b>". Just like it misses some recursive processing. Focusing the cell will show its real value "<b>=A2</b>" which will next be interpreted correctly.</p>
<div id="example1" class="handsontable"></div>
<p>This one is interesting, because when the cell "<b>A2</b>" tries to calculate "<b>C1 * B2</b>" it does "<b>3 * =5 + 1"</b> instead of "<b>3 * 6</b>", which obviously fails.</p>
<div id="example2" class="handsontable"></div>
<p>The only way to correct it is to edit "<b>C1</b>" (even without changing its value).</p>
</body>
</html>
If you prefer JSFiddle, here you go.
Best regards.
Edit: You may not see the first bug when using the embed snippet and going to fullscreen because it seems to trigger a refresh of the table. Use the JSFiddle for better results.
Edit 2 (SOLVED): Ok I think I've patched it, you can find the result here. I'll post a complete answer when Stackoverflow allows me to do it. Any feedback is still welcome, I'm sure there is a better way to do it but at least it seems to work now.

The working code can be found here : http://jsfiddle.net/71o23gp0/8/.
The important part was to replace :
var custom = {
cellValue: instance.getDataAtCell
};
By
var custom = {
cellValue: function(row, col){
var value = instance.getDataAtCell(row, col);
if (value && value[0] === '=') {
var formula = value.substr(1).toUpperCase();
var cellId = instance.plugin.utils.translateCellCoords({
row: row,
col: col
});
var item = instance.plugin.matrix.getItem(cellId);
if (!item) {
item = instance.plugin.matrix.addItem({
id: cellId,
formula: formula
});
} else {
item = instance.plugin.matrix.updateItem({
id: cellId,
formula: formula
});
}
var formulaResult = instance.plugin.parse(formula, {
row: row,
col: col,
id: cellId
});
value = formulaResult.result || '#ERROR';
formulasResults[cellId] = value;
instance.plugin.matrix.updateItem(item, {
formula: formula,
value: formulaResult.result,
error: formulaResult.error
});
}
return value;
}
};
Instead of simply returning the value of the cell, it checks if it's a formula and resolve it if so. Because this method is called by RuleJS when resolving a formula, this make the resolution recursive. The result is then cached for better performance.
There are other minor modifications in the source code, but I've added comments in the fiddle before and after every modification.

Following on from the answer https://stackoverflow.com/a/35528447/489865 in this question, I have patched a little further. The working code can be found at http://jsfiddle.net/ufL1vts5/.
The essential change is to store in formulasResults[] not just the "result" but rather the whole object returned by instance.plugin.parse(), so that cell highlighting for formulas is picked up, as per:
// parse formula
var newValue = instance.plugin.parse(formula, {row: row, col: col, id: cellId});
// cache result
formulasResults[cellId] = newValue;
My modifications include:
Store whole instance.plugin.parse() object in formulasResults[],
so that the formula/formula-error CSS style gets applied. [Note
that this is not perfect: it picks up "calculated" formula style
correctly, but sometimes what should be formula-error style only
get formula style --- but sufficient for my needs.]
Added formula & formula-error CSS styles (from supplied
handsontable.formula.css) into JSFiddle example, so that cell
highlighting can be seen.
Added 2 extra examples: one from
handsontable formula returning #NEED_UPDATE,
to show that works too, and one from the example supplied with
handsontable-ruleJS at https://github.com/handsontable/handsontable-ruleJS/blob/master/index.html.
Removed the newly added beforeRender hook via
instance.removeHook('beforeRender', beforeRender); in this.init = function ().
Changed some code layout in handsontable.formula.js, so that it
minimises the differences from that supplied with
handsontable-ruleJS.

Related

Jexcel removes all cells and leaves a number 1 on an if statement

When trying to run an if statement with Javascript on a Jexcel to look at Cell 1,1 it seems to remove all the cells and leaves just one cell with a number 1 in it. I am new to Javascript so it is quite possible I am just not understanding it well enough, so dont be surprised if I have got the code completely wrong as my background is VBA. However if someone could just guide me on how to get it to look in one cell I am sure I can write the rest.
I have been trying to get the on-line guides on Jexcel to try understand it but I am not getting what I am missing. I have tried to follow the guide on the following https://www.teamdev.com/downloads/jexcel/docs/JExcel-PGuide.html
but I am not getting exactly what I want it to do, which is look at the cell and follow a process depending if it is empty or not. It doesn't debug so I am not sure what else to try.
<script>
function findIt() {
var r = confirm("This will find all data, do you wish to
proceed?");
if (r == true) {
$('#FRSTable').jexcel(data,{
table: function (instance, cell, col, row, val, id) {
cell = worksheet.getcell(1,1);
if (cell() == null)
{
alert("Please Enter a Value");
}
}
});
} else {
alert ( "You pressed Cancel!");
}
}
</script>
So what I expect is for it to say Please enter a value, what happens is all the Cells get removed and a single box with a number 1 replaces it, this resets after reloading the page.
The guide you are looking for actually is here. But, actually, jExcel brings a native searchable option.
<html>
<script src="https://bossanova.uk/jexcel/v3/jexcel.js"></script>
<script src="https://bossanova.uk/jsuites/v2/jsuites.js"></script>
<link rel="stylesheet" href="https://bossanova.uk/jexcel/v3/jexcel.css" type="text/css" />
<link rel="stylesheet" href="https://bossanova.uk/jsuites/v2/jsuites.css" type="text/css" />
<div id="spreadsheet"></div>
<script>
jexcel(document.getElementById('spreadsheet'), {
csv:'https://bossanova.uk/jexcel/v3/demo.csv',
csvHeaders:true,
search:true,
pagination:10,
columns: [
{ type:'text', width:300 },
{ type:'text', width:200 },
{ type:'text', width:100 },
{ type:'text', width:100 },
{ type:'text', width:100 },
]
});
<script>
</script>
</html>
The example above can be found at:
https://bossanova.uk/jexcel/v3/examples/datatables

Does Depreciated version of JQuery Compat Edge mean this code will not run?

I am having trouble getting JQuery to initialize my code when the document is ready. The developer mode in Chrome runs the code without any flags, but nothing loads either. The original author used JQuery Compat Edge, which officially was never released. Does this matter?
The code I am using came from http://jsfiddle.net/Tfs2M/2/. I researched here and here and found many people have problems with their code loading. JQuery does a great job with that so I made what i thought were appropriate modifications. I noticed though the author used Compact Edge. This was a cutting edge version of JQuery about 3 years ago no longer in use. I figured JQuery 3.2.1 would suffice, this is what I came up with.
function starter(GRASP) { //removed $ reference and added a func name.
var GRID_ROWS,
GRID_COLS,
GRID_ELEMENT;
GRASP.config = {
gridContainer: "grid",
matrixContainer: "matrix",
matrixHeader: "matrixHeader"
};
GRASP.start = function () {
GRID_ROWS = $("#rows").val();
GRID_COLS = $("#cols").val();
createGrid();
};
function createGrid() {
//Love to know what the # is doing
GRID_ELEMENT = $("#" + GRASP.config.gridContainer);
var cell; // Contains the 1 or 0 based upon the cell selection
var newGrid = $('<div id="grid" class="gridContainer" ></div>');
//add cells to grid top to bottom with class 'cell and hover attribute
for (var i = 1; i <= GRID_ROWS; i++) {
for (var j = 1; j <= GRID_COLS; j++) {
$("<div class='cell' data-hover-text='"+i+","+j+"'>0</div>")
.appendTo(newGrid);
newGrid.on('click', '.cell', cellClick);
}
}
newGrid.height(38 * GRID_ROWS);
newGrid.width(38 * GRID_COLS);
//add all the new cells to GRID_ELEMENT
GRID_ELEMENT.replaceWith(newGrid);
}
//Changes contents of a cell from 0 to 1, fancy if else statement
function cellClick() {
$(this).text($(this).text() == "0" ? "1" : "0");
}
} // removed the null, false, undefined code since I was using JQuery
I also added the following JQuery too.
$(document).ready(function () {
starter();
});
Here is the HTML if this is of any use.
<html>
<head>
<link rel="stylesheet" type="text/css" href="Coordinate Plane.css">
<script type="text/javascript" src="Coordinate Plane.js"></script>
<script src="jquery-3.2.1.min.js"></script>
<script type="text/javascript" src="Coordinate PlaneJQ.js">
</head>
<body>
<div id="gridLayout" class="gridLayout">
<div id="gridHeader">
<h2>Aperture Configuration:</h2>
Grid Size:
<input id="rows" type="number" min="1" max="50" value="10" width="40"
size="3" onChange="GRASP.start();"/>x
<input id="cols" type="number" min="1" max="50" value="10"
width="40" size="3" onChange="GRASP.start();"/>
</div>
<div id="grid" class="gridContainer"></div>
</div>
</body>
</html>
Posts like this get voted down, I have made about 3 programs in Javascript so far. If there is a more appropriate site for beginners, please leave a note in the comments.
Thank you!
Your script does not run as-is without throwing console errors. The reason is that you've "half-converted" the code from the Fiddle you references (incompletely, with various problems) from an Immediately-Invoked Function "Class" to, well, what you've got here.
Problem #1 is that GRASP is not defined, because of the way you've modified the last portion of the IIFE.
Adding this somewhere before you call starter() solves that problem.
window.GRASP = {};
Problem #2 is that you set up function starter(GRASP) to accept the variable GRASP to be passed in, but you don't pass it in, so it's still undefined inside the function. I have removed that, and made it simply function starter().
Here is a working Fiddle with your code, updated to work properly.

Copy and pasted Microsoft example of Javascript to check value in cell, but fails to work

I have been staring at the code below for hours, and I am not sure where to begin on how to fix the problem. In advance, I believe this is more of a javascript problem on my end then a Microsoft Web API problem, since I am literally copying and pasting their code.
I am trying to use Microsoft Excel's Web API to embed an excel sheet on my web page (which works fine) . More specifically, I am trying to have, when highlighted on a cell, it display the value of the selected cell in an alert javascript box.
Here is their working example with code of exactly what I am trying to do http://www.excelmashup.com/APIBrowser#example105
Simply change the tab from "Output" to "HTML" in the bottom right to see the same code as below:
<html>
<head>
<script type="text/javascript" src="http://r.office.microsoft.com/r/rlidExcelWLJS?v=1&kip=1"></script>
<script type="text/javascript">
// run the Excel load handler on page load
if (window.attachEvent) {
window.attachEvent("onload", loadEwaOnPageLoad);
} else {
window.addEventListener("DOMContentLoaded", loadEwaOnPageLoad, false);
}
function loadEwaOnPageLoad() {
var fileToken = "SDBBABB911BCD68292!110/-4923638281765748078/t=0&s=0&v=!ALTlXd5D3qSGJKU";
var props = {
uiOptions: {
showGridlines: false,
selectedCell: "'Sheet1'!C9",
showRowColumnHeaders: false,
showParametersTaskPane: false
},
interactivityOptions: {
allowTypingAndFormulaEntry: false,
allowParameterModification: false,
allowSorting: false,
allowFiltering: false,
allowPivotTableInteractivity: false
}
};
Ewa.EwaControl.loadEwaAsync(fileToken, "myExcelDiv", props, onEwaLoaded);
}
function onEwaLoaded() {
document.getElementById("loadingdiv").style.display = "none";
}
// This sample gets the value in the highlighted cell.
// Try clicking on different cells then running the sample.
function execute()
{
// Get unformatted range values (getValuesAsync(1,...) where 1 = Ewa.ValuesFormat.Formatted)
ewa.getActiveWorkbook().getActiveCell().getValuesAsync(1,getRangeValues,null);
}
function getRangeValues(asyncResult)
{
// Get the value from asyncResult if the asynchronous operation was successful.
if (asyncResult.getCode() == 0)
{
// Get the value in active cell (located at row 0, column 0 of the
// range which consists of a single cell (the "active cell")).
alert("Result: " + asyncResult.getReturnValue()[0][0]);
}
else
{
alert("Operation failed with error message " + asyncResult.getDescription() + ".");
}
}
</script>
</head>
<body>
<input type="button" onclick="execute();">Execute Sample</input> <<<<<Here is the problem
<div id="myExcelDiv" style="width: 402px; height: 346px"></div>
</body>
</html>
When I change the above to onclick="alert('hello')" that works fine, but it does not alert the value of the cell when I use execute(); . Maybe someone could copy and past the code into an .html file and see if it is just a problem on my end and whether the Microsoft code works for them. If it does not work, that would also be useful information.
The key lays on the variable "ewa". Normally when the page loads, inside loadEwaOnPageLoad() there is this line: Ewa.EwaControl.loadEwaAsync(fileToken, "myExcelDiv", props, onEwaLoaded); So we need to grab an Ewa object inside the onEwaLoaded function. I saw it somewhere like this (ewa declared somewhere else):
function onEwaLoaded(asyncResult) {
/*
* Add code here to interact with the embedded Excel web app.
* Find out more at http://msdn.microsoft.com/en-US/library/hh315812.aspx.
*/
if (asyncResult.getSucceeded()) {
// Use the AsyncResult.getEwaControl() method to get a reference to the EwaControl object
ewa = asyncResult.getEwaControl();
//...
After you got the ewa object the rest would be fine. Without it then the variable ewa is indeed not defined.
The Excel Interactive View feature has been disabled. However, I've just fixed some parts of your code to make it work. I've put all details in the comments with asterisks
<html>
<head>
<script type="text/javascript" src="http://r.office.microsoft.com/r/rlidExcelWLJS?v=1&kip=1"></script>
<script type="text/javascript">
var ewa = null;//*******************ADDING THIS IS BETTER**************************
// run the Excel load handler on page load
if (window.attachEvent) {
window.attachEvent("onload", loadEwaOnPageLoad);
} else {
window.addEventListener("DOMContentLoaded", loadEwaOnPageLoad, false);
}
function loadEwaOnPageLoad() {
var fileToken = "SDBBABB911BCD68292!110/-4923638281765748078/t=0&s=0&v=!ALTlXd5D3qSGJKU";
var props = {
uiOptions: {
showGridlines: false,
selectedCell: "'Sheet1'!C9",
showRowColumnHeaders: false,
showParametersTaskPane: false
},
interactivityOptions: {
allowTypingAndFormulaEntry: false,
allowParameterModification: false,
allowSorting: false,
allowFiltering: false,
allowPivotTableInteractivity: false
}
};
Ewa.EwaControl.loadEwaAsync(fileToken, "myExcelDiv", props, onEwaLoaded);
}
function onEwaLoaded(asyncResult) { //*******************PASS asyncResult PARAMETER**************************
//*******************THERE IS NO SUCH THING CALLED "loadingdiv"**************************
//document.getElementById("loadingdiv").style.display = "none";
//*******************ADD THIS IF-ELSE STATMENT**************************
if (asyncResult.getSucceeded()) {
// Use the AsyncResult.getEwaControl() method to get a reference to the EwaControl object
alert("Async operation Succeeded!");
ewa = asyncResult.getEwaControl();
}
else {
alert("Async operation failed!");
}
}
// This sample gets the value in the highlighted cell.
// Try clicking on different cells then running the sample.
function execute() {
// Get unformatted range values (getValuesAsync(1,...) where 1 = Ewa.ValuesFormat.Formatted)
ewa.getActiveWorkbook().getActiveCell().getValuesAsync(1, getRangeValues, null);
}
function getRangeValues(asyncResult) {
// Get the value from asyncResult if the asynchronous operation was successful.
if (asyncResult.getCode() == 0) {
// Get the value in active cell (located at row 0, column 0 of the
// range which consists of a single cell (the "active cell")).
alert("Result: " + asyncResult.getReturnValue()[0][0]);
}
else {
alert("Operation failed with error message " + asyncResult.getDescription() + ".");
}
}
</script>
</head>
<body>
<!-- *******************THE SIMICOLON AFTER execute() IS REMOVED*********************** -->
<input type="button" onclick="execute()" value="Execute Sample"></input>
<!-- *******************STYLE IS IMPROVED*********************** -->
<div id="myExcelDiv" style="width: 100%; height: 1000px"> </div>
</body>
</html>

Creating Dynamic Javascript AJAX

Alright, I'm currently working to create on an account mainpage a applet to show each "kid" the user has registered to the site. My idea is simple :
Kid 1 / Kid 2 / Kid 3
As buttons (with style and such) when he goes on this page. When he clicks on one of those buttons/names, I use javascript to show the description of the infos of the kid, etc. When I click on another name, the current content closes and shows the new appropriate content.
The content is dynamically created, so the id's of the divs containing the info are named after the number of kids. Example : content_Info_Kid1, content_Info_Kid2, ... It doesnt matter how many kids there are, they will be named content_Info_Kid32 if need be.
Now, I'm not too comfy with AJAX and javascript in general. In fact, I am not at all.
My first idea was to do this in a separate javascript file.
$(document).ready(function() {
$("#content_info_kid1").hide();
$("#content_info_kid2").hide();
$("#content_info_kid3").hide();
$("#KID_1").click(function () {
if ($("#content_info_kid1").is(":hidden")){
$("#content_info_kid2").hide();
$("#content_info_kid3").hide();
$("#content_info_kid1").show("slow");
$(this).css("font-weight","bold");
$("#KID_2").css("font-weight","normal");
$("#KID_3").css("font-weight","normal");
}
});
$("#KID_2").click(function () {
if ($("#content_info_kid2").is(":hidden")){
$("#content_info_kid1").hide();
$("#content_info_kid3").hide();
$("#content_info_kid2").show("slow");
$(this).css("font-weight","bold");
$("#KID_1").css("font-weight","normal");
$("#KID_3").css("font-weight","normal");
}
});
$("#KID_3").click(function () {
if ($("#content_info_kid3").is(":hidden")){
$("#content_info_kid2").hide();
$("#content_info_kid1").hide();
$("#content_info_kid3").show("slow");
$(this).css("font-weight","bold");
$("#KID_1").css("font-weight","normal");
$("#KID_2").css("font-weight","normal");
}
});
});
Obviously, this is not dynamic. And I don't want to create 32 alternatives, of course. Can somebody point me the right direction to create a dynamic way to show my content based on the number of kids ?
EDIT (see bottom for updated on loading just one kid data at a time)
An example on how you could achieve that:
<style type='text/css' media='screen'>
button { margin-left:20px; display:inline; }
</style>
<script type='text/javascript' src='jquery-1.7.1.min.js'></script>
<script type='text/javascript'>
function loadKidData(kidID) {
switch (kidID) {
case 1 : $('#kName').text(' John Doe');
$('#kNickname').text(' Speedy');
$('#kHobbies').text(' Booling');
break;
case 2 : $('#kName').text(' Mathews Doe');
$('#kNickname').text(' Slowy');
$('#kHobbies').text(' Basketball, baseball');
break;
case 3 : $('#kName').text(' Jackson Doe');
$('#kNickname').text(' J-DOE');
$('#kHobbies').text(' Archery');
break;
case n : $('#kName').text(' Enne Doe');
$('#kNickname').text(' The-Nanny');
$('#kHobbies').text(' Anything goes');
break;
default : $('#kName').text('');
$('#kNickname').text('');
$('#kHobbies').text('');
}
}
jQuery( function () {
$('.nav').click( function () {
loadKidData($(this).html().replace('KID ','')*1.0); // *1.0 same as parseInt(...,10).
})
});
</script>
</head>
<body>
<button class='nav' >KID 1</button><button class='nav' >KID 2</button><button class='nav' >KID 3</button>
<div id='KID_INFO' style='margin:20px auto; overflow:auto; ' >
<p>Name:<span id='kName'></span></p>
<p>Nickname:<span id='kNickname'></span> </p>
<p>Hobbies:<span id='kHobbies'></span> </p>
</div>
</body>
Sample at: http://zequinha-bsb.int-domains.com/kidsinfo.html
Now, as far as dynamically displaying the data, it will have to do with your resources: database? If so, you could read the data and pass it over:
$.get('url-of-the-database-reading-script',function (data) {
// assumed all data comes back formatted:
$('#KIDS_INFO').html(data);
});
I can/could help you further, more details would help. Are you using classic asp (.asp); php; etc?
EDIT:
Instead of this:
jQuery( function () {
$('.nav').click( function () {
loadKidData($(this).html().replace('KID ','')*1.0); // *1.0 same as parseInt(...,10)
})
});
Do this:
jQuery( function () {
$('.nav').click( function () {
$.get('your-data-fetching-url?kidID='+$(this).html().replace('KID ','')*1.0, function (data) {
//assumed the data comes back formatted:
$('#KIDS_DATA').html(data);
})
})
});
Note that I put a question mark at the end of the url; followed by the querystring kidID=
Give each "Kid" button the same class and use that for the click handler. From there, you can associate the "content_info_kid" with the "kid" button either by
1)Using the index of the element. The button for kid2 should be index 1 relative to its parent and the content_info for kid2 should also be index 1 relative to its parent.
or
2)Extract the number from the ID of the button.
Both approaches are documented below.
$('.kid_button').click(function(){
// get number from index (this starts at '0')
// if your kid #'s start at 1, you should add 1 to this
var id = $(this).index();
// OR...get number from id where id format is kid_{#}
var id = $(this).attr('id').split('_').pop();
// now we have the number to append to everything else
// we should also associate all "content_info" with a class
// which we will call "kid_content"
if($("#content_info_kid"+id).is(":hidden")){
// hide all of the 'kid_contents'
$(".kid_content").hide();
// show the one we want
$("#content_info_kid"+id).show("slow");
// normalize all buttons
$(".kid_button").css("font-weight","normal");
// bold this one
$(this).css("font-weight","bold");
}
});

Dojo: dojox.grid.enhanced.plugins.Filter - all items are cleared from the grid on filtering

I've got a dojox.grid.EnhancedGrid with a dojox.grid.enhanced.plugins.Filter and a dojo.store.Memory wrapped in a dojo.data.ObjectStore. Whenever I try to filter, all records are removed from the grid. I get a '0 of 0 items shown' message. When i click 'clear filter' the grid remains empty.
Update:
The plot thickens. It seems that just sorting the grid by a column clears the grid. I'm trying to get a basic example working here: http://jsfiddle.net/wp64T/4/
I had the same problem and only managed to fix it by running the grid filter periodically in the background with the help of some jQuery. Here is some sample code; hope this helps someone else having problems with this.
// ADD JQUERY
<script src="http://code.jquery.com/jquery-latest.js"></script>
.
// PUT THIS IN THE <HEAD> OF THE PAGE
<script type="text/javascript">
$(document).ready(function() {
function filterTheDataGrid() {
if (dijit.byId("grid") != undefined) {
dijit.byId("grid").filter({color: "Red"});
}
}
// RUN THE filterTheDataGrid FUNCTION EVERY ONE SECOND (1000 MILLISECONDS) //
// LOWER '1000' FOR FASTER REFRESHING, MAYBE TO 500 FOR EVERY 0.5 SECOND REFRESHES //
var refreshDataGrid = setInterval(function() { filterTheDataGrid(); }, 1000);
}
</script>
.
// PUT THIS IN THE <HEAD> OF THE PAGE
<script type="text/javascript">
// SETUP THE LAYOUT FOR THE DATA //
var layoutItems = [[
{
field: "id",
name: "ID",
width: '5px',
hidden: true
},
{
field: "color",
name: "Color",
width: '80px'
}
]];
// Create an empty datastore //
var storeData = {
identifier: 'id',
label: 'id',
items: []
}
var store3 = new dojo.data.ItemFileWriteStore( {data : storeData} );
</script>
.
// PUT THIS IN THE <HTML> OF THE PAGE
<div id="grid" dojoType="dojox.grid.DataGrid" jsId="grid5" store="store3" structure="layoutItems" query="{ type: '*' }" clientSort="true" rowsPerPage="40"></div>
.
<script type="text/javascript">
function addItemToGrid(formdata) {
// THIS FUNCTION IS CALLED BY A DIALOG BOX AND GETS FORM DATA PASSED TO IT //
var jsonobj = eval("(" + dojo.toJson(formData, true) + ")");
var myNewItem = {
id: transactionItemID,
color: jsonobj.color
};
// Insert the new item into the store:
store3.newItem(myNewItem);
store3.save({onComplete: savecomplete, onError: saveerror});
}
</script>
Can you please provide a code snippet or jsFiddle? Without it the best guess I can provide is you are attempting to filter on a store value that does not exist, and your clear filter button only modifies the textbox and does not re-fire the filter command to reset it.
Edit :
Please try http://download.dojotoolkit.org/release-1.4.0/dojo-release-1.4.0/dojox/grid/tests/test_data_grid.html
Three console commands :
dijit.byId("grid").filter({name : "A*"})
Will give all that start with A.
dijit.byId("grid").filter({name : "*"})
Will give the original result set back(all).
dijit.byId("grid").filter({name : ""})
Will clear the grid, nothing matches.
I realize this isn't quite the API you are using(dojo.data.ObjectStore) but it should follow the same logic. My guess is you ended up trying to filter against "" and matched nothing, resulting in your zero element grid. Don' forget the asterisk if you are looking to do begins-width/contains/ends-width.

Categories

Resources