How to pass a value to razor variable from javascript variable? - javascript

How to pass a value to razor variable from javascript variable, is it possible asp.net mvc razor view engine?
#{
int a = 0;
}
<script>
var b = ...
#a = b;
</script>

You can't. and the reason is that they do not "live" in the same time.
The Razor variables are "Server side variables" and they don't exist anymore after the page was sent to the "Client side".
When the server get a request for a view, it creates the view with only HTML, CSS and Javascript code. No C# code is left, it's all get "translated" to the client side languages.
The Javascript code DOES exist when the view is still on the server, but it's meaningless and will be executed by the browser only (Client side again).
This is why you can use Razor variables to change the HTML and Javascript but not vice versa. Try to look at your page source code (CTRL+U in most browsers), there will be no sign of C# code there.
In short:
The server gets a request.
The server creates or "takes" the view, then computes and translates all the C# code that was embedded in the view to CSS, Javascript, and HTML.
The server returns the client side version of the view to the browser as a response to the request. (there is no C# at this point anymore)
the browser renders the page and executes all the Javascript

But it would be possible if one were used in place of the variable in #html.Hidden field.
As in this example.
#Html.Hidden("myVar", 0);
set the field per script:
<script>
function setMyValue(value) {
$('#myVar').val(value);
}
</script>
I hope I can at least offer no small Workaround.

Okay, so this question is old... but I wanted to do something similar and I found a solution that works for me. Maybe it might help someone else.
I have a List<QuestionType> that I fill a drop down with. I want to put that selection into the QuestionType property on the Question object that I'm creating in the form. I'm using Knockout.js for the select binding. This sets the self.QuestionType knockout observable property to a QuestionType object when the user selects one.
<select class="form-control form-control-sm"
data-bind="options: QuestionTypes, optionsText: 'QuestionTypeText', value: QuestionType, optionsCaption: 'Choose...'">
</select>
I have a hidden field that will hold this object:
#Html.Hidden("NewQuestion.QuestionTypeJson", Model.NewQuestion.QuestionTypeJson)
In the subscription for the observable, I set the hidden field to a JSON.stringify-ed version of the object.
self.QuestionType.subscribe(function(newValue) {
if (newValue !== null && newValue !== undefined) {
document.getElementById('NewQuestion_QuestionTypeJson').value = JSON.stringify(newValue);
}
});
In the Question object, I have a field called QuestionTypeJson that is filled when the user selects a question type. I use this field to get the QuestionType in the Question object like this:
public string QuestionTypeJson { get; set; }
private QuestionType _questionType = new QuestionType();
public QuestionType QuestionType
{
get => string.IsNullOrEmpty(QuestionTypeJson) ? _questionType : JsonConvert.DeserializeObject<QuestionType>(QuestionTypeJson);
set => _questionType = value;
}
So if the QuestionTypeJson field contains something, it will deserialize that and use it for QuestionType, otherwise it'll just use what is in the backing field.
I have essentially 'passed' a JavaScript object to my model without using Razor or an Ajax call. You can probably do something similar to this without using Knockout.js, but that's what I'm using so...

I see that this problem was discussed some time ago, but if anyone 'll meet with this again, here is my solution:
In your *.cshtml View file:
<script>
var data = JsFunction("#Html.Raw(Model.Path)");
$(function () {
$("#btn").click(function () {
var model = { Id: '#Html.Raw(Model.Id)', Data: data }
$.ajax({
type: "POST",
url: "/Controller/Action",
data: model,
datatype: "html",
success: function() {
console.log('Success');
}
});
});
});
</script>
JavaScript variable model is something that I need to pass to Razor ViewModel.
It can be done with ajax request.
You just need to have proper argument/s in your action, that matches Json object created in JavaScript.
Hope it'll help someone!

Step: 1 Your Html,
First Store the value in your localstorage using javascript then add the line like below ,this is where you going to display the value in your html, my example is based on boostrap :
<label for="stringName" class="cols-sm-2 control-
label">#Html.Hidden("stringName", "")</label>
Step:2 Javascript
$('#stringName').replaceWith(localStorage.getItem("itemName"));

here is my solution that works:
in my form i use:
#using (Html.BeginForm("RegisterOrder", "Account", FormMethod.Post, new { #class = "form", role = "form" }))
{
#Html.TextBoxFor(m => m.Email, new { #class = "form-control" })
#Html.HiddenFor(m => m.quantity, new { id = "quantity", Value = 0 })
}
in my file.js I get the quantity from a GET request and pass the variable as follows to the form:
$http({
method: 'Get',
url: "https://xxxxxxx.azurewebsites.net/api/quantity/" + usr
})
.success(function (data){
setQuantity(data.number);
function setQuantity(number) {
$('#quantity').val(number);
}
});

Yes You Can
Asp.net MVC razor
I have 2 Input
<input id="TXTCount" type="number" readonly="readonly" class="form-control text-center text-bold" step="1" min="0" max="10000" value="1" inputmode="numeric" />
<input id="TXTTOTal" type="number" readonly="readonly" class="form-control text-center text-bold" step="1" min="0" max="10000" value="1" inputmode="numeric" />
C# In view
#{string WatsMSG = "xxx";}
And WhatsApp Link
<a class="btn btn-success" id="WatsSendApi" href="https://api.whatsapp.com/send?phone=0000&text=#WatsMSG">
<b class="text-black" style="font-size:small"> whatsapp </b><i class="fa fa-whatsapp" style="color:white"></i> </a>
And In jQuery
<script>
$("#WatsSendApi").click(function () {
var StringMSG;
StringMSG=("Ineed : ");
StringMSG += (" Item Name : ");
StringMSG +='#item.ITName' ;
StringMSG += (" Count: ");
StringMSG += $('#TXTCount').val();
StringMSG += (" Price: ");
StringMSG += '#item.ITPrice';
StringMSG += (" Total: ");
StringMSG += $('#TXTTOTal').val();
alert(StringMSG);
this.href = this.href.replace("xxx", StringMSG);
});
</script>
I am passing script value And Model value to C# string

Razor View Server Side variable can be read to Client Side JavaScript using #
While
and JavaScript client side variable can read to Razor View using #:

Related

Can you pass a database Id into a Javascript function and get back a parameter corresponding to that Id in Asp,NET Core

I am using Visual Studio 2022, .Net 6, ASP.Net Core and SQL Server.
I am very new to all of this and I'm not sure if what I am trying to do is possible.
I have two buttons that invoke a javascript function and pass a number:
<div id=sidebar>
<input type="button" class="button" onclick="DisplayData('1')" value="World1"><br>
<input type="button" class="button" onclick="DisplayData('2')" value="World2">
</div>
I want the function to treat this number as an Id of an item from a connected database. Then I want to display the Name property of that database item in a div.
<script>
function DisplayData(id){
document.getElementById('name').innerHTML = //What do I put here;
}
</script>
<div id=main>
<p id="name"></p>
</div>
Is there something I can do in javascript or am I on a completely wrong track?
I think you are missing the step to read the entity from your DB. Your front-end JS code should send an AJAX call to your .net core backend to fetch that entity from the DB with seletec ID. And then you can display whatever property from the returned data.
You can use ajax to pass id to action,and action return related name.Then change innerHtml with the related name in js.Here is a demo:
js:
function DisplayData(id) {
$.ajax({
url: "GetName",
data: { id:id},
type: "POST",
success: function (name) {
document.getElementById('name').innerHTML = name;
}
})
}
action:
public JsonResult GetName(int id)
{
string name = //get name from database with the id
return new JsonResult(name);
}

Django: can't trigger AJAX call and send values back to my form

I need to run an AJAX call to perform a quick calculation in my django view and return the result in my html page, inside a tag.
I'm very new to Javascript so I don't understand why my AJAX call hasn't been triggered. This is my html and JS code:
<input type="text" name="SHm2" maxlength="10" type="number" value="50">
<input type="text" name="STm2" maxlength="10" type="number" value="50">
<button id="estimation" name= "estimation" onclick="calculate()">Estimation</button>
<span>{{estimation}}</span>
<script type="text/javascript">
function calculate () {
$.ajax({
url: '/myApp/templates/homepage/',
type: 'POST',
data: {
SHm2: $('#SHm2').val(),
STm2: $('#STm2').val()
},
success: function(estimation) {
alert(estimation);
document.getElementById("estimation").innerHTML = estimation;
}
});
}
</script>
And this is my views.py:
def homepage(request):
if request.method == 'POST' and request.is_ajax and 'estimation' in request.POST:
SHm2 = request.POST.get('SHm2')
STm2 = request.POST.get('STm2')
estimation = float(SHm2) + float(STm2)
estimation = json.dumps(estimation)
return HttpResponse(estimation, content_type='application/json')
The problem is that the AJAX code isn't triggered since I don't receive the alert. Nevertheless, the code in my django view is running anyway (which is strange, since I specified to run if 'request.is_ajax', which doesn't seem to be recognized on the other hand). It loads a new page where it correctly displays the result. But it's not what I want since I need the result to be in my form within the span tag where {{estimation}} is my variable.
Could you please tell me what I'm doing wrong? Thanks!
UPDATE:
Thanks to your answers, it's getting better. I've replaced in views.py 'request.is_ajax' by 'request.is_ajax()'. I've added the 'id' attribute to my input boxes. This helped me to trigger the AJAX call and not to load stuff in a new page. There is one last thing though. I'm still not able to display in my span tag the value of the estimation variable. I realised that it had no 'id' attribute so I did the following change:
<span id="estimation2">{{estimation}}</span>
Also in my JS code, I replaced in the success part the last line to:
document.getElementById("estimation2").innerHTML = estimation;
Basically I replaced "estimation" by "estimation2".
Unfortunately the span tag is not updated. Any idea what I am missing?
Change name to id. because #means id of the field. Like from name="SHm2" to id="SHm2"
<input type="text" id="SHm2" maxlength="10" type="number" value="50">
<input type="text" id="STm2" maxlength="10" type="number" value="50">
<button id="estimation" name= "estimation" onclick="calculate()">Estimation</button>
<span>{{estimation}}</span>
<script type="text/javascript">
function calculate () {
$.ajax({
url: '/myApp/templates/homepage/',
type: 'POST',
data: {
SHm2: $('#SHm2').val(),
STm2: $('#STm2').val()
},
success: function(estimation) {
alert(estimation);
document.getElementById("estimation").innerHTML = estimation;
}
});
}
</script>
1st
request.is_ajax is a function
2nd
'estimation' in request.POST
You have it in your statement but you did not pass it to view. Add it to data or remove from statement
It seemed that the issue came from the fact that I didn't declare the type of my button in my html code. The default value (i.e. "submit") prevented it from triggering my AJAX code as needed. So in the end I had to set it to 'type="button"' to make it work.

Calling jQuery code in razor block of code

I have a problem where I need to call jQuery code to fetch a value from an HTML element like following:
#using (Html.BeginForm("Login", "Home",new { Checked = $('#checkbox5').checked }, FormMethod.Post,new { #class = "form-horizontal", role = "form" }))
{
#Html.AntiForgeryToken()
}
Note that besides passing the entire model into my Login action I'm trying to pass an optional parameter named "Checked". This parameter basically states whether the "remember me" checkbox has been checked on the form or not.
The checkbox itself is not the one that .NET uses by default like:
#Html.CheckboxFor(somepropertyhere);
But instead a regular checkbox like this:
<input id="checkbox5" type="checkbox">
<label for="checkbox5">
Remember me?
</label>
How can I fetch this checkbox's value when passing it as an extra parameter besides my model?
So that my method in the end would look like:
Public ActionResult Login(bool Checked, LoginViewModel model)
{
// To have the checked value here now...
}
P.S. And I can't use Html.CheckboxFor for some reasons, but I don't wanna get too much into details since the question wouldn't make sense then (maybe it doensn't even now I'm not sure if this is doable what I'm trying to achieve).
Can someone help me out?
You can get checkbox value in Controller using Checkbox Field name like this :
bool isRememberMe=Request.Form["CheckBoxName"];
if you want to send any variable, you should set name for field, and on serverside you can call it with name
<input id="checkbox5" type="checkbox" **name="checkbox_name"** value="true">
<label for="checkbox5">
Remember me?
</label>
on server side
Public ActionResult Login(bool checkbox_name = false, LoginViewModel model){
// To have the checked value here now...
}
You can't use JavaScript within a Razor block, because they run at entirely different times. The Razor code runs server-side, long before the response is ever sent to the client. JavaScript runs client-side, only after the server has sent its response to the client, and Razor has already done its work.
On first load, the value of your checkbox will always be the default, which in your case is false. That's why none of the other answers help you. The user would have to interact with the checkbox and submit the form first, and then the checkbox would have that user-set value within the post action that handles the form. If you returned to the form, because of an error, then you could utilize the checkbox value.
To actually alter the form action without posting first, you'd have to handle the click event of the checkbox and manually change it via JavaScript. However, that's extremely brittle. If you want the value of the checkbox on post, then just bind it to something your action accepts. For example:
#Html.CheckBox("checked", Request["checked"] as bool? ?? false)
Then:
[HttpPost]
public ActionResult MyPostAction(MyClass model, bool checked)
I really don't understand why you don't want to use a new property model for the RememberMe value, but I think this might work for you:
Assuming your View looks like this:
#using (Html.BeginForm("Login", "Home", FormMethod.Post, new { #class = "form-horizontal", role = "form", id = "login-form" }))
{
#Html.AntiForgeryToken()
<div class="form-group">
#Html.LabelFor(x => x.Username, new { #class = "form-control" })
#Html.TextBoxFor(x => x.Username, new { #class = "form-control" })
</div>
<div class="form-group">
#Html.LabelFor(x => x.Password, new { #class = "form-control" })
#Html.PasswordFor(x => x.Password, new { #class = "form-control" })
</div>
<div class="form-group">
<input id="checkbox5" type="checkbox">
<label for="checkbox5">Remember me?</label>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Login</button>
</div>
}
And assuming your Controller looks like this:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginViewModel model, bool rememberMe)
{
// Do something with 'rememberMe'
// Do something with 'model'
return RedirectToAction("Index");
}
Then you must need a Javascript like this in your login view to replace the form action before the submit event was completed:
$(function () {
var form = $("#login-form");
var checkbox5 = $("#checkbox5");
form.submit(function () {
var checked = checkbox5.is(":checked") ? "true" : "false";
var action = updateQueryStringParameter(form.action || '', "rememberme", checked);
form.attr('action', action);
});
// stolen from http://stackoverflow.com/a/6021027/1605778
function updateQueryStringParameter(uri, key, value) {
var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
var separator = uri.indexOf('?') !== -1 ? "&" : "?";
if (uri.match(re)) {
return uri.replace(re, '$1' + key + "=" + value + '$2');
}
else {
return uri + separator + key + "=" + value;
}
}
});
Let me know if this works for you.
Just to give more context: when you have a parameter of a primitive type (like bool or int) in your action, MVC expects this parameter in the Url; but the values of the Complex Types (like LoginViewModel) should pass as a Request Body in the HTTP POST. So if you want to pass both (complex and primitive) you need to be careful to pass all primitive types in the url and the values of complex types in the request body.
The POST of the Login Form could looks like:
POST /Home/Login?rememberMe=false
username=admin&password=secret

