Populating Dynamic Fields in groovy GSP by using JavaScript - javascript

Hey Guys i am trying to populate dynamic fields in groovy GSP by using javascript and Groovy markup
*Here's the Effort 1 ->Works fine using plain html *
<r:script>
function createField()
{
var variable=0;
var d="<input type='text' name='item["+variable+"]' id='item["+variable+"]'/>";
reutrn d;
}
</r:script>
*Here's the Effort 2 ->JavaScript Error while using Groovy tags *
<r:script>
function createField()
{
var variable = 0;
var d = "<g:textField name='item["+variable+"]' id='item["+variable+"]' />";
return d;
}
</r:script>
By Using above function browser ends up with the error :javascript uncaught syntaxerror unexpected token illegal
So i decided to encode the tag using Grails InLine codec encodeAs="JavaScript".
*Here's the Effort 3 ->Error using Groovy tags *
y<r:script>
function createField()
{
var variable=0;
var d="<g:textField name='item["+variable+"]' id='item["+variable+"]' encodeAs="JavaScript"/>";
return d;
}
</r:script>
Problem with the third effort while encoding the tags, quotes besides the variable are also encoded so the output is something like u003b+variable+\u0026#39, this makes the nonidentical form fields which are unable to process further.
Any help will be appreciated.

GSP and javascript are evaluated at different times which is causing this not to work. GSP is executed server side then the result is sent back to the client the JS is executed client side. If you view source of the page from your browser you will see that the createField function has the g:textField already replaced.

Related

JavaScript (in jsp) receive String from Java

Good Morning:
I am having several problems trying to receive a String from Java to JSP (Javascript inside).
Java File
String var = "Hello World!";
JavaScript (inside the JSP):
window.onload = function() {
loadData();
};
function loadData() {
document.getElementById('paragraph').innerHTML = "<%=var%>";
alert(matr1); }
}
But I received org.apache.jasper.JasperException: Cannot compile the class.
The rest of JSP and JavaScript is correct, I am trying only to fill the select with the text received in Java, I read other topics but nothing works.
Any help?
Thanks.
The <%= %> or the expression tag is used in jsp as a replacement for out.print() function of java.
You don't need to put double quotes around it to use it in java script, in your case if you have imported the java file into your jsp correctly then i think this should work:
document.getElementById('paragraph').innerHTML = <%=var%>;
Or
try using the variable name directly,
document.getElementById('paragraph').innerHTML = var;

Accessing a local js variable in razor block

