onClick function is not being invoked in Google App scripts - javascript

I'm creating a script that can send emails to the selected people in which the checkbox is set to true and I'm creating custom sidebar for it. I have made the script successfully. But the sidebar is not working I have tried everything like creating an eventListner or adding a onClick event but still my function is not invoked I have checked in logs it is not invoking at all. Please could anyone tell what's wrong with my code?
This is my HTML file
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
<title>Hello, world!</title>
</head>
<body>
<div>
<div class="form-group">
<label for="enter-subject">Subject</label>
<input type="text" class="form-control" id="enter-subject" aria-describedby="emailHelp" placeholder="Enter Subject">
</div>
<div class="form-group">
<label for="enter-message">Message</label>
<input type="text" class="form-control" id="enter-message" placeholder="Enter Message">
</div>
<button class="btn btn-primary" id="mainButton" onClick="afterButtonIsClicked">Submit</button><!--
onClick="afterButtonIsClicked();" -->
</div>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
<script type="text/javascript">
function afterButtonIsClicked(){
var subject = document.getElementById("enter-subject")
var message = document.getElementById("enter-message")
var rowData = {subject: subject.value, message: message.value}
console.log(rowData)
google.script.run.addNewRow(rowData)
}
// document.getElementById("mainButton").addEventListner("click",afterButtonIsClicked)
</script>
</body>
</html>
This is my script file
function addNewRow(rowData) {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2;
var dataRange = sheet.getRange(startRow, 1, sheet.getLastColumn(),sheet.getLastColumn());
var data = dataRange.getValues();
for (var i = 0; i < data.length; ++i) {
var row = data[i];
var checkbox1 =row[1];
var emailAddress = row[0];
// var subject = "test subject";
// var message = "test message";
if(checkbox1) {
console.log(`${rowData.subject} ${rowData.message}`)
MailApp.sendEmail(emailAddress,rowData.subject,rowData.message)
}
}
}
this is my UI for sidebar file
function loadForm() {
const htmlForSidebar = HtmlService.createTemplateFromFile("index")
const htmlOutput = htmlForSidebar.evaluate()
const ui = SpreadsheetApp.getUi();
ui.showSidebar(htmlOutput)
}
function createMenu() {
const ui = SpreadsheetApp.getUi();
const menu = ui.createMenu("My Form")
menu.addItem("Show Form", "loadForm")
menu.addToUi();
}
function onOpen() {
createMenu()
}
Could anyone diagnose and tell me the error?

This should fix the onClick issue:
onClick="afterButtonIsClicked();"

Related

Webpage eventlistener and script section not running

Trying to make a basic webpage where you can type a message for it to be displayed on the website. However, the script section of my website does not seem to work.
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<script>
document.addEventListener('DOMContentLoaded', function()
{
let submit = document.querySelector('#submit');
submit.addEventListener('click',function()
{
let questions = document.querySelectorAll('.question');
let input = document.querySelector('input');
for (let i =0; i< questions.length; i++)
{
if questions[i].innerHTML == ""
{
questions[i].innerHTML = 'a';
}
else
{
continue;
}
}
});
function myfunction()
{
alert('test');
}
});
</script>
<title>Write A Message!</title>
</head>
<body class="p-3 mb-2 bg-secondary text-white">
<h1>How to write a message</h1>
<hr>
<p>Type a Message into the textbox below to display a public letter!</p>
<div>
<input type = 'text'>
<button id = 'submit'>Type a message!</button>
</div>
<div>
<h1>Message 1!</h1>
<hr>
<p class = 'question'></p>
<h2>Message 2!</h2>
<hr>
<p class = 'question'></p>
<h3>Message 3!</h3>
<hr>
<p class = 'question'></p>
<button onclick = 'myfunction()'>test</button>
</div>
</body>
</html>
I tried adding a button that would display an alert as well but it does not run as well when clicked.
First, javscript that contains listener/reference to DOM elements is better to include in the end on body, avoid putting in head.
Second, myfunction() is not accessible bebcause you included it under DOMContentLoaded. It should be outside of the listener (global scope).
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<title>Write A Message!</title>
</head>
<body class="p-3 mb-2 bg-secondary text-white">
<h1>How to write a message</h1>
<hr>
<p>Type a Message into the textbox below to display a public letter!</p>
<div>
<input type='text'>
<button id='submit'>Type a message!</button>
</div>
<div>
<h1>Message 1!</h1>
<hr>
<p class='question'></p>
<h2>Message 2!</h2>
<hr>
<p class='question'></p>
<h3>Message 3!</h3>
<hr>
<p class='question'></p>
<button onclick='myfunction()'>test</button>
</div>
<script>
document.addEventListener('DOMContentLoaded', function(){
let submit = document.querySelector('#submit');
submit.addEventListener('click',function(){
let questions = document.querySelectorAll('.question');
let input = document.querySelector('input');
for (let i =0; i< questions.length; i++){
if (questions[i].innerHTML == ""){
questions[i].innerHTML = 'a';
} else {
continue;
}
}
});
});
function myfunction() {
alert('test');
}
</script>
</body>
</html>

