Submitting a form to ASP.NET MVC from Knockout does not bring in all the values - asp.net-mvc

Here is what I have in my view in ASP.NET MVC 5
#model Entities.Coupon
#using (Html.BeginForm("coupon", "marketing", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="scsm-18 scmd-16 sclg-14">
<div class="form-group">
<label>Codes</label>
#Html.TextBoxFor(p => p.Code, new { #class = "form-control", #data_bind = "value: Code", #autofocus = true, #maxlength = "50" })
</div>
<input type="radio" name="IsPerCentOrDollar" value="1" data-bind="checked: IsPerCentOrDollar" />
<span>PercentageAmount</span>
<input type="radio" name="IsPerCentOrDollar" value="2" data-bind="checked: IsPerCentOrDollar" />
<span>DollarAmount</span>
<input type="radio" name="IsPerCentOrDollar" value="3" data-bind="checked: IsPerCentOrDollar" />
<span>FreeShipping</span>
</div>
<div class="panel-footer text-right">
<input type="submit" name="commandType" id="btnSave" class="btn btn-primary" data-bind="click:submit" value="Save" />
</div>
}
In the script:
$(document).ready(function () {
var viewModel = new CouponViewModel(couponModel);
ko.applyBindings(viewModel);
function CouponViewModel(data) {
self.Code = ko.observable(data.Code);
self.IsPerCentOrDollar = ko.observable("1");
self.DiscountLevel = ko.computed(function () {
return self.IsPerCentOrDollar();
});
};
}
Code in MVC:
[HttpPost, ActionName("coupon")]
public ActionResult coupon(Coupon coupon)
{
try
{
// some logic not yet in
}
catch (Exception ex)
{
}
return View();
}
That's all I have in there now.
In Developer tools inside the browser I can see values for self.DiscountLevel change on the selection of radio buttons.
On Submit, at MVC front the value of Code comes in but the values for DiscountLevel are not.
Any help is greatly appreciated.
Regards.

Let me expand on #StephenMuecke's comment (which has the gist of it I think).
ASP.NET MVC's default model binding will fill the argument (Coupon) with values found in the request. Only form elements are sent along with the request. You seem to expect that DiscountLevel is sent along, but it's just a JavaScript function that exists in the user's browser.
Adding something like this may solve your immediate problem:
<input type="hidden" name="DiscountLevel" data-bind="value: DiscountLevel" />
To note a related issue though: the property you have trouble with is a computed observable. However, you probably do not want to send it along as it depends entirely on IsPerCentOrDollar. Just have your server side Coupon class derive the discount level from that property too. That would also prevent users from hacking the hidden input and sending in a malicious value.

Related

How do I pass CheckBox values from a view to a controller using #Html.CheckBox?

I need to display 6 types of tests on my view and allow the user to check as many tests as they'd like to complete. I will then need to send their response to my controller so I can add that information to a database using the entity framework.
my View:
#using (Html.BeginForm("Quote", "Customers", FormMethod.Post))
{
<label for="test1"> BP</label>
#Html.CheckBox("test1", true)<br />
<label for="test2"> DS</label>
#Html.CheckBox("test2")<br />
<label for="test3"> IS</label>
#Html.CheckBox("test3")<br />
<label for="test4" class="iput">PS</label>
#Html.CheckBox("test4")<br />
<label for="test5">PF</label>
#Html.CheckBox("test5")<br />
<label for="test6">CS</label>
#Html.CheckBox("test6")<br />
<input type="submit" value="Begin Quote" class="btn btn-default" style="padding-left: 20px" />
}
and my controller method:
[HttpPost]
public ActionResult Quote(FormCollection collection )
{
if (!string.IsNullOrEmpty(collection["test1"]))
{
string checkResp = collection["test1"];
bool checkRespB = Convert.ToBoolean(checkResp);
}
return View("Index");
}
I am running into an issue when debugging...The collection["test1"] is returning a "true, false" value instead of the actual checked value of the checkbox. I cannot seem to get the form to collect the actual statuses of the check boxes.
I have tried other options but none have seemed to work. Any help is greatly appreciated!

asp.net mvc #Html.BeginForm diplays unwanted text

I am developing a web application without any models. I just do not need them for what I am trying to do. I want to take some input from the view and to pass it on the controller. So far so good. The problem is that on the view I get some unwanted text: "System.Web.Mvc.Html.MvcForm"; it comes from the follwoing line: #Html.BeginForm("GetInfo", "Test", FormMethod.Post, new { id = "TestForm" } )
More precisely, my code is this:
--the view
#Html.BeginForm("GetInfo", "Test", FormMethod.Post, new { id = "TestForm" } )
<br/>
<legend>Report</legend>
<br />
<div class="editor-label">
<label>Date From</label>
</div>
<div class="editor-field">
<input name="dateFrom" type="date" required />
</div>
<br />
<input type="submit" class="btn btn-primary" />
and the method from the controller is :
public ActionResult GetInfo(DateTime dateFrom)
{
//some code
return RedirectToAction("Index");
}
Any ideas?
Thank you in advance! :)
Try
#using (Html.BeginForm(.....))
{
// Html here
}

