I have a view where I got my Ajax.BeginForm and it submits as it should. But then I have a "save icon" and when I press that button I need the values from inside the form. The form submits presents a calculation and the save icon is suppose to save it all.
But when I press the save icon (with Url.Action("SaveExcel", "Save") I can't get the values from the textboxes. How do I do that?
My HTML:
<img src="../../Images/glyphicons_446_floppy_save.png" alt="save" id="saveIcon">
<!-- Contains forms and input for annuity calculation -->
<div class="calcInput" id="calcInput">
#using (Ajax.BeginForm("ShowDetailAnnuity", "Calculation", new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "CalcDetail",
LoadingElementId = "Loader",
}))
{
<div class="calculateBox">
<label for="calcOption">Choose value to calculate:</label>
<select id="calcOption" name="calcOption" title="Choose what value you want to calculate">
<option value="PMT" id="PMT" name="PMT">Payment (PMT)</option>
<option value="I" id="I" name="I">Interest (I)</option>
<option value="FV" id="FV" name="FV">Future value (FV)</option>
<option value="PV" id="PV" name="PV">Present value (PV)</option>
</select>
</div>
<div class="calculateBox" background-color="#777777">
#Html.Label("Present value (PV)", new { #id = "pvLabel" })
#Html.TextBox("PresentValue", null, new { #class = "PresentValue" })
#Html.Label("Future value (FV)", new { #id = "fvLabel" })
#Html.TextBox("FutureValue", null, new { #class = "FutureValue" })
#Html.Label("Interest rate", new { #id = "intRateLabel" })
#Html.TextBox("InterestRate", null, new { #class = "InterestRate" }) <br /> <br />
<input type="radio" name="advanceOrArrears" id="inAdvance" value="inAdvance" /> In advance<br />
<input type="radio" name="advanceOrArrears" id="inArrears" value="inArrears" /> In arrears
</div>
<div class="calculateBox">
<label for="startDate">Start date:</label>
<input type="date" id="StartDate" name="startdate" title="Choose start date for your calculation" /><br />
#Html.Label("Payment frequency")
<select id="PmtFreq" name="PmtFreq" title="Choose the payment frequency, for example: Every month">
<option value="Monthly">Monthly</option>
<option value="Quarterly">Quarterly</option>
</select><br /><br />
#Html.Label("No of payment periods")
#Html.TextBox("PaymentPeriods")
#Html.Label("Date time convention")
<select id="DTC" name="DTC" title="Choose your Date time convention">
<option value="360/360">360/360</option>
<option value="365/365">365/365</option>
</select><br /><br />
<input type="submit" id="CalcBtn" class="calcBtn" name="SubmitBtn" value="Calculate" title="Calculate your calculation" />
</div>
}
</div>
My controller:
public class SaveController : Controller
{
public ActionResult SaveExcel(string PresentValue) //Can't get PresentValue here..
{
return View();
}
}
I have tried using the names of the textboxes as parameter in the controller, and I have also tried Request.Form["PresentValue"] but nothing of that works
Sounds like you need two submit buttons.
Try turning your save button into a submit button inside your form, so that you have:
<input type="submit" name="SubmitButton" value="Calculate"/>
<input type="submit" name="SubmitButton" value="Save"/>
And then in your controller, differentiate between which button was pressed by having something like:
public ActionResult SaveExcel(string PresentValue, string SubmitButton)
{
if(SubmitButton == "Save") .... <save code>
if(SubmitButton == "Calculate") .... <calc code>
return View();
}
Related
I have checkboxes and select options inside a form.
<label>
<input type="checkbox" name="checkedBoxes" value="Reseller"checked />
<span>Reseller</span>
</label>
<label>
<input type="checkbox" name="checkedBoxes" value="SI" checked/>
<span>SI</span>
</label> //selects
...
Checkboxes are displayed as checked.
This is what my controller looks like:
public IActionResult combinedForm(string[] checkedBoxes, string SelectOption, string SelectOptionComp, string SelectOptionSer, string SelectOptionSoft, string SelectOptionApp)
{ //viewModel=...
var deneme = viewModel.Where(x =>x.Companies.company_type.Contains(checkedBoxes[0]));
}
How can I keep the state of checkboxes, preferably with the selected select options on view when I clicked the submit button?
Used viewbags for both
#if (((string[])ViewBag.checkedBoxes).Contains("Component provider"))
{
<label>
<input type="checkbox" name="checkedBoxes" value="Component provider" checked />
<span>Component provider </span>
</label>
}
else if (!((string[])ViewBag.checkedBoxes).Contains("Component provider"))
{
<label>
<input type="checkbox" name="checkedBoxes" value="Component provider" />
<span>Component provider </span>
</label>
}
<select style="width:100px" id="SelectOption" name="SelectOption" value="a">
<option>#Html.Label("-",(string)ViewBag.Name,new {#class = "mylabel" })</option>
I have a problem with my form its not passing radio button selected value to controller but another values are passed successfully when debugging.
Please note Job.PublicSubmissionReviewed its boolean, I noticed the this Job.PublicSubmissionReviewed passed through the form at all.
What am I missing on the radio button:
Here is my form and controller, your assistance will be greatly appreciated:
<form asp-action="Review">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="Job.Id" />
<div class="form-group">
<p><strong>Approve or Reject public submission</strong></p>
<div class="form-group form-check-inline">
<label class="form-check-label">
<input class="form-radio-input" name="status" value="True" type="radio" asp-for="Job.PublicSubmissionReviewed" /> Approve
</label>
</div>
<div class="form-group form-check-inline">
<label class="form-check-label">
<input class="form-check-input" name="status" value="False" type="radio" asp-for="Job.PublicSubmissionReviewed" /> Reject
</label>
</div>
</div>
<div class="form-row showapprove" id="True">
<div class="form-group col-md-6">
<label asp-for="Job.JobCategoryId" class="control-label"></label>
<select asp-for="Job.JobCategoryId" class="form-control" asp-items="ViewBag.JobCategoryId">
</select>
</div>
<div class="form-group col-md-6">
<label asp-for="Job.Name" class="control-label"></label>
<input asp-for="Job.Name" class="form-control" />
<span asp-validation-for="Job.Name" class="text-danger"></span>
</div>
<div class="form-group col-md-6">
<label asp-for="Job.JobNo" class="control-label"></label>
<input asp-for="Job.JobNo" class="form-control" />
<span asp-validation-for="Job.JobNo" class="text-danger"></span>
</div>
<div class="form-group col-md-6">
<label asp-for="Job.ContractorId" class="control-label"></label>
<select asp-for="Job.ContractorId" class="form-control" asp-items="ViewBag.ContractorId">
</select>
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-outline-primary"><i class="fas fa-save" aria-hidden="true"></i> Submit</button>
</div>
</form>
public async Task<IActionResult> Review(int id, JobViewModel model)
{
if (id != model.Job.Id)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
var job = _context.Jobs.Where(j => j.Id == id).SingleOrDefault();
if (model.Job.PublicSubmissionReviewed == true) // approve public submission
{
job.PublicSubmissionReviewed = true;
job.PublicSubmissionReviewDate = DateTime.Now;
job.Name = model.Job.Name;
job.New = true;
job.JobNo = model.Job.JobNo;
job.JobCategoryId = model.Job.JobCategoryId;
job.ContractorId = model.Job.ContractorId;
_context.Update(job);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Public));
}
else if (model.Job.PublicSubmissionReviewed == false) // reject public submission
{
job.PublicSubmissionReviewed = true;
job.PublicSubmissionReviewDate = DateTime.Now;
job.New = false;
job.PublicSubmissionRejected = true;
job.PublicSubmissionRejectedDate = DateTime.Now;
job.PublicSubmissionReviewRejectReason = model.Job.PublicSubmissionReviewRejectReason;
_context.Update(job);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Public));
}
}
catch (DbUpdateConcurrencyException)
{
if (!JobExists(model.Job.Id))
{
return NotFound();
}
else
{
throw;
}
}
}
return View(model);
}
The name HTML attribute in a form element is what will be sent to the server to identify that field once you submit the form. Razor's model binding expects a certain name for form fields, and asp-for automatically sets that name for you. Since you've manually specified a name instead, the model binder will not be able to recognize the field, and therefore will not set it in your model.
It looks like you're setting the name in order to group the radio buttons together. Since asp-for will use the same name for a given bound property, you do not need to worry about that; all radio buttons corresponding to a certain property will be grouped together.
Therefore, you can simply remove the name attribute and your code should then work fine:
<input class="form-radio-input" value="True" type="radio" asp-for="Job.PublicSubmissionReviewed" /> Approve
<input class="form-check-input" value="False" type="radio" asp-for="Job.PublicSubmissionReviewed" /> Reject
I append my select option from database table. Select option has two type
scalar
event
If the option type is scalar, I need to show 2 input fields (alarm, reset) so that user can inset values in it and when the option type is event I need to hide 2 input fields (alarm, reset) so that user cannot inset values in it.
When the option type is scalar, my form saves successfully but when option type is event form submit button not going to perform any action.
Can you please help?
Here is my code
HTML
<div class="row">
<form method="post" action="/Home/SaveTriggers" class="form-inline">
<div class="col-md-12">
<div class="col-md-2">
<select name="sourceId" class="select2" required>
#foreach (var i in ViewBag.opt)
{
<option value="#i.Id,#i.name,#i.type" id="opt">#i.name</option>
}
</select>
</div>
<div class="col-md-2">
<input id="alarm" name="alarm" type="text" placeholder="alarm" style="display:none" required />
</div>
<div class="col-md-2">
<input id="reset" name="reset" type="text" placeholder="reset" style="display:none" required />
</div>
<div class="col-md-1">
<input type="text" name="delay" id="delay" placeholder="delay" required />
</div>
<div class="col-md-3">
<select class="address2" name="action" id="select" required>
<option selected disabled>Select alarm action</option>
<option>John Doe, Switch on warning light</option>
<option>John Doe</option>
<option>Do anything</option>
</select>
</div>
<div class="col-md-2">
<button id="delete2" type="button" class="btn btn-default">Delete</button>
</div>
<button class=" add btn btn-primary" type="submit">Add</button>
</div>
</form>
</div>
Jquery(as i have to hide or show alarm or reset fields respectively)
<script>
$(document).ready(function () {
$(".select2").change(function () {
var text = $(".select2 option:selected").text();
var val = $(".select2 option:selected").val();
var res = val.split(",");
var type = res[2];
if (type == "scalar") {
document.getElementById("reset").style.display = "block";
document.getElementById("alarm").style.display="block"
}
else if(type=="event") {
document.getElementById("reset").style.display = "none";
document.getElementById("alarm").style.display = "none"
var alarm = document.getElementById("alarm");
}
});
});
</script>
The problem is most likely your inputs for alarm and reset.
If type is event, they are hidden and will most likely hold no value. But since they are required, the form will not submit until that error is resolved.
So you can either remove the required attribute from those 2 input fields, populate them with default values or use novalidate in your form tag. This disables form validation. You'd have to validate your inputs by hand in javascript.
<div class="col-md-2">
<input id="alarm" name="alarm" type="text" placeholder="alarm" style="display:none" />
</div>
<div class="col-md-2">
<input id="reset" name="reset" type="text" placeholder="reset" style="display:none" />
</div>
<div class="col-md-2">
<input id="alarm" name="alarm" type="text" placeholder="alarm" style="display:none" required />
</div>
<div class="col-md-2">
<input id="reset" name="reset" type="text" placeholder="reset" style="display:none" required />
as you're having required attribute in your input element, the validation is getting triggered and not letting you submit the form.
i would suggest you to do a validation on jquery on submit instead of using default html5 validation
I want to display a search box, submit button and 2 drop down boxes in the same line for ipads to large screens. If the screen is smaller than ipad size it will break in to 2 or 3 lines. I tried all samples given in here, but no luck.
I am using ASP.NET MVC 4.Here is my code:
Index.cshtml
<div class="row">
<div class="abc">
#using (Html.BeginForm("Contact", "Home", FormMethod.Get, new { id = "f1", #class = "form-inline" }))
{
<div class="form-group col-xs-6 col-lg-4">
<label class="sr-only" for="find-input">Find: </label>
<div class="input-group ">
<input type="text" name="filter" value="#ViewBag.filter" class="form-control" placeholder="Search by Product or Description" id="find-input" />
<span class="input-group-btn ">
<button class="btn btn-default" type="submit" onclick="this.form.submit();">Go</button>
</span>
</div>
</div>
<div class="col-xs-6 col-lg-4">
<div class="form-group ">
<div class="input-group ">
<label class="control-label " for="sort-drop-down">Sort </label>
#Html.DropDownList("sortColumn", ViewBag.SortColumns as SelectList, "", new { onchange = "this.form.submit();", #class = "form-control", id = "sort-drop-down" })
</div>
</div>
</div>
<div class="col-xs-6 col-lg-4">
<div class="form-group ">
<label class="control-label " for="page-size-drop-down">Show </label>
<div class="input-group ">
#Html.DropDownList("pageSize", ViewBag.pageSizes as SelectList, "", new { onchange = "this.form.submit();", #class = "form-control", id = "page-size-drop-down" })
</div>
</div>
</div>
<input type="hidden" name="viewMode" id="hd1" value="#ViewBag.DisplayMode" />
}
</div>
</div>
HomeController.cs
public ActionResult Index(int pageSize = 8, string sortColumn = "Id", string viewMode = "grid")
{
ViewBag.Message = "Your contact page.";
Dictionary<string, string> sortByColumnsList = new Dictionary<string, string>() { { "Id", "Id" }, { "ProductName", "Product Name" }, { "Description", "Description" } };
ViewBag.SortColumns = new SelectList(sortByColumnsList, "Key", "Value", sortColumn); // NOTE: To set a default value(4) we can use: new SelectList(sortByColumnsList, "Key", "Value", "Id=4")
//Page Sizes
List<string> pageSizeList;
if (viewMode.ToLower() == "table")
{
pageSizeList = new List<string>() { "10", "25", "50", "100" };
if (pageSizeList.IndexOf(pageSize.ToString()) < 0)
{
pageSize = 10;
}
}
else
{
pageSizeList = new List<string>() { "8", "12", "16", "20" };
if (pageSizeList.IndexOf(pageSize.ToString()) < 0)
{
pageSize = 8;
}
}
ViewBag.pageSizes = new SelectList(pageSizeList, pageSize);
return View();
}
CSS
.abc {
margin-top: 10px;
}
Please can someone help?
You have just handled case for a large device(col-lg) or an extra small device(xs). So when customising customise it for md as well i.e. Medium Sized devices.
In your case just don't handle it and let outer inline-form class handle it for you.
Also, try enclosing your row within a div with class container. As I'm not much familiar with .NET, but let's say we are observing our final html page obtained.
See sample output fiddle here.
https://jsfiddle.net/3vnxncke/
Also, see screenshots below for same scenarios with the code by screen adjustment.
You may try adjusting html screen size to see other device scenarios.
Hope it helps.
If someone having same issue when using MVC templates, I would like to show what I have done to fix this issue. The correct way to use bootstrap html is described on #Vinay Prajapati's answer. Although it works for pure html page it doesn't work when we use MVC scaffolding. So I have made some css adjustment as follows.
.input-group
{
display:inline-table;
}
.control-label{
vertical-align:middle;
}
.form-group .control-label
{
margin-top:-15px;
}
.input-group-btn{
width:auto;
}
Adjusted html
<div class="container body-content">
<form class="form-inline" id="f1" method="get">
<div class="row">
<div class="form-group">
<label class="sr-only" for="find-input">Find: </label>
<div class="input-group ">
<input type="text" name="filter" value="ViewBag.filter" class="form-control" id="find-input" />
<span class="input-group-btn ">
<button class="btn btn-default" type="submit" onclick="this.form.submit();">Go</button>
</span>
</div>
</div>
<div class="form-group">
<label class="control-label " for="sort-drop-down">Sort </label>
<div class="input-group ">
<select class="form-control" id="sort-drop-down" name="sortColumn" onchange="this.form.submit();">
<option selected="selected" value="Id">Id</option>
<option value="ProductName">Product Name</option>
<option value="Description">Description</option>
</select>
</div>
</div>
<div class="form-group">
<label class="control-label " for="sort-drop-down">Show: </label>
<div class="input-group ">
<select class="form-control" id="page-size-drop-down" name="pageSize" onchange="this.form.submit();">
<option>8</option>
<option>12</option>
<option>16</option>
<option>20</option>
</select>
</div>
</div>
</div>
</form>
</div>
I have a method GenerateCSV(string accountNumber, string dt1, string dt2) in my ReportController
How do i initiate this request from my Report.cshtml?
<h2>Settled Report</h2><br />
#using (Html.BeginForm("Report", "ReportController", FormMethod.Get))
{
<p>
Accounts: #Html.DropDownList("accountNumber")
Start Date: #Html.TextBox("dt1", null, new { #class = "date-picker" })
End Date: #Html.TextBox("dt2", null, new { #class = "date-picker" })
#*#Html.Hidden("reportType", 1)*#
<input type="hidden" id="" value="1" name="reportType" />
<input type="submit" value="View Report" />
</p>
<div class="exportbuttons">
#Html.ActionLink("Export to CSV", "GenerateCSV")
</div>
}
The GenerateCSV is called but all params are null, and the server tries to navigate to Report/GenerateCSV
Your ActionLink is just a link. It won't invoke the GenerateCSV action with the parameters you want because it is just a link with no parameters being passed.
UPDATE
I'm not sure what the intent of your page is:
Is the intent that the user has two buttons, one to view the report, one to export? If so, refer to Option 2 below.
Is the intent that the user has one button and all it does is export to CSV? If so, refer to Option 1 below.
Option 1 - Only one button on the page
Change your Razor as follows:
#using (Html.BeginForm("GenerateCSV", "Report", FormMethod.Get))
{
<p>
Accounts: #Html.DropDownList("accountNumber")
Start Date: #Html.TextBox("dt1", null, new { #class = "date-picker" })
End Date: #Html.TextBox("dt2", null, new { #class = "date-picker" })
#*#Html.Hidden("reportType", 1)*#
<input type="hidden" id="" value="1" name="reportType" />
<input name="reportType" type="submit" value="Export to CSV" />
</p>
}
Option 2 - Two buttons on the page
If you want to allow the user to either click the View Report button to view it in a browser or Export to CSV to have the report exported instead of shown to the user, I would suggest:
Change your Report() method so that it accepts a string parameter called reportType, and check the value to determine whether to show it in a browser or call GenerateCSV()
public ActionResult Report(string accountNumber, string dt1, string dt2, string reportType)
{
if (reportType == "View Report")
{
// code to show report to user in browser
}
else
{
return GenerateCSV(accountNumber, dt1, dt2);
}
}
Change your razor as follows:
#using (Html.BeginForm("Report", "ReportController", FormMethod.Get))
{
<p>
Accounts: #Html.DropDownList("accountNumber")
Start Date: #Html.TextBox("dt1", null, new { #class = "date-picker" })
End Date: #Html.TextBox("dt2", null, new { #class = "date-picker" })
#*#Html.Hidden("reportType", 1)*#
<input type="hidden" id="" value="1" name="reportType" />
<input name="reportType" type="submit" value="View Report" />
<input name="reportType" type="submit" value="Export to CSV" />
</p>
}
Your model should be like
public class CSVDetails
{
public List<long> AccountNumber {get; set;}
public DateTime dt1 {get; set;}
public DateTime dt2 {get; set;}
}
Then your view should be like
#model YourProjectNamespace.Models.CSVDetails
<h2>Settled Report</h2><br />
#using (Html.BeginForm("Report", "ReportController", FormMethod.Get))
{
<p>
Accounts: #Html.DropDownListFor(a=>a.AccountNumber)
Start Date: #Html.TextBoxFor(a=>a.dt1, new { #class = "date-picker" })
End Date: #Html.TextBoxFor(a=>a.dt2, new { #class = "date-picker" })
<input type="hidden" id="" value="1" name="reportType" />
<input type="submit" value="View Report" />
</p>
<div class="exportbuttons">
#Html.ActionLink("Export to CSV", "GenerateCSV")
</div>
In controller
public ActionResult GenerateCSV(CSVDetais csv)
{
// your logic here
}
Hope it helps you!!!