Calling jQuery code in razor block of code - javascript

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

Related

Why isn't my TextBoxFor displaying currency values correctly?

I have the following TextBoxFor on an MVC form:
<div class="col-xs-3">
#Html.TextBoxFor(m => m.SalesSubTotal, null, new { #class = "form-control", title = "", #tabindex = "-1", #readonly = "readonly", #style = "text-align:right", Value = String.Format("{0:C2}", Model.SalesSubTotal) })
</div>
The user will never actually enter a value in this field. The field is always updated via a line in a JavaScript function that looks as follows:
$("#SalesSubTotal").val(salesSubTotal.toFixed(2));
When the page first displays the input displays $0.00 as I would expect. However, when the field is updated, the currency symbol is never displayed. So, instead of displaying something like $90.15, it displays 90.15.
Can someone see what I'm doing wrong?
Your number format {0:C2} isn't active anymore when javascript is invoked:
$("#SalesSubTotal").val(salesSubTotal.toFixed(2));
will actually just set the field to the value with two decimals just like you have experienced it. You have to add the dollar sign there aswell to get the correct result:
$("#SalesSubTotal").val("$" + salesSubTotal.toFixed(2));
The string format is being applied when the element is rendered for the first time with Value = String.Format("{0:C2}", Model.SalesSubTotal), but then you change the value without that format in JS.
You can create a helper function that formats the value and use it like so:
(function() {
function currencyFormat(val) {
return `$${val.toFixed(2)}`;
}
let salesSubTotal = 90.1525346252;
$("#SalesSubTotal").val(currencyFormat(salesSubTotal));
})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="SalesSubTotal">
Alternatively, you can extend the jQuery prototype with jQuery.fn.extend().
(function() {
$.fn.extend({
currencyVal: function(val) {
this.val(`$${val.toFixed(2)}`);
}
});
let salesSubTotal = 90.1525346252;
$("#SalesSubTotal").currencyVal(salesSubTotal);
})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="SalesSubTotal">

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);
});
});
});

Url.Action call Javascript Function