Multiple Search Buttons in MVC3

There are a few questions on SO about multiple submit buttons, such as How do you handle multiple submit buttons in ASP.NET MVC Framework? but what I am having trouble with is having multiple search buttons, each with it's own associated textbox for the value being searched for, and which searches it's own set of data. For example..
<div class="leftContentColumnRow">
#Html.TextBox("SearchString", null, new { placeholder = "Search Roles..." })
<input type="submit" value="" class="searchbtn" name="SearchRoles" />
</div>
<div class="rightContentColumnRow">
#Html.TextBox("SearchString", null, new { placeholder = "Search Permissions..." })
<input type="submit" value="" class="searchbtn" name="SearchPermissions" />
</div>
I can determine which button has been clicked, but I am struggling to get hold of the data in both textboxes.
Use a separate form for each input button pair with a different action for the form.
Like Oded said, 2 forms, each has it'w own action paramter value.
#using(Html.Beginform("SearchRole","User")
{
<div class="leftContentColumnRow">
#Html.TextBox("SearchString", null, new { placeholder = "Search Roles..." })
<input type="submit" value="" class="searchbtn" name="SearchRoles" />
</div>
}
#using(Html.Beginform("SearchPermissions","User")
{
<div class="rightContentColumnRow">
#Html.TextBox("SearchString", null, new { placeholder = "Search Permissions..." })
<input type="submit" value="" class="searchbtn" name="SearchPermissions" />
</div>
}
and the Action methods
public ActionResult SearchRole(string SearchString)
{
//get data and return something
}
public ActionResult SearchPermissions(string SearchString)
{
//get data and return something
}

CheckBOX ASP MVC

Hi i am new to ASP.NET MVC. I am not sure how to deal with Check box or Radio Button to get values when they are clicked. Can any one help me? I am providing a simple code that might help you understand what i meant to be. Please share examples.
<script type="text/javascript" >
function check(browser)
{
document.getElementById("answer").value=browser;
} </script>
<form action="">
<input type="radio" name="browser"
onclick="check(this.value)"
value="Internet Explorer"/>Internet
Explorer<br />
<input type="radio" name="browser"
onclick="check(this.value)"
value="Firefox"/>Firefox<br />
<input type="radio" name="browser"
onclick="check(this.value)"
value="Netscape"/>Netscape<br />
<input type="radio" name="browser"
onclick="check(this.value)"
value="Opera"/>Opera<br />
<br />
Your favorite browser is: <input type="text" id="answer"
size="20"/> </form>
controller code
public ActionResult Index()
{
ViewData["list"] = new[]
{
new SelectListItem {Text = "InternetExplorer", Value = "InternetExplorer"},
new SelectListItem {Text = "Firefox", Value = "Firefox"},
new SelectListItem {Text = "Safari", Value = "Safari"},
new SelectListItem {Text = "Opera", Value = "Opera"}
};
return View();
}
[AcceptVerbs(HttpVerbs.Post),ActionName("Index")]
public ActionResult IndexPost(string browser)
{
// ...
}
view code
<% using (Html.BeginForm()) { %>
<% foreach(var item in (IEnumerable<SelectListItem>)ViewData["list"]) { %>
<label>
<% = Html.RadioButton("browser", item.Value) %>
<% = item.Text %></label>
<% } %>
<input type="submit" value="Select" />
<% } %>
<script type="text/javascript" src="<% = Url.Content("~/Scripts/jquery-1.3.2.js") %>" ></script>
<script type="text/javascript">
$(function() {
$("form:first").submit(function(e) {
e.preventDefault();
alert($(this).find(":radio:checked").val());
});
});
</script>
If you want browser value in action, you coding in IndexPost method.
or you want in javascript, onsubmit or onclick(and other) event handling, get checked radiobutton value at jQuery.
This was logic taken from: http://byatool.com/mvc/asp-net-mvc-how-to-handle-multiple-checkboxes-with-viewsactions-jquery-too/. I simply modified it very minimally.
----------
HTML Part|
----------
{form action="/Test/CheckForIds/" method="post"}
{div}
{input type="checkbox" name="IdList" value="1" /}
{input type="checkbox" name="IdList" value="2" /}
{input type="checkbox" name="IdList" value="3" /}
{input type="checkbox" name="IdList" value="4" /}
{/div}
{div}
{input type="submit" value="go" /}
{/div}
{/form}
----------------
Controller Part|
----------------
{AcceptVerbs(HttpVerbs.Post)} _
Function GroupPageSend(ByVal selectedObjects() As String) As ActionResult
{!--- YOUR CODE GOES HERE ---}
EX//
For Each item In selectedObjects
If i = 0 Then
string = Trim(item)
i = i + 1
Else
string = string & "," & Trim(item)
End If
Next
End Function
The above will gather values from selected checkboxes and will allow you to manage results.
Keep in mind all { = < and all } = >
I am probably not getting your question, but your sample will work well.
When you submit the form and the controller's method is called asp.net mvc will set the "browser" parameter to the value of the selected radio button's value.
hai friend try this,
<asp:RadioButton ID="RadioButton1" runat="server" onmousedown="yourjsfunc();" />