MVC Ajax.BeginForm JavaScript parameters

I have an AJAX form where the url id needs to be from JavaScript
#using(Ajax.BeginForm("Add","Comments", new { ArticleID = 3 }, new AjaxOptions { UpdateTargetId="Comments"}))
Where ArticleID = 3 should be replaced so that the ArticleID value is set equal to the result of a called Javascript function. Something like
JS:
function GetArticleID()
{
return 3;
}
Razor:
#using(Ajax.BeginForm("Add","Comments", new { ArticleID = GetArticleID() }, new AjaxOptions { UpdateTargetId="Comments"}))
Controller:
public ActionResult Add(int ArticleID, Comment model)
{
}
How can I use JavaScript function result as BeginForm parameter?
The line #using(Ajax.BeginForm(" will be executed by razor on server. At that time it does not have any knowledge of the javascript methods in your client browser. So you cannot mix a javascript function there.
I prefer to write clean custom code to do the ajax form submit (instead of using Ajax.BeginForm) because it allows me to customize any way i want.
Keep your form as a normal form.
#using(Html.BeginForm("Add","Comments"))
{
<input type="hidden" name="ArticleId" id="ArticleId" value=""/>
<input name="CommentText" type="text" />
<input type="submit" id="saveCmntBtn" />
}
Now listen to the click event of the submit button. Assign the ArticleId value to the input field, get the serialized version of the form and post to server. You may use jQuery serialize() method to get the serialized version of your form.
$(function(){
$("#saveCmntBtn").click(function(e){
e.preventDefault();
$("#ArticleId").val(GetArticleID());
var f=$(this).closest("form");
$.post(f.attr("action"),f.serialize(),function(res){
$("#Comments").append(res);
});
});
});

