How can I tell which image has been clicked? - asp.net-mvc

<%using (Html.BeginForm("ChangeLanguage", "AppController", FormMethod.Post))
{ %>
<div id="China">
<input id="imageChina" name="btnsubmitLan" type="image" value="CN" alt='China' src="/Content/Image/IconHH/FlatCN.gif" />
</div>
<div id="US">
<input id="ImageUS" name="btnsubmitLan" type="image" value="US" alt='English' src="/Content/Image/IconHH/FlatUS.jpg" />
</div>
<div id="VietNam">
<input id="ImageVN" name="btnsubmitLan" type="image" value="VN" alt='VietNam' src="/Content/Image/IconHH/FlatVN.jpg" />
</div>
<%} %>
In controller :
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult ChangeLanguage(string btnsubmitLan, FormCollection form)
{//chu yeu load o phan template
if (btnsubmitLan != null)
{
switch (btnsubmitLan)
{
case "VN": Session["language"] = "VN"; break;
case "CN":
case "US": Session["language"] = "EN"; break;
}
}
return RedirectToAction("Index");
}
But btnSubmit always null. Why????

I'd be using jQuery and then do an AJAX post to a controller passing in an id of some sort.
<input id="ImageVN" name="btnsubmitLan" type="image" value="VN" alt='VietNam' src="/Content/Image/IconHH/FlatVN.jpg" />
$('input').click( function() {
var id = this.attr("id");
//now do your ajax postback passing in the id.
} );

Related

How to get Input control value in controller's Index method asp.net core

I am working on captcha authentication. I want to get user entered captcha value in controller's Index method. Below is my cshtml file code
#{
ViewData["Title"] = "Home Page";
}
<div class="container">
<label for="captcha"><b>Enter chaptcha - </b></label>
<label id="lblshowCaptcha"><b>#ViewData["captcha"]</b></label>
<input id="txtCapValue" type="text" placeholder="Enter captcha" name="cap" required>
<br/>
<button class="button" type="submit">Login</button>
<br />
</div>
When user entering captcha value in txtCapValue and click submit button I need that value in controller. Here is my controller
public IActionResult Index()
{
randnumber = RandomString(6);
ViewData["captcha"] = randnumber;
return View();
}
how can I get txtCapValue input control value when user click on submit button ?
One of the easy ways using the Form Tag Helper:
<form asp-controller="Controller_Name" asp-action="Captcha" method="post">
<div class="container">
<label for="captcha"><b>Enter chaptcha - </b></label>
<label id="lblshowCaptcha"><b>#ViewData["captcha"]</b></label>
<input id="txtCapValue" type="text" placeholder="Enter captcha" name="cap" required>
<br />
<button class="button" type="submit">Login</button>
<br />
</div>
</form>
And on the server side:
[HttpPost]
public IActionResult Captcha(string cap)
{
... using the `cap`
return View("Index");
}
I want to get user entered captcha value in controller's Index
method.
There are two options, you can try:
Option1: use Form Tag Helper
Index method:
public IActionResult Index(string cap)
{
ViewData["captcha"] = 6;//do your staff
return View();
}
Index view:
<form method="get" asp-action="Index">
<div class="container">
<label for="captcha"><b>Enter chaptcha - </b></label>
<label id="lblshowCaptcha"><b>#ViewData["captcha"]</b></label>
<input id="txtCapValue" type="text" placeholder="Enter captcha" name="cap" required>
<br />
<button class="button" type="submit">Login</button>
<br />
</div>
</form>
Option 2: use ajax
Index method:
public IActionResult Index(string cap)
{
ViewData["captcha"] = 6;
return View();
}
Index view:
<div class="container">
<label for="captcha"><b>Enter chaptcha - </b></label>
<label id="lblshowCaptcha"><b>#ViewData["captcha"]</b></label>
<input id="txtCapValue" type="text" placeholder="Enter captcha" name="cap" required>
<br />
<button id="buttonDemo1" class="button" type="submit">Login</button>
<br />
</div>
#section scripts{
<script type="text/javascript">
$(document).ready(function () {
$('#buttonDemo1').click(function () {
var cap = $("#txtCapValue");
$.ajax({
type: 'GET',
url: '/Home/Index',
data: cap
});
});
});
</script>
}
result:

