How to save a variable in Webpagetest script - scripting

Is there a way to save variable in a Webpagetest script? e.g. I have this javascript code that works in my developer tools:
var range = document.createRange();
var sel = window.getSelection();
range.setStart(document.getElementById("editable").childNodes[0], 5);
sel.removeAllRanges();
sel.addRange(range);
I need the range variable to be saved as in line 1 so that I can modify it in Line 3, and reuse it in line 5. If i try to execute the following WPT command.
execAndWait var range=document.createRange()
//or execAndWait range=document.createRange()
I get an error. Does this mean there is no way I can modify a variable in Webpagetest script?

If you are using a script, you first need to navigate to the page where you want to run the script (navigate command). Assuming you're doing that, you can just collapse your whole script into a single line and run it all in one command:
navigate https://www.example.com/
execAndWait var range = document.createRange(); var sel = window.getSelection(); range.setStart(document.getElementById("editable").childNodes[0], 5); sel.removeAllRanges(); sel.addRange(range);

Related

How to save as image a QR codes created in Google Sheets with api.qrserver?

I am generating QR codes in a column in Google Sheets with data entered via a Google Forms, and I would like to save them as images.
Using Ctrl + C and Ctrl+V works only inside the Google Sheet and trying to copy and paste that one outside the sheet doesnt work either. The clipboard is detected as not containing images to paste elsewhere.
The problem is not in generating the QR, but exporting or saving it as image.
To generate the QR's I'm using the api.qrserver, but the documentation for this only goes about creating or reading QR's [http://goqr.me/api/doc/] , for which this base is used to technically generate a PNG image:
http(s)://api.qrserver.com/v1/create-qr-code/?data=[URL-encoded-text]&size=[pixels]x[pixels]
However, If I use that formula externally to link directly to the cell, the PNG created only gives the URL address of the Google Sheet and not the information of the QR.
This is the array formula I'm using at row 1 to generate the QR's:
={"QR";arrayformula( if(
len(INDIRECT("A2:A")),IMAGE("https://api.qrserver.com/v1/create-qr-
code/?size=120x120&data="&ENCODEURL(
"-Tip: "&indirect("B2:B")& char(10)&
"-Ub: "&INDIRECT("C2:C")& char(10)&
"-#: "&indirect("D2:D")& char(10)&
"-IDE: "&INDIRECT("E2:E")& char(10)&
"-Serial: "&INDIRECT("G2:G") & char(10)&
"-Pa: "&indirect("H2:H") & char(10)&
"-IP: "&INDIRECT("I2:I") & char(10)&
"-As: "&indirect("J2:J") & char(10)&
"-R: "&INDIRECT("K2:K") & char(10)&
"-Ar: "&indirect("L2:L") & char(10)
),2)
,""))}
Ideally, I would like to automatically make the QR's as images and save them to a folder in google drive automatically. If possible, assigning them an IDE value that is contained in another column as well as in the same QR code.
Here is the example for the QR generation:
[https://docs.google.com/spreadsheets/d/16pALQ0LNbBqqdRNNejar8zJJPPNEP8I7HSbKDOJHZaw/edit?usp=sharing ]
You want to save the QR codes in the Spreadsheet as the image files using Google Apps Script.
In this case, you want to achieve this without changing the Spreadsheet.
Values are put to from the column "A" to "L", when the form was submitted.
If my understanding is correct, how about this sample script? Please think of this as just one of several answers.
In this sample script, the QR code is directly retrieved from api.qrserver.com and those are saved as the image files, because in your situation, the images cannot be retrieved from the Spreadsheet. In this case, all parameters of QR code are used from the Spreadsheet.
Sample script:
Before you run the script, please set the variables of sheetName and folderId. When you run this script, all QR codes in the sheet of Hoja_calculos are created as the image files.
function myFunction() {
var sheetName = "Hoja_calculos"; // Sheet name is from your shared Spreadsheet.
var folderId = "###"; // Folder ID of the folder where the image files are created.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName(sheetName);
var url = "https://api.qrserver.com/v1/create-qr-code/?size=120x120&data=";
var keys = ["-Tipo:", "-UbicaciĆ³n:", "-# registro:", "-ID-C:", "-# Serial:", "-Pas:", "-Di I:", "-Asi:", "-RP:", "-Ar:"];
var values = sheet.getRange(2, 2, sheet.getLastRow() - 1, 11).getValues()
.filter(function(e) {return e.some(function(f) {return f})})
.map(function(row) {
row.splice(4, 1);
return row;
});
var length = values.length;
// values = [values.pop()]; // If you want to save only the QR code of the last row, please use this line.
var reqs = values.map(function(e) {return {url: url + encodeURIComponent(keys.map(function(f, j) {return f + e[j]}).join("\r"))}});
var res = UrlFetchApp.fetchAll(reqs);
res.forEach(function(r, i) {
var blob = r.getBlob().setName(length == values.length ? "row" + (i + 2) + ".png" : "row" + (length + 1) + ".png");
DriveApp.getFolderById(folderId).createFile(blob);
});
}
Note:
If you want to save only the QR code of the last row, please use this line. At that time, please remove // of // values = [values.pop()];. By this, only the QR code of the last row is retrieved.
Because I thought that above situation might be required for your situation, I added it. For example, by using the installable trigger to the function, when the form was submitted, only QR code of the last row is created as the image file.
But I'm not sure about your environment of the form. So I'm not sure whether this can be used for your situation. I apologize for this.
I confirmed that this script worked for your shared Spreadsheet. If the actual Spreadsheet is different from this, please modify the script, because it might not work fine.
References:
Class UrlFetchApp
Class DriveApp
You can not use a custom function and interacts with Google Drive, there is a limitation to access user data using custom function and onEdit function on G script:
https://developers.google.com/apps-script/guides/sheets/functions
AFAIK the only way to achieve this is creating a custom menu and interacts with a custom function by menu.
var url = "https://api.qrserver.com/v1/create-qr-code/?data=Sample&size=128x128";
var folders = DriveApp.getFoldersByName("QRCodeFolderName");// Put here the name of the folder inside root folder
var folder = folders.next();
var response = UrlFetchApp.fetch(url);
if (response.getResponseCode() == 200){
var fileBlob = response.getBlob();
folder.createFile(qrcodevalue+".png",fileBlob);
}

creating a PDF via google apps script but creates the PDF with an additional blank page

I have a apps script bound to a spreadsheet that creates a pdf file from the sheet. this creates one single page pdf and saves it in a folder in drive. Up until recently, this worked perfectly. Now every time I run the code it does what it is supposed to but the file has a second page that is blank. When I create the pdf manually via file/download as/pdf doc, it creates the pdf as it should, with only one page. I have tried this with both the original and copy that the script temporarily creates. Both work when done manually. I am looking for some suggestions on what could have gone wrong and what to change. Here is an example of the code:
function makePDF() {
var sheet1 = SpreadsheetApp.getActive().getSheetByName('eTimesheet');
var sheet2 = SpreadsheetApp.getActive().getSheetByName('Time Sheet');
var sheet3 = SpreadsheetApp.getActive().getSheetByName('Data');
var triggercell3 = sheet1.getRange('M33').getValue();
if (triggercell3 == 'GO'){
var techNumber = sheet3.getRange('B5').getValue();
var date = sheet3.getRange('B3').getValue();
var fileID = sheet3.getRange('B7').getValue();
var pdfName = "TimeSheet- "+ techNumber + " " + date
var ss = SpreadsheetApp.getActive();
var folder = DriveApp.getFolderById(fileID);
sheet2.showSheet();
sheet1.hideSheet();
//Copy whole spreadsheet
var destSpreadsheet = SpreadsheetApp.open(DriveApp.getFileById(ss.getId()).makeCopy("tmp_convert_to_pdf", folder))
//save to pdf
var theBlob = destSpreadsheet.getBlob().getAs('application/pdf').setName(pdfName);
var newFile = folder.createFile(theBlob);
DriveApp.getFileById(destSpreadsheet.getId()).setTrashed(true);
sheet1.showSheet();
sheet2.hideSheet();
sheet1.getRange('M33').clearContent();
}
}
thanks for any assistance...
Without an example, first question I have is... if you delete a few rows from the sheet and run the script, are you back to 1 page?
I am asking in case the issue is just margin settings. If this is the issue, maybe you can adjust rows or use the UrlFetchApp.fetch approach as PDF page formatting can be specified (eg: margin size).

How to Download PDF Links in Column and Save to Common Folder

We have a column that contains links to PDFs that starts on line 4 (e.g B4:B). I am trying to find a way to automatically download the PDF files that are accessed via the links to a folder on Drive. This is what I have so far:
function savePDFs() {
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange().getValues();
for (var i = 3; i < data.length; i++) {
Logger.log(data[i][1]);
}
}
Presumably the above code would write the links starting in column B (index value of [1]) on row 4 (i value of 3) (ie., B4) until the bottom of the data set (eg., data.length()).
I'm now confused about how to access and save the PDF link that are written in the logger to a folder.
Would someone be willing to help me out? I'm currently having to go to each link, click Save Link As... and then navigate to the folder that I'd like to save the linked PDF to. My hope is to modify the above process using code.
Update: I found this bit of code here that may help me out. Note, I changed the PDF link to a currently valid PDF link.
var urlOfThePdf = 'http://download.p4c.philips.com/l4b/9/929000277411_eu/929000277411_eu_pss_aenaa.pdf';// an example of online pdf file
var folderName = 'GAS';// an example of folder name
function saveInDriveFolder(){
var folder = DocsList.getFolder(folderName);// get the folder
var file = UrlFetchApp.fetch(urlOfThePdf); // get the file content as blob
folder.createFile(file);//create the file directly in the folder
}
Okay, I'm going to go and noodle with the data that is in the logger to confirm that the data is in properly formatted PDF links, then I'm going to test this new bit of code out. I feel like I'm getting close.
You can't force a download of a file from an apps script, you must try that from an HTMLService and not sure it will work.
For your need I would recommend to create a dedicated folder and you add all the pdf in it and you use the download function of the drive interface to download all files in one clic.
In drive, a file can be put in several folders so the pdf files stay in the original folder but you create a new folder 'PDF for download" for example and you put them in it. To do that from drive interface you have to click on "shift"+Z when file(s) is/are selected.
For you current list of file you just have to add in your loop the add to folder function. You can use this function.
function addFileToFolder(id){
var folderPDF = DriveApp.getFolderById("Id OFFolder to put pdf");
var file = DriveApp.getFileById(id);
folderPDF.addFile(file);
}
EDIT : Function will browse list of url, get the file and make a copy in a dedicated folder on the user drive.
function downloadInDriveFolder(){
var folderID = 'Id of the folder';// put id of the folder
var folder = DriveApp.getFolderById(folderID)// get the folder
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange().getValues();
for (var i = 3; i < data.length; i++) {
var blob = UrlFetchApp.fetch(data[i][1]).getContent();
var pdf = DriveApp.createFile(blob);
pdf.setName(data[i][0]);//Put as name of the file the value in col A
folder.addFile(pdf);
}
}
Well I figured it out. I was expecting more code, but this does it for me:
function listPDFs() {
var out = new Array();
var row = 3; //row index of 0 = row 1
var column = 4; // column index of 0 = column A
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange().getValues();
var folder = DriveApp.getFolderById("this is where you paste your folder id"); // destination folder (this is the 0978SDFSDFKJHSDF078Y98hkyo looking value when you right click your folder and select "Get Link")
for (var i=row ; i<data.length ; i++) {
if(data[i][column] !== "") {
var file = UrlFetchApp.fetch(data[i][column]);
folder.createFile(file);
}
}
return
}
As you can see, I included a row and column variable so that I could easily change these.
I haven't figured out how to assemble them into a merged PDF, but I did figure out that I could sort them by date (which places the top most item first) and then right click and select "Open With...PDF Mergy", which then moves the PDFs into PDF Mergy and merges them up in the correct order. You can find PDF Mergy in the Chrome App Store. If I figure out how to automatically call PDF Mergy from GAS, I'll post that up--but for the time being the above code has saved us a ton of time...so I'm calling it good enough for the time being.

%%GLOBAL variables not working in custom Bigcommerce templates

I want to customise the product template, but not for all cases hence I am creating a new template layout file.
I have tried to do this two ways, however both don't work and encounter the same issue with %%GLOBAL variables not working.
Using Product.html as a base, I created _Product.html and changed %%Panel.ProductDetails%% to my custom ProductDetails file %%Panel._ProductDetails%%, which I haven't customised at all at this stage. I then change a test product to use that template. When viewing the product, console errors ar produced and the page doesn't show properly. The cause of the first console error is a syntax error where script variables are being set to a %%GLOBAL variable. Looking at the page source, this is the result:
<script type="text/javascript">//<![CDATA[
var ThumbURLs = new Array();
var ProductImageDescriptions = new Array();
var CurrentProdThumbImage = ;
var ShowVariationThumb =false;
var ProductThumbWidth = ;
var ProductThumbHeight = ;
var ProductMaxZoomWidth = ;
var ProductMaxZoomHeight = ;
var ProductTinyWidth = ;
var ProductTinyHeight = ;
where the template is
<script type="text/javascript">//<![CDATA[
var ThumbURLs = new Array();
var ProductImageDescriptions = new Array();
var CurrentProdThumbImage = %%GLOBAL_CurrentProdThumbImage%%;
var ShowVariationThumb =false;
var ProductThumbWidth = %%GLOBAL_ProductThumbWidth%%;
var ProductThumbHeight = %%GLOBAL_ProductThumbHeight%%;
var ProductMaxZoomWidth = %%GLOBAL_ProductMaxZoomWidth%%;
var ProductMaxZoomHeight = %%GLOBAL_ProductMaxZoomHeight%%;
var ProductTinyWidth = %%GLOBAL_ProductMaxTinyWidth%%;
var ProductTinyHeight = %%GLOBAL_ProductMaxTinyHeight%%;
The weird part is that there are %%global variables just above it that work fine.
<script type="text/javascript" src="%%GLOBAL_CdnAppPath%%/javascript/jquery/plugins/jCarousel/jCarousel.js?%%GLOBAL_JSCacheToken%%"></script>
gets correctly gets interpreted as
<script type="text/javascript" src="http://cdn3.bigcommerce.com/r-8a870c678fbffbf4184af752aed70da3f3454036/javascript/jquery/plugins/jCarousel/jCarousel.js?"></script>
The second way I tried was to include everything in the top level template. Instead of linking to %%Panel._ProductDetails%%, I inserted the contents of that panel into _Product.html, however this also encounters exactly the same issue.
Does anyone know why neither of these options work and how I can achieve what I want?
You have to call Panel.ProductDetails prior to using those variables.
Even if you are using a custom product details alternative panel you need to reference the standard one first. Then your global variables will work.
This is because GLOBALS in the BigCommerce system will only print a value where they have been permitted by the BigCommerce development team. This can be a pain, especially for the values you are after, and what you want to do makes perfect sense.
At this time however, I suggest you make it known to the developers you want this at http://ideas.bigcommerce.com.
I can't say whether this will change anytime soon as the main reason for the GLOBALS being banned in certain areas is for security, although the ones you are after are useful, and I don't see why they aren't enabled either. Who knows, the developers may surprise us.

problem with RegisterClientScriptBlock

i have to run following javascript through one of my method. But its not running
Whats wrong with the code.
private void fillGrid1()
{
GridView1.DataSource = myDocCenter.GetDsWaitingForMe(Session["UserID"].ToString());
HiddenField1.Value = { myDocCenter.GetDsWaitingForMe(Session["UserID"].ToString()).Tables[0].Rows.Count).ToString();
GridView1.DataBind();
String csname1 = "PopupScript1";
String csname2 = "ButtonClickScript1";
Type cstype = this.GetType();
// Get a ClientScriptManager reference from the Page class.
ClientScriptManager cs = Page.ClientScript;
// Check to see if the client script is already registered.
if (!cs.IsClientScriptBlockRegistered(cstype, csname2))
{
StringBuilder cstext2 = new StringBuilder();
cstext2.Append("<script type=\"text/javascript\"> ");
// You can add JavaScript by using "cstext2.Append()".
cstext2.Append("var count = document.getElementById('ctl00_ContentPlaceHolder1_HiddenField2');");
cstext2.Append("var count = '100';");
cstext2.Append("document.getElementById('sp2').innerHTML = count;");
cstext2.Append("script>");
cs.RegisterClientScriptBlock(cstype, csname2, cstext2.ToString(), false);
}
}
Your script tag is not properly closed.
Change
cstext2.Append("script>");
to
cstext2.Append("</script>");
On top of what adamantium said, your JS looks a bit strange. You seem to declare and set the count variable twice - did you mean to do this.
Following that, best thing to do, render the page then view source. is your JS getting rendered to the page? try and stick an alert in there... is it firing?
> cstext2.Append("var count =
> document.getElementById('ctl00_ContentPlaceHolder1_HiddenField2');");
I would use the ClientID property here. HiddenField2.ClientID
RegisterClientScriptBlock emits the script just after the <form> tag openning. Browser executes this script just after the tag openning as well but referenced elements are not processed yet at this time - browser cannot find them.
RegisterStartupScript method emits the script just before the <form> tag ending. Nearly all page elements are processed by the browser at this place and getElementById could find something.
See http://jakub-linhart.blogspot.com/2012/03/script-registration-labyrinth-in-aspnet.html for more details.