Where does my dynamically added script go? - html

I'm new to web development and I'm trying to understand how the DOM works.
I have a basic page with 2 buttons and some text. One of the buttons does a call to Jquery's Get function. My server returns some html with some script as well. Which is then added to my DIV on my main page which has an ID of 'content'
See below for the code.
Main Page
<!DOCTYPE html>
<link rel="stylesheet" href="css/toastr.css">
<html>
<body>
<h1>My Main Page </h1>
<button class="alertmsg">click me</button>
<button class="addDom" >Call Add HTML</button>
<div id="content">
</div>
</body>
</html>
<script src="js/jquery.js"></script>
<script src="js/toastr.js"></script>
<script>
$(document).ready(function(){
$(".alertmsg").click(function() {
alert("Hello World!");
});
$(".addDom").click(function(){
$.get( '/adddom',
function (data) {
// put html into the section
$("div#content").html(data);
})
});
});
</script>
Code Returned
<div>
<h1>Added Via $.html</h1>
<button class="showmsg">click me for jquery</button>
</div>
<script>
$(document).ready(function(){
$(".showmsg").click(function(){
toastr.warning( "Test Warning", 'Warning');
});
});
</script>
The Updated DOM - notice that my new javascript aren't seen.
<!DOCTYPE html>
<link rel="stylesheet" href="css/toastr.css">
<html>
<body>
<h1>My Main Page </h1>
<button class="alertmsg">click me</button>
<button class="addDom" >Call Add HTML</button>
<div id="content">
<div>
<h1>Added Via $.html</h1>
<button class="showmsg">click me for jquery</button>
</div>
</div>
</body>
</html>
<script src="js/jquery.js"></script>
<script src="js/toastr.js"></script>
<script>
$(document).ready(function(){
$(".alertmsg").click(function() {
alert("Hello World!");
});
$(".addDom").click(function(){
$.get( '/adddom',
function (data) {
// put html into the section
$("div#content").html(data);
})
});
});
</script>
What I'm trying to understand is;
1) Where does my new script code exist?
<script>
$(document).ready(function(){
$(".showmsg").click(function(){
toastr.warning( "Test Warning", 'Warning');
});
});
</script>
is it in memory only and not in the DOM?
2) I can get the warning to show correctly i.e $(".showmsg").click
fires and shows what is expected. So my my script can reference the existing libraries in the DOM which are needed. How does this work?
3) What is the best way to trouble shoot this code if I cannot see it in my browser?
Many thanks!

If you really want to append the script to the dom you need to use appendChild() not .html(). link about appendChild
An example of doing this would be
var script = document.createElement( 'script' );
script.type = 'text/javascript';
script.text = 'alert("test");';
$('div')[0].appendChild(script);
Here is a fiddle showing this.

Related

Move a script to its own js file

I want to move the angular to its own .js file, so I looked at Using an HTML button to call a JavaScript function.
<input id="clickMe" type="button" value="clickme" onclick="doFunction();" />
As far as I understand, an event has to be triggered when I click on the button, so I tried following this example on w3schools
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<button ng-click="count = count + 1">Click Me!</button>
<p>{{ count }}</p>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.count = 0;
});
</script>
</body>
</html>
It simply counts the number of times a button has been clicked and it works. However, when I move the <script> to its own .js, the function is not found. Am I missing something? a dependency perhaps?
New files:
HTML:
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<button ng-click="count = count + 1">Click Me!</button>
<p>{{ count }}</p>
</div>
</body>
</html>
.js
<script>
var app = angular.module('myApp', ['ngRoute']);
app.controller('myCtrl', function($scope) {
$scope.count = 0;
});
</script>
So two problems.
First, in your .js file you can remove the <script> tags. You only need this for javascript in html files.
Second, in your .html file, you need to add a reference to your script file. This needs to go below the angular script since it is dependent on that script, so just add, <script src="[link to your script file]"></script> to your html right below the angular script.
.html
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<script src="app.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<button ng-click="count = count + 1">Click Me!</button>
<p>{{ count }}</p>
</div>
</body>
</html>
app.js
var app = angular.module('myApp', ['ngRoute']);
app.controller('myCtrl', function($scope) {
$scope.count = 0;
});