Edit action has not been hitting while I push the submit button

I have an edit button in each row of my Datatable. I have two actions for editing. One for Getting data in a Datatable and the other one for posting my information. The code behind my Edit button in the my Home Index is:
{
"data": "Id",
"render": function (data, type, full, meta) {
return `<div class="text-center"> <a class="btn btn-info"
href="/Home/EditGet/` + data + `" >Edit</a> </div> `;
}
and my home controller methods are:
/// Get Edit
[HttpGet]
[Route("{Id}")]
public IActionResult EditGet(int? id)
{
if (id == null || id == 0)
{
return NotFound();
}
var obj = _sv.OpenRecord(id);
if (obj == null)
{
return NotFound();
}
return View("EditGet", obj);
}
/// Post Edit
[HttpPost]
public IActionResult EditPost(SalesVeiwModel sales)
{
if (ModelState.IsValid)
{
var res= _sv.Update(sales.Comment);
if (res==null )
{
return Json(data: "Not found");
}
return RedirectToAction("EditGet");
}
return Json(data: "Is not valid");
}
And finally my EditGet view is like bellow:
<form id="contact-form" method="post" asp-controller="Home" asp-
action="EditPost" role="form" >
<input asp-for="Id" hidden />
<div class="form-group">
<label>Invoice Nomber</label>
<input id="form_IBNo" type="text" class="form-control" disabled asp-for="IBNo">
</div>
.
.
.
<div class="col-md-12">
<input type="submit" class="btn btn-success btn-send" value="Confirm" asp-
controller="Home" asp-action="EditGet">
</form>
You should have two buttons,one call EditGet,one call EditPost,here is a demo:
<form id="contact-form" method="post" asp-controller="Home" asp-
action="EditPost" role="form" >
<input asp-for="Id" hidden />
<div class="form-group">
<label>Invoice Nomber</label>
<input id="form_IBNo" type="text" class="form-control" disabled asp-for="IBNo">
</div>
.
.
.
<div class="col-md-12">
<input type="submit" class="btn btn-success btn-send" value="Confirm">
<a class="btn btn-success btn-send" value="Confirm" asp-controller="Home" asp-action="EditGet" asp-route-id="1">EditGet</a>
</div>
</form>

ASP.NET MVC Show message before redirects if success

Here's my web api on account controller using identity that can change the password wit validation using data annotations
[HttpGet]
[AllowAnonymous]
public IActionResult ChangePassword(string email, string returnUrl)
{
return email == null || returnUrl == null ? View("Error") : View();
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> ChangePassword(ChangePasswordViewModel model)
{
if (model == null)
{
return BadRequest();
}
if (ModelState.IsValid)
{
var result = await _changePasswordCommand.ChangePassword(model);
if (result.Succeeded)
{
ViewBag.IsSuccess = true;
ModelState.Clear();
return Redirect(model.returnUrl);
}
foreach (var error in result.Errors)
{
ModelState.AddModelError(string.Empty, error.Description);
}
}
return View(model) ;
}
then in my div razor views
<form class="change-password-form" asp-controller="Account" asp-action="ChangePassword" method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input id="email-hidden" asp-for="Email" type="hidden" />
<input id="return-url" asp-for="ReturnUrl" type="hidden" />
<div class="form-group change-password">
#if (ViewBag.IsSuccess == true)
{
<div class="alert alert-success alert-dismissible fade show text-center">Successfully Changed Password!</div>
}
<label asp-for="CurrentPassword" class="control-label"></label>
<input class="form-control" type="password" asp-for="CurrentPassword">
<span asp-validation-for="CurrentPassword" class="text-danger"></span>
</div>
<div class="form-group change-password">
<label asp-for="NewPassword" class="control-label">New password</label>
<input id="password" class="form-control" type="password" name="newPassword" asp-for="NewPassword" onkeyup="isGood(this.value)">
<span asp-validation-for="NewPassword" class="text-danger"></span>
</div>
<div class="form-group change-password">
<label asp-for="ConfirmNewPassword" class="control-label"></label>
<input asp-for="ConfirmNewPassword" class="form-control" type="password" />
<span asp-validation-for="ConfirmNewPassword" class="text-danger"></span>
</div>
<div class="change-password-footer">
<button id="btn-cancel" type="button" class="btn btn-primary cancel">
CANCEL
</button>
<button id="btn-save" type="submit" class="btn btn-secondary save" disabled>
SAVE
</button>
</div>
</form>
I want to be able to show the successfully changed password message before it redirects problem is it always redirect to account/changepassword after submit
You can write if condition outside the form tag, like this
#if (ViewBag.IsSuccess == true)
{
<div class="alert alert-success alert-dismissible fade show text-center">Successfully
Changed Password!
</div>
}
<form class="change-password-form" asp-controller="Account" asp-action="ChangePassword" method="post">
#*your code*#
</form>
Or remove method="post" then try
look at this place in your account controller.
...
if (result.Succeeded)
{
ViewBag.IsSuccess = true;
ModelState.Clear();
return Redirect(model.returnUrl);
}
...
Instead of the re-direct, use "return View(model);". then you can redirect the page ajax, (testing if the ViewBag.IsSuccess == true and model.returnUrl != null) you in the account controller, you will instead have.
...
if (result.Succeeded)
{
ViewBag.IsSuccess = true;
ModelState.Clear();
//return Redirect(model.returnUrl);
return View(model);
}
...
With this, the success alert would show. Then have a javascript method onload, test if success is true and the the return is not null. something like this (in the view)
...
#{
bool isSuccess = ViewBag.IsSuccess;
string rUrl = model.returnUrl;
}
...
<script>
function redirect(isSuccess, returnUrl)
{
//use ajax to redirect;
}
redirect(#isSuccess, #rUrl);
</script>

Loading partialView through ajax not working

i am trying to show order Summary through partial View and ajax.Request is going to server but my action method of Showsummary never hits. i want to summary of order through partial view.
[HttpPost]
public PartialViewResult Showsummary(OrderViewModel model)
{
try
{
var p = model.Packages.SelectMany(x => x.Packages).Select(y => new OrderPackagesViewModel()
{
PkgName = y.PkgName,
pkg_Id = y.id,
Ser_Id = y.Ser_Id,
Quantity = y.Quantity,
price = (y.TotalPrice - (y.DiscountPercent / 100 * y.TotalPrice)) * y.Quantity
}).ToList();
model.OrderPackages = p;
return PartialView("OrderSummary", model);
}
catch
{
return PartialView("OrderSummary", model);
}
}
My Ajax
$("#summary").click(function () {
console.log("calling summary");
event.preventDefault();
$.ajax({
type: "POST",
url: "/Order/Showsummary",
data: $("form.signup-form").serialize(),
success: function (data) {
console.log(data)
$('#page_2').hide();
$('#page_3').show();
$('#page_3').html(data);
},
failure: function (response) {
console.log(response.responseText);
},
error: function (response) {
console.log(response.responseText);
}
});
})
//Html Code
<div id="page_1">
<input asp-for="cus_name" placeholder="First Name" >
<input asp-for="Email" placeholder="Email" >
<select asp-for="Country" class="ui search dropdown">
<option value="">Select Country</option>
<option value="AF">Afghanistan</option>
<option value="AX">Ă…land Islands</option>
</select>
<input asp-for="cus_phone" placeholder="Phone Number"/>
<select asp-for="FirstPreferences" class="custom-select mr-sm-2"
asp-items="#(newSelectList(Preferences))">
<option value="">Select</option>
</select>
<select asp-for="FirstPreferedTimeStart" class="menu">
<option value="">HH:MM</option>
<option value="00:00:00">00:00</option>
<option value="01:00:00">01:00</option>
</select>
<textarea asp-for="Message" class="form-control"> </textarea>
</div>
//Page2 details of packages available. It is list of GroupByServices which contain fields ser_id Ser_Name and List of ServicePackages.
<div id="page_2" style="display:none">
<div>
<h1 id="heading">Choose a Package!</h1>
</div>
<div class="buttons">
#foreach (var services in Model.Packages)
{
<a href="#service_#services.Ser_Id"><div class="logo-p">
<h2>#services.Ser_Name</h2></div></a>
}
</div>
<!-- packages -->
#for (int i = 0; i < Model.Packages.Count; i++)
{
<div class="packages" id="service_#Model.Packages[i].Ser_Id">
<h1 id="custom-website-design">
#Model.Packages[i].Ser_Name
</h1>
<div class="packs-content">
#for (int j = 0; j < Model.Packages[i].Packages.Count(); j++)
{
<div class="pack1">
<div class="pack-price">
<div>
<input asp-for="#Model.Packages[i].Packages[j].id" hidden />
<input asp-for="#Model.Packages[i].Packages[j].PkgName" hidden />
<input asp-for="#Model.Packages[i].Packages[j].Ser_Id" hidden />
<input asp-for="#Model.Packages[i].Packages[j].Ser_Name" hidden />
<h1>#Model.Packages[i].Packages[j].PkgName</h1>
<p>#Model.Packages[i].Packages[j].Ser_Name PACKAGE</p>
</div>
<p>$#Model.Packages[i].Packages[j].TotalPrice</p>
<input asp-for="#Model.Packages[i].Packages[j].TotalPrice" hidden />
</div>
<div class="pack-features">
<div class=""></div>
#foreach (var features in Model.Packages[i].Packages[j].Description)
{
<h2>#features</h2>
}
</div>
<div class="pack-order">
<div class="row-1">
#{
double discount = (Model.Packages[i].Packages[j].DiscountPercent / 100 * Model.Packages[i].Packages[j].TotalPrice);
double PriceAfterDiscount = Model.Packages[i].Packages[j].TotalPrice - discount;
}
<p>SPECIAL DISCOUNT</p>
<P>-$#discount</P>
</div>
<div class="row-2">
<p>FINAL PRICE FOR LIMITED TIME</p>
</div>
<div class="row-3">
<a asp-controller="Packages" asp-action="Detail" asp-route-id="#Model.Packages[i].Packages[j].id" target="_blank">view details</a>
<h1>$#PriceAfterDiscount</h1>
<input asp-for="#Model.Packages[i].Packages[j].DiscountPercent" hidden />
</div>
<div class="row-4">
<h4>Add To Buying List</h4>
<div class="input-group mb-3 order-btn-pack">
<div class="input-group-prepend">
<div class="input-group-text">
<input asp-for="#Model.Packages[i].Packages[j].is_selected" aria-label="Checkbox for following text input">
</div>
</div>
<input asp-for="#Model.Packages[i].Packages[j].Quantity" value="1" min="1" required placeholder="Quantity" class="form-control" aria-label="Text input with checkbox">
</div>
</div>
<div class="row-5">
<p>Discuss this offer with expert</p>
<div class="discuss">
<p>12345467889</p>
<p id="chat-btn_10">Live Chat</p>
</div>
</div>
</div>
</div>
}
<input asp-for="HoldPackage" hidden/>
</div>
</div>
}
<div>
<button type="button" class="btn btn-danger px-2 btn-lg" onclick="PageBack(this.parentElement.parentElement)">Back</button>
<button type="button" class="btn btn-danger px-2 btn-lg" id="summary">Summary!</button>
</div>
</div>
Edit!!!!
i have changed this line in ajax now it start hitting my controller action but still all form values are empty seems model binding is unable to recognize my fields
**const model= $("form").serialize()**
console.log(model); //data is there thats fine
and in ajax
data: { model },
my model have field called packages which is list of some fields and inside it there is one another list.
One thing is clear. $("form").serialize() is not working in my case its giving me 415 Unsupported Media Type client error response. I think problem is due to nested List
I have checked your code on my side with a simple OrderViewModel object, it works well. I suggest you could try to add '[FromBody]' in the action method, Like this:
....
Edit
According your description, it seems that you are using the Nested List and meet 415 error when using the [FromBody]. I have modified the sample code, in the action method, it's not using the [FromBody] attribute and in the JQuery Ajax method, there is no need to use the JSON.stringify method to change the JavaScript object. More detail information, please check the following code:
Model Class (Suppose the OrderViewModel contain a List):
public class OrderViewModel
{
public int OrderId { get; set; }
public string OrderName { get; set; }
public List<Package> Packages { get; set; }
}
public class Package
{
public int Pid { get; set; }
public string PackageTitle { get; set; }
}
Code in the Controller:
/// <summary>
/// //display the order
/// </summary>
/// <returns></returns>
public IActionResult ShowOrder()
{
OrderViewModel ovm = new OrderViewModel()
{
OrderId = 1001,
OrderName = "order 1",
Packages = new List<Package>()
{
new Package(){ Pid=101, PackageTitle="first Package"},
new Package(){ Pid=102, PackageTitle="second package"}
}
};
return View(ovm);
}
/// <summary>
/// JQuery ajax post method
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
[HttpPost]
public PartialViewResult Showsummary(OrderViewModel model)
{
try
{
//...
return PartialView("OrderSummary", model);
}
catch
{
return PartialView("OrderSummary", model);
}
}
ShowOrder.cshtml:
#model MVCSample.Models.OrderViewModel
#{
ViewData["Title"] = "ShowOrder";
}
<div class="row">
<div class="col-md-4">
<form asp-action="Showsummary" asp-controller="Home" method="post" class="signup-form">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="OrderId" class="control-label"></label>
<input asp-for="OrderId" class="form-control" />
<span asp-validation-for="OrderId" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="OrderName" class="control-label"></label>
<input asp-for="OrderName" class="form-control" />
<span asp-validation-for="OrderName" class="text-danger"></span>
</div>
<div id="packages">
#for (int i = 0; i < Model.Packages.Count; i++)
{
<div class="form-group">
<label asp-for="#Model.Packages[i].Pid" class="control-label"></label>
<input asp-for="#Model.Packages[i].Pid" class="form-control" />
<span asp-validation-for="#Model.Packages[i].Pid" class="text-danger"></span>
<br />
<label asp-for="#Model.Packages[i].PackageTitle" class="control-label"></label>
<input asp-for="#Model.Packages[i].PackageTitle" class="form-control" />
<span asp-validation-for="#Model.Packages[i].PackageTitle" class="text-danger"></span>
</div>
}
</div>
#*<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>*#
</form>
</div>
</div>
<div>
<input type="button" id="summary" value="Summary" />
<div id="page_3">
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$(function () {
$("#summary").click(function () {
console.log("calling summary");
event.preventDefault();
//create a object to store the entered value.
var OrderViewModel = {};
//using jquery to get the entered value.
OrderViewModel.OrderId = $("input[name='OrderId']").val();
OrderViewModel.OrderName = $("input[name='OrderName']").val();
var packages = [];
//var count = $("#packages>.form-group").length; //you could use it to check the package count
$("#packages>.form-group").each(function (index, item) {
var package = {}
package.Pid = $(item).find("input[name='Packages[" + index + "].Pid']").val();
package.PackageTitle = $(item).find("input[name='Packages[" + index + "].PackageTitle']").val();
packages.push(package);
});
OrderViewModel.Packages = packages;
$.ajax({
type: "POST",
url: "/Home/Showsummary", //remember change the controller to your owns.
data: OrderViewModel,
success: function (data) {
console.log(data)
$('#page_3').html(data);
},
failure: function (response) {
console.log(response.responseText);
},
error: function (response) {
console.log(response.responseText);
}
});
});
});
</script>
Then the output as below:
Edit:
Besides, I also found that by using the above sample, if I just change the data: OrderViewModel to data: $("form.signup-form").serialize() (in the Ajax method), I could also get the OrderViewModel and the Packages in the action method.

