I'm new in javascript and i need to maintain a site.
The actual fonctionnality is to download several card into a file, one card per tab. As users can have plenty of cards, treatment can not always succeed (too many tabs), i wanted create a file evey 20 tabs for instance.
var printTerm = function(grid){
var rows = grid.selected;
if(rows==null) return;
var ids = rows.map(function(val){return grid.getDataByRow(val).num_terme;});
var nbMax = 20;
var nbFic;
var idsPartiel;
var posDebut;
var posFin;
var a;
if(ids.length > nbMax)
{
idsPartiel = ids;
if(ids.length % nbMax == 0) nbFic = ids.length / nbMax;
else nbFic = ((ids.length - (ids.length % nbMax)) / nbMax) + 1;
for (i=0 ; i< nbFic ; i++)
{
posDebut = (nbMax * i);
if(i == nbFic - 1) posFin = idsPartiel.length + 1;
else posFin = posDebut + nbMax;
ids = idsPartiel.slice(posDebut,posFin);
a = new Element('a', 'id':'download','href':'php/utils/export2pdf.php?ids='+ids.join(',')})
.addEvent('click',function(){location.href=this.href;}).inject(document.body);
a.fireEvent('click');
a.dispose();
}
}
else
{
a = new Element('a',{'id':'download','href':'php/utils/export2pdf.php?ids='+ids.join(',')})
.addEvent('click',function(){location.href=this.href;}).inject(document.body);
a.fireEvent('click');
a.dispose();
}
};
When the number of cards is less or equal to nbMax, it works well, bu when there must be several files, not: only the last passage of the loop is creating the file.
When i try to see what happens with firebug, i see my lines of treatment, but only the last is ended.
Thanks for helping me.
If I read your code correctly, you are trying to make the browser download a ton of files into separate tabs. Most browsers won't really appreciate you trying to launch a loop of downloads that way, nor would a user really want that many save as dialogs potentially popping off.
You would be way better off packaging them into a zip file server side and sending ONE file. It would be more efficient and way more user friendly.
Related
I have two problems.
1) My function noDateAlert(); is SLOW. Any suggestions to make it take less than 5 seconds? Currently takes 17-30 depending on how many lines it has to check.
2) The error message will not pop up when I run noDateAlert(); in another function from my custom menu. It works fine when I run it by itself from the script page. It also works fine when run within the other program from the script page.
I'm using this program to warn me if the 3 cells are empty.
When it is enclosed in the other function it is the first thing listed.
Here's the function:
function noDateAlert() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh0 = ss.getSheetByName("Loads");
// get data from Loads sheet
var data = sh0.getRange(8,29,53,31).getValues();
var data2 = sh0.getRange(8,3,53,3).getValues();
for(var i=0; i < 45; i++) { //Controls how many rows it goes through for posting // len = data.length; i < len
//Only work on loads currently wanting to post
if(data2[i][0] == "P-Post"){
//Warn me if all 3 cells in one row are empty/blank
if(data[i][0] == "" && data[i][1] == "" && data[i][2] == ""){
Browser.msgBox("Some of the loads you want to post are missing dates. Please check dates and run 'Post Loads' again.");
return false;
break;
};
};
};
};
Try this for your msgbox. And I'll keep on looking at the other problem.
SpreadsheetApp.getUi().alert('Some of the loads you want to post are missing dates. Please check dates and run \'Post Loads\' again.');
I'm not privy to your data but I doubt that I do things this way. But since you have access to and knowledge of your data I'll assume that breaking this up in two ranges makes sense. However, I hope you realize that data2[i][0] is actually column 3 and data[i][0] is actually column 29. I left the limit for i at 53 since you specified 53 rows in both ranges. But again. I don't know the detail nor do I have access to the data. So if this doesn't help, you can change it back.
function noDateAlert()
{
var ss=SpreadsheetApp.getActiveSpreadsheet();
var sh0=ss.getSheetByName("Loads");
var data = sh0.getRange(8,29,53,31).getValues();
var data2 = sh0.getRange(8,3,53,3).getValues();
for(var i=0;i<53;i++)
{
if(data2[i][0]=="P-Post")
{
if(!data[i][0] && !data[i][1] && !data[i][2])
{
SpreadsheetApp.getUi().alert('Some of the loads you want to post are missing dates. Please check dates and run \'Post Loads\' again.');
return false;
}
}
}
}
I'm interested in using Firebase, but have some questions.
One demo I'm really interested in is the drawing demo: https://www.firebase.com/tutorial/#session/lijxbwexqv1
The key thing I'm curious about is how sessions in Firebase are handled and established. How is a random session key being created, and also how is it being put in the URL to establish where the data is coming from (see code below).
//Create a reference to the pixel data for our drawing.
var pixelDataRef = new Firebase('https://lijxbwexqv1.firebaseio-demo.com/');
I'd like to create an educational app. Where the user is shown a picture of something, and then on their phone are seeing corresponding information to the picture they're being shown. I know this is different from the drawing demo, but the concepts of sessions is similar. Basically each user would have a "session" or a firebase data set--that they could access using a custom URL.
Any help or pointers (docs even) regarding the establishment and storage sessions would be greatly appreciated.
Thanks in advanced.
The "session" keys are random strings. They are generated in the source as follows:
UserSession.prototype.generateSessionID_ = function () {
if (window.isDebugMode) {
return "chat";
} else {
var chars = "abcdefghijklmnopqrstuvwxyz0123456789";
var retVal = chars.charAt(Math.floor(Math.random() * 26, 1));
for (var i = 0; i < 10; i++) {
retVal = retVal + chars.charAt(Math.floor(Math.random() * chars.length, 1));
}
return retVal;
}
}
You could also simply use Firebase.push(), which generates random ids that also serve as sequential, chronological record ids:
function generateSessionId(ref) {
return ref.push().name();
}
var fb = new Firebase(URL);
console.log( generateSessionId(fb) );
Currently I have 3 or 4 galleries loaded on one page. It's a photographers site, so each gallery has about 40 images. I originally pre-loaded the images, where I would just load the first two images so the page loads quickly, then use JS in the background to cycle through a loop and load the rest. It worked well, except that it didn't honor the order, and the order is important. I have seen some examples where you hide the images until they load, but since there are about 120 large images being loaded in the page it causes the page to load slowly. Is there a way I can use my code, and sort the images once they're loaded? Or, should I load them through an array, would it still ignore the load order? Here's my jsfiddle: http://jsfiddle.net/drrobotnik/YKPEu/
The piece of js i am looking at mostly is this part:
var stack = [];
for (var i = 3; i <= 59; i++) {
var img = new Image(782,521);
img.src = 'http://anikalondon.com/Images/weddings/weddings-3-' + i + '.jpg';
$(img).bind('load', function() {
stack.push(this);
var len = stack.length+2;
$(".numbers").text(($(".enggal img:visible").index()+1)+"/"+len);
if(i>=58){$(".numbers").css("visibility", "visible");}
});
}
again, in this example it's loading the images out of order (probably whichever ones load first, not sure).
well idk if it helps but here's a sorting algorithm that you could use to order them before inserting them into the DOM
stack.sort(function(a,b){
return a.src.substring(a.src.lastIndexOf("-")+1,a.src.lastIndexOf(".")) - b.src.substring(b.src.lastIndexOf("-")+1,b.src.lastIndexOf("."))
})
What if you replaced you simplify things and use this for loop
for (var i = 3; i <= 59; i++)
{
$(".enggal").append("<img src='http://anikalondon.com/Images/weddings/weddings-3-" + i + ".jpg' />");
}
This inserts all of your images in order. You may want to add in the width/height attributes.
Without knowing the deal with how stack is used, I'm not totally sure this would work, but why don't you just save the index information to a store right away, rather than on the callback when it's done loading?
And you should also set src after you bind load or it might miss.
[totally revised from original answer]
var img,i,stack = [];
var imageLoaded=function(e) {
var len = stack.length+2,
index = parseInt(this.src.split('-')[2])-3
$(".numbers").text(($(".enggal img:visible").index()+1)+"/"+len);
if(index>=58){$(".numbers").css("visibility", "visible");}
}
for (i = 3; i <= 59; i++) {
img = new Image(782,521);
$(img).bind('load', imageLoaded);
stack.push(img);
}
// Just to make sure that the first image doesn't finish loading before the loop isdone
// throwing off the count in the imageLoaded function
for (i = 3; i <= 59; i++) {
stack[i-3].src = 'http://anikalondon.com/Images/weddings/weddings-3-' + i + '.jpg';
}
NOTE: Originally had this listed as a memory leak. After looking into this deeper, I discovered that it's not a memory issue. It's just a very slow script. Any suggestions to speed this up would be greatly appreciated.
ANOTHER NOTE: After looking into this even further, I see that FF does not support any type of CSS that formats text in overflow. There is a hack and a workaround for that hack...but that will not be a suitable solution.
I have voted for and joined the e-mail list on this particular bug at mozilla. It's almost six years old so I resolve that users will just have to deal with it for now. At least it's not a common scenario for our product.
Original post:
The script truncates the value of an element and appends '...' while its scrollWidth is greater than it's offsetWidth. (e.g. A value of "LastName, VeryLongFirstName"will change to something like "LastName, Ver...", depending on the width of the column)
var eTable = document.getElementById(this._eDiv.id + "_tbl");
//...lots of code here...
//function called that gets all cells in a table, loops through them and clips the text
addEventListenerEx(window, "load", function() {
var aCells = eTable.getElementsByTagName("DIV");
window.alert(aCells.length);
//When aCells is length of 100, we're ok...but when it's big (like 3,000) I have problems
for (var i = 0; i < aCells.length; i++){
Grid.clipText(aCells[i]);
}
}, false);
//...lots of code here...
//This is the function doing the actual clipping
Grid.clipText = function (oDiv) {
//for tooltip
var oCurDiv;
var oTagA;
var sToolTip;
if (oDiv.firstChild) {
if (oDiv.firstChild.firstChild){
oCurDiv = oDiv.firstChild;
while (oCurDiv) {
if (is.ie) {
oTagA = oCurDiv;
} else {
// there are some different between IE & FireFox.
oTagA = oCurDiv.firstChild.parentNode;
}
if (oTagA.tagName == "A") {
sToolTip = oTagA.innerHTML;
if (sToolTip.indexOf('<b>') > 0) {
sToolTip = sToolTip.replace('<b>',"");
sToolTip = sToolTip.replace('</b>',"");
}
if (sToolTip.indexOf('<B>') > 0) {
sToolTip = sToolTip.replace('<B>',"");
sToolTip = sToolTip.replace('</B>',"");
}
oTagA.parentNode.title = convertHTMLToText(sToolTip);
}
oCurDiv = oCurDiv.nextSibling;
}
} else {
oDiv.title = convertHTMLToText(oDiv.innerHTML);
}
}
//NOTE: Additional steps to take for non-IE browsers
if (!is.ie) {
var oText = oDiv;
while (oText.nodeType != 3) {
oText = oText.firstChild;
}
var sDisplayText = oText.nodeValue;
if (sDisplayText.length < 3) return;
var lastThree;
sDisplayText = sDisplayText.slice(0, parseInt(oDiv.offsetWidth / 5));
oText.nodeValue = sDisplayText + "...";
//NOTE: Bad things happen here because of this loop
while (oDiv.scrollWidth > oDiv.offsetWidth && sDisplayText != "") {
lastThree = sDisplayText.slice(-3);
sDisplayText = sDisplayText.slice(0, sDisplayText.length - 3);
oText.nodeValue = sDisplayText + "...";
}
oText.nodeValue = sDisplayText + lastThree.slice(0, 1) + "...";
while (oDiv.scrollWidth > oDiv.offsetWidth && sDisplayText != "") {
oText.nodeValue = sDisplayText + "...";
}
}
The code works. However, the problem is that it's called over and over again after a table is loaded on the page. When the table is huge (>1,500 cells), that's when the issue starts.
So, I'm really looking for a way to make this sample (particularly the WHILE loop) more efficient.
Nothing in that is going to leak by itself. You're probably leaking oText in the closure, can you show the surrounding code?
Btw, here is a vastly more efficient way of doing this:
http://jsfiddle.net/cwolves/hZqyj/
If you really want to keep doing it the way you are, you can estimate the cutoff point by taking the length of the string and multiplying it by the proportional width it needs to be...
e.g. if the string is 100 characters and it's 2x as long as it should be, cut it to 50 chars and re-check. Or you could implement a binary 'search' algorithm to get the correct length.
The work-around, and best answer to my problem came from basic arithmetic: cross multiplication
I posted my answer in a more popular stackoverflow thread discussing the topic in better detail.
I'm sure you know the case in which gmail shows the free storage on the "Lots of space" paragraph when you are on the login page. There is a counter running on that page and I'm curious to know how it works. Can me give me some pointers, links, tutorials, reads, explanations?
If you look at the source for that page you will find that it is a simple javascript function that just updates the number once a second. There is no magic involved and it is not live data in any way, just an estimate.
This is the code in charge of it. Looks like it is based on a time computation being mapped to a number of Bytes.
function updateQuota() {
if (!quota_elem) {
return;
}
var now = (new Date()).getTime();
var i;
for (i = 0; i < CP.length; i++) {
if (now < CP[i][0]) {
break;
}
}
if (i == 0) {
setTimeout(updateQuota, 1000);
} else if (i == CP.length) {
quota_elem.innerHTML = CP[i - 1][1];
} else {
var ts = CP[i - 1][0];
var bs = CP[i - 1][1];
quota_elem.innerHTML = format(((now-ts) / (CP[i][0]-ts) * (CP[i][1]-bs)) + bs);
setTimeout(updateQuota, 1000);
}
}
var PAD = '.000000';
You'll find a nice slideshow here
http://www.slideshare.net/kuchmuch/gmails-quota-secrets
Detailing how it works.
It is as mentioned just a date set to a predefined size, which the ticker then counts towards.