Possible dijit.Tree Cookie issue (SaveStateCookie) - dojo

So our app is set up like the standard left frame with the tree, right frame has the main content (loaded from clicking the tree).
Our web app inconsistently displays a blank page in the main frame in Firefox. By inconsistent I mean everyday for a few, rarely for others, never for most. Once we get this, going to any other page through our tree results in a blank page. We found that deleting the "aTreeSaveStateCookie" restores normal operation. "aTree" is the name of our Div. I found "SaveStateCookie" strings in dijit/Tree.js.
This also happens in IE, except I would get a browser error page which I can't recall right now. I would then delete the only cookie I could find for our app (not sure how to do the Firefox steps in IE)
Any ideas on why this would happen?
Thanks
Dojo 1.3 through http://ajax.googleapis.com/ajax/libs/dojo/1.3/dojo/dojo.xd.js
Firefox 3.1x
IE 8
Windows XP
In my case, I don't recall ever changing browser settings around Private Data.

Please check to see if the response code is 413 (413 = request entity too large), usually this happens when the cookie(s) used to store the tree(s) expansion state (aTreeSaveStateCookie) exceed(s) the maximum request size for your server
You could try increasing the maximum request size (follow instructions for your specific web app server) or at least display a meaningful error message like "please clear your browser cache" when the 413 error code is encountered

If the persist property is set to a truthy value, dijit.Tree is persisting its state to remember which nodes were expanded, and expand them after a page reload. If you need to persist the tree state in presence of a very large data structure, I recommend overriding Tree to use localStorage instead of dojo.cookie.
This is Dojo v. 1.9, but similar changes can be done to the non-AMD version 1.3
_saveExpandedNodes: function(){
if(this.persist && this.cookieName){
var ary = [];
for(var id in this._openedNodes){
ary.push(id);
}
// Was:
// cookie(this.cookieName, ary.join(","), {expires: 365});
localStorage.setItem(this.cookieName, ary.join(","));
}
},
And:
_initState: function(){
// summary:
// Load in which nodes should be opened automatically
this._openedNodes = {};
if(this.persist && this.cookieName){
// Was:
// var oreo = cookie(this.cookieName);
var oreo = localStorage.getItem(this.cookieName);
if(oreo){
array.forEach(oreo.split(','), function(item){
this._openedNodes[item] = true;
}, this);
}
}
},

Related

How to add modernizr build so that I can properly check Modernizr.capture? (currently always undefined)

I need to check if the user's device can input from a camera on my site. To do this I am attempting to use modernizr. I have followed the steps/example code provided on their site but when I test the capture attribute, I always get undefined, regardless of if I am on a device that supports capture.
Steps I followed:
I browsed for the input[capture] attribute and added it to the build
I copied the demo code to check this feature and added it to my project
I downloaded the build, added the js file to my project, and included the appropriate reference in my page
However after all of this, when inspecting Modernizr.capture in the chrome inspector, it always shows up as undefined.
My basic check function is as follows:
$scope.hasCamera = function() {
if (Modernizr.capture) {
// supported
return true;
} else {
// not-supported
return false;
}
}
This is my first time using Modernizr. Am I missing a step or doing something incorrectly? I also installed modernizr using npm install and tried adding the reference to a json config file from the command line.
Alternatively, how might I check if my device has a camera?
Thank you very much for your time. Please let me know if I am being unclear or if you need any additional information from me.
A few things
while photos are helpful, actual code hosted in a public website (either your own project, or on something like jsbin.com) is 10x as useful. As a result, I am not sure why it is coming back as undefined.
The actual capture detect is quite simple. It all comes down to this
var capture = 'capture' in document.createElement('input')`
Your code is a lot more complicated than it needs to be. Lets break it down. You trying to set $scope.hasCamera to equal the result of Modernizr.capture, and you are using a function to check the value of Modernizr.capture, and if it is true, return true. If it is false, return false. There is a fair bit of duplicated logic, so we can break it down from the inside out.
Firstly, your testing for a true/false value, and then returning the same value. That means you could simplify the code by just returning the value of Modernizr.capture
$scope.hasCamera = function() {
return Modernizr.capture
}
While Modernizr will always be giving you a boolean value (when it is functioning - without seeing your actual code I can't say why it is coming back as undefined), if you are unsure of the value you can add !! before it to coerce it into a boolean. In your case, it would make undefined into false
$scope.hasCamera = function() {
return !!Modernizr.capture
}
At this point, you can see that we are setting up a function just to return a static value. That means we can just set assign that static value directly to the variable rather than setting up a function to do that
$scope.hasCamera = !!Modernizr.capture
Now, the final thing you may be able to do something better is if you are only using Modernizr for this one feature. Since it is such a simple feature detection, it is overkill to be using all of Modernizr.
$scope.hasCamera = 'capture' in document.createElement('input')`

Cannot refresh content in browser using http-server with Aurelia

