I'm trying to access a JSON object in my model in my Javascript code.
It's working when I use inline javascript, but it does not work when import a JS file.
What am I missing?
Controller:
String jsonInModel = "{'y':'Jan', 'ty':2000, 'ly':1000}";
model.addAttribute("jsonInModel", jsonInModel);
View:
<script th:inline="javascript">
function printTest(){
var test = [[${jsonInModel}]]; //works
}
</script>
Import (bottom):
<script src="js/lib/morris-chart/morris-init.js"></script>
JS file:
$( function () {
"use strict";
var test = [[${jsonInModel}]]; //doens't work
});
I already tried:
Defer script:
<script defer="defer" src="js/lib/morris-chart/morris-init.js"></script>
Using CDATA in JS file:
//<![CDATA[
var test = ${jsonInModel}; //doesn't work
//]]>
Beginning JS with:
$(document).ready( function ()
Related
My actual code is dense, so I'm trying to reduce this to a minimal example.
I have MainUI.js which contains:
var MainUI = function(){
'use strict';
var singleton = null;
class MainUI {
makeSomethingHappen(){
console.log("MAGIC!");
}
}
return {
getSingleton: function(){
if (singleton == null) singleton = new MainUI();
return singleton;
}
};
}();
Then I have test.js which contains:
function test(code){
var uis = MainUI.getSingleton();
retValue = new Function("ui", "use strict'" + code)(uis);
}
This is all run from index.html which contains:
<html>
<script type="text/javascript" src="MainUI.js"></script>
<script type="text/javascript" src="test.js"></script>
<body onload="test('ui.makeSomethingHappen();');">
</body>
</html>
But when I call
test("ui.makeSomethingHappen();");
or even
test("console.log('NARF!');");
I get an exception with the message
MainUI is not defined
The singleton accessor and the MainUI works in all my code outside of "new Function()", so I know it's working (even if I made typographical error producing the minimal test).
So I'm hoping someone can tell me how I can give the code inside the Function access to the class definitions outside.
Make sure that the MainUI.js script is referenced correctly and that it is referenced prior to the test.js script that will use it.
How to use var aid value assign into $data array? I am getting error: "Use of undefined constant aid". I am working on Laravel 5.4. I want to show ($data['services'][aid]->servicesubdetails) value in tage. My code is below:
<script language="JavaScript">
function theFunction(e)
{
var aid= e.target.id;
$("p").html('{{ ($data['services'][aid]->servicesubdetails) }}');
}
</script>
Single quotes are interrupted by another single quote.
<script language="JavaScript">
function theFunction(e)
{
var aid= e.target.id;
$("p").html(“{{ ($data['services'][aid]->servicesubdetails) }}”);
}
</script>
Notice “ instead of ‘.
EDIT
You can use json to use you PHP array in javascript
Look at LaravelDisplayData and PHPJsonEncode
<script language="JavaScript">
var data = #json($data)
function theFunction(e)
{
var aid= e.target.id;
$("p").html(data.services[aid].servicesubdetails);
}
</script>
consider the following code -->
<template id="foo">
<script type="text/javascript">
console.log("00000000");
</script>
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script type="text/javascript">
console.log(11111111);
</script>
<script type="text/javascript">
console.log(22222222);
var xyz = $;
console.log(33333333);
</script>
</template>
now on appending this to the DOM
var template = document.getElementById('foo')
var clone = document.importNode(template.content,true);
document.appendChild(clone);
gives this output in console -->
00000000
11111111
22222222
Uncaught ReferenceError: $ is not defined
So the question in general is -->
How to properly load into DOM, an html <template> that has
an external script (like jQuery in this case), followed by an inline script having some dependency on it.
Also - this does not happen if template tag is removed -->
<script type="text/javascript">
console.log("00000000");
</script>
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script type="text/javascript">
console.log(11111111);
</script>
<script type="text/javascript">
console.log(22222222);
var xyz = $;
console.log(33333333);
</script>
How in the latter case, does the browser download it synchronously?
Is it possible to have blocking script download (line by line) in the former case (with template) ?
The problem is that the script is loaded async. That means that it start to load the script from the web, but continues running the code below. So in that case it will execute code below without having loaded jQuery yet.
You only need to load it once, so you could do it at the start, and only once:
var template = document.getElementById('foo')
var clone = document.importNode(template.content,true);
document.body.appendChild(clone);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<template id="foo">
<script type="text/javascript">
console.log(00000000);
</script>
<script type="text/javascript">
console.log(11111111);
</script>
<script type="text/javascript">
console.log(22222222);
var xyz = $;
console.log(33333333);
</script>
</template>
Another option would be to make sure code below is only executed once the file is loaded:
var template = document.getElementById('foo')
var clone = document.importNode(template.content, true);
document.body.appendChild(clone);
<template id="foo">
<script type="text/javascript">
console.log(00000000);
</script>
<script type="text/javascript">
function scriptOnload() {
console.log(11111111);
console.log(22222222);
var xyz = $;
console.log(33333333);
}
</script>
<script onload="scriptOnload()" src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</template>
Here's how I handle it in my application (with jQuery):
//Load the template from an external file and append it to the HEAD of the document
$.get("/path/to/your_external_template_file.html", function (html_string) {
$('head', top.document).append(
new DOMParser().parseFromString(html_string, 'text/html').querySelector('template')
);
}, 'html');
//Locate the template after you've imported it
var $template = $("#top_template_element_id");
//If you want to reuse the content, be sure to clone the node.
var content = $template.prop('content').cloneNode(true);
//Add a copy of the template to desired container on the page
var $container = $('#target_container_id').append(content);
I have an external javascript file called test.js as seen below. This file needs user configuration parameters passed to it, in this case user and show values.
<script type="text/javascript">
<!--//
user = '123';
show = 'appts';
//-->
</script>
<script src="{{ STATIC_URL }}js/widgets/test.js" type="text/javascript"></script>
Above is currently how I tell 3rd parties to add the script to their own site. However, I cannot help to feel this is a bad way to pass these values i.e. clashes.
Is the way I have done it acceptable? Is there a better way?
A simple answer would be to append something to your variable names, such as:
<script type="text/javascript">
<!--//
widget_test_12331_user = '123';
widget_test_12331_show = 'appts';
//-->
</script>
You can stick to namespace convention "reverted domain":
<script type="text/javascript">
<!--//
if (!org) var org = {};
if (!org.mylibrary_domain) org.mylibrary_domain = {};
if (!org.mylibrary_domain.settings) org.mylibrary_domain.settings = {};
org.mylibrary_domain.settings.user = '123';
org.mylibrary_domain.settings.show = 'appts';
//-->
</script>
<script src="{{ STATIC_URL }}js/widgets/test.js" type="text/javascript"></script>
You can use the concept of javascript namespace (How do I declare a namespace in JavaScript?).
so you can add another js file named testConfig.js, which include :
var yourAppNamespaceTestConfig = {
user: function(){ return '123' ;} ,
show: function(){ return 'appts';}
};
then inside test.js, you can read the config by:
var user = yourAppNamespaceTestConfig.user();
var show = yourAppNamespaceTestConfig.show();
And if you're more about OO, try Coffeescript (http://coffeescript.org/). They introduce OO to your javascript.
I'm trying to use Knockout js in a simple web application.
Here's my dummy javascript code:
function MainViewModel() {
this.myText = ko.observable('Hello world');
}
var MainViewModelInstance = new MainViewModel();
ko.applyBindings(MainViewModelInstance);
But when I run the index.html, the debug console says "ko.applyBindings is not a function"!
Help!
Thanks
You have not included the link to the knockout.js library in your source code or the link is wrong. Fix this and it will work.
<script src="/scripts/knockout-2.0.0.js" type="text/javascript"></script>
Where the /scripts directory is the location on the server where knockoutjs resides.
EDIT
Here is an example of your code that works.
<html>
<head>
<script src="knockout-2.0.0.js" type="text/javascript"></script>
</head>
<body>
<script type="text/javascript">
function MainViewModel() {
this.myText = ko.observable('Hello world');
}
var MainViewModelInstance = new MainViewModel();
ko.applyBindings(MainViewModelInstance);
</script>
</body>
</html>