Add a Google Sheet list of values to the materialize autocomplete function

I'm trying to create a simple web app that add countries to a google sheet. And use materialize autocompletes to assist the user (which simply autocomplete the country, with no images attached). I saw a couple of examples of the materialize autocomplete, but always with a predefined autocomplete list. This is the html I used:
<html>
<head>
<!--Import Google Icon Font-->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!--Import materialize.css-->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<!--Let browser know website is optimized for mobile-->
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
<div class="row">
<div class="col s12">
<div class="row">
<div class="input-field col s12">
<i class="material-icons prefix">work_outline</i>
<input id="autocomplete-input" type="text" class="autocomplete">
<label for="autocomplete-input">Country</label>
</div>
</div>
</div>
</div>
<div class="input-field col s12">
<button class="btn waves-effect waves-light amber accent-4" id="add_btn">Add country
<i class="material-icons right">send</i>
</button>
</div>
<!-- Compiled and minified JavaScript -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<script>
google.script.run.withSuccessHandler(tags).getCountry();
function tags(data) {
var availableTags = data;
$('input.autocomplete').autocomplete({
data: availableTags
});
};
document.getElementById("add_btn").addEventListener("click", doStuff);
function doStuff() {
var ucountry = document.getElementById("autocomplete-input").value;
google.script.run.userClicked(ucountry);
document.getElementById("autocomplete-input").value = "";
};
</script>
</body>
</html>
And this is my code in google script, the function getCountry works, and returns a list of countries. But I didn't succeed in adding them to the materialize autocomplete function.
function doGet() {
var template = HtmlService.createTemplateFromFile("page");
var html = template.evaluate();
return html;
}
function userClicked(country){
var url = "https://docs.google.com/spreadsheets/d/1_GtmVrdD1Es6zQZna_Mv-Rc3JkIu66-q_knQ8aqcUIc/edit#gid=0";
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("Data");
ws.appendRow([country]);
}
function getCountry(){
var ws = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Data");
var list = ws.getRange(1,1,ws.getRange("A1").getDataRegion().getLastRow(),1).getValues(); // contains countries
list = list.map(function(r){return r[0]; });
Logger.log(list);
var data = "{";
for (var i = 0; i < list.length; i++) {
data = data + "'" + list[i] + "': null,";
}
data = data.slice(0, -1) + "}";
Logger.log(data);
return data;
}
This is the information on https://materializecss.com/autocomplete.html
// Or with jQuery
$(document).ready(function(){
$('input.autocomplete').autocomplete({
data: {
"Apple": null,
"Microsoft": null,
"Google": 'https://placehold.it/250x250'
},
});
});
Answer:
You can use web polling to update your page with a set interval such that it always retrieves updated data from the Sheet.
Code:
Piggybacking off the answer here, edit your script to include:
function polling(){
setInterval(update, 500);
}
function update(){
google.script.run.withSuccessHandler(tags).getCountry();
}
and make sure that you run the polling() function on load:
<body onload="polling()">
<!-- your body goes here -->
</body>
Full page.html:
<html>
<head>
<meta charset="utf-8">
<!--Import Google Icon Font-->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!--Import materialize.css-->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<!--Let browser know website is optimized for mobile-->
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link rel="stylesheet" href="/resources/demos/style.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body onload="polling()">
<div class="row">
<div class="col s12">
<div class="row">
<div class="input-field col s12">
<i class="material-icons prefix">work_outline</i>
<input id="autocomplete-input" type="text" class="autocomplete" placeholder="Country">
</div>
</div>
</div>
</div>
<div class="input-field col s12">
<button class="btn waves-effect waves-light amber accent-4" id="add_btn">Add country
<i class="material-icons right">send</i>
</button>
</div>
<script>
function polling(){
setInterval(update, 500);
}
function update(){
google.script.run.withSuccessHandler(tags).getCountry();
}
google.script.run.withSuccessHandler(tags).getCountry();
function tags(list) {
console.log(list);
var availableTags = list;
$("#autocomplete-input").autocomplete({
source: availableTags
});
};
document.getElementById("add_btn").addEventListener("click", doStuff);
function doStuff() {
var ucountry = document.getElementById("autocomplete-input").value;
google.script.run.userClicked(ucountry);
document.getElementById("autocomplete-input").value = "";
};
</script>
</body>
</html>
And leave your code.gs file unchanged.
References:
Stack Overflow - Creating an autocomplete function in Google Script that works with a list of values from the Google Sheet
Stack Overflow - Is it possible to import XML or JSON data from a table within a Word online document into Apps Script website as an HTML table?
Changing the getCountry() function, so it reads the data as an object and not as a string fixed it.
function doGet() {
var template = HtmlService.createTemplateFromFile("page");
var html = template.evaluate();
return html;
}
function userClicked(country){
var url = "https://docs.google.com/spreadsheets/d/1_GtmVrdD1Es6zQZna_Mv-Rc3JkIu66-q_knQ8aqcUIc/edit#gid=0";
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("Data");
ws.appendRow([country]);
}
function getCountry(){
var ws = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Data");
var list = ws.getRange(1,1,ws.getRange("A1").getDataRegion().getLastRow(),1).getValues(); // contains countries
list = list.map(function(r){return r[0]; });
Logger.log(list);
var data = {};
for (var i = 0; i < list.length; i++) {
data[list[i]] = null;}
return data;
}
And the html stayed the same:
<html>
<head>
<!--Import Google Icon Font-->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!--Import materialize.css-->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<!--Let browser know website is optimized for mobile-->
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
<div class="row">
<div class="col s12">
<div class="row">
<div class="input-field col s12">
<i class="material-icons prefix">work_outline</i>
<input id="autocomplete-input" type="text" class="autocomplete">
<label for="autocomplete-input">Country</label>
</div>
</div>
</div>
</div>
<div class="input-field col s12">
<button class="btn waves-effect waves-light amber accent-4" id="add_btn">Add country
<i class="material-icons right">send</i>
</button>
</div>
<!-- Compiled and minified JavaScript -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<script>
google.script.run.withSuccessHandler(tags).getCountry();
function tags(data) {
var availableTags = data;
$('input.autocomplete').autocomplete({
data: availableTags
});
};
document.getElementById("add_btn").addEventListener("click", doStuff);
function doStuff() {
var ucountry = document.getElementById("autocomplete-input").value;
google.script.run.userClicked(ucountry);
document.getElementById("autocomplete-input").value = "";
};
</script>
</body>
</html>