I'm using Aurelia with http-server, as it is described in Aurelia getting started docs. I'm unable to see changes, because any browser seems to cache entire page at first load. When I use F5, ctrl+F5 or ctrl+r, page refreshes but nothing changes, none of my modifications are visible. Then I can use another browser and at first visit changes are visible, but any subsequent visit shows always the first one. It occurs in every browser I use (Chrome and Firefox, ever in private mode). I'm certain that it is not bug in Aurelia itself.
I tried to change port and use http-server with -c parameter. Nothing changed. Any ideas?
If you want to force your Aurelia app to be constantly refreshed after you modify it, you can have a look at the following thread:
https://github.com/aurelia/framework/issues/94
Aaike commented on 8 May 2015:
change your index.html to add the extension right before you import
the aurelia-bootstrapper
<script>
var systemLocate = System.locate;
System.locate = function(load) {
var System = this;
return Promise.resolve(systemLocate.call(this, load)).then(function(address) {
if(address.lastIndexOf("html.js") > -1) return address;
if(address.lastIndexOf("css.js") > -1) return address;
return address + System.cacheBust;
});
};
System.cacheBust = '?bust=' + Date.now();
System.import('aurelia-bootstrapper');
</script>
This is a caching issue that pops up sometimes with http-server. I don't know exactly what causes it but I believe the -c modifier changes the length of cache-control so I would set that as 0 or 1 instead of assigning a port that way.

Cannot read second page scanned via ADF