Multiple forms in ASP.NET MVC

Context
Let`s say i have:
In layout Site.Master:
<div class="leftColumn">
<asp:ContentPlaceHolder ID="MainContent" runat="server" />
</div>
<div class="rightColumn">
<% Html.RenderPartial("_Login"); %>
<asp:ContentPlaceHolder ID="SideContent" runat="server" />
</div>
Login partialView looks like:
<form action="/myApp/Account/Login" method="post">
<input name="name" />Name<br />
<input name="password" type="password" />Password<br />
<button>Login</button>
</form>
Is it possible to update only login widget form, not the entire content page?
If you are referring to a http post, only a post initiated (it can also be initiated by javascript) by a submit button from within the form will be posted to the server.
If your forms are nested then this won't work. The outer form will always post to the server.
In the sample HTML below, clicking on the submit button on the first form will not send the values from the second form to the server. Likewise, clicking the second submit button won't post the values from the first form.
<html>
...
<body>
<div>
<form action="/Login/Login" method="post">
<input type="text" name="username" value="" />
<input type="text" name="passowrd" value="" />
<input type="submit" name="login" value="Login" />
</form>
<form action="/Login/AdminLogin" method="post">
<input type="text" name="username" value="" />
<input type="text" name="passowrd" value="" />
<input type="submit" name="login" value="Login Admin" />
</form>
</div>
</body>
</html>
If you only wish to update/change one of the form section, then no this can not be done without using javascript and performing a javascript post(aka Ajax).
If you build a controller method that accepts a FormCollection and your view has two forms defined, the formcollection returned will either be populated with values from form A or form B. You can inspect the formCollection and branch your logic based on the value therein. If you want the be very explicit you could have the same hidden variable occur in both forms with a value that would help your make your choice.
That's one approach. there are a few ways to deal with this I'm sure.
If you have two simple forms, you can use this aproach:
You create two different partial views.
#model CustomerInfoModel
#using (Ajax.BeginForm("CustomerInfo", "Customer", new AjaxOptions { HttpMethod = "Post", OnBegin = "InfoLoading", OnComplete = "InfoCompleted" }, new { id = "info", #class = "form-horizontal" }))
{
<input type="text" class="form-control" name="Name" id="Name" value="#Model.Name" />
<input type="email" class="form-control" name="Email" id="Email" value="#Model.Email" />
<button type="submit" id="save-info" class="btn-medium red">Save</button>
}
and
#model CustomerPasswordChangeModel
#using (Ajax.BeginForm("CustomerPasswordChange", "Customer", new AjaxOptions { HttpMethod = "Post", OnBegin = "InfoLoading", OnComplete = "InfoCompleted" }, new { id = "change", #class = "form-horizontal" }))
{
<input type="password" class="form-control" name="OldPassword" id="OldPassword" value="" />
<input type="password" class="form-control" name="NewPassword" id="NewPassword" value="" />
<button type="submit" id="save-change" class="btn-medium red" autocomplete="off">Save</button>
}
In your parent view,
#Html.Partial("CustomerInfo", Model.CustomerInfo)
and
#Html.Partial("CustomerPasswordChange", Model.CustomerPasswordChange)
In Controller:
[HttpPost]
public ActionResult CustomerInfo([Bind(Include = "Name,Email")] CustomerInfoModel model)
{
if (ModelState.IsValid)
return new Json(new { success=true, message="Updated.", errors=null);
// do you logic
return new Json(new { success=false, message="", errors=getHtmlContent(ModelState.Values.SelectMany(v => v.Errors).ToList(), "ModelError"));
}
[HttpPost]
public ActionResult CustomerPasswordChange([Bind(Include = "OldPassword,NewPassword")] CustomerPasswordChangeModel model)
{
if (ModelState.IsValid)
return new Json(new { success=true, message="Updated.", errors=null);
// do you logic
return new Json(new { success=false, message="", errors=getHtmlContent(ModelState.Values.SelectMany(v => v.Errors).ToList(), "ModelError"));
}
This will do what you want to do.
Note: getHtmlContent method is just generating an error message to be displayed on page. Nothing so special. I may share it if required.
Your question is not very clear.
But as far as I could understand, the answer is most likely yes. You can update anything you want depending on the user input.
if(pass != true)
{
ViewData["Message'] = "Hey your login failed!"; Return View("Login")
}
On ViewPage
<form action="/tralala/Account/Login" method="post">
<input name="name" />Name<br />
<input name="password" type="password" />Password<br />
<button>Login</button>
<div style="color: red"><%=ViewData["Message"] %><div>
</form>

Resources