How to use Model data inside javascript code? - javascript

In my View (asp.net) code, I am simply displaying a bunch of checkboxes. Whenever one of them is clicked, the following java script code is called (which I found in another stackoverflow question):
var RatingClicked = function (rate) {
//some initial work goes here
$.ajax({
url: '#Url.Action("SetRate","Home")',
data: { SelectedRate: rate},
success: function (data) {
//call is successfully completed and we got result in data
},
error: function (xhr, ajaxOptions, thrownError) {
//some errror, some show err msg to user and log the error
alert(xhr.responseText);
}
});
}
So far so good. The code works as expected and my SetRate action method gets called passing the right data (i.e. rate, which is the value of the check box). The problem is that I need to pass some other data in addition to "rate" which are my view's model info. However, as soon as I change the line of code to the following, javascript seems to stop working altogether:
data: { SelectedRate: rate, SomeOtherData:#Model.MyData},
I understand that javascript runs on the client-side vs razor's server side run. But what would be the workaround? How can I call my SetRate action method passing the correct values?
Edit: here is all I have inside my view (aside from a couple of other javascript functions)
#using Impoware.Models
#model HomeViewModel
<input type="checkbox" value="1" id="Rating1" onclick="RatingClicked(1)" onmouseover="MouseOverRating(1)" onmouseout="MouseOutRating(1)" />
<input type="checkbox" value="2" id="Rating2" onclick="RatingClicked(2)" onmouseover="MouseOverRating(2)" onmouseout="MouseOutRating(2)" />
<input type="checkbox" value="3" id="Rating3" onclick="RatingClicked(3)" onmouseover="MouseOverRating(3)" onmouseout="MouseOutRating(3)" />
<input type="checkbox" value="4" id="Rating4" onclick="RatingClicked(4)" onmouseover="MouseOverRating(4)" onmouseout="MouseOutRating(4)" />
<input type="checkbox" value="5" id="Rating5" onclick="RatingClicked(5)" onmouseover="MouseOverRating(5)" onmouseout="MouseOutRating(5)" />
Edit 2: I changed the code as Shyju suggests below and it worked for the primary data types (int, bool, etc.) However, when I tried to pass in my whole data Model, I got the following error:
An exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll but was not handled in user code
Additional information: Self referencing loop detected with type 'System.Data.Entity.DynamicProxies.UserParticipation_D381F3E084EC9A0B56FA60725061B956AEF865280516092D8BDE683C9A32725B'. Path 'userParticipation.AspNetUser.UserParticipations'.
UserParticipation is a class that has a foreign key connecting to AspNetUser (many to 1 relationship). The model was created using EntityFramework. Why would there be a loop back to UserParticipation? Oh and lastly, I am passing back the whole Model data in order to save some trips to the database again to re-retrieve the same data for the trip back to the same View (if that makes any sense).

You can use JsonConvert.SerializeObject method to get a serialized string version of your C# Model/Model property.
This should work.
var myData = { SelectedRate: rate,
SomeOtherData: #Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model.MyData)) };
console.log(myData);
//Use myData variable for the ajax call now.
Also, since it is a complex js object, you should stringify this js object and send that in your ajax call. Make sure you are explicitly specifying "application/json" as the contentType so that model binding will not fail. You may also consider doing a HttpPost ajax call as GET use querystring to send data and querystring has limitations on how much data you can send(varies in browsers)
$.ajax({
url: '#Url.Action("SetRate","Home")',
type:'POST',
data: JSON.stringify(myData),
contentType : "application/json",
success: function (data) {
//call is successfully completed and we got result in data
},
error: function (xhr, ajaxOptions, thrownError) {
//some errror, some show err msg to user and log the error
alert(xhr.responseText);
}
});
While this answers your question, You should double check why you want to send the entire data back ? May be send a unique Id from which your server method will be able to reconstruct the model/specific data as needed

Did you want something a bit more dynamic like this?
<% foreach( var item in Model.Items ) { %>
<input type="checkbox" value="#item.value" onclick="RatingClicked(#item.value,#item.value2) />
<% } %>
var RatingClicked = function (rate,otherValue) {
......

Related

Exchange data between HTML page and Java servlet without page refreshing

I would like to create a simple login form with HTML and Java (and maybe JSON). So, I have a login form with several input fields with the following id-s: txtUsername, txtPasswd, btnLogin.
After click on the button (btnLogin) I would like to send data to the servlet, and get back just a true/false value deepends on the user-passwd combination.
I can write the HTML code of this form, and the server side code, but I don't know, how can I send and recive data without page refreshing.
Here is my frontend code:
<script>
function login(){
var user=document.getElementById("txtUsername");
var passwd=document.getElementById("txtPasswd");
//???
}
</script>
Username: <input type="text" id="txtUsername"/> <br/>
Password: <input type="password" id="txtPasswd"/> <br/>
<input type="button" value="Login" id="btnLogin" onclick="login()"/>
You have to use an AJAX request. One way of doing it is to wire up and event handler on a your login button (like onclick), which calls a JS function to use an Ajax request (XmlHttpRequest), just like you have started.
You can do it in vanilla Javascript, but it is easier to use a library like jQuery. The code would look something like this (with jQuery, note the '$'):
function login() {
$.ajax({
type: 'POST',
url: url, //Url of login endpoint
data: DATA, //Now here you would want to send a payload i.e. your username and password data
dataType: 'json',
contentType: 'application/.json',
success: function(data) {
//HERE 'data' would represent your true or false that came back from the server.
//You can do stuff here with the response
},
error: function(jqXHR, textStatus, errorThrown) {
//IF ERROR then this code would be executed.
}
});
}
Hope this gives you a starting point!
You must use jquery AJAX.
Here is a link to the official documentation: http://api.jquery.com/jquery.ajax/
Hope it helps.

Grails javascript call controller method

In a grails view I need to call a javascript method to get some info and so I have a submit action like this:
<input type="submit" name="submit" class="submit action-button" value="Generar" onclick="generateReport()" style="float: right" />
and at the end of the generateReport() I need to call/redirect to the show action of a Controller (because I'm at the create action already)
I'have tried with
1) var jSon = generateJSON();
<g:remoteFunction controller="report" action="show" params="[data:jSon]" />
2) var jSon = generateJSON();
<g:remoteFunction controller="report" action="show" params="[data:${jSon}]" />
1) data reaches null
2) compile error:
org.codehaus.groovy.grails.web.taglib.exceptions.GrailsTagException
Message
Attribute value quote wasn't closed (controller="report" action="show" params="[data:${jSon}]").
you can try this..
declare a variable in your gsp like this..
<script type="text/javascript">
var yourVariable = "${createLink(url: [controller: 'yourController', action: 'yourAction'])}";
</script>
then in your js file..you can use ajax.
example ajax
function checkUsernameAvailable(user, example){
$.ajax(
{
url: yourVariable, <- this variable take from your gsp
contentType:"text/json",
type: "get",
data: ({ id: usernamenya}),
dataType: "json",
cache: false,
async: false,
success: function(data) {
//do something here
},
error: function(xhr) {
}
});
}
var json cannot be assigned to data as params in , as var jSon is a javascript variable. Data in params attribute requires model parameter coming from controller.
In 1st option when it is assigned as params as it is not a model parameter from controller its showing null.
2nd option would not work as this is not the way to define model parameter from controller so giving compile error.
So you should better try getting jSon as model from controller and then define as params.
Or you can follow this link to define g:remoteFunction in onclick itself
http://grails.github.io/grails-doc/2.2.1/ref/Tags/remoteFunction.html
Hope this helps! Thanks.
The remoteFunction tag won't work for your situation because it's rendered into html and JavaScript (server side) before the value of jSon is known (client side).
You'll have to do the ajax call on your own (ex. Jquery).