HTML File including another HTML file

I created a web page wherein I want to display there another HTML file. I used jQuery to do this but wasn't able to display the content of the file I have included. Why do you think this happened. Thanks a lot.
Here's my code for my mainpage.
sample.html
<html>
<head>
<title> Sample Only </title>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.js"></script>
<script>
$(function(){
$('#footerLang').load("sampleFooter.html");
});
</script>
</head>
<body>
<div id="footerLang">
<h1></h1>
</div>
</body>
</html>
sampleFooter.html
<p> THIS IS A FOOTER </p>
It is highly possibly because you are placing the following block in head without $(document).on("ready", function() { ...; });
$(function(){
$('#footerLang').load("sampleFooter.html");
});
In this case jQuery will unable to find the #footerLang element since the DOM is not ready, you could revise the script as follow
$(function(){
$(document).on("ready", function () {
$('#footerLang').load("sampleFooter.html");
});
});
or move the script tag just before the </body>
<html>
<head>
<title> Sample Only </title>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.js"></script>
</head>
<body>
<div id="footerLang">
<h1></h1>
</div>
<script>
$(function(){
$('#footerLang').load("sampleFooter.html");
});
</script>
</body>
</html>
I found out that this was just a browser compatibility issue. I launch it in Firefox and it worked.

Converting from NATIVE to IFRAME sandbox

I have a large application that I want to convert from NATIVE to IFRAME sandbox now that NATIVE is deprecated. The general flow of the application is as follows: The user fills out a form on the beginning page and presses a Begin button. The beginning page is then hidden, and based upon values from the first page, the user is then shown a new page. My problem when using IFRAME is that the new page is never shown. It works as expected in NATIVE mode. I have created a simplified script that exhibits the problem. Please help me understand what I am forgetting or doing wrong.
Code.gs
function doGet() {
Logger.log('enter doget');
var html = HtmlService.createTemplateFromFile('BeginHeader').evaluate()
.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;
}
Javascript.html
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js">
</script>
<script
src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js">
</script>
<script
src="https://apis.google.com/js/api.js?onload=onApiLoad">
</script>
<script>
function showForm(hdr) {
console.log('enter showform');
console.log(hdr);
console.log('hiding first page');
document.getElementById('beginDiv').style.display = 'none';
var el = document.getElementById('recordDiv');
el.innerHTML = hdr;
console.log('showing new page');
el.style.display = 'block';
}
function oops(error) {
console.log('entered oops');
alert(error.message);
}
</script>
<script>
$(document).ready(function() {
console.log('begin ready');
$("#beginForm").submit(function() {
console.log('enter begin submit');
//console.log('hiding first page');
//document.getElementById('beginDiv').style.display = 'none';
console.log('including page 2');
google.script.run
.withSuccessHandler(showForm)
.withFailureHandler(oops)
.include('Page2');
});
});
</script>
BeginHeader.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<div id="beginDiv" style="display:block">
<p>Click on Begin. </p>
<form id="beginForm">
<input type="submit" value="Begin">
</form>
</div>
<!-- results of content being filled in -->
<div id="recordDiv"></div>
<?!= include('Javascript'); ?>
</body>
</html>
Page2.html
<!DOCTYPE html>
<html>
<body>
<p> This is page 2. </p>
</body>
</html>
There is no point in ever using a button of the "submit" type, unless you want to force the form to make an HTTP Request, and reload the application. That's what a "submit" type button does. It causes the page to be reloaded. The "submit" type button is meant to work together with a form in a certain way. It causes a GET or POST request to happen. That's what the problem is. So, you'll need to reconfigure things a little bit.
Just use a plain button.
<input type="button" value="Begin" onmouseup="gotoPg2()">
I created a gotoPg2() function to test it:
<script>
window.gotoPg2 = function() {
console.log('enter begin submit');
//console.log('hiding first page');
//document.getElementById('beginDiv').style.display = 'none';
console.log('including page 2');
google.script.run
.withSuccessHandler(showForm)
.withFailureHandler(oops)
.include('Page2');
};
</script>
If you use that, they you don't need the $(document).ready(function() { etc. code anymore. And, if you don't need that code, then you don't need to load jQuery.
Unless you are using jQuery for other things, then you don't need:
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js">
</script>
<script
src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js">
</script>
The NATIVE mode was probably blocking the intended usage of the "submit" request. That's why the code in NATIVE was working. IFRAME allows things to work as they are built and intended to work, which means that the page was probably trying to be reloaded, and an error was occurring. I was getting a 404 page error in the browser console.

