Jade Template Event Handling - javascript

I'm new to a lot of javascript and definitely new to Jade templates. I have figured out how to render a small form (textbox and a button) with a template and I have compiled the javascript file to use on the client. I have been able to read that html template up and put into a div in a consuming web page and it shows correctly.
{
html = template()
document.getElementById("container").innerHTML=html;
}
Here's what I can't figure out:
I want other areas of the consuming web page to be able to subscribe to click events on that button. I'm not clear at all how I can have some kind of event notification on this button so when it is clicked, the listeners will be notified of what was typed in the box when the button was clicked.
At the consuming web page level, I guess I could run some kind of event listener and have subscribers listen and be notified at that level. However, I'd like to be able to look at this as a 'component' and subscribe to events directly on what the template produces...
Long story short, is there any way to add functions like 'addListener' to this button in the template? Since the template just produces a string of html rather than an object I'm a bit at a loss as to how I might do this.
Am I trying to do something that is beyond the scope of templates? What should I be using that will separate my code into a 'component' that can be rendered in it's own page or loaded into a consuming web page, and have events subscribed to?
Thanks for any guidance.
---EDIT---
Here is some code that might show more about what I'm trying to accomplish. This does not work, as expected... I hope it illustrates what I'm after though. Essentially I want the produced code from the template to be an object that I can subscribe to events. I don't think it's possible, but if someone could guide me in another direction that would be great! Thanks
main.html -- shows how I'd like to add listeners to a component
{
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Main Content</title>
<link rel="stylesheet" type="text/css" href="main.css">
<link rel="stylesheet" href="bootstrap-3.3.4-dist/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="bootstrap-3.3.4-dist/css/bootstrap.min.css">
<script src="jquery-2.1.4.js"></script>
<script src="bootstrap-3.3.4-dist/js/bootstrap.min.js"></script>
<script src="jade.js"></script>
<script src="search.js"></script>
<script src="runtime.js"></script>
<script>
$(window).load(function() {
html = search()
alert(html)
document.getElementById('left').innerHTML = html
});
searchListener = function(searchText){
alert(searchText);
}
addSearchListener(searchListener);
</script>
</head>
<body>
<div class="row">
<div id="left" class="col-sm-4">
</div>
<div id="right" class="col-sm-8">
</div>
</div>
</body>
</html>
}
search.html (produced from jade template)
{
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<link rel="stylesheet" href="search.css">
<script src="jquery-2.1.4.js"></script>
<script type="text/javascript">
var listeners = [];
function search(){
var searchText = $('#searchText').val();
notifySearchListeners(searchText);
}
function addSearchListener(listener){
listeners.push(listener)
}
function notifySearchListeners(searchText){
for (i = 0; i < listeners.length; i++) {
listener = listeners[i];
listener(searchText);
}
}
</script>
</head>
<body>
<div id="search">
<h3>Search</h3>
<input type="text" id="searchText">
<button onClick="search()">Search</button>
</div>
</body>
</html>
}

Related

Why doesn't my console.log message show when I press Start?

