View Code
#using(Html.BeginForm("Edit",
"Products",
FormMethod.Post,
new {
enctype = "multipart/form-data"
})) {
#Html.AntiForgeryToken()
< div class = "form-horizontal" >
#Html.ValidationSummary(true, "", new {
#class = "text-danger"
})
#Html.HiddenFor(model => model.Id)
< div class = "form-group" >
#Html.LabelFor(model => model.Image, htmlAttributes: new {
#class = "control-label col-md-2"
}) < div class = "col-md-10" >
< img src = "#Url.Content(Model.Image)"
width = "150" / >
< /div> < /div>
}
Controller
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(Product product, HttpPostedFileBase file) {
if (ModelState.IsValid) {
Product p = new Product {
Id = product.Id,
Name = product.Name,
Description = product.Description,
Image = product.Image
};
if (file != null) {
string Image = Path.Combine(Server.MapPath("~/Upload"), Path.GetFileName(file.FileName));
file.SaveAs(Image);
p.Image = "~/Upload/" + file.FileName;
}
db.Entry(p).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
} else {
return View(product);
}
}
public ActionResult Edit(int ? id) {
if (id == null) {
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Product product = db.Products.Find(id);
if (product == null) {
return HttpNotFound();
}
return View(product);
}
I want to delete the picture with the button. How can I do it ? I can delete products but I can not delete pictures. I can delete products with Id. I tried to do examples on the internet but I could not. Would you make an illustrative example?
Below are some basic setup which should work for you.
Action Methods:
public ActionResult Index()
{
//Adding some dummy product data for example, Usually you will get real details from DB.
List<Product> products = new List<Product>();
Product product1 = new Product()
{
Id = 1,
Name = "Bint Beef",
Description = "Product Bint Beef",
ImageName = "bintbeef-1"
};
Product product2 = new Product()
{
Id = 2,
Name = "Bint Beef 2",
Description = "Product Bint Beef 2",
ImageName = "bintbeef-2"
};
products.Add(product1);
products.Add(product2);
return View(products);
}
[HttpPost]
public ActionResult DeleteProductImage(int productID)
{
try
{
string file_name = Convert.ToString(productID);
//Here you can instead use `ImageName` property to fetch the name from db based
on product id and then delete image
string path = Server.MapPath("~/Content/Images/" + file_name + ".jpg");
FileInfo file = new FileInfo(path);
if (file.Exists)//check file exsit or not
{
file.Delete();
}
return Json(new { status = true }, JsonRequestBehavior.AllowGet);
}
catch
{
return Json(new { status = false }, JsonRequestBehavior.AllowGet);
}
}
Index View
#model IEnumerable<DemoMvc.Models.Product>
<h2>Product List</h2>
<table class="table">
<tr>
<th>
Product Id
</th>
<th>
Name
</th>
<th>
Image Name
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<th>
#item.Id
</th>
<td>
#item.Name
</td>
<td>
#item.ImageName
</td>
<td>
#using (Html.BeginForm("DeleteProductImage", "Home"))
{
<input name="productID" type="hidden" value="#item.Id" />
<button type="submit">Delete Image</button>
}
</td>
</tr>
}
</table>
Reference.
Related
I am doing an ASP.NET Framework MVC project and I need to send the combo boxes selected items from below partial view to the server with Jquery Ajax but these combo boxes must be validated at first and then the data must be sent in view model with Ajax to the action (DigestFile(ModelDto Mappings)) in the controller. My project parts is as below :
The partial view as below:
#using Web.Library.Bases;
#inherits Common.DataTransferObjects.Originals.ModelDto
#{
Layout = "";
List<(string Caption, bool IsAsigned, bool IsMandatory, bool IsSelected, string Name, string Title)> dataBaseFields = ViewBag.DataBaseFields;
int counter = 0;
}
<div id="Excel_B" class="editor-block">
#Html.Hidden("IsNotMatched")
<div class="block-label">
<p class="vertical-text">
تناظر فیلدها
</p>
</div>
<div class="block-content">
#foreach (var chlItem in dataBaseFields)
{
<div id="ExcelFields_G" class="editor-group ">
<div id="ExcelFields_L" class="editor-label mandatory">
<span class="MappingLabel">#chlItem.Caption :</span>
</div>
#switch (chlItem.Name)
{
case "RowNumber":
<div id="ExcelFields_A" class="editor-field ">
#Html.EditorFor(model => model.RowNumber, "ComboBox")
#Html.ValidationMessageFor(model => model.RowNumber)
</div>
break;
case "Name":
<div id="ExcelFields_B" class="editor-field ">
#Html.EditorFor(model => model.Name, "ComboBox")
#Html.ValidationMessageFor(model => model.Name)
</div>
break;
case "Family":
<div id="ExcelFields_C" class="editor-field ">
#Html.EditorFor(model => model.Family, "ComboBox")
#Html.ValidationMessageFor(model => model.Family)
</div>
break;
case "Code":
<div id="ExcelFields_D" class="editor-field ">
#Html.EditorFor(model => model.Code, "ComboBox")
#Html.ValidationMessageFor(model => model.Code)
</div>
break;
case "NationalCode":
<div id="ExcelFields_E" class="editor-field ">
#Html.EditorFor(model => model.NationalCode, "ComboBox")
#Html.ValidationMessageFor(model => model.NationalCode)
</div>
break;
default:
break;
}
</div>
}
</div>
#if (Model.IsNotMatched > 0)
{
<div class="DigestBut" title="Read File">
<a href="#" class="submitLink" onclick="DigestButtonClicked()">
Read File
</a>
</div>
}
</div>
</div>
The View Model as below:
namespace Common.DataTransferObjects.Originals
{
public class ModelDto
{
[Display(Name = "RowNumber")]
[Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(FoundationValidationMessages))]
public string RowNumber { set; get; }
[Display(Name = "Name")]
[Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(FoundationValidationMessages))]
public string Name { set; get; }
[Display(Name = "Family")]
[Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(FoundationValidationMessages))]
public string Family { set; get; }
[Display(Name = "Code")]
[Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(FoundationValidationMessages))]
public string Code { set; get; }
[Display(Name = "NationalCode")]
[Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(FoundationValidationMessages))]
public string NationalCode { set; get; }
}
}
The Action is as below:
public ActionResult DigestFile(ModelDto Mappings)
{
....
}
Here is how you have to proceed in case you have many 'entries' to send in same time to save in your controller, but of course you can use it to send only one:
In your view:
<input id="Button1" type="button" value="button" onclick="SaveMe()" />
<script>
function SaveMe() {
// Get the value of your edit
var RowNumber0 = $("#RowNumber").val();
var Name0 = $("#Name").val();
var Family0 = $("#Family").val();
var Code0= $("#Code").val();
var NationalCode0= $("#NationalCode").val();
// Creat Object
var lineItems = new Object();
lineItems.Entrys = new Array();
// Example Filling your object...
lineItems.Entrys[0] = new Object({ RowNumber: RowNumber0, Name: Name0, Family: Family0, Code : Code0, NationalCode: NationalCode0 });
//lineItems.Entrys[1] = ... same logic for your other entries
// send by ajax to your controller and getting answer ...
$.ajax({
type: "POST",
url: "/Home/AjaxMethodDigestFile",
data: JSON.stringify({ Entrys: lineItems.Entrys }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) { alert(response.message); },
failure: function (response) { alert("failure"); },
error: function (response) { alert("error"); }
});
}
in your controller:
[HttpPost]
public JsonResult AjaxMethodDigestFile(ICollection<Common.DataTransferObjects.Originals.ModelDto > Entrys)
{
string message = "";
int counter = 0;
foreach (var entry in Entrys)
{
// How to use this data example
string RowNumber = entry.RowNumber;
string Name= entry.Name;
counter += 1;
message += "Saved " + ": " + counter + Constants.vbCrLf;
}
// The following lines are not necessary, it's just an example code to know what happen and return it to client side ...
if (counter > 0)
message = counter.ToString() + " Entrys received" + Constants.vbCrLf + message;
else
message = "no entrys";
var response = new { counter, message };
return Json(response);
}
EDIT:
About the validation
I don't know the library that you are using FoundationValidationMessages so can't help much with this, but I tried a classic way that work:
In Model:
[Required(ErrorMessage = "Required")]
public string RowNumber { set; get; }
In View:
#using (Html.BeginForm("Test2", "Home", FormMethod.Post))
{
...
#Html.EditorFor(model => model.RowNumber)
#Html.ValidationMessageFor(model => model.RowNumber)
...
}
And in your controller :
[HttpPost]
public ActionResult Test2(ModelDto um)
{
if (ModelState.IsValid)
{
return View(um);
}
else
{
return View();
}
}
Was receiving this error:
An exception of type 'System.Web.HttpException' occurred in System.Web.dll but was not handled in user code
Additional information: DataBinding: 'Final.Models.Hello' does not contain a property with the name '700'.
I looked through google for some answers, but I still feel lost.
Model class:
public Hello () {
db = new ExtensionDBEntities();
}
public List<Hello> getID()
{
var que = (from rel in db.Table1
select new Hello
{
ID = rel.ID
}).ToList();
return que;
}
public List<Hello> getStuff()
{
var que = (from wre in db.View
select new Hello
{
ID = wre.ID,
Summary = wre.Summary,
Description = wre.Description
}
}
getHello() is the same exact method as the getStuff(), just accepts a string ID parameter.
Controller class:
public ActionResult Index()
{
var model = test.getStuff();
ViewBag.Releases = new SelectList(test.getID(), "", "ID");
ViewBag.Managers = new SelectList(test.getManagers(), "", "Managers");
return View("");
}
[HttpPost]
public ActionResult Selection()
{
string selectedId = Request["IDText"].ToString();
string Managers = Request["ManagersText"].ToString();
var model = test.getStuff();
ViewBag.Releases = new SelectList(test.getID(), selectedId, "ID");
ViewBag.Managers = new SelectList(test.getManagers(), Managers, "Managers");
var que = test.getHello(selectedId, Managers);
return View(que);
}
Index View Class:
$(document).ready(function () {
$("#Releases").on("change", function () {
var value = $('#Releases :selected').text()
$("#IDText").val(value);
});
$("#Managers").on("change", function () {
var value = $('#Managers :selected').text()
$("#ManagersText").val(value);
});
});
#using (Html.BeginForm("Selection", "Sample", FormMethod.Post))
{
<div class="container" id='div_release'>
#Html.DropDownList("Releases", ViewBag.Releases as SelectList)
#Html.DropDownList("Managers", ViewBag.Managers as SelectList)
#Html.Hidden("IDText", "")
#Html.Hidden("ManagersText", "")
<input type="submit" name="Submit" id="btnUploadData" class="btn btn-primary" value="Upload" />
</div>
}
Selection View Class:
<div class="container">
<table id="myTable" align="left">
<tr>
<th>#Html.DisplayNameFor(model => model.ID)</th>
<th>#Html.DisplayNameFor(model => model.Summary)</th>
<th>#Html.DisplayNameFor(model => model.Description)</th>
</tr>
#foreach (var item in Model)
{
<tr id="Home">
<td>#Html.DisplayFor(x => item.ID)</td>
<td>#Html.DisplayFor(x => item.Summary)</td>
<td>#Html.DisplayFor(x => item.Description)</td>
</tr>
}
$(document).ready(function () {
$("#Releases").on("change", function () {
var value = $('#Releases :selected').text()
$("#IDText").val(value);
});
$("#Managers").on("change", function () {
var value = $('#Managers :selected').text()
$("#ManagersText").val(value);
});
});
#using (Html.BeginForm("Selection", "Sample", FormMethod.Post))
{
<div class="container" id='div_release'>
#Html.DropDownList("Releases", ViewBag.Releases as SelectList) // Getting the error here....
#Html.DropDownList("Managers", ViewBag.Managers as SelectList)
#Html.Hidden("IDText", "")
#Html.Hidden("ManagersText", "")
<input type="submit" name="Submit" id="btnUploadData" class="btn btn-primary" value="Submit" />
</div>
}
</table>
</div>
The error occurs in the Selection View Class. The View classes are almost identical, the only difference being is the data being displayed in the Selection View Class based on the selected value from the drop down list.
Here is a link to a fiddle that combines the views into one: https://dotnetfiddle.net/5uCKhI
This should help you. Please let me know if there is anything else.
Controller/Model
public class caitlinpRealViewModel
{
public List<SelectListItem> IDList { get; set; }
public string selectedId { get; set; }
public List<SelectListItem> ManagerList { get; set; }
public string selectedManager { get; set; }
}
public class HomeController : Controller
{
public caitlinpRealViewModel SetupViewModel(caitlinpRealViewModel vm)
{
caitlinpRealViewModel viewModel = new caitlinpRealViewModel();
if (vm != null)
{
viewModel.selectedId = vm.selectedId;
}
else
{
viewModel.selectedId = "1";
}
SelectListItem listItem = new SelectListItem() { Text = "1", Value = "1" };
SelectListItem listItem2 = new SelectListItem() { Text = "2", Value = "2" };
List<SelectListItem> list = new List<SelectListItem>();
list.Add(listItem);
list.Add(listItem2);
if (vm != null)
{
viewModel.selectedManager = vm.selectedManager;
}
else
{
viewModel.selectedManager = "1";
}
SelectListItem listItem3 = new SelectListItem() { Text = "aManager", Value = "1" };
SelectListItem listItem4 = new SelectListItem() { Text = "bManager", Value = "2" };
List<SelectListItem> list2 = new List<SelectListItem>();
list2.Add(listItem3);
list2.Add(listItem4);
viewModel.IDList = list;
viewModel.ManagerList = list2;
return viewModel;
}
[HttpPost]
public ActionResult Selection(caitlinpRealViewModel vm)
{
caitlinpRealViewModel viewModel = SetupViewModel(vm);
return View(viewModel);
}
public ActionResult Tut135()
{
caitlinpRealViewModel viewModel = SetupViewModel(null);
return View(viewModel);
}
View 1
#model Testy20161006.Controllers.caitlinpRealViewModel
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Tut135</title>
</head>
<body>
#using (Html.BeginForm("Selection", "Home", FormMethod.Post))
{
<div class="container" id='div_release'>
#Html.DropDownListFor(m => m.selectedId, new SelectList(Model.IDList, "Value", "Text"))
#Html.DropDownListFor(m => m.selectedManager, new SelectList(Model.ManagerList, "Value", "Text"))
<input type="submit" name="Submit" id="btnUploadData" class="btn btn-primary" value="Upload" />
</div>
}
</body>
</html>
View 2 (Selection)
#model Testy20161006.Controllers.caitlinpRealViewModel
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Selection</title>
</head>
<body>
<div class="container">
<table id="myTable" align="left">
#using (Html.BeginForm("Selection", "Home", FormMethod.Post))
{
<div class="container" id='div_release'>
#Html.DropDownListFor(m => m.selectedId, new SelectList(Model.IDList, "Value", "Text"))
#Html.DropDownListFor(m => m.selectedManager, new SelectList(Model.ManagerList, "Value", "Text"))
<input type="submit" name="Submit" id="btnUploadData" class="btn btn-primary" value="Submit" />
</div>
}
</table>
</div>
</body>
</html>
I have dynamically loaded Partial Views (depends on "Add button"):
$.get('/Home/LoadSpread', {}, function (response) {
var newHTML = response;
$(newHTML).hide().appendTo("#Spreads").fadeIn(1000);
});
$('#loadPartialViewBtn').hide().fadeIn(1000);
Each Partial View is rendered in main page form:
<form method="post" action="GetInitializedBranch">
<div id="Spreads" align="center">
</div>
<input type="submit" value="Send" />
</form>
Each Partial View loads by same model (which should have different values on post):
public IActionResult LoadSpread()
{
BranchView branchView = new BranchView
{
SelectorViewID = ++partialViewID,
Spreads = new List<Spread>()
};
foreach (var rate in Handlers.DataAccessHandler.GetRatesFromDB())
{
branchView.Spreads.Add(new Spread { Curr = rate.Curr });
}
return PartialView("_Spread", branchView);
}
This is my Partial View model:
public class BranchView
{
public int BranchID { get; set; }
public string BranchName { get; set; }
public int SelectorViewID { get; set; }
public List<Spread> Spreads { get; set; }
}
This is the Partial view which is a table with unique input elements:
<table class="table table-bordered" style="margin-left: 480px; margin-top: 10px;">
<tbody>
<tr>
<td valign="middle" rowspan="2"> Currency </td>
<td style="text-align: center;" colspan="4">Cash</td>
<td style="text-align: center;" colspan="4">Non Cash</td>
</tr>
<tr>
<td>Spread Buy</td>
<td>Buy Current</td>
<td>Spread Sell</td>
<td>Sell Current</td>
<td>Spread Buy</td>
<td>Buy Current</td>
<td>Spread Sell</td>
<td>Sell Current</td>
</tr>
#{ var j = 1;}
#for (var i = 0; i < Model.Spreads.Count; i++)
{
var currencyName = Model.Spreads[i].Curr.ShortName;
var cashSpreadBuy = "cashSpreadBuy" + currencyName + Model.Spreads[i].ID;
var cashBuyCurrent = "cashBuyCurrent" + currencyName + Model.Spreads[i].ID;
var cashSpreadSell = "cashSpreadSell" + currencyName + Model.Spreads[i].ID;
var cashSellCurrent = "cashSellCurrent" + currencyName + Model.Spreads[i].ID;
var nonCashSpreadBuy = "nonCashSpreadBuy" + currencyName + Model.Spreads[i].ID;
var nonCashBuyCurrent = "nonCashBuyCurrent" + currencyName + Model.Spreads[i].ID;
var nonCashSpreadSell = "nonCashSpreadSell" + currencyName + Model.Spreads[i].ID;
var nonCashSellCurrent = "nonCashSellCurrent" + currencyName + Model.Spreads[i].ID;
<tr>
<td>
<div id="#currencyName">
#Html.DisplayTextFor(m => m.Spreads[i].Curr.ShortName)
</div>
</td>
<td>
#Html.EditorFor(m => m.Spreads[i].CashSpreadBuy,
new { htmlAttributes = new { #id = cashSpreadBuy, #type = "number", #step = "0.01", #class = "form-control" } })
</td>
<td>
<div id="#cashBuyCurrent">
#Html.DisplayTextFor(m => m.Spreads[i].CashBuyCurrent)
</div>
</td>
<td>
#Html.EditorFor(m => m.Spreads[i].CashSpreadSell,
new { htmlAttributes = new { #id = cashSpreadSell, #type = "number", #step = "0.01", #class = "form-control" } })
</td>
<td>
<div id="#cashSellCurrent">
#Html.DisplayTextFor(m => m.Spreads[i].CashSellCurrent)
</div>
</td>
<td>
#Html.EditorFor(m => m.Spreads[i].NonCashSpreadBuy,
new { htmlAttributes = new { #id = nonCashSpreadBuy, #type = "number", #step = "0.01", #class = "form-control" } })
</td>
<td>
<div id="#nonCashBuyCurrent">
#Html.DisplayTextFor(m => m.Spreads[i].NonCashBuyCurrent)
</div>
</td>
<td>
#Html.EditorFor(m => m.Spreads[i].NonCashSpreadSell,
new { htmlAttributes = new { #id = nonCashSpreadSell, #type = "number", #step = "0.01", #class = "form-control" } })
</td>
<td>
<div id="#nonCashSellCurrent">
#Html.DisplayTextFor(m => m.Spreads[i].NonCashSellCurrent)
</div>
</td>
</tr>
}
</tbody>
</table>
I'm trying to get the array of BranchView models on post (i.e. BranchView[] branches), but I have no idea how to do that:
[HttpPost]
public void GetInitializedBranch (BranchView[] branches)
{
//TODO: Collect All branches data
}
What should I do for getting all Partial Views user inputs results and get it as array of models?
I have web app for testing.
My very simple class:
public class MyClass
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Value { get; set; }
}
I changed my default controller this way:
// GET: MyClasses/Create
public ActionResult Create()
{
MyClass myClass = new MyClass()
{
Name = "First",
Value = 1
};
var Names = new[]{
new SelectListItem{ Value="First", Text="First" },
new SelectListItem{ Value="Second", Text="Second" },
new SelectListItem{ Value="Third", Text="Third" },
};
ViewBag.Names = new SelectList(Names, "Value", "Text");
return View(myClass);
}
// POST: MyClasses/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create([Bind(Include = "Id,Name,Value")] MyClass myClass, string Action)
{
if (Action == "Change name")
{
myClass.Value = myClass.Name == "First" ? 1 :
myClass.Name == "Second" ? 2 :
myClass.Name == "Third" ? 3 :
0;
ModelState.Clear();
}
else
if (ModelState.IsValid)
{
db.MyClasses.Add(myClass);
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
var Names = new[]{
new SelectListItem{ Value="First", Text="First" },
new SelectListItem{ Value="Second", Text="Second" },
new SelectListItem{ Value="Third", Text="Third" },
};
ViewBag.Names = new SelectList(Names, "Value", "Text");
return View(myClass);
}
I changed "Create" view this way:
#using (Html.BeginForm(null, null, FormMethod.Post, new { #id = "MainForm" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>MyClass</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#*#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })*#
#Html.DropDownListFor(model => model.Name, (IEnumerable<SelectListItem>)new SelectList(ViewBag.Names, "Value", "Text", Model.Name), htmlAttributes: new { #class = "form-control", #onchange = "changeName()" })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Value, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Value, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Value, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script>
function changeName() {
var input = $("<input>")
.attr("type", "hidden")
.attr("name", "Action").val("Change name");
$('#MainForm').append($(input));
$('#MainForm').submit();
}
</script>
}
I want make this app multilingual (change culture). I added some code to Global.asax.cs for it:
protected void Application_BeginRequest(object sender, EventArgs e)
{
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("someculture");
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("someculture");
}
This app works well when I use "en" or other culture/language ("someculture" in Global.asax.cs), DropDownListFor changes the Value, controller (async Task Create) works as it should.
My browser default culture/language is English. So when I use "fr" or other culture/language I get an error in "Create" view "The field Value must be a number.".
To fix this error user can change "," to "." in "Value", but it is not the solution.
To number validation I added the scripts I use in my other apps. I added its to "Create" view scripts section:
$.validator.methods.number = function (value, element) {
return this.optional(element) ||
!isNaN(Globalize.parseFloat(value));
}
$(document).ready(function () {
Globalize.culture('#(System.Threading.Thread.CurrentThread.CurrentCulture.Name)');
});
jQuery.extend(jQuery.validator.methods, {
range: function (value, element, param) {
var val = Globalize.parseFloat(value);
return this.optional(element) || (val >= param[0] && val <= param[1]);
}
});
But after adding this scripts DropDownListFor stopped working. Number validation is works, DropDownListFor - no.
My question is some way to do to work validation and DropDownListFor one time in one View? Or my approach is wrong and I should implement this functionality otherwise.
UPDATE
I found solution.
Added new input in view:
<input type="hidden" value="no" id="submitform" />
And modified scripts this way:
<script>
function changeName() {
var input = $("<input>")
.attr("type", "hidden")
.attr("name", "Action").val("Change name");
$('#MainForm').append($(input));
document.getElementById("submitform").value = "yes";
$('#MainForm').submit();
}
jQuery.extend(jQuery.validator.methods, {
range: function (value, element, param) {
var val = Globalize.parseFloat(value);
return this.optional(element) || (val >= param[0] && val <= param[1]);
}
});
$.validator.methods.number = function (value, element) {
if (document.getElementById("submitform").value == "yes") {
document.getElementById("submitform").value = "no";
document.getElementById("MainForm").submit();
}
return this.optional(element) || !isNaN(Globalize.parseFloat(value));
}
$(document).ready(function () {
Globalize.culture('#(System.Threading.Thread.CurrentThread.CurrentCulture.Name)');
});
</script>
I am writing a small mvc.net web application that takes some input from the user and when the user clicks the button the input data is calculated and displayed in two input fields. However when the button is clicked (see file Index.cshtml) nothing is displayed in the two input fields. Would appreciate any help to figure out what might be wrong. :)
An image of the web application.
Here follows my code...
SelectPurchaseModel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace TheMakingOfAWebApplication.Models
{
public class SelectPurchaseModel
{
public string Name { get; set; }
public IEnumerable<Article> Articles { get; set; }
public int Quantity { get; set; }
public double Price { get; set; }
public double AmountExVat { get; set; }
public double AmountInVat { get; set; }
}
}
Article.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace TheMakingOfAWebApplication.Models
{
public class Article
{
public string Name { get; set; }
}
}
HomeController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using TheMakingOfAWebApplication.Models;
namespace TheMakingOfAWebApplication.Controllers
{
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
//List<Article> articles;
SelectPurchaseModel model = new SelectPurchaseModel();
model.Name = "";
model.Articles = new List<Article>{
new Article { Name = "Bananas"},
new Article { Name = "Apples"},
new Article { Name = "Oranges"},
new Article { Name = "Melons"},
new Article { Name = "Grapes"},
new Article { Name = "Sallad"},
new Article { Name = "Potatoes"},
new Article { Name = "Cucumber"},
new Article { Name = "Beans"},
new Article { Name = "Tomatoes"}
};
model.Quantity = 0;
model.Price = 0.0;
model.AmountExVat = 0.0;
model.AmountInVat = 0.0;
return View(model);
}
// POST: Home
[HttpPost]
public ActionResult Index(SelectPurchaseModel purchase)
{
purchase.Articles = new List<Article>{
new Article { Name = "Bananas"},
new Article { Name = "Apples"},
new Article { Name = "Oranges"},
new Article { Name = "Melons"},
new Article { Name = "Grapes"},
new Article { Name = "Sallad"},
new Article { Name = "Potatoes"},
new Article { Name = "Cucumber"},
new Article { Name = "Beans"},
new Article { Name = "Tomatoes"}
};
purchase.AmountExVat = purchase.Quantity * (purchase.Price - (purchase.Price * 0.10));
purchase.AmountInVat = purchase.Quantity * (purchase.Price * 1.10);
return View(purchase);
}
}
}
Index.cshtml
#model TheMakingOfAWebApplication.Models.SelectPurchaseModel
#{
ViewBag.Title = "Index";
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$(".btn btn-default").click(function () {
debugger;
var quantity = $("#Quantity").attr('value');
var price = $("#Price").attr('value');
var AmountExVat = quantity * (price - (price * 0.10));
var AmountInVat = quantity * (price * 1.10);
$("#AmountExVat").val(AmountExVat);
$("#AmountInVat").val(AmountInVat);
});
});
</script>
<h2>Index</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Article</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<fieldset>
<p>
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
#Html.DropDownListFor(m => m.Name, new SelectList(Model.Articles, "Name", "Name"))
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</p>
<p>
#Html.LabelFor(model => model.Quantity, htmlAttributes: new { #class = "control-label col-md-2" })
#Html.TextBoxFor(m => m.Quantity)
#Html.ValidationMessageFor(model => model.Quantity, "", new { #class = "text-danger" })
</p>
<p>
#Html.LabelFor(model => model.Price, htmlAttributes: new { #class = "control-label col-md-2" })
#Html.TextBoxFor(m => m.Price)
#Html.ValidationMessageFor(model => model.Price, "", new { #class = "text-danger" })
</p>
<p>
<input type="submit" value="Save" class="btn btn-default" />
</p>
<p>
#Html.LabelFor(model => model.AmountExVat, htmlAttributes: new { #class = "control-label col-md-2" })
#Html.TextBoxFor(m => m.AmountExVat)
#Html.ValidationMessageFor(model => model.AmountExVat, "", new { #class = "text-danger" })
</p>
<p>
#Html.LabelFor(model => model.AmountInVat, htmlAttributes: new { #class = "control-label col-md-2" })
#Html.TextBoxFor(m => m.AmountInVat)
#Html.ValidationMessageFor(model => model.AmountInVat, "", new { #class = "text-danger" })
</p>
</fieldset>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
1st: use $(".btn.btn-default") instead of $(".btn btn-default")
2nd use .val() instead of attr('value');
3rd you may need to use parseInt() or pareseFloat();
<script type="text/javascript">
$(document).ready(function () {
$(".btn.btn-default").click(function () {
debugger;
var quantity = $("#Quantity").val();
var price = $("#Price").val();
var AmountExVat = quantity * (price - (price * 0.10));
var AmountInVat = quantity * (price * 1.10);
$("#AmountExVat").val(AmountExVat);
$("#AmountInVat").val(AmountInVat);
});
});
</script>
About using parseInt() and parseFloat()
var quantity = parseInt($("#Quantity").val() , 10);
var price = parseFloat($("#Price").val());
Additional: if all of that not work .. you can try
$(".btn.btn-default").on('click',function () {
or
$("body").on('click',".btn.btn-default",function () {
Your selector is not binding property so fixed as mentioned below and you should use val() instead of attr('value')
$(".btn.btn-default").click(function () {
var quantity = $("#Quantity").val();
var price = $("#Price").val();
var amountExVat = quantity * (price - (price * 0.10));
var amountInVat = quantity * (price * 1.10);
$("#AmountExVat").val(amountExVat);
$("#AmountInVat").val(amountInVat);
});