Ajax .load() function not working

.load() only works on files coming from a server, so it will work later as I'm going to put this on a server
Edit: This code works on firefox but not on chrome
I've been trying to use ajax to load a webpage after selecting an option but the script doesn't even seem to load
here's the script + html:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="DaVinciRace.css" />
<title> Da Vinci Race 2014-2015 </title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js" ></script>
</head>
<body style="background:#f2f2f2;">
<div id="logo">
<img src="Resources\DVRLogo.png"/>
<!-- <p class="text">Da Vinci Race</p> -->
</div>
<div id="options" style="background:#0c0c0c; float:right;">
<div class="menu">
<div class="chronometre" ></div>
</div>
</div>
<div id="DVRChrono">
</div>
<script>
$(document).ready(function(){
$("#options").on("click", ".chronometre", function() {
$( "#DVRChrono" ).load( "Chronometre.html" );
})
});
</script>
</body>
</html>
the document "Chronometre.html" is in the same folder as this html page
I feel like I'm missing something obvious but can't for the life of me figure out what it is
Try this:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js" ></script>
<script>
(function($){
$("#options").on("click", ".chronometre", function() {
$( "#DVRChrono" ).load( "Chronometre.html" );
})
})(jQuery)
</script>
This isn't adding a click handler:
$("#options").on("click", ".chronometre", function() {
// code
});
Because it executes before the #options element exists on the page. The code is executing without error, the jQuery selector simply isn't finding anything. So there are no elements to which a handler can be attached.
You can fix this either by moving the code to the end of the page or by wrapping it in the document.ready handler:
$(function() {
$("#options").on("click", ".chronometre", function() {
$( "#DVRChrono" ).load( "Chronometre.html" );
});
});
Additionally, your script tags are broken. Each tag should have either a src or content, but not both. Separate them:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script type="text/javascript">
// your code
</script>

Mootools - why not run?

you can test my code , when i click buton , we will get 2 link
click on first link , not alert
click on second link , show alert
why first link not alert, how to it can alert ?
<html>
<head>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">google.load("mootools", "1.1.2");</script>
<script>
window.addEvent('domready', function(){
$('button').addEvent('click', function(){
$('content').innerHTML = $('test').innerHTML;
});
});
</script>
</head>
<body>
<input id="button" type="button" name="button" value="Click"/>
<div id="content">
</div>
<div id="test">
<script>
function test(){
$('a-content').addEvent('click', function(){
alert(1);
});
}
window.addEvent('domready', function(){
test();
});
</script>
<a id="a-content" href="#">CLICK HERE</a>
</div>
</body>
</html>
When injecting HTML on the fly events aren't carried over unless you use event delegation. If you don't use event delegation the event will only be on the original element. See http://mootools.net/docs/more/Element/Element.Delegation
You'll need to do something like this. $('body').addEvent('click:relay(#a-content)', function(){...}); Where the body would capture the click event and delegate it to any element with the id of "a-content".
Also by setting the content like this $('content').innerHTML = $('test').innerHTML; you will have duplicate elements with the id "a-content" this is wrong. HTML id's should be unique. Try classing stuff that you'll reuse instead.