I took the following example for using google data chart with Selection handler. But it says it could not return Column index.
It says it should
anyone could give me some hints on how to implement the handler to select the column index?
// Note: This sample shows the select event.
// The select event is a generic select event,
// for selecting rows, columns, and cells.
// However, in this example, only rows are selected.
// Read more here: http://code.google.com/apis/visualization/documentation/gallery/table.html#Events
function drawVisualization() {
visualization = new google.visualization.Table(document.getElementById('table'));
visualization.draw(data, null);
// Add our selection handler.
google.visualization.events.addListener(visualization, 'select', selectHandler);
}
// The selection handler.
// Loop through all items in the selection and concatenate
// a single message from all of them.
function selectHandler() {
var selection = visualization.getSelection();
var message = '';
for (var i = 0; i < selection.length; i++) {
var item = selection[i];
if (item.row != null && item.column != null) {
var str = data.getFormattedValue(item.row, item.column);
message += '{row:' + item.row + ',column:' + item.column + '} = ' + str + '\n';
} else if (item.row != null) {
var str = data.getFormattedValue(item.row, 0);
message += '{row:' + item.row + ', (no column, showing first)} = ' + str + '\n';
} else if (item.column != null) {
var str = data.getFormattedValue(0, item.column);
message += '{(no row, showing first), column:' + item.column + '} = ' + str + '\n';
}
}
if (message == '') {
message = 'nothing';
}
alert('You selected ' + message);
}
Related
First off, let me say that I am not a developer, nor do I really code beyond basic HTML. So I appreciate your patience. :)
I'm working with a script that is for AdWords, but I believe it's more or less written in Javascript. (I've included the script below.)
Basically, I'm receiving the error message 'Parsing Error: Please check your selector. (line XX)' when I preview the script.
I've searched all around for hours and have yet to find a solution.
I think it may be that a query being returned contains either a single or double quote, and may be messing up the code? Though I can't actually prove that.
Also, yes, I was sure to update lines 17-21 with the correct details.
Any help would be much appreciated!
Thanks!
John
/*
// AdWords Script: Put Data From AdWords Report In Google Sheets
// --------------------------------------------------------------
// Copyright 2017 Optmyzr Inc., All Rights Reserved
//
// This script takes a Google spreadsheet as input. Based on the column headers, data filters, and date range specified
// on this sheet, it will generate different reports.
//
// The goal is to let users create custom automatic reports with AdWords data that they can then include in an automated reporting
// tool like the one offered by Optmyzr.
//
//
// For more PPC management tools, visit www.optmyzr.com
//
*/
var DEBUG = 0; // set to 1 to get more details about what the script does while it runs; default = 0
var REPORT_SHEET_NAME = "report"; // the name of the tab where the report data should go
var SETTINGS_SHEET_NAME = "settings"; // the name of the tab where the filters and date range are specified
var SPREADSHEET_URL = "https://docs.google.com/spreadsheets/d/1dttJTb547L81XYKdTQ56LcfO9hHhbb9wm06ZY5mKhEo/edit#gid=0"; // The URL to the Google spreadsheet with your report template
var EMAIL_ADDRESSES = "example#example.com"; // Get notified by email at this address when a new report is ready
function main() {
var currentSetting = new Object();
currentSetting.ss = SPREADSHEET_URL;
// Read Settings Sheet
var settingsSheet = SpreadsheetApp.openByUrl(currentSetting.ss).getSheetByName(SETTINGS_SHEET_NAME);
var rows = settingsSheet.getDataRange();
var numRows = rows.getNumRows();
var numCols = rows.getNumColumns();
var values = rows.getValues();
var numSettingsRows = numRows - 1;
var sortString = "";
var filters = new Array();
for(var i = 0; i < numRows; i++) {
var row = values[i];
var settingName = row[0];
var settingOperator = row[1];
var settingValue = row[2];
var dataType = row[3];
debug(settingName + " " + settingOperator + " " + settingValue);
if(settingName.toLowerCase().indexOf("report type") != -1) {
var reportType = settingValue;
} else if(settingName.toLowerCase().indexOf("date range") != -1) {
var dateRange = settingValue;
} else if(settingName.toLowerCase().indexOf("sort order") != -1) {
var sortDirection = dataType || "DESC";
if(settingValue) var sortString = "ORDER BY " + settingValue + " " + sortDirection;
var sortColumnIndex = 1;
}else {
if(settingOperator && settingValue) {
if(dataType.toLowerCase().indexOf("long") != -1 || dataType.toLowerCase().indexOf("double") != -1 || dataType.toLowerCase().indexOf("money") != -1 || dataType.toLowerCase().indexOf("integer") != -1) {
var filter = settingName + " " + settingOperator + " " + settingValue;
} else {
if(settingValue.indexOf("'") != -1) {
var filter = settingName + " " + settingOperator + ' "' + settingValue + '"';
} else if(settingValue.indexOf("'") != -1) {
var filter = settingName + " " + settingOperator + " '" + settingValue + "'";
} else {
var filter = settingName + " " + settingOperator + " '" + settingValue + "'";
}
}
debug("filter: " + filter)
filters.push(filter);
}
}
}
// Process the report sheet and fill in the data
var reportSheet = SpreadsheetApp.openByUrl(currentSetting.ss).getSheetByName(REPORT_SHEET_NAME);
var rows = reportSheet.getDataRange();
var numRows = rows.getNumRows();
var numCols = rows.getNumColumns();
var values = rows.getValues();
var numSettingsRows = numRows - 1;
// Read Header Row and match names to settings
var headerNames = new Array();
var row = values[0];
for(var i = 0; i < numCols; i++) {
var value = row[i];
headerNames.push(value);
//debug(value);
}
if(reportType.toLowerCase().indexOf("performance") != -1) {
var dateString = ' DURING ' + dateRange;
} else {
var dateString = "";
}
if(filters.length) {
var query = 'SELECT ' + headerNames.join(",") + ' FROM ' + reportType + ' WHERE ' + filters.join(" AND ") + dateString + " " + sortString;
} else {
var query = 'SELECT ' + headerNames.join(",") + ' FROM ' + reportType + dateString + " " + sortString;
}
debug(query);
var report = AdWordsApp.report(query); //THIS IS LINE 103 WITH THE ERROR
try {
report.exportToSheet(reportSheet);
var subject = "Your " + reportType + " for " + dateRange + " for " + AdWordsApp.currentAccount().getName() + " is ready";
var body = "currentSetting.ss<br>You can now add this data to <a href='https://www.optmyzr.com'>Optmyzr</a> or another reporting system.";
MailApp.sendEmail(EMAIL_ADDRESSES, subject, body);
Logger.log("Your report is ready at " + currentSetting.ss);
Logger.log("You can include this in your scheduled Optmyzr reports or another reporting tool.");
} catch (e) {
debug("error: " + e);
}
}
function debug(text) {
if(DEBUG) Logger.log(text);
}
The area between SELECT and FROM is the selector. You're not selecting any fields with that query. That's happening because the headerNames array is empty. Verify the value of REPORT_SHEET_NAME
I have an array of objects and I'm able to loop through the array using a for loop and I can print it to the page without problems if the value is found, but I'm trying to get an alert message to display if the value is not found and continue asking for the next value until the user types quit. The problems with my code is that the alert message keeps appearing until the loops ends if the value is not found. Here's my code:
var message = '';
var student;
var search;
function print(message) {
var outputDiv = document.getElementById('output');
outputDiv.innerHTML = message;
}
function getStudentReport( student ) {
var report = '<h2>Student: ' + student.name + '</h2>';
report += '<p>Track: ' + student.track + '</p>';
report += '<p>Points: ' + student.points + '</p>';
report += '<p>Achievements: ' + student.achievements + '</p>';
return report;
}
function findStudent( look ){
for (var i = 0; i < students.length; i += 1) {
student = students[i];
if (look === student.name) {
message += getStudentReport( student );
print(message);
} else{
alert(look + ' was not found');
}
}
print(message);
}
while (true){
search = prompt('Search student records: type a name [Jody] (or type "quit" to end)');
if (search === null || search === 'quit'){
break;
}
findStudent(search);
}
Any help is appreciated. Thanks.
i think it could be help full for you https://codepen.io/kalaiselvan/pen/YQGbar
var message = '';
var student;
var search;
function print(message) {
var outputDiv = document.getElementById('output');
outputDiv.innerHTML = message;
}
function getStudentReport( student ) {
var report = '<h2>Student: ' + student.name + '</h2>';
report += '<p>Track: ' + student.track + '</p>';
report += '<p>Points: ' + student.points + '</p>';
report += '<p>Achievements: ' + student.achievements + '</p>';
return report;
}
function findStudent( look ){
var flag=0;
for (var i = 0; i < students.length; i += 1) {
student = students[i];
if (look === student.name) {
message += getStudentReport( student );
print(message);
flag=0;
break;
} else{
flag=1;
}
}
if(flag==1){
alert(look + ' was not found');
showprompt();
}
}
function showprompt(){
search = prompt('Search student records: type a name [Jody] (or type "quit" to end)');
if (search != null && search !== "quit"){
findStudent(search);
}
}
showprompt();
Lets explain this part of code:
function findStudent( look ) {
for (var i = 0; i < students.length; i += 1) {
student = students[i];
if (look === student.name) {
message += getStudentReport( student );
print(message);
} else{
alert(look + ' was not found');
}
}
print(message);
}
What that does is it loops with a for loop over an array/object and prints a message or alerts for every record inside the array. That is the problem. You only want to check if the value is found and print or alert if so.
function findStudent( look ) {
var found = false;
for (var i = 0; i < students.length; i += 1) {
student = students[i];
if (look === student.name) {
found = true;
break; // if the student is found no need to loop further
// move on with rest of code
}
}
// so if the student was found in the for loop, found will be true
// else found will be false cause we set it to false at the beginning
if(found) {
message += getStudentReport( student );
print(message);
} else {
alert(look + ' was not found');
}
}
you can use indexof
https://www.w3schools.com/jsref/jsref_indexof_array.asp
else if (students.indexOf(look) == -1){
alert(look + ' was not found');
})
You need to stop the loop inside findStudent() function.
First, add a boolean varible: var flag = true;
Second, use it as condition of while loop: while(flag){...}
Finally, assign flag = falsewhenever want to stop the loop:
function findStudent( look ){
for (var i = 0; i < students.length; i += 1) {
student = students[i];
if (look === student.name) {
message += getStudentReport( student );
print(message);
//possible stop here if you want
flag = false;
} else{
alert(look + ' was not found');
//possible stop here if you want
flag = false;
}
}
print(message);
//possible stop here if you want
flag = false;
}
var message = '';
var student;
var search;
function print(message) {
var outputDiv = document.getElementById('output');
outputDiv.innerHTML = message;
}
function getStudentReport( student ) {
var report = '<h2>Student: ' + student.name + '</h2>';
report += '<p>Track: ' + student.track + '</p>';
report += '<p>Points: ' + student.points + '</p>';
report += '<p>Achievements: ' + student.achievements + '</p>';
return report;
}
function findStudent( look ){
message = '';
for (var i = 0; i < students.length; i += 1) {
student = students[i];
if (look === student.name) {
message += getStudentReport(student);
}
}
return message;
}
while (true){
search = prompt('Search student records: type a name [Jody] (or type "quit" to end)');
if (search === null || search === 'quit'){
break;
}
if(findStudent(search)){
print(findPurpose(search));
break;
} else {
alert(search + ' was not found');
}
}
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
Is there a cleaner, more concise way to write the following conditional statement that creates a string in Javascript?
var search;
if (text === '' && user === '' && filter !== '') {
search = filter;
} else if (filter === '' && text === '' && user !== '') {
search = 'email="' + user + '"';
} else if (filter === '' && user === '' && text !== '') {
search = 'text~"' + text + '"';
} else if (text !== '' && user !== '' && filter === '') {
search = 'text~"' + text + '" ANDemail="' + user + '"';
} else if (text !== '' && filter !== '' && user === '') {
search = 'text~"' + text + '" AND ' + filter;
} else {
search = 'text~"' + text + '" AND ' + filter + '" ANDemail="' + user + '"';
}
// using computed switch
var TEXT = 1, haveText = (text !== "") << 0;
var FILTER = 2, haveFilter = (filter !== "") << 1;
var USER = 4, haveUser = (user !== "") << 2;
switch(haveText + haveFilter + haveUser)
{
case FILTER: search = filter; break;
case USER: search = 'email="' + user + '"'; break;
case TEXT: search = 'text~"' + text + '"'; break;
case TEXT+USER: search = 'text~"' + text + '" AND email="' + user + '"'; break;
case TEXT+FILTER: search = 'text~"' + text + '" AND ' + filter; break;
case TEXT+FILTER+USER: search = 'text~"' + text + '" AND ' + filter + '" AND email="' + user + '"'; break;
case FILTER+USER: search = filter + '" AND email="' + user + '"'; break;
default: search = ""; // no search criteria
}
makes two possible errors in the compound if statement version stand out:
The case of FILTER+USER was not tested for and produced a search using TEXT,
The case of no criteria was not tested in the if statement and also produced a search using TEXT.
Off the top of my head, one thing you can do to simplify this is to use the js rule that '' falsy which simplifies this. Also, short circuits with return would help.
var search;
function getSearch(user, text, filter) {
if (!text && !user && filter) return filter;
if (!filter && !text && user) return 'email="' + user + '"';
if (!filter && !user && text ) return 'text~"' + text + '"';
if (text && user && !filter) return 'text~"' + text + '" ANDemail="' + user + '"';
if (text && filter && !user) return 'text~"' + text + '" AND ' + filter;
return 'text~"' + text + '" AND ' + filter + '" ANDemail="' + user + '"';
}
search = getSearch(user, text, filter);
I think that's a little cleaner. It could be cleaned up a lot if the formatting of your string wasn't so strange, but I'm assuming it's specific and required so this maintains the exact formatting you're after in the "search" string.
You can make a function to build the search string, that way you can easily add more variables in the future. The builder is messy, it's a messy process, but it won't get much more messy, no matter how many variables you add. As a side-note, remember that in some cases like this (with a lot of conditionals) you can consider refactoring using polymorphism, that probably wouldn't work for you here, though. The fiddle for this is here: https://jsfiddle.net/ytg1rxu8/
function buildSearchString(text, user, filter) {
var returnString = '';
var strings = [];
if (text) {strings.push('text~ =' + text);}
if (user) {strings.push('email = ' + user);}
if(filter){
strings.push(filter);}
var length = strings.length;
for(var i =0; i < length; ++i){
var s = strings[i];
if(i ===length -1){
returnString += s;
}
else{
returnString += s+' AND ' ;
}
}
return returnString;
}
alert(buildSearchString('', 'there', 'guy'));
The following may fit the criterion "concise", but it may not fit "cleaner":
var text = 'someText';
var filter = '';
var user = 'aUser';
var search = text? 'text~"' + text + '"' : '';
search += search && filter? ' AND ' + filter : filter? filter : '';
search += search && user? ' AND email="' + user + '"' : user? 'email="' + user + '"' : '';
document.write('Search: ' + search); // text~"someText" AND email="aUser"
var search;
if (filter)
search = appendFilter(search, filter);
if (text)
search = appendFilter(search, 'text~"' + text + '"');
if (user)
search = appendFilter(search, 'email="' + user + '"');
function appendFilter(search, f) {
return search ? search + ' AND ' + f : f;
}
Ok so I have this code. Sorry, I didn't know where the problem is so I pasted it all. It says: Invalid assignment left-hand side. (line 1, file "Code"). I know the problem cannot be on line one but have no idea where it is.
function send(sheet, email, row){
var tmp = GmailApp.getAliases();
var alias = tmp[0];
var subject = "Thank you for signing up for "+ sheet.getSheetName()+ "!";
var body = "Hello "+ sheet.getRange(row,3).getValue() + " " + sheet.getRange(row,4).getValue() + "," + '\n'+'\n';
var temp = 2;
var bool = "TRUE";
while (bool == "TRUE"){
if (sheet.getRange(temp,11).getValue() != ''){
body += '\n' + sheet.getRange(temp,11);
temp += 1;
}
if (sheet.getRange(temp + 1,11).getValue() != '')
body += '\n' + body += '\n' + sheet.getRange(temp + 1,11);
else {bool = "FALSE"}
}
Logger.log(body);
if ( sheet.getRange('L2').getValue() != ""){
var html = sheet.getRange('L2').getValue(); // Place HTML code here
try {
GmailApp.sendEmail(email, subject, body, {'from': alias, 'htmlbody': html});
sheet.getRange(row, 9).setBackground("green");
sheet.getRange(row, 9).setValue("Yes");
sheet.getRange("J2").setValue(row - 2);
} catch (e) {
var me = Session.getActiveUser().getEmail();
MailApp.sendEmail(me, "Autoreply error", "There was a problem sending an email to: " + email +".");
}
}
else{
try {
GmailApp.sendEmail(email, subject, body, {'from': alias});
sheet.getRange(row, 9).setBackground("green");
sheet.getRange(row, 9).setValue("Yes");
sheet.getRange("J2").setValue(row - 2);
} catch (e) {
MailApp.sendEmail(me, "Autoreply error", "There was a problem sending an email to: " + email +".");
}
}
}
function main(){
var ss = SpreadsheetApp.openById("1a2xvZ6hx69hst0CoLnCc8V5Igi-V5_HaNm6GTpEU8B4"); // Unique ID for the 'Responses' spreadsheet
var sheet = ss.getActiveSheet();
if ( sheet.getRange('J2').getValue() == "" ){
sheet.getRange('I1').setValue("Sent"); // Initialize labels
sheet.getRange('J1').setValue("Count");
sheet.getRange('K1').setValue("Email body");
sheet.getRange('L1').setValue("HTML body");
var row = 2;
} else {
var row = sheet.getRange("J2").getValue() + 2;
}
while ( (sheet.getRange(row,9).getValue() != '') && (sheet.getRange(row,2).getValue() != '')) {
var email = sheet.getRange(row, 2).getValue();
send(sheet, email, row);
row += 1;
}
}
You cannot write a line like this : ( 2 x += in the same statement)
body += '\n' + body += '\n' + sheet.getRange(temp + 1,11); // this throws the error
I'd suggest to use an intermediate variable like this :
var xxx = '\n' + sheet.getRange(temp + 1,11);
body+= '\n'+ body + xxx ;
if this is really what you want to do... but it seems strange to me...
Shouldn't it be something like this : body+= '\n'+sheet.getRange(temp + 1,11);
I want to convert this shortcode generating form into one that will generate either of two different shortcodes depending on a value selected in the form. So, a radio button says, "Which shortcode do you want to build?" Then they choose it, then they go on with the other fields to fill out the attribute values. Then when it comes time to generate the code, the JS will condition its output based on the radio button question. I've tried to modify it myself, but the problem is, this script generates the attributes from the options index, so I don't know how to include an option that doesn't go into the index:
var table = form.find('table');
form.appendTo('body').hide();
form.find('#myshortcodeidstem-submit').click(function(){
var options = {
'shortcodename' : '', \\ THIS IS THE ONE TO DETERMINE THE SHORTCODE NAME
'attribute' : '', \\ THIS IS THE ATTRIBUTE THAT BOTH SHORTCODES SHARE
};
var shortcode = '[myshortcode'; \\ THIS LINE NEEDS TO BE CONDITIONAL ON OPTION 1
for( var index in options) {
var value = table.find('#myshortcodeidstem-' + index).val();
if ( value !== options[index] && value != null )
shortcode += ' ' + index + '="' + value + '"';
}
shortcode += '] Content Here [/myshortcode]'; \\ THIS LINE CONDITIONAL ON OP1
--- UPDATE ---
Barmar pointed me in the right direction, and I got it to work, but I'd like to know if there's a more economical way to do it. Here's what I have:
var table = form.find('table');
form.appendTo('body').hide();
form.find('#myshortcodeid-submit').click(function(){
var codeselector = table.find('#myshortcodeid-codeselector').val();
if (codeselector === '1'){
var options = {
'attribute' : '',
};
var shortcode = '[shortcode_one';
for( var index in options) {
var value = table.find('#myshortcodeid-' + index).val();
if ( value !== options[index] && value != null )
shortcode += ' ' + index + '="' + value + '"';
}
shortcode += '] Content Here [/shortcode_one]';
}
if (codeselector === '2'){
var options = {
'attribute' : '',
};
var shortcode = '[shortcode_two';
for( var index in options) {
var value = table.find('#myshortcodeid-' + index).val();
if ( value !== options[index] && value != null )
shortcode += ' ' + index + '="' + value + '"';
}
shortcode += '] Content Here [/shortcode_two]';
}
--- UPDATE ---
Found a more economical way, without repeating the options index. See the answer below.
Here's the most economic way I could come up with. Doesn't repeat the options index this way. Working good. Just had to create a var for the dropdown field that chooses the shortcode, then do if statements referencing that var's value.
var codeselector = table.find('#myid-codeselector').val();
if (codeselector === '1'){
var shortcode = '[shortcode_one';
}
if (codeselector === '2'){
var shortcode = '[shortcode_two';
}
var options = {
'attribute' : '',
};
for( var index in options) {
var value = table.find('#myid-' + index).val();
if ( value !== options[index] && value != null )
shortcode += ' ' + index + '="' + value + '"';
}
if (codeselector === '1'){
shortcode += '] Content Here [/shortcode_one]';
}
if (codeselector === '2'){
shortcode += '] Content Here [/shortcode_two]';
}