uncaught SyntaxError: Unexpected token < line one js

I have seen many questions similar to this one on here but none of them seem to fix the problem I am having.
I keep getting the following error-
Uncaught SyntaxError: Unexpected token <
It says the error is in line one of the js file but the sources only shows a red line on line one of the html file.
Should also mention it is running on a go server.
Thanks a mil!
Here is my HTML
<!DOCTYPE html>
<html lang="en">
<head>
<title>Hello, world!</title>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Sourcing jquery and ajax -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<!--external script.js file-->
<script type = "text/JavaScript" src="ChatBot.js"></script>
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous">
<style>
body {
padding-top: 65px;
padding-bottom: 100px;
}
</style>
</head>
<body>
<nav class="navbar fixed-top navbar-dark bg-dark">
<a class="navbar-brand" href="#">Eliza chat bot</a>
</nav>
<div class="container-fluid">
<ul class="list-group">
<div class="fixed-bottom bg-dark p-2">
<div class="container">
<div>
<ul class="list-group"></ul>
</div>
<form action="/Chat" method="GET">
<div class="form-group">
<input type="text" class="form-control" id="userInput" placeholder="Talk to eliza...">
</div>
</form>
</div>
</div>
</ul> </div>
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js" integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js" integrity="sha384-alpBpkh1PFOepccYVYDB4do5UnbKysX5WZXm3XxPqe5iKTfUKjNkCk9SaVuEZflJ" crossorigin="anonymous"></script>
</body>
</html>
and here is my js
const form = $("#userInput");
const listItem = $("#list-group");
//add the keypress function for when the user types an input for eliza to compute
$(document).ready(()=>{
form.keypress(function(event){
const keyCodes = {
ENTER : 13
}
let keyCode = event.keyCode;
//for enter
if(event.keyCode != keyCodes.ENTER){
return;
}
event.preventDefault();
const input = form.val();
form.val(" ");
listItem.append("<li class='list-group-item list-group-item-success'>"+"User : " + input + "</li>");
// GET/POST
const queryParams = {"userInput" : input }
$.get("/Chat", queryParams)
.done(function(response){
var nextListItem = "<li class='list-group-item list-group-item-info'>"+"ELiza : " + response + "</li>";
setTimeout(function(){
listItem.append(nextListItem)
}, 1000);//set timeout to give wait to response
}).fail(function(){
var nextListItem = "<li class='list-group-item list-group-item-danger' >Sorry I'm not home right now.</li>";
list.append(nextListItem);
});
});
});
Does your webserver happen to have a rule where if the requested resources is not found it will default to serving the index.html file? This is a popular configuration for Single Page Applications.
If that is the case, if the server can not find the js file requested it will serve the contents of the html file, which the browser will try parse as JavaScript. Since the first character on the first line of the html file is < you'll get a syntax error since that is not valid JavaScript.

