How to call .sjs file from HTML? - javascript

I just started learning programming using MarkLogic.
I followed documentation, created "sample.sjs" file like in below.
https://docs.marklogic.com/guide/jsref/language#id_71272
xdmp.setResponseContentType("text/plain");
"hello"
How should I call this "sample.sjs" to display result in HTML?
Or should I better include HTML code inside "sample.sjs" file?

Your SJS code must construct whatever content you want to return to the caller, including HTML. The content returned by your module becomes the response data.
There's a bit more robust example using JSON instead of HTML, here:
https://developer.marklogic.com/learn/sjs/http

Related

Thymeleaf syntax is not working in java script file

I am using spring boot to provide data to thymeleaf.
var list = [(${listStudents})];
listStudents is a list of students with the help of which I populate data in HTML which is working fine but fetching the same list in java script using thymeleaf shows error in the above line as:
, expected.
I have added th:inline="javascript" attribute to script tag in HTML file as:
<script th:inline="javascript" src="home_script.js"></script>
Trying to solve this since yesterday.
Thanks in advance!
The , expected error is the standard JavaScript syntax error for var list = [(${listStudents})];. To handle this, Thymeleaf supports placing its inline expressions inside JavaScript comments:
var list = /*[[${listStudents}]]*/ [];
Because the Thymeleaf expression is in a JS comment, note how we have to provide a default (visible) JS value, to keep JavaScript from raising a different syntax error. I used [] because you have a list. You could have used '', or null or whatever is most suitable. Assuming your Thymeleaf is rendered correctly, this extra syntax will be ignored.
See JavaScript natural templates for details.
However, I do not think this will completely resolve your problem, unless you have already configured a JavaScript template resolver in your application.
You are using this:
<script th:inline="javascript" src="home_script.js"></script>
First of all, the th:inline="javascript" portion has no effect, because your JavaScript code is in an external file: home_script.js (i.e. it is not embedded in your HTML file).
If you want Thymeleaf to process the Thymeleaf expressions in that separate JS file, you have to tell Thymeleaf to explicitly process external JavaScript files (just like it processes HTML files).
You probably only have a HTML resolver - and your JS code is not embedded in your HTML file - it is in its own separate JS file. See this demo application which shows how to set up what I think you may need.
Alternatively you can simply embed your JS directly into the <body> of your HTML file, and don't use an external JS file:
<body>
<script th:inline="javascript">
var list = /*[[${listStudents}]]*/ [];
</script>
</body>
If you still need to use an external JS file, you can assign all your Thymeleaf-generated variables inside your HTML file (like the example above) and then pass these variables as function parameters into the various JavaScript functions in your JS file.
Using this approach means your JS file does not need to contain any Thymeleaf expressions - it just receives the rendered values from the JS fragment in your HTML file.
You should use [[${listStudents})]] (so 2 square brackets, not using round brackets)

Preferred way to dynamically change variable in Javascript using Python/Flask framework