I have a Brother mutlifunction networked printer/scanner/fax (model MFC-9140CDN). I am trying to use the following code with WIA, to retrieve items scanned in with the document feeder:
const int FEEDER = 1;
var manager=new DeviceManager();
var deviceInfo=manager.DeviceInfos.Cast<DeviceInfo>().First();
var device=deviceInfo.Connect();
device.Properties["Pages"].set_Value(1);
device.Properties["Document Handling Select"].set_Value(1);
var morePages=true;
var counter=0;
while (morePages) {
counter++;
var item=device.Items[1];
item.Properties["Bits Per Pixel"].set_Value(1);
item.Properties["Horizontal Resolution"].set_Value(300);
item.Properties["Vertical Resolution"].set_Value(300);
var img=(WIA.ImageFile)item.Transfer();
var path=String.Format(#"C:\Users\user1\Documents\test_{0}.tiff",counter);
img.SaveFile(path);
var status=(int)device.Properties["Document Handling Status"].get_Value();
morePages = (status & FEEDER) > 0;
}
When the Transfer method is reached for the first time, all the pages go through the document feeder. The first page gets saved with img.SaveFile to the passed-in path, but all the subsequent pages are not available - device.Items.Count is 1, and trying device.Items[2] raises an exception.
In the next iteration, calling Transfer raises an exception -- understandably, because there are now no pages in the feeder.
How can I get the subsequent images that have been scanned into the feeder?
(N.B. Iterating through all the device properties, there is an additional unnamed property with the id of 38922. I haven't been able to find any reference to this property.)
Update
I couldn't find a property on the device corresponding to WIA_IPS_SCAN_AHEAD or WIA_DPS_SCAN_AHEAD_PAGES, but that makes sense because this property is optional according to the documentation.
I tried using TWAIN (via the NTwain library, which I highly recommend) with the same problem.
I have recently experienced a similar error with a HP MFC.
It seems that a property was being changed by the driver. The previous developer of the software I'm working on just kept reinitalisating the driver each time in the for loop.
In my case the property was 'Media Type' being set to FLATBED (0x02) even though I was doing a multi-page scan and needed it to be NEXT_PAGE (0x80).
The way I found this was by storing every property before I scanner (both device and item properties) and again after scanning the first page. I then had my application print out any properties that had changed and was able to identify my problem.
This is a networked scanner, and I was using the WSD driver.
Once I installed the manufacturer's driver, the behavior is as expected -- one page goes through the ADF, after which control is returned to the program.
(Even now, when I use WIA's CommonDialog.ShowSelectDevice method, the scanner is available twice, once using the Windows driver and once using the Brother driver; when I choose the WSD driver, I still see the issue.)
This bug did cost me hours...
So thanks a lot Zev.
I also had two scanners shown in the dialog for physically one machine. One driver scans only the first page and then empties the feeder without any chance to intercept. The other one works as expected.
BTW: It is not needed to initialize the scanner for each page. I call my routines for initialization prior to the Transfer() loop. Works just fine.
Another hickup I ran into was to first initialize page sizes, then the feeder. So if you do not get it to work, try switching the sequence how you change the properties for your WIA driver. As mentioned in the MSDN, some properties also influence others, potentially resetting your changes.
So praise to ZEV SPITZ for the answer on Aug. 09, 2015.
You should instantiate and setup device inside the 'while' loop. See:
const int FEEDER = 1;
var morePages=true;
var counter=0;
while (morePages) {
counter++;
var manager=new DeviceManager();
var deviceInfo=manager.DeviceInfos.Cast<DeviceInfo>().First();
var device=deviceInfo.Connect();
//device.Properties["Pages"].set_Value(1);
device.Properties["Document Handling Select"].set_Value(1);
var item=device.Items[1];
item.Properties["Bits Per Pixel"].set_Value(1);
item.Properties["Horizontal Resolution"].set_Value(300);
item.Properties["Vertical Resolution"].set_Value(300);
var img=(WIA.ImageFile)item.Transfer();
var path=String.Format(#"C:\Users\user1\Documents\test_{0}.tiff",counter);
img.SaveFile(path);
var status=(int)device.Properties["Document Handling Status"].get_Value();
morePages = (status & FEEDER) > 0;
}
I got this looking into this free project, which I believe is able to help you too: adfwia.codeplex.com

Change ItemFileWriteStore URL, get data and refresh Grid

I have an EnhancedGrid with ItemFileWriteStore. After calling startup() on the grid, I hide the same by using following code:
dojo.style(grid.domNode, 'display', 'none');
And then on the click of a button, I change the URL of store for this grid and try to refresh the store and show the grid by using following code:
store.save();
store.close();
store.url='AjaxPopulate.json?os_type='+dijit.byId('osType').get('value');
store.save();
store.fetch({query:{id: '*'}});
dojo.style(grid.domNode, 'display', '');
grid.store.close();
grid.setStore(store);
The above code works fine with Firefox and Chrome but not on IE8 and IE9. I simply get "Object Error" message in IE Developer tools console.
Pls. help me identify any issues with the above code.
Howto reload store
If using the 'data' property to populate store initially (via constructor), you should set clearOnClose: true as well.
Use of .save() is only for a ItemFileWriteStore that has some settings changed (isDirty) and needs to propagate these to server. That said, you dont need .save on a closed store (allthough url has changed, no fetch has been run and definately no items has changed).
Try the following code, you'd only need the grid component to do it as calling .render() on the grid will get it to reload it's data.
// save if dirty, otherwise we cannot close a store unless its reset
grid.store.save();
// close store, this should clear data
grid.store.close();
// set new URL
grid.store.url = '??';
// rerun fetch XHR
// reload grid data with new items (no need to setStore as its same object reused)
grid.store.fetch({query:{id: '*'}, onComplete: function() {grid.render}});
Problem was that I had invalid JSON coming from server with one extra comma.
IE is very specific on these things.
Thanks everyone who viewed and tried to reply.

How to remember variables with Greasemonkey script when a page reloads

Ive got an problem currently on an mobile site that i'm running directly in my pc's firefox browser. Everytime a button is clicked, the page reloads, thus resetting my variables. I've got this script:
// ==UserScript==
// #name trada.net autoclick 55_1min_mobile
// #namespace airtimeauction auto click
// #include http://www.trada.net/Mobile/
// #version 0.1
// #description Automatically click // ==/UserScript==
var interval = 57000;
var bidClickTimer = setInterval (function() {BidClick (); }, interval);
var numBidClicks = 0;
function BidClick ()
{var bidBtn1=document.getElementById("ctl00_mainContentPlaceholder_AirtimeAuctionItem7_btn_bidNow");
numBidClicks++;
if (numBidClicks > 500)
{
clearInterval (bidClickTimer);
bidClickTimer = "";
}
else
{
bidBtn1.click (1);
}
};
BidClick();
It should click the button every 57 seconds, but the moment it clicks the button, the page reloads, thus resetting the variables. How can i get greasemonkey to "remember" or carry over the variables to the next page/script when it reloads? Will it have something to do with GM_setValue? It will only be this few variables, but the second problem or question wil be, will it subtract the few seconds it takes the page to reload from the "57" seconds? How do i compensate for that?
In addition to GM_setValue...
you also can use the new Javascript "localStorage" object, or a SQL Javascript API.
The advantage of the SQL approach is it is very meager in its resource consumption in a script (think about it; rather than concatenating a humongous string of results, you can tuck away each result and recall it if needed with a precise query. The downside is you have to set up a SQL server, but using something like SQLite that's not a big deal these days. Even postgres or mysql can be quickly spun on a laptop...
Yes, I think you have to use GM_setValue/GM_getValue.
And if you have to do something exactly every 57 seconds, then calculate the time when the next action should take place after the reload, and store it using GM_setValue.
When your script starts, read first if the next action is stored, if it is, use that time to schedule the next action, and calculate the time for the action after that, and so on...
GM.setValue will set a value indefinitely and is scoped to the script, but will work if your script runs across multiple domains.
window.localStorage will set a value indefinitely and is scoped to the domain of the page, so will not work across domains, but will work if you need several GreaseMonkey scripts to access the same value.
window.sessionStorage will set a value only while the window or tab is open and is scoped to only that window or tab for that domain.
document.cookie can set a value indefinitely or only while the browser is open, and can be scoped across subdomains, or a single domain, or a path, or a single page.
Those are the main client-side mechanisms for storing values across page loads that are intended for this purpose. However, there is another method which is sometimes possible (if the page itself is not using it), and can also be quite useful; window.name.
window.name is scoped to the window or tab, but will work across domains too. If you need to store several values, then they can be put into an object and you can store the object's JSON string. E.g. window.name = JSON.stringify(obj)