Httppost not firing in mvc

I have two buttons on a page and I want the user to click one and they both go to different pages, the problem is my httpPost attribute is not firing.
Here is my controller:
public ActionResult Index()
{
if (Session["AccountConfirmationViewModel"] != null)
{
AccountConfirmationViewModel accountConfirmationViewModel = Session["AccountConfirmationViewModel"] as AccountConfirmationViewModel;
if (accountConfirmationViewModel == null || !TryValidateModel(accountConfirmationViewModel))
{
return RedirectToAction("AccountSearch", "Home");
}
MobileStep1ViewModel mobileModel = new MobileStep1ViewModel();
mobileModel.GetMobileNumbers(accountConfirmationViewModel.CustomerReferenceNumber);
Session["MobileModel"] = mobileModel;
}
return View();
}
[HttpPost]
public ActionResult Index(string button)
{
if (button == "btnNotMobileQuery")
{
RedirectToAction("AcconutSearch", "Home");
}
else if (button == "btnMobileQuery")
{
RedirectToAction("SecurityQuestion", "Mobile");
}
return View();
}
Here is my view:
#model OutsourcedTicketPlatform.UI.ViewModels.Mobile.MobileStep1ViewModel
#using OutsourcedTicketPlatform.UI.ViewModels.Mobile
#{
MobileStep1ViewModel mobileModel = Session["MobileModel"] as MobileStep1ViewModel;
ViewBag.Title = "Mobile Issue";
}
<h2>Mobile Issue Reporter</h2>
<p>Hi #mobileModel.CustomerName are you phoning today to log the mobile device as lost or stolen?</p>
#Html.RadioButton("IsMobileQuery", "MobileQuery")Yes
#Html.RadioButton("IsMobileQuery", "NotMobileQuery")No
<br /><br />
<div id="NotMobileQuery" class="HideDiv">
<input type="submit" class="btn" id="btnNotMobileQuery" value="Proceed" />
</div>
<div id="ConfirmMobile" class="HideDiv">
<p>"Please Confirm your mobile number"</p>
#foreach (var items in mobileModel.MobileNumbers)
{
#Html.RadioButton("SelectedMobileNumber", items)#items
}
<br /><br />
<input type="submit" class="btn" id="btnMobileQuery" value="Next" />
</div>
<script src="../../Scripts/Controllers/Mobile/MobileStepOne.js" type="text/javascript"></script>
<script src="../../Scripts/ViewModels/Mobile/MobileStepOneViewModel.js" type="text/javascript"></script>
Can anyone see if I am doing anything wrong? Do I need parameter in my second index method?
Try this :
#model OutsourcedTicketPlatform.UI.ViewModels.Mobile.MobileStep1ViewModel
#using OutsourcedTicketPlatform.UI.ViewModels.Mobile
#{
MobileStep1ViewModel mobileModel = Session["MobileModel"] as MobileStep1ViewModel;
ViewBag.Title = "Mobile Issue";
}
#using(Html.BeginForm("Index","Your_controller_name",FormMethod.Post)){
<h2>Mobile Issue Reporter</h2>
<p>Hi #mobileModel.CustomerName are you phoning today to log the mobile device as lost or stolen?</p>
#Html.RadioButton("IsMobileQuery", "MobileQuery")Yes
#Html.RadioButton("IsMobileQuery", "NotMobileQuery")No
<br /><br />
<div id="NotMobileQuery" class="HideDiv">
<input type="submit" class="btn" id="btnNotMobileQuery" value="Proceed" />
</div>
<div id="ConfirmMobile" class="HideDiv">
<p>"Please Confirm your mobile number"</p>
#foreach (var items in mobileModel.MobileNumbers)
{
#Html.RadioButton("SelectedMobileNumber", items)#items
}
<br /><br />
<input type="submit" class="btn" id="btnMobileQuery" value="Next" />
</div>
}
<script src="../../Scripts/Controllers/Mobile/MobileStepOne.js" type="text/javascript"></script>
<script src="../../Scripts/ViewModels/Mobile/MobileStepOneViewModel.js" type="text/javascript"></script>
You can use FormCollection instead of string for getting all values form view.

Resources