I have an Url Action Link that sends to my controller 1 paramater, but I need that paramater to call a javascript function to get document.getElementById and send that value to my controller. In my view I have the follwoing code:
#foreach (var item in ViewBag.PersonsContacts as List<Software___FPPD.Models.Contact>)
{
<tr>
<td>#Html.DisplayFor(model => item.ContactType.Name)</td>
<td>#Html.EditorFor(model => item.ContactValue, new { htmlAttributes = new { #class = "form-control", id = "contactValue"} })</td>
<td>
Alterar
</td>
</tr>
}
My javascript:
function getValue(contactValue) {
document.getElementById("contactValue").value = contactValue;
}
What I'm I doing wrong because I can not get this to work.
Url.Action is a method which gets executed in the server by razor and your javascript executes on the client side. So it is not that easy to mix both.
I am not sure what you are trying to do. In your question you mentioned you want to set value to some form field. But since you are going to be redirected to the new page, there is no point ! whatever value you set is gone (unless you are opening the new page in a new tab)
Anyway, What you can do is to listen for the click event of the anchor tag in your javascript and do whatever you want at the client side (ex: setting some form field value /executing a javascript function etc).
You have some problem in your view code, you are creating the same id value for each item in the loop in #Html.EditorFor(model => item.ContactValue .Duplicate id's are not valid. So avoid that.
<td>
#Html.EditorFor(model => item.ContactValue,
new { htmlAttributes = new { #class = "form-control myContactVal"} })
</td>
<td>
<a href="#Url.Action("SignUp", "Home")" data-contactvalue="#item.ContactValue"
class="btn btn-success myEdit"> Alterar</a>
</td>
I added 2 new css classes , myContactVal and myEdit to the form fields to help us do our jQuery selection. We are setting the item.ContactValue value in html5 data attribute to the anchor tag for accessing later in our javascript code.
And the javascript to handle the link click event
$(function () {
$("a.myEdit").click(function (e) {
e.preventDefault();
_this = $(this);
var contactVal = _this.data("contactvalue");
var url = _this.attr("href");
url = url + "?contactValue=" + contactVal;
alert(url);
//You can do any other thing here.
//If you want to update the field with myContactVal class in prev td
_this.closest("tr").find(".myContactVal").val(contactVal);
// finally do the redirect
window.location.href=url;
})
})

Calling an Action Method based on the value of DropDownList and the model

I have a dropdownlist in my View. I need to enable the user to select a value from the dropdownlist and click a button/ActionLink to call another action method in the same controller. The values that needs to be passed to the new ActionMethod are the ID of the selected Value from the dropdownlist and also the ID of the model which is being passed into the View. The model and the Dropdownlist are not linked together by any means.
I have tried onchnage = document.location.href to set the path of the action method and pass a single value to the action method. But the issue with document.location.href is that it appends the url to the existing url which is not appreciated; i.e, the final url turns out be localhost:port/controller1/action1/controller1/action2 which should have been simply localhost:port/controller1/action2
I am looking for a way where it could be done without using javascript as I have already tried it.
Code in the View
#using (Html.BeginForm("Copy","SetValues",FormMethod.Post))
{
<p>
#Html.DropDownList("OptionValueID", null, "Select")
<input type="submit" value="Copy" />
//This is the preferable method though
#*#Html.ActionLink("Copy", "Copy", "SetValues", new { #OptionValueID = #ViewBag.id,#CopyID = CopyDDL.SelectedValue},null)*#
</p>
}
The copy function is going to take two arguments: Id of the selected item and ID that is being passed through ViewBag.id
The View that is being returned by View would a different View
JavaScript that I have tried
<script language="javascript" type="text/javascript">
function copy(_OptionValueID)
{
var url = "/SetValues/Copy";
$.ajax({
url: url,
data: { copyid: _OptionValueID},
type: "POST",
success: function (data) { }
});
response();
}
</script>
It doesn't evaluate at all.
Action Method that calls this View
public ActionResult Index(int id)
{
var ov = db.OptionValue.Include(x => x.Option).FirstOrDefault(x => x.OptionValueID == id);
var opid = ov.OptionID;
var op = db.Option.Include(x => x.TechnicalCharacteristic).FirstOrDefault(x => x.OptionID == opid);
var tcid = op.TechnicalCharacteristicID;
var tc = db.TechnicalCharacteristic.Include(x => x.TcSets).FirstOrDefault(x => x.TechnicalCharacteristicID == tcid);
var tcset = tc.TcSets;
var opv = db.OptionValue.FirstOrDefault(x => x.OptionValueID == id);
ViewBag.OptionValue = opv.OptionVal;
ViewBag.Option = opv.Option.OptionName;
ViewBag.Lsystem = opv.Option.Lsystem.LsystemName;
ViewBag.FamilyName = opv.Option.Lsystem.LsystemFamily.FamilyName;
ViewBag.OptionValID = id;
ViewBag.OptionID = opv.OptionID;
var setValue = db.SetValue.Where(x=>x.OptionValueID==id).OrderBy(x=>x.TcSet.SetName);
ViewBag.OptionValueID = new SelectList(db.OptionValue.Where(x=>x.OptionID==opid), "OptionValueID", "OptionVal");
return View(setValue.ToList());
}
I ahve checked most question relating to this, but none had the overhead of passing two parameters without using a model.
UPDATE: making it more clear
public ActionResult copy(int OptionValueID,int CopyID)
{
//do Something
return View("Error");
}
Above is the Copy Method
OptionValueID = ViewBag.OptionValID //Got from the Action Method Index of SetValues
CopyID = Value from the DropDownlist
Edit Based on Answer
#using (Html.BeginForm("Copy","SetValues",FormMethod.Post))
{
<p>
#Html.DropDownList("CopyID", null, "Select")
<button type="submit" id="Copy" data-id="#ViewBag.OptionValID"> Copy </button>
</p>
}
now the page is being redirected but the no parameters are being passed. Should I be adding routevalues?
You cannot do it without javascript. Your ActionLink() method is parsed on the server before its sent to the client, so any route values are the initial values in the controller, not any edited values the user makes in the view. In order to respond to client side events you need javascript.
You can use ajax to post the values to the server method.
Include a button and handle its click event
<button type="button" id="Copy" data-id="#ViewBag.id">Copy</button>
Script
var url = '#Url.Action("Copy", "SetValues")';
$('#Copy").click(function() {
var optionID = $(this).data('id');
var copyID = $('#OptionValueID').val();
$.get(url, { OptionValueID: optionID, copyID : CopyID }, function(response) {
// do something with the response
});
});
or alternatively if you wanting to redirect, then replace the $.get() with
location.href = url + '?OptionValueID=' + optionID + '&CopyID=' + copyID;
Edit
Based on revised question and comments, if you wanting to post and redirect, there is no need for any javascript or the link. The dropdownlist needs to be #Html.DropDownList("CopyID", null, "Select") so that its selected value is bound to method parameter int CopyID and since the OptionValueID is not edited, then either add its value as a route parameter in the form
#using (Html.BeginForm("Copy", "SetValues", new { OptionValueID = ViewBag.OptionID }, FormMethod.Post))
or add a hidden input for the value
<input type="hidden" name="OptionValueID" value="#ViewBag.OptionID" />

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

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 #:

Categories

Resources