JSP variable initialization is happening after JS runs - javascript

I'm initializing a JSP string inside a Liferay portlet:
String json = "{}";
// returns json
json = LiferayPortlet.makeCurlCall();
...
<script>
$(window).load(function(){
//initialize js variable
jsData = "${json}";
// initialize the page
initializePage(jsData);
});
</script>
The issue I'm having is that LiferayPortlet.makeCurlCall(); is returning json, but jsData is not being initialized to it, instead its being set to "". Is there a way to initialize jsData to the json that is being returned from the function above?

Don't do it
You cannot initialize a JavaScript variable with a scriptlet or JSTL. The Java code is executed on the server and will not execute in top down order on your jsp page.
While I don't recommend this you can use the following
<script type="text/javascript">
var message = '<c:out value="${json}"/>';
</script>
That will technically work - however I want to stress that I do not recommend this. Maybe you can explain exactly what you are trying to accomplish and we can recommend a more optimal way of doing it.
JSTL v. Scriplets
You might also have a scope issue using JSTL and scriplets together indiscriminately. They are of different scopes. JSTL works with the following scopes.
page
request
session
application
Scriplets are in the page scope always. So while your code doesn't contain this issue it most likely will be something you will encounter.
Recommendation
If you are using Liferay, I suggest you learn Alloy UI (a JavaScript library) and become comfortable with their AJAX modules. Generally, when I see the code you posted, it is better to have an AJAX function that makes a GET call to your portlet for the JSON when it is needed.

Related

JSTL. How to call a function from <script> in c:set jstl tag?

I just need something like this:
<c:set var="cls" value="${myFunc(param)}"/>
.....
<script>
function myFunc(param) {
if(param == true) {
return "aaa";
} else {
return "bbb";
}
}
</script>
When I try it then get this error:
org.apache.jasper.el.JspELException: /script.jsp(22,12) '${myFunc()}'
Function [:myFunc] not found
Is what you are trying to do, possible??
Answer to this in one word would be NO...
Let's dive into the reason, hint is here.. JSTL (JavaServer Pages Standard Tag Library).. see the word 'Server'. Yes.
The JSP pages gets compiled as like your Java files. Once the compilation is successful, it can be then sent as a response and then browser renders this response and displays the page.
JavaScript : is a client side programming language which means codes in JavaScript are run by the browser not by the server.
When compiler compiles Jsp file, it only plays around the Scriptlet and JSTL part, and rest of the code (I mean the rest of HTML, CSS and JS code) is just a piece of string.
Now, imagine a situation in your code, while Java compiler is trying to compile it finds that myFunc must be a method but where to look for?
It cannot see it as a javascript function, because javascript runs only in browser not in server side. And hence, you are not able to set the value of cls variable, because myFunc is unknown for Java.
Hope this helps you understand JSP and Server Side working.
Keeping above things in mind, try some better approach to solve your problem.
Happy Coding :)

Using gsp layout declared variable in javaScript file that is being loaded in the same page

I recently started learning grails and I am trying to use a gsp variable declared in the layout of the page as:
<g:set var="abtestType" value="newSearchBar" />
in the js file that is being loaded on the same page. Things that I have tried:
alert(${abtestType});
alert(<%=abtestType%>);
alert("abtestType:"+abtestType);
but its showing error as variable is not defined. Probably I am trying to fetch it in wrong way, need help regarding this.
Even thinking about doing so neither makes sense nor applicable.
Reason for such statement is that when a gsp page is rendered to an html page, it replace grails tags with appropriate html tags or value. Similarly it replaces the ${} or <%%> with html or javascript or whatever that goes on front-end.
Hence the code that you have tried could have worked fine if you were having those javascript code lines in the gsp itself but as you have called externalised js file it actually don't know anything about gsp or jsp or any other Language's front-end support.
The one way of doing that if using global variable in javascript. e.g.
declare abtestType above like below:
<script>
var abtestType = "${abtestType}"
</script>
Now you have access to global variable abtestType in your javascript.
Use it in your javascript but remember now you need to have this variable iff the code using it is called otherwise very same error would you get i.e. variable is not defined
There is another way that I found in this post but is a manipulation actually.
Is there any analogue in Javascript to the __FILE__ variable in PHP?
Also, another good links is
Pass vars to JavaScript via the SRC attribute
Hope it helps!

