I want to load a list of items into a dropdown select box using a combination of html and javascript (google apps script).
I have been able to get all of the javascript functions to call and return values as expected, but when my code tries to add options to the select object, it seems to fail.
Here is my current HTML ('index'):
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
// The code in these functions run when the page is loaded.
google.script.run.withSuccessHandler(addItems).getFolderList();
//This function uses an array of folder names to create options for the select list
function addItems(folders){
alert('addItems was called!');
var htmlSelect = document.getElementById('folder');
for(var z = 0; z < folders.length; z++){
var selectBoxOption = document.createElement('OPTION');
selectBoxOption.value = folders[z];
selectBoxOption.text = folders[z];
htmlSelect.add(selectBoxOption);
}
}
//this function lets the user know if the upload failed or not
function successMess(returnText) {
var div = document.getElementById('output');
div.innerHTML = '<p>'+returnText+'</p>';
}
</script>
</head>
<body>
<form id="myForm">
<p>Please choose a folder to receive the upload</p>
<select name="folder" id="folder">
<option value="Test Value">Test Value</option>
</select>
<br>
<input name="myFile" type="file" id="myFile"/>
<br>
<input type="button" value="Submit"
onclick="google.script.run.withSuccessHandler(successMess).processForm(this.parentNode)" />
</form>
<div id="output"></div>
</body>
</html>
Here is the accompanying JavaScript (.gs):
function doGet(){
return HtmlService.createHtmlOutputFromFile('index');
}
function processForm(formObject) {
var formBlob = formObject.myFile;
var folderName = formObject.folder;
var returnText = 'Please choose a valid file to upload';
if(formBlob.length > 0){
returnText = 'Your document was uploaded successfully!';
try{
var folder = DriveApp.getFoldersByName(folderName).next();
var driveFile = folder.createFile(formBlob);
}catch(e){
returnText = 'There was an error processing your document';
}
}
return returnText;
}
function getFolderList(){
Logger.log('getFolderList was called');
var ParentFolder = DriveApp.getFoldersByName('Test Folder').next();
var shopFolders = ParentFolder.getFolders();
var folderList = [];
while(shopFolders.hasNext()){
folderList.push(shopFolders.next().getName());
}
folderList.sort();
return folderList;
}
Everything is working beautifully...except the folder list population. I have manually populated the select options just to make sure the processForm function is working correctly. I have even tested (using another alert) to make sure that the folder name array from "getFolderList()" is being passed faithfully (and it is). It doesn't seem to have any problems getting the select item called "folder" or creating a new "option" item. It seems to fail when "addItems" tries to add the option to the list. Can anyone tell me what I'm doing wrong, and/or how to fix it?
Thanks!
Here is a solution to your problem:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<form id="myForm">
<p>Please choose a folder to receive the upload</p>
<select name="folder" id="fldrList">
<option value="Test Value">Test Value</option>
</select>
<br>
<input name="myFile" type="file" id="myFile"/>
<br>
<input type="button" value="Submit"
onclick="google.script.run.withSuccessHandler(successMess).processForm(this.parentNode)" />
</form>
<div id="output"></div>
</body>
<script type="text/javascript">
// The code in these functions run when the page is loaded.
google.script.run.withSuccessHandler(addItems).getFolderList();
//This function uses an array of folder names to create options for the select list
function addItems(folders){
console.log('addItems was called!' + folders);
var htmlSelect = document.getElementById('fldrList');
console.log('htmlSelect: ' + htmlSelect);
var optionHTML = '';
for(var z = 0; z < folders.length; z++){
console.log('z: ' + z);
console.log('folders[z]: ' + folders[z]);
optionHTML = optionHTML + "<option value='" + folders[z] + "'>" + folders[z] + "</option>";
};
htmlSelect.innerHTML = optionHTML;
}
//this function lets the user know if the upload failed or not
function successMess(returnText) {
var div = document.getElementById('output');
div.innerHTML = '<p>'+returnText+'</p>';
}
</script>
</html>
Change the id name of your select element from folder to fldrList.
Unfortunately, the add method is not working. You can create the HTML in the form of a string and inject it.
Notice that the FOR LOOP creates an HTML string, then when the FOR LOOP is done, the HTML is injected into the SELECT element. It works. For some reason, Apps Script doesn't seem to be allowing the .add method. Don't know why.
Related
I created a web form using Google Apps Script, where form visitors would see result.html after data submission. However, the data may be submitted multiple times if visitors reload the result.html by pressing F5, Ctrl + R, ignoring the alert of resubmission. The same concern has already been posted here, and I tried implementing one of the solutions for that, but in vain.
I have now four files in the same project of Google Apps Script:
index.html that produces the form
JavaScript.html that defines functions used in index.html
result.html that is presented after the form submission
code.gs that shows the form by doGet(), and processes the submitted data and presents result.html by doPost(). include() defined in this file enables to input JavaScript.html into index.html
The solution I have tried is adding the following JavaScript code result.html. I also add that to JavaScript.html so that the code is to be executed in index.html, too.
<script>
if ( window.history.replaceState ) {
window.history.replaceState( null, null, window.location.href );
}
</script>
However, the resubmission still occurs when I reload the result.html even after I added that code to both result.html and index.html. What am I missing?
index.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<!-- <?!= include("css"); ?> -->
</head>
<body onload="addOptions()"> <!--Execute addOptions function immediately after a page has been loaded-->
<form class="" action="<?!= getScriptUrl(); ?>" method="post" onSubmit="document.getElementById('submit').disabled=true;">
<div>
<h1 id="Question">
Choose either cheesecake or chocolate cake.
</h1>
<select id="dropdownList" name="cake" class="form-control">
</select>
</div>
<div class="form-submit">
<input type="submit" name="" value="Submit">
</div>
</form>
</body>
<?!= include('JavaScript') ?>
</html>
JavaScript.html
<script>
function addOptions() {
/*This will call server-side Apps Script function getAvailableExps and if it is successful,
it will pass the return value to function addListValues which will add options to the drop down menu*/
google.script.run
.withFailureHandler(onFailure)
.withSuccessHandler(addListValues)
.getAvailableExps();
}
function addListValues(values) {
//Add options to drop down menu using the values of parameter 'values'.
for (var i = 0; i < values.length; i++) {
var option = document.createElement("option");
option.text = values[i][0];
option.value = values[i][0];
var select = document.getElementById("dropdownList");
select.appendChild(option);
}
}
function onFailure(err) {
alert('Error: ' + err.message);
}
if ( window.history.replaceState ) {
window.history.replaceState( null, null, window.location.href );
}
</script>
result.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<base />
<title>Thank you for your order!</title>
<!-- <?!= include('css'); ?> -->
</head>
<script>
if ( window.history.replaceState ) {
window.history.replaceState( null, null, window.location.href );
}
</script>
<body>
<p>
Don't forget what you've ordered!
</p>
</body>
</html>
code.gs
var sheetID = "............................................";
var inventory_sheet = "Inventory";
function doGet(){
return HtmlService.createTemplateFromFile("index").evaluate();
}
function include(filename){
return HtmlService.createHtmlOutputFromFile(filename).getContent();
}
function getScriptUrl() {
var url = ScriptApp.getService().getUrl();
Logger.log(url);
return url;
}
function doPost(e){
var ss = SpreadsheetApp.openById(sheetID);
var sh = ss.getSheets()[0];
sh.appendRow([String(e.parameters.cake)]);
//update Inventory
var inventory = ss.getSheetByName(inventory_sheet);
var row = inventory.createTextFinder(e.parameters.cake).findNext().getRow();
var range = inventory.getRange(row, 2);
var data = range.getValue();
range.setValue(parseInt(data - 1))
return HtmlService.createTemplateFromFile("result").evaluate();
}
function getAvailableExps(){
var inventory = SpreadsheetApp.openById(sheetID).getSheetByName(inventory_sheet);
var data = inventory.getRange(2, 1, 2, 2).getValues();
var filtered = data.filter(arr => arr[1] > 0 || arr[1] != ''); //remove exp to array if quantity is 0 or empty
return filtered;
}
In your situation, how about checking the submit using PropertiesService? When your script is modified, it becomes as follows.
Modified script:
In this modification, 2 functions of doGet and doPost of code.gs are modified.
doGet
function doGet() {
PropertiesService.getScriptProperties().setProperty("key", "sample");
return HtmlService.createTemplateFromFile("index").evaluate();
}
doPost
function doPost(e) {
var p = PropertiesService.getScriptProperties();
if (p.getProperty("key") == "sample") {
var ss = SpreadsheetApp.openById(sheetID);
var sh = ss.getSheets()[0];
sh.appendRow([String(e.parameters.cake)]);
//update Inventory
var inventory = ss.getSheetByName(inventory_sheet);
var row = inventory.createTextFinder(e.parameters.cake).findNext().getRow();
var range = inventory.getRange(row, 2);
var data = range.getValue();
range.setValue(parseInt(data - 1))
p.deleteProperty("key");
}
return HtmlService.createTemplateFromFile("result").evaluate();
}
When you access to your Web Apps, sample is stored by setProperty("key", "sample") in doGet(). And, when the HTML form is submitted, the PropertiesService is checked in doPost(e). When sample is existing, the data is put, and the PropertiesService is cleared. By this, even when the submitted page is reopened, the PropertiesService is not existing. By this, the resubmitted can be avoided.
Reference:
Properties Service
I am trying to build a simple dashboard where if user access their dashboard it will show data from the google spreadsheet. But There is one problem I don't know why only my first div is getting target via JavaScript not the second one..
any Help and solution would apricated..
Why My Second Line Targeting div id="load1" is not executing ????
Code.gs
`function loadDetails(id){
var ss = SpreadsheetApp.openById("14RM_170AefKbQq82NXAdSOemQLyAGcv_BTwYWd1-qtM")
var ws = ss.getSheetByName("Data")
var data = ws.getDataRange().getValues()
for(var i=0; i<data.length; i++){
var row = data[i]
if(row[0]== id){
password = {
psd: row[1],
id: row[0]
}
}
}
if(row[0]!= id){
password = "not found"
}
return password;
}`
Dashboard.HTML
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<h1>Hey this is other Employee Dashboard</h1>
<p>Your Employee Id: = </p>
<p>Your Password : = </P>
<div id="load">
<div>
<div id="load1">
<div>
<script>
window.onload = function(){
var id = "MN00018"
google.script.run.withSuccessHandler(function(output){
document.getElementById("load").innerHTML = `passing objects are ${output.psd} & ${output.id}`
document.getElementById("load1").innerHTML = `passing objects are ${output.id}`
}).loadDetails(id)
}
</script>
</body>
</html>
If you are actually testing your showing script, I think that there are 2 modification points.
HTML & Javascript side:
The tag of div is not enclosed. How about modifying as follows?
From:
<div id="load">
<div>
<div id="load1">
<div>
To:
<div id="load">
</div>
<div id="load1">
</div>
I think that this is the reason of your issue of Why My Second Line Targeting div id="load1" is not executing ????.
Google Apps Script side:
At Google Apps Script side, by if(row[0]!= id){password = "not found"}, even when id is found from the column "A", "not found" is returned. How about modifying as follows?
Modified script:
function loadDetails(id) {
var ss = SpreadsheetApp.openById("###");
var ws = ss.getSheetByName("Data")
var data = ws.getDataRange().getValues()
var password = {psd: "", id: ""};
for (var i = 0; i < data.length; i++) {
var row = data[i]
if (row[0] == id) {
password = {
psd: row[1],
id: row[0]
}
break;
}
}
return password;
}
I have a similar problem to this post when trying to convert my apps script web app to use IFRAME Sandbox. I have converted to 'input = "button"' as suggested.
My web app is a simple form for students to use to sign in and out of a school library. The idea for the app is for it to be as easy as possible for students to use. Students should enter their id number and be able to either click the submit button or hit the enter key. Their ID is then validated before being stored in a spreadsheet and they get a message back saying thanks for signing in or out, or please enter a valid ID Number. Then focus should return to the text box and be cleared, ready for the next student to enter their id.
I had it working as described above using NATIVE mode. When I tried to convert it to IFRAME mode, clicking the button works, but if you hit the enter key everything just disappears and no data goes to the spreadsheet. How can I get hitting the enter key to work the same as clicking the submit button?
index.html code:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">
</head>
<body>
<h3>Please Sign In & Out</h3>
<div id="box" class="frame">
<form id="signSheet" onsubmit="google.script.run
.withSuccessHandler(updateInfo)
.validateID(this.parentNode)">
<input type="text" name="myID" id="myID" placeholder="Enter your student ID" autocomplete="off">
<input type="button" value="Submit" onmouseup="google.script.run
.withSuccessHandler(updateInfo)
.validateID(this.parentNode)">
</form>
<span id="thank_you" hidden="true"></span>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<?!= include('javascript'); ?>
</body>
</html>
javascript.html code:
<script>
function updateInfo(ret){
if(ret[0]){
$( "#thank_you" ).removeClass("error");
$( "#thank_you" ).addClass("valid");
}
else{
$( "#thank_you" ).removeClass("valid");
$( "#thank_you" ).addClass("error");
}
$( "#thank_you" ).text(ret[1]);
$( "#thank_you" ).show("slow");
$( "#signSheet" )[0].reset();
$( "#myID" ).focus();
console.log(ret);
}
</script>
Code.gs code:
//spreadsheet key is needed to access the spreadsheet.
var itemSpreadsheetKey = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
//Open the spreadsheet and get the sheet objects
var openedSS = SpreadsheetApp.openById(itemSpreadsheetKey);
var studentList = openedSS.getSheetByName("Student List");//Spreadsheet must match with sheet name
var studentRecord = openedSS.getSheetByName("Sign In-Out Record");
function doGet() {
var html = HtmlService.createTemplateFromFile('index').evaluate()
.setTitle('Sign In/Out Sheet')
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
return html;
}
function include(filename) {
Logger.log('enter include');
Logger.log(filename);
var html = HtmlService.createHtmlOutputFromFile(filename).getContent();
Logger.log(html);
return html;
}
function validateID(form){
var idNum = form.myID;
var valid = false;
var numIdList = studentList.getLastRow()-1; //-1 is to exclude header row
//get the item array
var idArray = studentList.getRange(2,1,numIdList,1).getValues();
i= idArray.length;
while(i--){
if(idArray[i][0]==idNum & idNum!='') {
valid=true;
break;
}
}
if(valid)
return [1, updateRecord(idNum)];
else return [0, "ID number " + idNum + " not recognized. Please enter a valid ID number."];
}
function updateRecord(idNum){
studentRecord.appendRow([idNum]);
var formulas = studentRecord.getRange("B2:D2").getFormulasR1C1();
var lRow = studentRecord.getLastRow();
var range = studentRecord.getRange(lRow, 2, 1, 3);
range.setFormulas(formulas);
var vals = range.getValues();
var now = new Date();
studentRecord.getRange(lRow, 5, 1, 1).setValue(now);
now = Utilities.formatDate(now, "EST", "HH:MM a");
idNum = "Thanks " + vals[0][0] + ", you have signed " + vals[0][2] + " at " + now;
return idNum;
}
Update: I found this post and added the following code to javascript.html:
$(document).ready(function() {
$(window).keydown(function(event){
if(event.keyCode == 13) {
var idVal = $("#myID").val();
google.script.run.withSuccessHandler(updateInfo).validateID(idVal);
return false;
}
});
})
This solved the the problem for me with a little more tweaking to parts of index.html and Code.gs
I found this post and added the following code to javascript.html:
$(document).ready(function() {
$(window).keydown(function(event){
if(event.keyCode == 13) {
var idVal = $("#myID").val();
google.script.run.withSuccessHandler(updateInfo).validateID(idVal);
return false;
}
});
})
This listens for the enter key and sends the value of the text field to the apps script function. In this case I didn't need to use `event.preventDefault();'
Then I had to adjust the button's onmouseup function to take this.parentNode.myID and change my apps script function to take a value instead of a form object.
You must remove the onsubmit attribute from the <form> tag:
Currently you have:
<form id="signSheet" onsubmit="google.script.run
.withSuccessHandler(updateInfo)
.validateID(this.parentNode)">
Change it to this:
<form id="signSheet">
You already have a call to google.script.run in your button, so leave that.
I need some help because my callback function, parseMovie() is only being called once! Despite being in a for loop which iterates it twice. I am using a free Rottentomatoes API
The output only returns one ID, and not two ID's!
And runs parseMovie() only once and returns the movie ID with the last movie.
Does anyone have a fix for this script running problem?
HTML CODE
<!doctype html>
<html class="no-js">
<head>
<title>Movies</title>
<link rel="stylesheet" href="css/main.css">
<script src="js/main.js"></script>
</head>
<body>
<form name="input">
<p> Actor/Actress Name: <input type="text" name="fullName"> </p>
<p> Movie 1 <input type="text" name="movie"> </p>
<p> Movie 2 <input type="text" name="movie"> </p>
<p><input type="button" value="Search movies" onclick="getMovies()"></p>
<p><textarea name="output" readonly> </textarea> </p>
</form>
</body>
</html>
JAVASCRIPT
//api key
var APIKEY = "qf54ubt95fea9n7jytr5xh6h";
var movieID = new Array();
var actor = new Array();
var actorName = "Jennifer Lawrence";
var movieTitle;
var output;
function callScript(call) {
var script = document.createElement('script');
script.setAttribute("src", call);
document.body.appendChild(script);
}
function getMovies() {
for (var x=0; x<2; x++) {
movieTitle = document.getElementsByName('movie')[x].value;
movieTitle= cleanMovieTitle(movieTitle);
var movieURL = "http://api.rottentomatoes.com/api/public/v1.0/movies.json?q=";
callScript(movieURL + movieTitle + "&page_limit=10&page=1&apikey=" + APIKEY + "&callback=parseMovie");
}
}
function cleanMovieTitle(movie) {
movie = movie.trim();
movie = movie.replace(/ /g, "+");
return movie;
}
function parseMovie(data) {
var titleData = data.movies;
for (var t=0; t<titleData.length; t++) {
movieID[movieID.length] = titleData[t].id;
aCast = titleData[t].abridged_cast;
sample = [];
for (var person = 0; person < aCast.length; person++) {
sample[sample.length] = aCast[person].name;
}
actor[actor.length] = sample;
}
for (var arry = 0; arry < actor.length; arry++) {
if (actor[arry].indexOf(actorName) >= 0) {
output = movieID[arry];
break;
} else {
alert("spelling error of some sort! Error 404");
}
}
document.input.output.value = output;
}
Your statement var titleData = data.movies; is wrong, because the data returned by the API contains an array of movies.
You have to iterate through data.movies to get the data for the other movies (and not only the first one).
See the raw JS code and JSON data returned by the API: api.rottentomatoes.com
Three things that strike me as odd that might be causing the problem.
Using for…in for an array is considered bad practice, especially when there's a native forEach method and a polyfill for ie8-
cleanMovieTitle isn't doing anything because it doesn't return a value. If you were passing it an array or object, it would pass by reference and it would be altered, but that is considered bad practice for the exact reason that it's not working. You're passing a value, the function modifies that value within the function's scope, then does nothing with it. You need to return the string and set movieTitle = cleanMovieTitle(movieTitle); So maybe the API isn't returning for one of the titles because it hasn't been cleaned. See Passing by Reference or by Value.
The callback may be is getting called again before it finishes running. Not sure on this one, but you could check by flooding the loop with console.logs and seeing whether it's the case.
Edit
So I just ran your script on this page and I'm getting an error on document.input.output.value = output; As expected, parseMovies runs twice when I remove this line. What's document.input?
SO I have code that I'm trying to implement from my jsfiddle into an actual working website/mini-app. I've registered the domain name and procured the hosting via siteground, and I've even uploaded the files via ftp so I'm almost there...
But I'm thinking there's something wrong with my HTML code or JS code or how I implemented my JS code into my HTML code, because all of the HTML and CSS elements are present, but the javascript functionality is absent.
Here is my fiddle:
jsfiddle
^^ Click on start to see the display in action (which doesn't work in the actual website, which leads me to believe there's an issue with my JS file - whether it be code-related or whether that's because I integrated the file incorrectly) (or maybe even uploaded to the server incorrectly, perhaps?)...
And here is the actual site:
http://www.abveaspirations.com/index.html
And here's my HTML code uploaded to the server via FTP:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<script type="text/javascript" src="script.js"></script>
</head>
<body>
<div id='frame'>
<div id='display'>
<h1 id='output'></h1>
</div>
</div>
<div class="spacer">
</div>
<div id="main"> <!-- 11main -->
<h1 id='consoleTitle'>Control Board</h1>
<h5 id='consoleSub'><i>Double-click on an entry to remove. And add entries to your heart's desire...</i></h5>
<div id="controlbox"> <!-- ##controlbox -->
<div id="controlpanel"></div>
<div class="spacer"></div>
<div id="formula"> <!--formula -->
<form id="frm" method="post">
<input id="txt" type="text" placeholder="Insert your own entry here..." name="text">
<input id='submitBtn' type="submit" value="Start">
<input id='stop' type="button" value="Stop">
<select id="load1">
<option id='pre0' value="Preset 0">Preset 0</option>
<option id='pre1' value="Preset 1">Preset 1</option>
<option id='pre2' value="Preset 2">Preset 2</option>
</select>
<!-- These are for buttons as opposed to OPTION...
<input id="load" type="button" value="Preset 1">
<input id="load2" type="button" value="Preset 2"-->
</form>
</div> <!-- formula -->
</div> <!-- ##controlbox -->
</div> <!-- 11main -->
</body>
And my JS code, also uploaded to server via FTP (I didn't include the accompanying CSS file, but if that would help, I can provide ):
$(document).ready(function () {
var txtBox = $('#txt');
var frm = $('#frm');
var output = $('#output');
var subBtn = $('#submitBtn');
var stopBtn = $('#stop');
var loadBtn = $('#load');
var loadBtn2 = $('#load2');
var loadBtnA = $('#load1');
var pre0 = $('#pre0');
var pre1 = $('#pre1');
var pre2 = $('#pre2');
var txt = $('#display');
var preset1 = ["1", "2", "3"];
var preset2 = ["a", "b", "c"];
var container = ["What we do in life echoes in all eternity.", "Find your purpose and give it life.", "When you work your hardest, the world opens up to you."];
var console = $('#controlpanel');
var oldHandle;
function loadPreset0() {
container = [];
console.empty();
container = ["What we do in life echoes in all eternity.", "Find your purpose and give it life.", "When you work your hardest, the world opens up to you."];
updateConsole();
};
function loadPreset1() {
container = [];
console.empty();
container = preset1;
updateConsole();
};
function loadPreset2() {
container = [];
console.empty();
container = preset2;
updateConsole();
};
$(pre0).data('onselect', function() {
loadPreset0();
});
$(pre1).data('onselect', function() {
loadPreset1();
});
$(pre2).data('onselect', function() {
loadPreset2();
});
$(document).on('change', 'select', function(e) {
var selected = $(this).find('option:selected'),
handler = selected.data('onselect');
if ( typeof handler == 'function' ) {
handler.call(selected, e);
}
});
function updateConsole() {
for (var z = 0; z < container.length; z++) {
var resultC = container[z];
var $initialEntry = $('<p>' + '- ' + resultC + '</p>');
console.append($initialEntry);
};
};
updateConsole();
frm.submit(function (event) {
event.preventDefault();
if (txtBox.val() != '') {
var result = txtBox.val();
container.push(result); //1.
var resultB = container[container.length-1];
var $entry = $('<p>' + '- ' + resultB + '</p>');
console.append($entry); //2.
}
var options = {
duration: 5000,
rearrangeDuration: 1000,
effect: 'random',
centered: true
};
stopTextualizer();
txt.textualizer(container, options);
txt.textualizer('start');
txtBox.val('');
});
$("#controlbox").on('dblclick', 'p', function() {
var $entry = $(this);
container.splice($entry.index(), 1);
$entry.remove();
});
function stopTextualizer(){
txt.textualizer('stop');
txt.textualizer('destroy');
}
$(stopBtn).click(function() {
stopTextualizer();
});
});
Any help would be appreciated. I guess I'm just not sure what to do after uploading the html file to the server via ftp. Or maybe I did that correctly and there's something wrong with my code that I'm overlooking. Basically I'm lost. So help please!
You forgot to load jQuery. Make sure that you use <script src="../path-to-jquery/jquery.js"></script> before you load your script.js script.
Also, I noticed that you're loading your scripts in the head tag. This is bad practice, load them right before </body>.
I believe your site is missing jQuery. Add this to the top of your code to hotlink to google's jQuery.
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>