How to use variable in Handlebars? - javascript

My question is: How can i use variable ime in Handlebars template(sadrzaj-template)?
My HTML code:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>2 kolokvijum</title>
</head>
<body>
Ime autora: <input id="imeAutora" type="text" value="..."><br><br>
<button id="btnAutor" type="submit" onClick="autorIme()">Prikazi</button><br><br>
<script src="handlebars-v4.0.11.js"></script>
<script id="sadrzaj-template" type="text/x-hanldebars-template">
{{#each knjige}} {{#equal autor ime}}
<h2>{{naslov}}</h2>
<img src="{{slika}}">
<h4>{{brojstrana}} strana</h4>
<h3>Autor: {{autor}}</h3>
<h3>cena: {{cena}}</h3>
{{/equal}} {{/each}}
</script>
<div id="sadrzaj"></div>
<script>
function autorIme() {
var ime = document.querySelector("#imeAutora");
console.log(ime.value);
var ourRequest = new XMLHttpRequest();
ourRequest.open('GET', 'json.json');
ourRequest.onload = function() {
if (ourRequest.status >= 200 && ourRequest.status < 400) {
var data = JSON.parse(ourRequest.responseText);
createHTML(data);
} else {
console.log("We connected to the server, but it returned an error.");
}
};
ourRequest.onerror = function() {
console.log("Connection error");
};
ourRequest.send();
function createHTML(knjigeData) {
var knjigeTemplate = document.querySelector("#sadrzaj-template").innerHTML;
var compiledTemplate = Handlebars.compile(knjigeTemplate);
var ourGeneratedHTML = compiledTemplate(knjigeData);
var knjigeContainer = document.querySelector("#sadrzaj");
knjigeContainer.innerHTML = ourGeneratedHTML;
};
};
</script>
<script>
Handlebars.registerHelper('equal', function(lvalue, rvalue, options) {
if (arguments.length < 3)
throw new Error("Handlebars Helper equal needs 2 parameters");
if (lvalue != rvalue) {
return options.inverse(this);
} else {
return options.fn(this);
}
});
</script>
</body>
</html>

You need to pass it as an argument (as a field in the argument object actually) to the compiled template (which is actually a function). In your case, it is compiledTemplate(). Since you're already passing knjigeData to it, just add your variable as a field to the data object which eventually becomes knjigeData.
var data = JSON.parse(ourRequest.responseText);
data.ime = ime.value;
createHTML(data);
Now you can use it like {{ime}} if you want the variable's direct value in the template. Or you can use it like how you've done, like {{#equal autor ime}}

Related

Button Event-listener is unresponsive

I'm following a tutorial and I made a button to show some content. However this button doesn't work and I'm at my wits end unable to figure out what could be causing this.
Can someone show why this doesn't work?
const users = document.querySelector('#user');
const getUsers = document.getElementById('getUsers');
getUsers.addEventListener('click', loadUsers);
var loadUsers = () => {
console.log('hello button clicked')
let xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.github.com/users', true);
xhr.onload = () => {
if (this.status == 200) {
let gusers = this.responseText
console.log(gusers);
}
}
xhr.send()
}
console.log(getUsers)
<h1>USER</h1>
<button id="getUsers">Get Users</button>
<div id="users"></div>
Order of your variable declarations matters in this scenario due to hoisting - move the loadUsers definition above the call.
JavaScript only hoists declarations, not initializations. If a
variable is declared and initialized after using it, the value will be
undefined.
The block-quote above from MDN explains why function declarations can be defined after they are called (reading code from top-to-bottom), but variables that are initialized after they are used would have a value of undefined.
const users = document.querySelector('#user');
const getUsers = document.getElementById('getUsers');
const loadUsers = () => {
console.log('Load users..');
}
getUsers.addEventListener('click', loadUsers);
<head>
<meta charset="UTF-8">
<title>Testing AJAX</title>
</head>
<body>
<h1>USER</h1>
<button id="getUsers">Get Users</button>
<div id="users"></div>
</body>
Or you could keep the function at the bottom but use a function declaration which will be hoisted:
const users = document.querySelector('#user');
const getUsers = document.getElementById('getUsers');
getUsers.addEventListener('click', loadUsers);
function loadUsers() {
console.log('Load users..');
}
<head>
<meta charset="UTF-8">
<title>Testing AJAX</title>
</head>
<body>
<h1>USER</h1>
<button id="getUsers">Get Users</button>
<div id="users"></div>
</body>
In addition to the correct answer have a look at your code that I have refactored below. Hope this helps.
// Get Elements
const usersList = document.querySelector('#usersList');
const usersBtn = document.querySelector('#usersBtn');
// Bind listener to usersButton
usersBtn.addEventListener('click', () => {
// XHR Request function
const xhr = new XMLHttpRequest();
xhr.open('GET','https://api.github.com/users')
xhr.send()
xhr.onload = function() {
if (xhr.status == 200) {
// Convert the response to JSON and assign it to data
const data = JSON.parse(xhr.responseText)
// Loop throug through data
for(let i = 0; i <data.length; i++) {
// Create LI element and append the user name
const listItem = document.createElement('li');
usersList.appendChild(listItem).innerHTML = data[i].login
}
}
}
})
<h1>USERS</h1>
<button id="usersBtn">Get Users</button>
<ul id="usersList"></ul>

Uncaught TypeError: google.script.run.doSomething is not a function

I am trying to check if the input name is already in a Google Sheet. However, I am getting this error:
Uncaught TypeError: google.script.run.doSomething is not a function.
Here is my Index.html file.
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<meta charset="UTF-8">
</head>
<body>
<input type="text" id="meetingTitle" value=""> // Getting value here
<button onclick="checkName()">Check if available</button> //Calling function is is causing the error.
<p id=nameVerification><i>Click the button above to check availability.</i></p>
<script>
function checkName() {
var toPass = document.getElementById("meetingTitle").value;
prompt("toPass " + toPass);
google.script.run.doSomething();
}
function checkNameCS(checkNameSSReturn) {
if (checkNameSSReturn == "") {
document.getElementById('nameVerification').innerHTML = "Already in Use: Please try with another name."
document.getElementById("meetingTitle").value = "";
} else {
document.getElementById("meetingTitle").value = checkNameSSReturn;
document.getElementById('nameVerification').innerHTML = "Meeting name available. Procced."
}
}
function doSomething () {
var nameGiven = document.getElementById("meetingTitle").value;
var nameExists = false;
var nameVerified = false;
var name = nameGiven.toLowerCase();
name = strip(name);
prompt("name " + name);
var spreadsheetId = ''; //Sheet id entered
var rangeName = 'Sheet1';
var values = Sheets.Spreadsheets.Values.get(spreadsheetId, rangeName).values;
if (!values) {} else {
for (var row = 0; row < values.length; row++) {
if (name == values[row][0]) {
nameExists = true;
}
}
}
if (nameExists) {
checkNameCS("");
prompt("name2 " + " ");
return;
}
nameVerified = true;
prompt("name2 " + name);
checkNameCS(name);
return;
}
function strip(str) {
return str.replace(/^\s+|\s+$/g, '');
}
</script>
</body>
</html>
I tried debuging it with prompts but with no success. It seems like the function do something is properly called. But the code stops working aftergoogle.script.run.doSomething();.
I have looked at the documentation for successhandlers but they dont solve the issue either.
How about this modification?
Issue of your script:
doSomething() of google.script.run.doSomething() is required to be Google Apps Script.
In your script, doSomething() is put in HTML (index.html), and a method for using Google Apps Script is included. When google.script.run.doSomething() is run, doSomething() cannot be found at Google Apps Script (code.gs). By this, such error occurs. And if doSomething() is run at HTML side, also an error occurs at Sheets.Spreadsheets.Values.get(), because Sheets.Spreadsheets.Values.get() is the method of Advanced Google Services with Google Apps Script.
If you put it to Google Apps Script (code.gs), Javascript which is used at the script of doSomething() is required to be modified.
Modified script:
In this modification, your script was separated to Google Apps Script (code.gs) and HTML (index.html). var nameGiven = document.getElementById("meetingTitle").value; and checkNameCS(name); are used in index.html.
By the way, before you run this script, please enable Sheets API at Advanced Google Services.
Google Apps Script: code.gs
function strip(str) {
return str.replace(/^\s+|\s+$/g, '');
}
function doSomething (nameGiven) {
var nameExists = false;
var nameVerified = false;
var name = nameGiven.toLowerCase();
name = strip(name);
var spreadsheetId = '###'; //Sheet id entered
var rangeName = 'Sheet1';
var values = Sheets.Spreadsheets.Values.get(spreadsheetId, rangeName).values;
if (values) {
for (var row = 0; row < values.length; row++) {
if (name == values[row][0]) {
nameExists = true;
}
}
}
if (nameExists) {
return "";
}
nameVerified = true;
return name;
}
HTML: index.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<meta charset="UTF-8">
</head>
<body>
<input type="text" id="meetingTitle" value="">
<button onclick="checkName()">Check if available</button>
<p id=nameVerification><i>Click the button above to check availability.</i></p>
<script>
function checkName() {
var toPass = document.getElementById("meetingTitle").value;
prompt("toPass " + toPass);
var nameGiven = document.getElementById("meetingTitle").value; // Added
google.script.run.withSuccessHandler(checkNameCS).doSomething(nameGiven); // Modified
}
function checkNameCS(checkNameSSReturn) {
console.log(checkNameSSReturn)
if (checkNameSSReturn == "") {
document.getElementById('nameVerification').innerHTML = "Already in Use: Please try with another name."
document.getElementById("meetingTitle").value = "";
} else {
document.getElementById("meetingTitle").value = checkNameSSReturn;
document.getElementById('nameVerification').innerHTML = "Meeting name available. Procced."
}
}
</script>
</body>
</html>
Reference:
Class google.script.run

element is getting variable without declared

I am having a JavaScript code that is having a value in #message but i have not defined anywhere.
Does $("#message").html(result); is something inbuilt in Javascript?
I apologize if it is very basic and stupid question.
It is linked to my another question "
https://stackoverflow.com/questions/41745209/save-javascript-value-when-converting-speech-to-text-via-webkitspeechrecognition#
Complete Code
<!DOCTYPE html>
<html>
<head>
<script src="Content/SpeechScript.js"></script>
<title>Login Screen</title>
<meta charset="utf-8" />
</head>
<body >
<div id="results">
<span id="final_span" class="final"></span>
<span id="interim_span" class="interim"></span>
</div>
<script type="text/javascript">
function Typer(callback) {
speak('Welcome ,Please Speak your CPR Number');
var srcText = 'WelcomeToDanske,PleaseSpeakyourCPR Numberwhat';
var i = 0;
debugger;
var result = srcText[i];
var interval = setInterval(function () {
if (i == srcText.length - 1) {
clearInterval(interval);
callback();
return;
}
i++;
result += srcText[i].replace("\n", "<br />");
$("#message").html(result);
debugger;
document.getElementById('user').innerHTML = result;
// var parent = document.getElementById('parentDiv');
// var text = document.createTextNode('the text');
// var child = document.getElementById('parent');
// child.parentNode.insertBefore(text, child);
// var div = document.getElementById('childDiv');
//var parent = document.getElementById('parentDiv');
//var sibling = document.getElementById('childDiv');
////var text = document.createTextNode('new text');
// //parent.insertBefore(result, sibling);
},
100);
return true;
}
function playBGM() {
startDictation(event);
}
Typer(function () {
playBGM();
});
// say a message
function speak(text, callback) {
var u = new SpeechSynthesisUtterance();
u.text = text;
u.lang = 'en-US';
u.onend = function () {
if (callback) {
callback();
}
};
u.onerror = function (e) {
if (callback) {
callback(e);
}
};
speechSynthesis.speak(u);
}
</script>
</div>
<div id="clockDisplay">
<span id="id1">Welcome:</span>
<table width="100%" border="1"><tr><td width="50%"> Username : </td><td><div id="message"></div></td></tr></table>
</body>
</html>
$("#message").html(result); is something inbuilt in Javascript?
No.
$ is a variable that is no part of the JavaScript spec, nor is it part of the common extensions to JS provided by browsers in webpages. It is commonly used by libraries such as PrototypeJS and jQuery. This particular case looks like jQuery, but you aren't including that library in your page.
Fist off, remember to include jQuery as script in your html document or $ will not be defined.
#message Refers to an element in your html document with the tag of id="message"
To get an element in jQuery, by id, you use this syntax: var Element = $("#ID");
So, to make sure your code works, ensure that both there is an element with the ID message, and a defined variable named result containing the html text to put into your element.
Since you want to append to <div id="clockDisplay"> <span id="user">Username :</span></div>, why not change it to:
<div id="clockDisplay">
<span id="user">Username :</span>
<div id="message"></div>
</div>

Reading files with jQuery?

I would like to read a file (server-side) using jQuery. I have tried code supplied by multiple sites and it has not worked.
The code I tried last is:
jQuery.get("users/" + get("user") + "/display.txt", function(data) {
fullName = data;
});
However the variable 'fullName' (which is previously declared in the code) comes out as 'undefined'. How can I get this to work?
EDIT: Full code (excluding CSS)
<!DOCTYPE html>
<html>
<head>
<title>Chat</title>
<script src="jquery-1.11.3.min.js"></script>
<script type="text/javascript">
function get(variable) {
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
if(pair[0] == variable){return pair[1];}
}
return(false);
}
var fullName;
var file = "users/" + get("user") + "/display.txt";
jQuery.get(file, function(data) {
fullName = data;
});
</script
</head>
<body bgcolor="#B2C2F0">
<div class="window">
<div class="rightCorner">
<span><script type="text/javascript">document.write(fullName)</script></span>
</div>
</div>
</body>
</html>
You can't modify fullName var with data value inside that function and read it outside.
If you need to use that info outside the function, you need to export the data value within another function.
Something like:
var fullName = "not-set";
console.log('fullName is:', fullName); // not-set
function set_fullName( data ) {
fullName = data;
console.log('fullName is:', fullName); // must be `Levi` now
}
jQuery.get("users/" + get("user") + "/display.txt", function(data) {
set_fullName(data);
});
You're probably just trying to access fullname before the ajax call finishes.
Try this:
var fullName = "";
function getUserName(username){
jQuery.get("users/" + get("user") + "/display.txt", onGetComplete);
}
function onGetComplete(data){
fullName = data;
continueProgram();
}
function continueProgram(){
console.log(fullName);
}
getUserName();

Javascript does not work upon AJAX call

I have a page which does an AJAX call and loads an entire page. The page that gets loaded has some Javascript. The javascript works on page by itself when loaded, but when its gets loaded by AJAX, the Javascript does not work. I dont know what I am missing.
The code of the loaded page
<html>
<script type="text/javascript">
function showfield(name){
if(name=='lstbox')document.getElementById('div1').style.display="block";
else document.getElementById('div1').style.display="none";
}
function hidefield() {
document.getElementById('div1').style.display='none';
}
</script>
<head>
</head>
<body onload="hidefield()">
<form action = "test2.php" method = "post">
Please enter a name for the App <input type = "text" name = "name">
<table border = "1"><tr><th>Choose a Label</th><th>Choose an element</th></tr>
<tr><td><input type = "text" name = "label1" /></td> <td>
<select name = "elementtype1" id="elementtype1" onchange="showfield(this.options[this.selectedIndex].value)">
<option value = 'select'> Select </option>
<option value='txtbox'>Text Box</option>
<option value='lstbox'>List Box</option>
<option value='chkbox'>Check Box</option>
<option value='radio'>Radio Button</option>
</select></td><td><div id="div1">Enter Listbox options: <input type="text" name="whatever1" /></div></td></tr>
</table>
<input type = "submit" value = "Submit">
</form>
</body>
</html>
The code of the loading(AJAX) page is
<html>
<head>
</head>
<body>
<script src="ajax.js" type="text/javascript"></script>
<script src="responseHTML.js" type="text/javascript"></script>
<div id="storage" style="display:none;">
</div>
<div id="displayed">
<FORM name="ajax" method="POST" action="">
<p>
<INPUT type="BUTTON" value="Get the Panel" ONCLICK="loadWholePage('appcreator.php')">
</p>
</FORM>
</div>
</body>
</html>
The ajax.js code
function createXHR()
{
var request = false;
try {
request = new ActiveXObject('Msxml2.XMLHTTP');
}
catch (err2) {
try {
request = new ActiveXObject('Microsoft.XMLHTTP');
}
catch (err3) {
try {
request = new XMLHttpRequest();
}
catch (err1)
{
request = false;
}
}
}
return request;
}
The responseHTML.js code
function getBody(content)
{
test = content.toLowerCase(); // to eliminate case sensitivity
var x = test.indexOf("<body");
if(x == -1) return "";
x = test.indexOf(">", x);
if(x == -1) return "";
var y = test.lastIndexOf("</body>");
if(y == -1) y = test.lastIndexOf("</html>");
if(y == -1) y = content.length; // If no HTML then just grab everything till end
return content.slice(x + 1, y);
}
/**
Loads a HTML page
Put the content of the body tag into the current page.
Arguments:
url of the other HTML page to load
id of the tag that has to hold the content
*/
function loadHTML(url, fun, storage, param)
{
var xhr = createXHR();
xhr.onreadystatechange=function()
{
if(xhr.readyState == 4)
{
//if(xhr.status == 200)
{
storage.innerHTML = getBody(xhr.responseText);
fun(storage, param);
}
}
};
xhr.open("GET", url , true);
xhr.send(null);
}
/**
Callback
Assign directly a tag
*/
function processHTML(temp, target)
{
target.innerHTML = temp.innerHTML;
}
function loadWholePage(url)
{
var y = document.getElementById("storage");
var x = document.getElementById("displayed");
loadHTML(url, processHTML, x, y);
}
/**
Create responseHTML
for acces by DOM's methods
*/
function processByDOM(responseHTML, target)
{
target.innerHTML = "Extracted by id:<br />";
// does not work with Chrome/Safari
//var message = responseHTML.getElementsByTagName("div").namedItem("two").innerHTML;
var message = responseHTML.getElementsByTagName("div").item(1).innerHTML;
target.innerHTML += message;
target.innerHTML += "<br />Extracted by name:<br />";
message = responseHTML.getElementsByTagName("form").item(0);
target.innerHTML += message.dyn.value;
}
function accessByDOM(url)
{
//var responseHTML = document.createElement("body"); // Bad for opera
var responseHTML = document.getElementById("storage");
var y = document.getElementById("displayed");
loadHTML(url, processByDOM, responseHTML, y);
}
Javascript loaded in HTML through AJAX will not be executed.
If you want to include scripts dynamically, append <script> tags to the existing loaded page's <head> element.
execute the script with jquery rather than with innerHTML
//this is not working!
document.getElementById("chart-content").innerHTML = this.responseText;
//try this
$("#chart-content").html(this.responseText);
The script is outside the body tag, and the loader picks out only the code inside the body tag, so the script is not even part of what you add to the page.
Loading you Js within the <head> should work. use this.
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', loadJs);
} else {
loadJs();
}
function loadJs() {
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = '/assets/script/editor-controlls.js';
script.defer = true
document.getElementsByTagName('head')[0].appendChild(script);
}

Categories