I am relatively new to HTML/Javascript, and I have a need which I am sure is common, but I don't know the preferred/standard way to handle it.
Basically, I have a web page with Javascript/jQuery code to use AJAX to dynamically change values on a page. I prefer not to encode the AJAX URL statically in the Javascript, but rather be able to pass the URL using Jinja from the Flask application.
So, for example:
$("#inputtext").autocomplete({
source: function (request, response) {
$.getJSON("{{ url_for('main.auto') }}?q=" + request.term,
function(data) { console.log('doing something in the function') }}
The key question is the Jinja template in the middle {{ url_for('main.auto') }}. This correctly renders the route for 'main.auto' if the Javascript code is embedded in the HTML file. However, I prefer to separate the JS from the HTML. So, I took the above code and put it in a separate .js file and imported it into the HTML like this:
<script type="text/javascript" src="{{ url_for('static', filename='js/memberSearch.js') }}"></script>
The above code is in the memberSearch.js file in this example.
When I import the JS code like this, Jinja doesn't render the {{url_for('main.auto')}}. I suppose that this is because Jinja goes through the HTML code first before the JS code is imported.
I found an answer by #martijn-pieters here that lists four methods of passing data from HTML to Javascript:
You can put that information in HTML tags. In the above example, your data is put in the repeated tags.
Or you could add data attributes to your HTML, which are accessible both to Javascript code and to CSS.
Or use AJAX to load data asynchronously; e.g. when you pick an option in the box, use Javascript and AJAX to call a separate
endpoint on your Flask server that serves more data as JSON or
ready-made HTML, then have the Javascript code update your webpage
based on that.
Or generate JSON data and put it directly into your HTML page. Just a some_variable_name = {{datastructure|tojson|safe}};
section is enough; then access that some_variable_name from your
static Javascript code to do interesting things on the page. JSON is a
(almost entirely a) subset of Javascript, and the way the tojson
filter works is guaranteed to produce a Javascript-compatible data
structure for you. The browser will load it just like any other
embedded Javascript code.
Of these methods, I have successfully used the first one by embedding the Jinja template in a element like this, for example:
<input type="hidden" id="urlForPdf" value={{ url_for('main.auto') }}>
Which allows me to access the rendered URL in my JS code.
I have also tried the fourth method of generating JSON directly in JS like this:
<script type="text/javascript">var url = {{ url_for('main.auto')|tojson}}</script>
which allows me to access the variable url from the JS function.
The answer I referred to above also mentions using Data Attributes. I haven't tried this, but I believe it would work as well.
My question, then, is simply whether there is a preferred way of doing something like this? It seems that this must be a very common scenario and I assume that there is some more-or-less standard way of handling this. I'm just not sure which of the four possible solutions is preferred, or if perhaps there is another way altogether.
Thanks in advance for any light you can shed on this.

Why should JavaScript access to a list sent by Flask only if it is executed within the <script> tag in HTML?

I would like to send a list to JavaScript from Flask. I noticed that if I write JavaScript code inside an HTML tag it works, while if I do the same thing in a file linked inside the header I get the following error:
Uncaught SyntaxError: Unexpected token {
The javascript code is as follows:
var docs = {{ txtDocs | tojson }};
console.log(docs);
The Python code is the following:
app = Flask(__name__)
#app.route('/')
def landingPage():
return render_template('landingPage.html', txtDocs=json.dumps(os.listdir(pathToTxtDocs)))
I think that piece of JavaScript code inside the HTML is interpreted by Jinja2, while in case the js code is inside a file it is not interpreted. I'm quite sure.
But I would like to have separate html code and javascript code, for better reading.
So, is there a way to read a list sent by python to a js file? (Obviously linked in the HTML header).
Thanks in advance.
I think that piece of JavaScript code inside the HTML is interpreted by Jinja2, while in case the js code is inside a file in itself it is not interpreted
Indeed.
But I would like to have separate html code and javascript code, for better reading.
This only makes sense if your js code is used in more than one template - else having to open and read each js file linked in your template (directly or via a parent template) to find out what js code is actually executed really doesn't make your code more readable.
Now for the technical solutions: the first one is to have a function in your .js file and call it from the template - which means you'll STILL need to have some js in the template:
# yourlib.js
function doSomethingWithDocs(docs) {
// your real code here
}
and
# template
<script src="/your/js/yourlib.js"></script>
<script>doSomethingWithDocs({{ txtDocs | tojson }});</script>
The other solution is to expose an API endpoint in your flask app that returns the docs as json already, and make a call to this endpoint in your js file. You will very probably STILL need to pass some data from the view to the template to the js function to make the correct API call though...
IOW: your code is fine this way, it works, and it's as simple and obvious as possible.

How can I use custom template tags inside javascript in the Play! framework?

How can I use a custom tag inside my javascript code? For example:
function toHTML(message){
return #{customTag message:message /};
}
does not work..
Thanks!
//Some clarification
I am retrieving a list of messages using AJAX, and I have an html tag called "customTag" which contains the html code to format the message into a <li> element.
If I call
#{customTag message:'hello' /}
directly in the HTML file, it works and replaces it by <li>hello</li>. But when I try calling it from javascript, I get an error message.
The problem you have, is that you are trying to mix server-side logic (the rendering of templates) with client side events (the javascripts execution). So, your approach will not work, because the custom tag is executed from the serverside before you it ever gets to the client side.
You can get it to work using Play tags, but I would suggest that you think about using Javascript templates for doing this kind of client side. Take a look at the Chat application in the samples-and-tests folder in the Play download to see it in action. However, if you want to get it working using Play templates/tags, see below.
If you change your custom tag so that it does not take in an input, but instead is "aware" of the javascript variable, then this should work. So your tag code would look like
"<li>" +message+ "</li>";
So, this does not use the tag to pass variables into the tag, but instead uses the client side javascript variable.
I tested this with the following code in a test application (views/Application/index.html) and it outputted the javascript as expected.
<html><head></head>
<body>
<script type="text/javascript">
function toHTML(message){
return #{message /}
}
alert(toHTML("hello"));
</script>
</body>
</html>
This wont work. Try using double quotes around your value. Or, write clearly what you want actually.
In my opinion, this can't work because custom tag is evaluated on server side i.e. before the content was send to the client and then before the JavaScript was interpreted.
[sorry for my English !]

Importing external json files to a javascript script client-side without external libraries

I'm a bit new to javascript. Is there a way to do what I am describing in the title completely client-side and without any external libraries? Or is using jQuery the best/only way to go?
You can import a json file from a server via AJAX and them simply eval it. You don't need a library for that but using one makes it a lot easier. Of course just evaling a json string is not very secure as it can contain arbitrary text so all libraries parse it to see if it's well formed etc.
EDIT:
If you want to learn about AJAX you can start with this tutorial from w3schools. Ajax stands for Asynchronous Javascript And XML and it allows you to send a request to the server without reloading the whole page. In your case you will not be using Xml but JSON. Anyway, the tutorial explains the whole idea.
Yes there is. You can use the "document.write" to add scripts to the DOM at runtime:
in your case:
document.write('<script ...></script>');
Basically you are adding the script tag to the dom that will request the new file.
However there is something else to consider, although the script will be downloaded, you will need to have a variable assignment in it in order to use it in your page:
var x = { //json object };

Categories

Resources