Sorting javaScript created divs

Hay I have a problem with sorting divs from createElement function.
Problem:
I create divs from database-items which are align in row (latest item on the end)
What I want:
Display the Items in reversed direction. The latest item added to the database should appear as first item in the stream (like a newsstream on facebook).
Question:
How can I change just the direction the divs are loaded/created?
Further I thought about a technique to set an individual ID to each div created, for sorting them later by ID (Id could be ongoing numbers).
I found this one but it don´t works while i does not increment the ID-number: Javascript create divs with different ids
I know there are many Questions like this on stackoverflow, and I tried several before, with no success for my issue.
Check out my Code:
//create firebase reference
var dbRef = new Firebase("….com/");
var contactsRef = dbRef.child('contacts')
//load all contacts
contactsRef.on("child_added", function(snap) {
//console.log(snap.val())
snap.forEach(function(childSnapshot) {
var key = childSnapshot.key();
var childData = childSnapshot.val();
var divCount = 0;
//create divs from database-elements
var card = document.createElement('div');
card.id = 'div'+divCount;
card.setAttribute('class', 'linkprev');
document.body.appendChild(card);
var cardtitle = document.createElement('div');
cardtitle.setAttribute('class', 'cardtitle');
cardtitle.innerHTML = childData;
card.appendChild(cardtitle);
document.guteUrls.execute();
divCount++;
console.log(event);
//linkify plugin to convert div-elements (strings) to hyperlinks
$('div').linkify();
$('#sidebar').linkify({
target: "_blank"
});
});
});
//save contact
document.querySelector(".addValue").addEventListener("click", function( event ) {
event.preventDefault();
if( document.querySelector('#url').value != '' && document.querySelector('#url').value.charAt(0) == "h" && document.querySelector('#url').value.charAt(3) == "p"){
contactsRef.push({
name: document.querySelector('#url').value,})
contactForm.reset();}
else {
alert('Oops, seems like an error…');
}
}, false);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>frontendpublishing-test</title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<link rel="stylesheet" href="http://cdn.embed.ly/jquery.preview-0.3.2.css" />
<link href="css/flexboxgrid.min.css" rel="stylesheet">
<style type="text/css">
#contacts p,
#contacts p.lead{
margin: 0;
}
</style>
</head>
<body>
<div class="container">
<h1>Titel h1</h1>
<hr/>
<div class="row">
<div class="col-md-6">
<form method="post" name="contactForm">
<div class="form-group">
<input id="url" type="url" required name="url" placeholder="share a good article/blog/topic" class="input">
<button type="submit" class="btn btn-primary addValue">Submit</button>
</form>
<!-- <script>
$document.ready(function){
document.getElementsByClassName('linkified');
{console.log("linkified")};
};
        </script>
-->
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<!-- Latest compiled and minified Bootstrap -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<!-- Include Firebase Library -->
<script src="https://cdn.firebase.com/js/client/2.2.3/firebase.js"></script>
<!-- Contacts Store JavaScript -->
<script src="script.js"></script>
<script src="linkify.min.js"></script>
<script src="linkify-jquery.min.js"></script>
<link rel="stylesheet" href="style.css" type="text/css" media="screen" />
<script async src="https://guteurls.de/guteurls.js"
selector='.linkprev'
gif="http://loading.io/assets/img/default-loader.gif"
callback-a="(function(jqueryElement,url,$){console.log('url:'+url)})"
callback="(function($){console.log('finished')})"
init="(function($){console.log('JS will start to search URLs now')})"
></script>
</body>
</html>
Thanks for helping :)
since you are using jquery instead of
document.body.appendChild(card);
use
$('body').prepend($(card))
you can mark up the area with an id you want to add them into so that it does not insert into the top of your document like
$('#elementid').prepend($(card))
1.Why not query them descendent from db? :))
2.
card.childNodes.length
? card.insertBefore(cardtitle, card.childNodes[0])
: card.appenChild(cardtitle);