How to render HTML with jQuery from an AJAX call

I have a select box with a list of books. The user can select a book and hit the submit button to view the chapters on a separate page.
However, when the user changes the select box, I would like a partial page refresh to display the past notes the user entered on the book, and allow the user to write a new note for that book. I do not want the review and creation of notes for a particular book done on the next page with the chapters, as it will clutter it up.
I'm using Python/Bottle on the backend and its SimpleTemplate engine for the front end.
Currently, when the select box is changed, an ajax call receives a Json string containing the book information and all the notes. This json string is then converted into a json object via jQuery.parseJson().
What I would like to be able to do is then loop over the notes and render a table with several cells and rows.
Would I have to do this in jQuery/js (instead of bottle/template framework) ? I assume so as I only want a partial refresh, not a full one.
I'm looking for a piece of code which can render a table with variable numbers of rows via jQuery/js from a json object that was retrieved with ajax.
<head>
<title>Book Notes Application - Subjects</title>
<script src="http://code.jquery.com/jquery-latest.min.js"
type="text/javascript"></script>
<script>
$(document).ready(function(){
$('#subject_id').change(function(){
var subject_id = $(this).val();
$.ajax({
url : "subject_ajax?subject_id=" + subject_id,
success : function(data) {
alert(data)
json = jQuery.parseJSON(data);
},
error : function() {
alert("Error");
}
});
})
})
</script>
</head>
<body>
<!-- CHOOSE SUBJECT -->
<FORM action="/books" id="choose_subject" name="choose_subject" method="POST">
Choose a Subject:
<select name="subject_id" id="subject_id">
% for subject in subjects:
<option value="{{subject.id}}">{{subject.name}}</option>
% end
</select><input type="submit" name="sub" value="Choose Subject"/>
<BR />
</FORM>
This greatly depends on how your JSON and HTML are formatted. But with a table somewhere like:
<table id="books">
<tr>
<th>Chapter</th>
<th>Summary</th>
</tr>
</table>
You could do something like:
$(function(){
$('#choose_subject').submit(function () {
var subject_id = $(this).val();
$.getJSON("subject_ajax?subject_id=" + subject_id, function(data) {
console.log(data);
$.each(data.chapters, function (index, chapter) {
$('#books').append('<tr><td>' + chapter.title + '</td><td>' + chapter.summary + '</td></tr>');
})
});
return false;
})
})
This supposes JSON like:
{
"notes": [
"Note 1",
"Note 2"
],
"chapters": [
{
"title": "First chapter",
"summary": "Some content"
},
{
"title": "Second chapter",
"summary": "More content"
}
]
}
Other notes:
If you use HTML 4 or earlier, keep all your tags in upper case. If you're using XHTML or HTML5, keep all your tags in lower case.
You don't need $(document).ready(function () {...}), with recent versions of jQuery $(function () {...} ) works the same and it's easier to read.
You can use $.get instead of $.json if you're only using the success state (as you are here). And if you're confident that the data you'll get is valid JSON, you can use getJSON instead of get. It will parse the JSON for you deliver it to you as a JavaScript object automatically.
It's usually more convenient to use console.log rather than alert when you're testing. Actually, it's usually a bad idea in general to ever use alert.
I'm not familiar with Python/Bottle or its SimpleTemplate engine, but you could consider generating the html for the table on the server side and returning it in the ajax response, rather than returning JSON.
var subject_id = $(this).val();
$.ajax('subject_ajax', {
type: 'get',
data: { subject_id: subject_id },
dataType: 'html',
success : function(html) {
// Insert the html into the page here using ".html(html)"
// or a similar method.
},
error: function() {
alert("Error");
}
});
When calling .ajax():
The "type" setting defaults to "get", but I prefer to explicitly set it.
Use the "data" setting for the ajax call to specify the URL parameter.
Always specify the "dataType" setting.
I also recommend you perform the ajax call in an on-submit handler for the form, and add an on-change handler for the select that submits the form.
$(document).ready(function(){
$('#subject_id').change(function() {
$(this.form).submit();
});
$('#choose_subject').submit(function(event) {
event.preventDefault();
var subject_id = $('#subject_id').val();
if (subject_id) {
$.ajax(...);
}
});
});
This way your submit button should work in case it is clicked.
There are a few things you need to look at:
1) Is your SimpleTemplate library included?
2) Have you compiled your template via compileTemplate()?
Once you know your library is included (check console for errors), pass your data returned to your success handler method, compile your template, that update whichever element you are trying to update.
I'm not sure that you want to update the same element that you're defining your template in.
$(document).ready(function(){
$('#subject_id').change(function(){
var subject_id = $(this).val();
$.ajax({
url : "subject_ajax?subject_id=" + subject_id,
success : function(data) {
var template_data = JSON.parse(data);
var template = $('#subject_id').toString(); // reference to your template
var precompiledTemplate = compileTemplate(template);
var result = precompiledTemplate(template_data);
$('#subject_id').append(result);
},
error : function() {
alert("Error");
}
});
})
})
You might also try moving your template out of the element you're trying to update like this:
<script type="text/template" id="subject-select-template">
% for subject in subjects:
<option value="{{subject.id}}">{{subject.name}}</option>
% end
</script>
Then just create a blank select element like so:
<select id="select_id"></select>
Update references. Anyway, hope this is helpful. It should work but I can't test without your specific code ;)
Also, check out this demo example if you haven't yet:
https://rawgithub.com/snoguchi/simple-template.js/master/test/test.html

Categories

Resources