Play framework: javascripts in scala code? - javascript

If I have a html document with this:
<p onclick="hiho('#name')"> clicky </p>
<script>
function hiho(namevar){
var1 = #Names.find.where().eq("name", namevar).findUnique();
if( var1 != null){
alert("HIHO");
}
}
</script>
How do I use the JavaScript variable?
Play won't compile properly because inside
var1 = #Names.find.where().eq("name", namevar).findUnique();
it cannot find the value of namevar.

One, pretty straightforward, solution could be:
<p onclick="hiho('#name')"> clicky </p>
<script>
var map = {
'#name': '#Names.find.where().eq("name", name).findUnique()'
};
function hiho(namevar){
var value = map[namevar];
if( value != null){
alert("HIHO: " + value);
}
}
</script>
Supposing that the name variables are strings.

You'll probably want to make an AJAX request back to the server. This page talks about that some toward the bottom, and about the routing code you'll need.

Related

Is that possible to put Template7 code in a separate file rather than in html

I am using a framework called Framework7.
In my index.html, I have some Template7 code, like this format
<script type="text/template7" id="commentsTemplate">
{{#each this}}
<div> test this template 7 code </div>
</script>
However, I want to have this part of code into an another separated file (Just like I can have many other *.js files in, say, a static folder and refer to the file by "static/*.js).
I have tried to use a typical way to import js
<script type="text/template7" id="storiesTemplate" src="js/template.js"></script>
But it doesn't work, there is also no demo/sample code in the documentation.
Any help is appreciated!
You can do it. The idea behind is to include a HTML file in a HTML file. I can tell at least 3 ways that this can happen, but personally I fully validated only the third.
First there is a jQuery next sample is taken from this thread
a.html:
<html>
<head>
<script src="jquery.js"></script>
<script>
$(function(){
$("#includedContent").load("b.html");
});
</script>
</head>
<body>
<div id="includedContent"></div>
</body>
</html>
b.html:
<p> This is my include file </p>
Another solution, I found here and doesn't require jQuery but still it's not tested: there is a small function
My solution is a pure HTML5 and is probably not supported in the old browsers, but I don't care for them.
Add in the head of your html, link to your html with template
<link rel="import" href="html/templates/Hello.html">
Add your template code in Hello.html. Than use this utility function:
loadTemplate: function(templateName)
{
var link = document.querySelector('link[rel="import"][href="html/templates/' + templateName + '.html"]');
var content = link.import;
var script = content.querySelector('script').innerHTML || content.querySelector('script').innerText;
return script;
}
Finally, call the function where you need it:
var tpl = mobileUtils.loadTemplate('hello');
this.templates.compiledTpl = Template7.compile(tpl);
Now you have compiled template ready to be used.
=======UPDATE
After building my project for ios I found out that link import is not supported from all browsers yet and I failed to make it work on iphone. So I tried method number 2. It works but as you might see it makes get requests, which I didn't like. jquery load seems to have the same deficiency.
So I came out with method number 4.
<iframe id="iFrameId" src="html/templates/template1.html" style="display:none"></iframe>
and now my loadTemplate function is
loadTemplate: function(iframeId, id)
{
var iFrame = document.getElementById(iframeId);
if ( !iFrame || !iFrame.contentDocument ) {
console.log('missing iframe or iframe can not be retrieved ' + iframeId);
return "";
}
var el = iFrame.contentDocument.getElementById(id);
if ( !el ) {
console.log('iframe element can not be located ' + id );
return "";
}
return el.innerText || el.innerHTML;
}
How about lazy loading and inserting through the prescriptions?
(function (Template7) {
"use strict";
window.templater = new function(){
var cache = {};
var self = this;
this.load = function(url)
{
return new Promise(function(resolve,reject)
{
if(cache[url]){
resolve(cache[url]);
return true;
}
if(url in Template7.templates){
resolve(Template7.templates[url]);
return true;
}
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onload = function() {
if(this.status == 200 && this.response.search('<!DOCTYPE html>') == -1){
cache[url] = Template7.compile(this.response);
resolve(cache[url]);
}else{
reject(`Template ${url} not found`);
}
};
xhr.send();
})
}
this.render = function(url, data)
{
return self.load(url)
.then(function(tpl){
return tpl(data) ;
});
}
this.getCache = function()
{
return cache;
}
}
})(Template7);
Using :
templater.render('tpl.html').then((res)=>{ //res string })
Or :
templater.load('tpl.html').then( tpl => { Dom7('.selector').html( tpl(data) ) } )
It is possible to define your templates in .js-files. The template just needs to be a string.
Refer to this [JSFiddle] (https://jsfiddle.net/timverwaal/hxetm9rc/) and note the difference between 'template1' and 'template2'
var template1 = $$('#template').html();
var template2 = '<p>Hello, my name is still {{firstName}} {{lastName}}</p>'
template1 just extracts the content of the <script> and puts it in a string.
template2 directly defines the string

Toggle text with JavaScript

I am learning JavaScript.
I am trying toggle the text on a page using the replaceChild() method. I came up with the code below. I don't understand why it will not work. Pls help.
<html>
<head>
<script>
function toggleText() {
var be= document.getElementById("main");
var b4= be.getElementsByTagName("h1");
var l8 = document.createElement("h1").innerHTML="After";
var l88 = document.createElement("h1").innerHTML="Before";
if (b4[0].innerHTML=="Before"){
be.replaceChild(l8,b4[0])
}
if (b4[0].innerHTML=="After") {
be.replaceChild(l88,b4[0]);
}
}
</script>
</head>
<body>
<div id="main" onclick="toggleText()">
<h1>Before</h1>
</div>
</body>
</html>
As CBrone wrote, you have to create h1 instance first, store it to variable and then call innerHML on the variable.
Another problem is if structure. First you replace the element and then test the same element for another condition and do another operation. In this case is better to use if ... else if ... statement instead of if ... if ..., which is the root of your problem.
Here is working toggleText function
function toggleText() {
var be= document.getElementById("main");
var b4= be.getElementsByTagName("h1");
var l8 = document.createElement("h1");
l8.innerHTML="After";
var l88 = document.createElement("h1");
l88.innerHTML="Before";
if (b4[0].innerHTML == "Before")
{
be.replaceChild(l8, b4[0]);
}
else if (b4[0].innerHTML=="After")
{
be.replaceChild(l88, b4[0]);
}
}
Here is working fiddle
In addition to what’s been said in comments already:
var l8 = document.createElement("h1").innerHTML="After";
var l88 = document.createElement("h1").innerHTML="Before";
After this your variables do not contain references to the created elements, but the string values that you assigned to their innterHTML. (The result of an assignment operation is the assigned value.) And trying to pass text values instead of element references to replaceChild afterwards must fail for that reason.
Do this in two steps – create the elements first and save their reference into the variables – and then manipulate their innerHTML afterwards.
var l8 = document.createElement("h1");
l8.innerHTML="After";
var l88 = document.createElement("h1");
var l88 = .innerHTML="Before";
(And maybe use better suited variable names, because if you keep your current “naming scene” up you’ll get confused sooner or later.)
May I suggest the following, for better readability:
<html>
<head>
<script>
function toggleText() {
var be= document.getElementById("main");
var b4= be.getElementsByTagName("h1")[0];
if (b4.innerHTML=="Before") {
b4.innerHTML = "After";
}
else if (b4.innerHTML=="After") {
b4.innerHTML = "Before";
}
}
</script>
</head>
<body>
<div id="main" onclick="toggleText()">
<h1>Before</h1>
</div>
</body>
</html>

Replacing function contents dynamically in JavaScript

How do you completely replace a function in JavaScript?
I got this code, but it doesn't work. The DOM gets updated, though. What's up with that?
<html>
<head>
<script id="myScript" type="text/javascript">
function someFunction() {
alert("Same old.");
}
</script>
</head>
<body>
<input type="button" onclick="someFunction();" value="A button." />
<script>
function replace() {
var oldFunctionString = someFunction.toString();
var oldContents = oldFunctionString.substring(oldFunctionString.indexOf("{") + 1, oldFunctionString.lastIndexOf("}") );
var newCode = "alert(New code!);";
var newFunctionString = "function someFunction(){"+newCode+"}";
var scriptTag = document.getElementById('myScript');
scriptTag.innerHTML = scriptTag.innerHTML.replace(oldFunctionString,newFunctionString);
}
replace();
</script>
</body>
</html>
JSfiddle here
Setting .innerHTML doesn't re-execute a script. If you really wanted to do that, you'd have to create a new script element and append it to the DOM, which then overwrites what the previous script has done (not possible in all cases, of course).
If you want to replace that function, just use
somefunction = function() {
alert(New code!); // syntax error, btw
};
Of course, to replace only parts of the code (not knowing all of it) you could try regex and co. Still just reassign the new function to the variable:
somefunction = eval("("
+ somefunction.toString().replace(/(alert\().*?(\);)/, "$1New code!$2")
+ ")");
It seems you are trying to work with strings, not the function itself. Just do this instead:
someFunction = function () { /* your function code here */ }

How can I use a variable from an external .js file in my HTML?

I've got a function that I've written that populates a URL (that contains an image) based on the browser language. This subsequent URL is then written to a variable. All the images are based on language, so for germany it will be "de.gif", France would be "fr.gif" and so on.
My question is how can I call this variable in my HTML page?
To help me to better illustrate this problem here is the JavaScript, please note this is an EXTERNAL .js file called in the of this HTML page:
function IABEU_moused_detect() {
(function IAB_lang_detect() {"use strict";
var IAB_lang_map = {"de-at": "at","nl-be": "be-nl","fr-be": "be-fr","da": "den","de": "de","hu": "hu","en-ie": "ie","ga": "ie","es": "es","fr": "fr","it": "it","nl": "nl","no": "nor","pl": "pl","en": "uk","en-GB": "uk","en-US": "uk","en-gb": "uk","en-us": "uk"},
IAB_lang = (navigator && navigator.browserLanguage) || (window.navigator && window.navigator.language) || "en-GB";
IAB_url = ("http://www.someurl.com/" + IAB_lang_map[IAB_lang]);
IAB_img = ("http://www.myimagesarehere.com/" + IAB_lang_map[IAB_lang]+".gif");
}());}
So it's the IAB_img variable that I want to call in my HTML page (it's a global variable in the .js file)
The HTML is here:
<div>
<img src="HERE IS WHERE I WANT TO call the variable 'IAB_img'">
</div>
Thanks
EDIT: So I still can't solve this, is there a way for me to use the value in "IAB_img" as the image src in my HTML file?
I would start by giving the image an id.
<div>
<img id="TheImage" src="HERE IS WHERE I WANT TO call the variable 'IAB_img'">
</div>
Then in your JavaScript function, just assign the src of the image like so:
function IABEU_moused_detect() {
(function IAB_lang_detect() {"use strict";
var IAB_lang_map = {"de-at": "at","nl-be": "be-nl","fr-be": "be-fr","da": "den","de": "de","hu": "hu","en-ie": "ie","ga": "ie","es": "es","fr": "fr","it": "it","nl": "nl","no": "nor","pl": "pl","en": "uk","en-GB": "uk","en-US": "uk","en-gb": "uk","en-us": "uk"},
IAB_lang = (navigator && navigator.browserLanguage) || (window.navigator && window.navigator.language) || "en-GB";
IAB_url = ("http://www.someurl.com/" + IAB_lang_map[IAB_lang]);
IAB_img = ("http://www.myimagesarehere.com/" + IAB_lang_map[IAB_lang]+".gif");
var image = document.getElementById('TheImage');
image.src = IAB_img;
}());}
Are you rendering the html page via a template? If so, you could include a javascript snippet with a variable setup to be read further on:
<script type="text/javascript">
var IAB_img = {{value}};
</script>
Just put this before you load your other script, and then the IAB_img will already be defined for you.
Something like this:
<div>
<img src="javascript:document.write(IAB_img);" />
</div>

How can I change a JavaScript variable using Greasemonkey?

This is the page that I am trying to modify, I want to bypass the countdown timer, how should I write the script?
Is there a way that I can change the variable document.licenseform.btnSubmit.disabled to yes using Greasemonkey?
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>dsfsdf</title>
</head>
<body>
<form name="licenseform" method="post" action="">
<input name="btnSubmit" type="button" value="我同意">
</form>
<SCRIPT language=javascript type=text/javascript>
<!--
var secs = 9;
var wait = secs * 1000;
document.licenseform.btnSubmit.value = "我同意 [" + secs + "]";
document.licenseform.btnSubmit.disabled = true;
for(i = 1; i <= secs; i++)
{
window.setTimeout("Update(" + i + ")", i * 1000);
//这一句很关键,记得参数写法为("update("+i+")",i*1000)
}
window.setTimeout("Timer()", wait);
function Update(num)
{
if(num != secs)
{
printnr = (wait / 1000) - num;
document.licenseform.btnSubmit.value = "我同意 [" + printnr + "]";
}
}
function Timer()
{
document.licenseform.btnSubmit.disabled = false;
document.licenseform.btnSubmit.value = " 我同意 ";
}
-->
</SCRIPT>
</td>
<!--网页中部中栏代码结束-->
</body>
</html>
A more secure alternative to using unsafeWindow is to inject code into the document. The code that you inject will run in the same context as the page code, so it will have direct access to all of the variables there. But it will not have access to variables or functions in other parts of your user script code.
Another benefit of injecting code is that a user script written that way will work in Chrome as well as in Firefox. Chrome does not support unsafeWindow at all.
My favorite way to inject code is to write a function, then to use this reusable code to get back the source code for the function:
// Inject function so that in will run in the same context as other
// scripts on the page.
function inject(func) {
var source = func.toString();
var script = document.createElement('script');
// Put parenthesis after source so that it will be invoked.
script.innerHTML = "("+ source +")()";
document.body.appendChild(script);
}
To toggle btnSubmit you could write a script like this:
function enableBtnSubmit() {
document.licenseform.btnSubmit.disabled = false;
document.licenseform.btnSubmit.value = " 我同意 ";
// Or just invoke Timer()
}
function inject(func) {
var source = func.toString();
var script = document.createElement('script');
script.innerHTML = "("+ source +")()";
document.body.appendChild(script);
}
inject(enableBtnSubmit);
Remember that when you use the serialized form of a function in this way normal closure scope will not work. The function that you inject will not have access to variables in your script unless they are defined inside that function.
try calling the Timer() function since its what you want to happen anyway:
unsafeWindow.Timer();
while you are at it, change the Update function to do nothing:
unsafeWindow.update = function(){}
This is possible. The short answer is you can use the object unsafeWindow, for instance
unsafeWindow.document.licenseform.btnSubmit.disabled = true;
However it is not recomemended to do so, because it is unsecure. More information about this here:
http://wiki.greasespot.net/UnsafeWindow
Disregard anything said about "insecure", because script->document write operation IS perfectly secure.
unsafeWindow.document.licenseform.btnSubmit.disabled = false;
(Use mkoryak's method to suppress timeout callback)
That given form contains nothing but timeout, so you might want to bypass it completely:
// this example is INSECURE
unsafeWindow.document.licenseform.submit();
See?

Categories

Resources