"cannot read property length of null" - Google

I am writing a simple application using Flask. I am using Google API for drawing graphs. The first page displays correctly.
But in the next pages I am getting "cannot read property length of null" error.
My Code is as shown below:
Code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta http-equiv="refresh" content="100; URL=http://127.0.0.1:5000/">
<title>Test</title>
<!-- Bootstrap Core CSS -->
<link href="static/css/bootstrap.min.css" rel="stylesheet">
<link href="static/css/bootstrap-multiselect.css" rel="stylesheet">
<link href="static/css/new.css" rel="stylesheet">
<!-- Custom Fonts -->
<link href="static/lib/css/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/morris.js/0.5.1/morris.css">
<!-- JavaScript -->
<script src="static/js/jquery.js"></script>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script src="static/js/bootstrap.min.js"></script>
<script src="static/js/bootstrap-multiselect.js"></script>
<script src="static/js/Chart.js-master/Chart.js"></script>
</head>
<body onload = onLoading()>
<div class="container">
<div class="col-xs-12">
<div class="page-header">
<h3><b>Test</b></h3>
</div>
<div class="carousel slide" id="myCarousel">
<nav>
<ul class="control-box pager">
<li><a data-slide="prev" href="#myCarousel" class=""><i class="glyphicon glyphicon-chevron-left"></i></a></li>
<li><a data-slide="next" href="#myCarousel" class=""><i class="glyphicon glyphicon-chevron-right"></i></li>
</ul>
</nav>
<!-- /.control-box -->
<!-- Slide1 -->
<div class="carousel-inner" id="imp">
<!-- /Slide1 -->
</div><!-- /Carousel inner -->
</div><!-- /#myCarousel -->
</div><!-- /.col-xs-12 -->
</div><!-- /.container -->
<script type="text/javascript">
google.load("visualization", "1", {packages:["corechart"]});
// Carousel Auto-Cycle
$(document).ready(function() {
$('.carousel').carousel({
interval: 3000
})
});
function onLoading() {
//alert("Inside");
$.get("/load",function(calldata,status) {
//console.log(calldata);
//alert(calldata.length);
var num_nodes = calldata.length;
var loop = 0;
for (i=0;i<num_nodes;i++) {
if (i%4==0) {
if (i==0) {
var divoutput = document.getElementById("imp");
var divhtml = '<div class="item active" id="c'+(i/4)+'"></div>';
divoutput.innerHTML = divoutput.innerHTML+divhtml;
alert(i);
console.log(divoutput.innerHTML);
} else {
var divoutput = document.getElementById("imp");
var divhtml = '<div class="item" id="c'+(i/4)+'"></div>';
divoutput.innerHTML = divoutput.innerHTML+divhtml;
loop = i/4;
alert(loop);
console.log(divoutput.innerHTML);
}
}
var data = new google.visualization.DataTable();
data.addColumn('string', 'Errors');
data.addColumn('number', 'Statistics');
data.addRows([
['Success', calldata[i].errors.success],
['Authorization Failure', calldata[i].errors.auth_failure],
['Feature Failure', calldata[i].errors.feature_failure],
['FSOL Failure', calldata[i].errors.fsol_failure]
]);
var options = {
title: calldata[i].node_name,
is3D: true,
backgroundColor:'#ECECEA',
};
var output = document.getElementById("c"+loop);
//alert("***"+document.getElementById("c"+loop));
var html = '<div class="col-sm-6"><div class="fff"><div class="thumbnail" id="i'+i+'"></div></div></div>';
//alert(html);
output.innerHTML = output.innerHTML + html;
var tmp = "i";
var ele_id = tmp.concat(i);
//alert(ele_id);
if (calldata[i].errors.success < calldata[i].errors.auth_failure) {
document.getElementById("i"+i).style.backgroundColor = "red";
}
google.setOnLoadCallback(drawChart(ele_id,data,options));
}
});
}
function drawChart(ele_id,data,options)
{
google.load("visualization", "1", {packages:["corechart"]});
//alert(ele_id);
//alert("draw"+document.getElementById(ele_id));
var chart = new google.visualization.PieChart(document.getElementById(ele_id));
chart.draw(data, options);
}
</script>
</body>
</html>
I use bootstrap tabs and want to display a graph on a hidden tab and I get the same error as you
When I display the graph on an active table it show's up perfectly.
So I guess there is something linked to the DOM and hidden elements nothing to do with your data

Categories