I am trying to write razor code inside javascript where I am trying to use a local variable inside the razor code. Here is the sample code:
<script type="text/javascript">
for (i = 0; i < data.result.length; i++) {
$("#member-table tbody").append("<tr>");
var id = data.result[i].MemberId;
var actions = $("<td>" + #Html.ActionLink("Detay", "Edit", new { id }) + "</td>)");
}
</script>
the problem is that id is not recognized by the razor code (i.e. it does not exist in the current context). How can I achieve that ? Is there any way ?
It's not possible to access a javascript variable in a razor block.
That's because razor is executed in the server, and javascript is executed in the browser.
However, by looking at your code it seems like you are using javascript to populate a table and that's bad, there are two patterns for solving this problem, one that solves everything in the server, and another one that solves everything in the browser.
Solving everything in the server:
If you decide that you want to solve everything in the server, your javascript should request the contents from the server and load them into a placeholder without changing them, something like:
$("#myButton").click(function(){
$("#myDinamicDiv").load("/Path/ToView");
});
and then you use razor's foreach loop to generate the table's html:
#foreach (var x in ViewBag.MyData)
{
<tr>
<td>Generate contents here, including links </td>
</tr>
}
Solving everything in the client:
As pointed out in another answer, if you are using the default routing, you can just create direct strings in the javascript code and add them to your page, keep in mind however, that when using this solution, as your page gets complex, your javascript will became less and less maintainable, having a for loop that iterates over data is a sign that maybe you can benefit from javascript UI frameworks like Angular.js and Knockout.js, in fact, what you are doing is the core of Knockout.js's third lesson in its tutorial (Single page applications)
If you're just using default routing, then simply just don't bother with the Razor #Html.ActionLink. Stick with an explicit tag:
var actions = $('<td>Detay</td>');
...obviously with whatever your current controller name is substituted for [your-controller-here].
(And I'm assuming your 'id' isn't necessarily URL-encoded, hence the 'escape'.)
You are mixing server side and client side here. You cannot create #Html.ActioLink using client side variables. Html.ActionLink is rendered on the server, it does not have any clue at all about your client side variables.
If you want to use a client side variable, like "id", render a plain html link (a) tag.
This worked for me once
if ('#ViewBag.DownloadLink' != '') {
window.location.href = '#ViewBag.DownloadLink';
}

Transferring javascript from a view to a seperate JS file

I am working on a legacy application and I want to move some JS code onto a separate JS file.
I will have to refractor some of the code to do this. I can put #Url.Content statements into data attributes in the HTML.
But how would I replace this line of code?
var array = #Html.Raw(Json.Encode(ViewBag.JobList));
A separate JS file will not know what #Html.Raw means.
Server side code like that cannot run in a seperate javascript file. My solution for such problems is having a short javascript part in the head that runs on the onload event. There you can set variables that you can use in a seperate javascript file:
in the head:
array = #Html.Raw(Json.Encode(ViewBag.JobList));
in the seperate javascript file:
var array;
Then, in the seperate javascript file you can do with your array whatever is necessary.
The ViewBag.JobList data is only known at HTML page generation time. To include it in an external JavaScript file, you have to have another ASP.NET resource that recalculated ViewBag.JobList and then served as part of a dynamic JavaScript file. This is pretty inefficient.
Instead, do what you're doing with the URLs: pass the data through the DOM. If you're writing into normal DOM instead of a script block, you don't need the raw-output any more (*), normal HTML escaping is fine:
<script
id="do_stuff_script" src="do_stuff.js"
data-array="#Json.Encode(ViewBag.JobList)"
></script>
...
var array = $('#do_stuff_script').data('array');
// jQuery hack - equivalent to JSON.parse($('#do_stuff_script').attr('data-array'));
(Actually, the raw-output might have been a security bug, depending on what JSON encoder you're using and whether it chooses to escape </script to \u003C/script. Writing to HTML, with well-understood HTML-encoding requirements, is a good idea as it avoids problems like this too.)
I think you need to create action with JavaScriptResult
public ActionResult Test()
{
string script = "var textboxvalue=$('#name').val();";
return JavaScript(script);
}
But, before proceeding please go through following links
Beware of ASP.NET MVC JavaScriptResult
Working example for JavaScriptResult in asp.net mvc
I would also follow MelanciaUK's suggestion :
In your javascript file, put your code inside a function :
function MyViewRefactored( array ){
... your code ...
}
In your view, leave a minimal javascript bloc :
<script>
var array = #Html.Raw(Json.Encode(ViewBag.JobList));
MyViewRefactored( array );
</script>

MVC4 sending an xml string and reading it in javascript make my js function undefined

I am trying to load a tree view, in MVC4 view, by sending an xml (not that big ~30 "screen size lines").
Actually I fill it in my controller as a simple text string. Which is ok.
I fill a variable in js by
function buildTree() {
debugger
var s_s = #ViewBag.xml;
tree.setImagePath("../../Scripts/dhtmlxTree/imgs/csh_bluebooks/");
tree.enableDragAndDrop(true);
tree.setSkin("dhx_skyblue");
}
This changes my '<', newlines ... to &dl, &dt etc...
But when debugging the string s_s looks ok otherwise.
The problem is that I get an undefined error in javascript on my main js function that calls the buildTree(), that would otherwise go away when I comment
// var s_s = #ViewBag.xml;
I did some adidtional troubleshooting - and the issue is not even at the js in the view, where youread viewbag.xml. Actually as soon as you assign it in the conroller the js error would appear. Although it is a simple formatted string with relatively modest size.
Help please, many thanks
OK - I think my problem is really related to newline and newspace being sent in a string.
I think you may just need to quote the XML:
var s_s = '#ViewBag.xml';

grails gsp javascript integration, how to escape variables?

I have a gsp page (template) where I need to include some javascript. In the example below, how would I get the remoteFunction to understand, the moneyTransId will be set by the javascript function? MoneyTransId comes out fine in the alert, but I can't get it to work in the remoteFunction, and apparently need to escape it somehow.
<script type="text/javascript">
function confirmVoid(moneyTransId) {
var r = confirm("Please confirm the void");
if (r == true) {
alert("ID is: " +moneyTransId);
${remoteFunction(action:"voidTransaction", id:moneyTransId)};
...
Use the following syntax:
${remoteFunction(action:'voidTransaction', params:'\'id=\'+moneyTransId')};
This way, you won't mix server-side code with client-side code.
Hope this helps.
Server side variables and statements can not read client side (javascript) variables.
Server side code runs first, then html and javascript get generated and sent to the client (browser). Then the browser renders HTML and runs javascript. Hope this helps your thought process.
Dmitry.

Categories

Resources