form.serialize() doesn't send all values in the Ajax $.post()

I'm getting all the values from a form using serialize() and send them through a Ajax call using $.post() as follow:
$('button#btnBuscar').on('click', function (ev) {
ev.preventDefault();
$.post('someRoute', $('#buscadorNorma').serialize(), 'json')
.done(function (data, textStatus, jqXHR) {
console.log(data.entities);
})
.fail();
});
After click the submit button I check the POST data (in Firebug) send ​​to the route and I notice that only the last parameter was taken in this case comite_tecnico but what about the rest of them? Even if have values isn't send at all, why? I leave a fiddle for testing purpose, can I get some help?
This is a image showing the results:
Note: for check the POST data use Firebug or any other tool!
Add name attributes to your input elements like this:
<input type="text" id="codigo_norma" name="codigo_norma" class="form-control">

How to use a JavaScript variable in erb code in Rails?

I have a JavaScript variable:
var selectValUser = $('.select_user :selected').val();
I need to use this variable in erb code on the same page, i.e
<%= get_free_hours_for_user(selectValUser) %>
How can I do it?
You cannot do it because javascript run on client side while the code in ERB file runs at server side, you can send the value using ajax request,
Plus here is an awsome rails cast
Here is an example to send message from javascript to controller; When user click on apply we have an action 'set_id' in controller, it get the power, do the validations etc, the show the message in 'id_message' div in views.
$('#apply').live('click', function(event, data, status, xhr) {
event.preventDefault();
return $.ajax({
url: '/users/registrations/set_id',
type: 'GET',
data: {
code: $('#user_id').val()
},
success: function(data, event, status, xhr) {
$('#id_message').html(response);
return $("#id_message").show();
},
error: function(event, data, status, xhr) {
$('#id_message').html(response);
return $("#id_message").show();
}
});
});
Hope it would answer your question
There is no way to do it directly. Reason is, html runs in your server side whereas javascript runs in your local browser.
Additional discussion can be found here.
How to pass a javascript variable into a erb code in a js view?
And regarding different way to try it out, you can start with this.
http://jing.io/t/pass-javascript-variables-to-rails-controller.html
and
http://www.ruby-forum.com/topic/3818171