How to transfer mvc view javascript code to separate js file

I am using Knockoutjs in my asp.net MVC-5 application. I have the following javascript in view:
<script type="text/javascript">
var model = "#Html.Raw(Json.Encode(Model))";
$.get("#Url.Action("_CityPartial")" ...)
//any much more code using similar Html helpers + pure javacsript code.
</script>
Now i want to know, is there any way to transfer this javascript code in a separate js file (keeping Html helpers as it is).
I want to transfer javascript code to separate file because i dont want any user to check my javascript code (using chrome inspect element or any other way).
If the transfer is not possible than please let me know if there is a any way to minifiy the javascript in view itself ??
You could create an external .js file with your code in and pass your serialized json object to it like this:
<script type="text/javascript">
var model = #Html.Raw(Json.Encode(Model));
DoThis(model);
</script>
This has the benefits of keeping the main body of javascript in a separate file.
Any other razor variables can be passed across to the methods defined in the javascript in the same manor as the model has been above.
However as Stanyer mentions this is still javascript and it will run on the client.
You can load it via an external JavaScript file, but unfortunately as JavaScript is a client-side scripting language regardless of whether its loaded inline or externally, the client can still view the code which is being executed on their browser.
You mention minifying - again this can still be interpreted by a client if they really wanted to see your code, but there are many tools online which can minify your JavaScript for you.
Examples:
http://jscompress.com/
http://www.jsmini.com/
No you cant keep the #Html helpers in external javascript file. They are all server side syntax and will be rendered in your HTML page inline.
What maximum you can do is, assign it in a var variable in your page and refer it inside a external page.

In webpy, how can I assign a javascript value to a python variable?

I'm looking for a simple way to assign a value held by a javascript variable to a python variable in a webpy template. I have an int value held by a js variable that I want to use to get an element of a python array. For example (if I want $list[0] in a template):
<script>
...
foo = 0
$i = foo ??? (doesn't work...)
return $list[ foo ] ??? (doesn't work...)
...
</script>
Sorry if that isn't as clear as I hope it is. I've tried a ton of different ways to do this, and I can't seem to make it work. Thanks!!!
To expand on Pointy's answer, what you are asking for does not make sense because web pages code is run in a certain order, and you are trying to make it run backwards.
The webserver (python) gets a request. It uses templates to construct a response for that request, and returns and HTML page and sends it to the client. At this point, generally, the python code is done running.
The client (browser) gets the web page. It loads all the other resources it needs to display it, and then runs the javascript.
The javascript and python, therefore, are running on different computers at different times. The solution to your problem is probably going to be a little more complicated then you were hoping for: you have to make a server request from javascript to get the data from the server after the page is loaded on the client, and then manually add it to the DOM.

Accessing Django template {{Variable}} from JavaScript

I tried to access django template variable in html page inline javascript, it works fine.
But if I include js using <script src="..> then it dont work.
Is this limitation or I'm doing something wrong?
I really appreciate your help.
The included Javascript isn't processed by the Django template processor on the server, so that won't work. If you need to pass information through the template to included Javascript files, have your template create a small <script> block wherein some global variable is declared to contain those template variables. Then, your pure Javascript file can get the values by looking for the global object created by that <script> from the template.
Pointy's answer is correct. I often find this filter useful for that situation:
#register.filter(name='json')
def _json(obj):
#remember to make sure the contents are actually safe before you use this filter!
return safestring.mark_safe(json.dumps(obj))
then in a <script> tag I can just do something like this:
window.g_details = {{ details|json }};

Categories

Resources