I'm learning to use event listeners, I wanted to log pressing the "Start" button to the console to make sure the button works but I'm not getting any results when I test the .html file in devtools.
I've verified the index.js name referenced in the .html file is the same
I've tried the source code in the header
I've added the src=index.js jQuery library through Google to the bottom before </body>
I've copied the code to repl.it to try a different environment
JAVASCRIPT:
function startQuiz() {
$('#startButton').click(function(event){
console.log("Keep Going");
});
}
HTML:
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Herbal Medicine: Adaptogens</title>
<link href="style.css" rel="stylesheet" type="text/css" />
<link rel="questions" href="store.html">
</head>
<body>
<div class="container">
<p>Intro to Herbal Adaptogens explaining what they are</p>
<button id="startButton">Start</button>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="index.js"></script>
</body>
</html>
I expect the to see "Keep Going" in the console when I press "start" but instead nothing happens at all.
You have the JQuery click() function inside the startQuiz() function. So it won't work unless the outer function (startQuiz()) is run first. You should put it inside a ready function so that it loads once the page is 'ready'.
Change your javascript to look like this:
$(document).ready(function() {
$('#startButton').click(function(event) {
console.log("Keep Going");
});
});
No need to go with jQuery , you can just use js events.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Log Window</title>
</head>
<body>
<script>
function logMe() {console.log('clicked');}
</script>
<button onclick="logMe()">logMe</button>
</body>
</html>
You should put it inside a Jquery click function. This way it will fire when the document loads.
$(document).ready(function() {
$('#startButton').click(function(event) {
console.log("Keep Going");
}
});

refresh javascript after load ajax

Good evening,
I am importing with the method load different form which changes when submit, unfortunately the elements are not recorded by javascript after the use of ajax, I found answers to my prolet but I can not remedy it in square...
My test.php file simply returns a text & submite input with a form ^^
Thank you !
$("#voteform").load("test.php", { });
$(document).ready(function() {
$("#vote").submit(function () {
alert('test');
$("#voteform").load("test.php", {
username: $("#username").val()
});
return false;
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE HTML>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>WorldCube.fr || Votes</title>
<link rel="stylesheet" href="vote.css">
<meta content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0' name='viewport' />
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>
<div class="votesystem center">
<div class="votetitle">
</div>
<div id="voteform" class="voteform">
</div>
</div>
</body>
</html>
It's unclear to me what question you're asking, but if you're saying that your event listeners or selectors aren't working before/due to HTML changes after page load, then you can you a selector like this:
$(document).on("submit", "#vote", function(e){
// your code here
});
The difference here is that by applying the listener to the document then even after content loads, the event listener will be still work as expected.
You'll want to put this JavaScript code in a place that is loaded with the document only once, maybe initially, so that event listeners aren't attached twice.

Can a libgdx web application work along with web components technology?

I'm working with libgdx 1.9.2 and gwt 2.6.1.
After the GWT-compilation of my java app, I get a JS script (html.nocache.js) that I can include in my html page, and visualisate in a web browser (inside a div, here it's "embed-html"). That part is working nicely.
Here's the code:
<!doctype html>
<html>
<head>
<title>my-gdx-game</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link href="styles.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="html/html.nocache.js"></script>
</head>
<body>
<div id="embed-html"></div>
</body>
</html>
My next goal is to use web components, and more precisely custom elements, to have a simple tag <my-app></my-app> in any web page to get my application.
my index.html:
<!doctype html>
<html>
<head>
<title>my-gdx-game</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<script src="webcomponents.js/webcomponents.js"></script>
<link rel="import" href="component.html">
</head>
<body>
<my-app></my-app>
</body>
</html>
my component.html:
<template id="template">
<div id="embed-html"></div>
<link href="styles.css" rel="stylesheet" type="text/css">
</template>
<script>
var helloDoc = document._currentScript.ownerDocument;
var myApp = document.registerElement('my-app', {
prototype: Object.create(HTMLElement.prototype, {
createdCallback: {
value: function() {
var root = this.createShadowRoot();
var template = helloDoc.querySelector('#template');
var clone = document.importNode(template.content, true);
root.appendChild(clone);
}
}
})
});
</script>
<script type="text/javascript" src="html/html.nocache.js"></script>
But the JS script generated by GWT-compilation has some document.write(...) inside; so all that is included is my empty div, my style sheet correctly loaded, and warnings: "Warning: A call to document.write() from an asynchronously-loaded external script was ignored". Since it is generated, I don't think I can avoid using these document.write().
If I put the <script type="text/javascript" src="html/html.nocache.js"></script> in the head of index.html (where it was before I tried using webcomponents), the app is not added inside the div, as it should, but under (the div and style sheet are included as expected).
And if I put the script inside the template, nothing happens.
So I am wondering if there is a way to have a GWT application working with web components, or if I should search for another way to easily include my application into external websites.
(If you wonder the reasons why I want to do so, it's because I want clients to be able to add my app easily on their own website, with only an import and a tag, the same way I could import a YouTube video or a Google map.)

Reloading page in cordova

I have an issue with cordova that i don't understand how to handle relatively to the opening of the same page more than once.
Suppose that i have two basic html files like this with cordova and jquery mobile support:
index.html
<!DOCTYPE html>
<html>
<head>
<title>
ciao
</title>
<meta charset="UTF-8">
<!-- cordova -->
<script type="text/javascript" charset="utf-8" src="cordova.js"></script>
<!-- jquery mobile -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="js/libs/jquery-mobile/jquery.mobile.css" />
<script src="js/libs/jquery/jquery.js"></script>
<script src="js/libs/jquery-mobile/jquery.mobile.js"></script>
<!-- initialization files -->
<script src="js/mainjs.js"></script>
</head>
<body>
<section id="index" data-role="page" data-fullscreen="true">
<div data-role="content">
/*...*/
<a href="mappa.html">
<img src="img/map.png" />
</a>
/*...*/
</div>
</section>
</body>
</html>
mappa.html
<!DOCTYPE html>
<html>
<head>
<title>
mappa
</title>
<meta charset="UTF-8">
<!-- cordova -->
<script type="text/javascript" charset="utf-8" src="cordova.js"></script>
<!-- jquery mobile -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="js/libs/jquery-mobile/jquery.mobile.css" />
<script src="js/libs/jquery/jquery.js"></script>
<script src="js/libs/jquery-mobile/jquery.mobile.js"></script>
</head>
<body>
<section id="mappa" data-role="page" data-fullscreen="true">
<div data-role="content">
/* code*/
</div>
</section>
</body>
</html>
Now i need to load data in the mappa.html file so i use an handler that i choose to load in the mainjs.js file included in the index like this.
$(document).ready(function() {
console.log("deviceready");
$(document).on("pageshow","#mappa",function(){ //pageshow is thrown each time
/*code*/
});
});
If i use the code above each time i load the page all the handler start again and it's very user unfriendly in case of long operation like data downloading.
So i tried this handler
$(document).one("pageshow","#mappa",function(){ });
But the second time i enter in the mappa.html page simply is blank because the handler does't work 2 times.
So how can i maintain the page loaded?
EDIT: In this specific case i need to load a map and with this code
$(document).on("pageshow","#mappa",function(){ //pageshow is thrown each time
console.log("dentro script");
//setting div height
$("#map_canvas").height( $(window).height() - $("div[data-role='header']").height() - 32 );
//since page show is thrown each time i use a session storage variable
//so i make the init map only one time
if( !sessionStorage.mapinit ) {
console.log("----------mapinit is not set");
sessionStorage.mapinit=1;
console.log("----------mapinit=1");
// Initialize the map plugin
var mapDiv = document.getElementById("map_canvas");
var map = plugin.google.maps.Map.getMap(mapDiv);
map.setMyLocationEnabled(true);
var pisaCenter = new plugin.google.maps.LatLng(43.723072, 10.396585);
map.setCenter(pisaCenter);
map.setZoom(13);
map.one(plugin.google.maps.event.MAP_READY, onMapInit);
} else {
console.log("----------map already set");
var mapDiv = document.getElementById("map_canvas");
var map = plugin.google.maps.Map.getMap(mapDiv);
}
});
and it works fine thanks to
map.one(plugin.google.maps.event.MAP_READY, onMapInit);
that execute the onMapInit function only once.
But in a case like this one
<body>
<script>
$.support.cors=true;
$.mobile.allowCrossDomainPages = true;
$.getJSON('http://.../prestazioni.php?prestazioni=tutto&callback=?',function(data){
$.each(data, function(i, dat){
$("#listview").append('<li>'+dat.rep+'</li>');
});
$('#listview').listview('refresh');
});
</script>
</body>
it's absurd that i need to download data every time i open the page
The main issue is related to jquery mobile and how it load pages.
So in my case i use multiple html files and jquery does't cache the open pages; this behavoour can be overwritten adding data-dom-cache="true" at the page like this
<section id="prestazioni" data-role="page" data-fullscreen="true" data-dom-cache="true">
This works very well. The page remains loaded but it's also possible to modify it using the handler.
There is also an easy route that simply consist in the creation of a single html files with multiple pages. in this case the DOM is always the same and the pages are all cached.

window.onbeforeunload not working in second page

Hi I have two html pages in my mobile application as follows:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery Mobile: Demos and Documentation</title>
<link rel="stylesheet" href="jquery.mobile/jquery.mobile-1.1.0.css" />
<link rel="stylesheet" href="docs/assets/css/jqm-docs.css" />
<link rel="stylesheet" href="docsdemos-style-override.css" />
<script type="text/javascript" src="jquery.mobile/jquery-1.7.2.min"></script>
<script type="text/javascript" src="jquery.mobile/jquery.mobile-1.1.0.js"></script>
<!-- Uncomment following line to access PhoneGap APIs (not necessary to use PhoneGap to package web app) -->
<!-- <script type="text/javascript" charset="utf-8" src="cordova-1.6.1.js"></script>-->
</head>
<body>
<div data-role="page" id="jqm-home" class="type-home">
<div data-role="content">
Index
</div>
</div>
</body>
</html>
my example.html is like:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery Mobile: Demos and Documentation</title>
<link rel="stylesheet" href="jquery.mobile/jquery.mobile-1.1.0.css" />
<link rel="stylesheet" href="docs/assets/css/jqm-docs.css" />
<link rel="stylesheet" href="docsdemos-style-override.css" />
<script type="text/javascript" src="jquery.mobile/jquery-1.7.2.min"></script>
<script type="text/javascript" src="jquery.mobile/jquery.mobile-1.1.0.js"></script>
<!-- Uncomment following line to access PhoneGap APIs (not necessary to use PhoneGap to package web app) -->
<!-- <script type="text/javascript" charset="utf-8" src="cordova-1.6.1.js"></script>-->
</head>
<body>
<div data-role="page" id="jqm-home" class="type-home">
<div data-role="content">
Test
</div>
<script type="text/javascript">
window.onbeforeunload = function(evt) {
console.log ("*****************");
}
</script>
</div>
</body>
</html>
Now suppose on click of Index button I goes to example.html page. on click of back button in example.html it again goes to index.html. everything is fine, but it does not print console.log ("********"); If i press one more back on index.html then it prints it, what I want is it should print that on click of back button when I am on example.html.
Whats wrong in above code? and why it behave like this? Any suggestion will be appreciated thanks in advance.
In Jquery Mobile standard use you basically stay on the same page during your hole experience on the site. "Changing" page basically adds content dynamically to the current document, meaning it will not trigger your onbeforeunload event.
You can however use jquery mobile events, which one depends on exactly what kind of action you want to take. Most probably you would be looking at pagebeforehide or pagehide
What you can do is add an event to the back button.
If you have a button :
<button id="backButton"> Go Back </button>
you can add via jquery following event
$("#backButton).click(function(){
console.log ("*****************");
});
Keep in mind, if you click a button, a post will happen and the page will be refreshed. So you should add the log function inthe document ready of the other page.
So if the example.html page loads, you just fire this event
$(function(){
//All code that starts when the page is fully loaded.
console.log ("*****************");
});

Categories