getJSON fails, JSON validates

I have a getJSON call which is inexplicably failing. The idea is, you click to submit a comment, a URL gets hit which determines if the comment is OK or has naughty words in it. The response is given in JSON form.
Here's the paired down JS that generates the call. The comment and the URL are already on the page, it grabs them and hits the URL:
FORM HTML:
<fieldset id="mg_comment_fieldset" class="inlineLabels">
<div class="ctrlHolder">
<textarea id="id_comment" rows="10" cols="40" name="comment"></textarea>
</div>
<div class="form_block">
<input type="hidden" name="next" value="" />
<input id="mg_comment_url" type="hidden" name="comment_url" value="" />
<input id="mg_comment_submit" type="submit" value="Remark" />
</div>
</fieldset>
SPECIFIC JS BLOCK THAT SENDS/READS RESPONSE:
$('input#mg_comment_submit').click(function(){
var comment = $("textarea#id_comment").val();
var comment_url = $('input#mg_comment_url').val();
$.getJSON(
comment_url+"?callback=?&comment="+comment+"&next=",
function(data){
console.log(data);
alert(data);
});
});
The JSON response:
[{"errors": {"comment": ["Weve detected that your submission contains words which violate our Terms and Conditions. Please remove them and resubmit test"]}}]
It's being returned as a mimetype of application/json. It validates in JSONLint. I also tried adding a couple AJAX functions to try to catch errors, and they're both silent. I can see the request going out in Firebug, and coming back as status 200 responses, which validate in JSONLint and which I can traverse just fine in the JSON tab of the response. If I put an alert before the getJSON, it runs; it's just that nothing inside of it runs. I also find that if I change .getJSON to .get, the alerts do run, suggesting it's something with the JSON. I'm out of ideas as to what the problem could be. Using Firefox 3.0.13.
The querystring parameter "callback=?" comes into play if you are using cross-site scripting or jsonp, if you are posting the same server, you don't need to use that.
If you need or want to use that option, the server side code needs to come back with the callback function included in the json response.
Example:
$jsonData = getDataAsJson($_GET['symbol']);
echo $_GET['callback'] . '(' . $jsonData . ');';
// prints: jsonp1232617941775({"symbol" : "IBM", "price" : "91.42"});
So either make a server side change if necessary or simple remove the "callback=?" parameter from the url.
Here's more info on jsonp
Are you able to manually call your service without any errors? Have you tried using firebug and looked under XBR to see the post/response of the JSON payloads? I normally use .NET as my endpoints, and with .NET 3.5 I need to use content type "application/json; charset=utf-8".
Here is an example of a working JSON call I use in .NET with jQuery 1.3.2
$.ajax({
type: "POST",
url: "WebService1.ASMX/HelloWorld",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: "{}",
success: function(res) {
// Do your work here.
// Remember, the results for a ASMX Web Service are wrapped
// within the object "d" by default. e.g. {"d" : "Hello World"}
}
});
Have you tried it with $.ajax? You can then define both error and success callbacks and have better idea.
Can you try adding a global ajaxError function to log the error.
$.ajaxError( function(event, XMLHttpRequest, ajaxOptions, thrownError){
console.log( thrownError );
});

Categories

Resources