Button click not triggering an event - MVC Razor - c#

I have gone through previous posts on the same topic but I couldn't figure out what's wrong with my code. Here's my html
#model Models.Submissions
#{
ViewBag.Title = "Application";
}
<h2 class="Centre" >#ViewBag.Title</h2>
#using (Html.BeginForm("Create","Submissions",FormMethod.Post))
{
#Html.ValidationSummary(true)
<fieldset>
<table id="ApplicationTable">
<tr>
<td>
#Html.LabelFor(model => model.SubmissionId)
</td>
<td>
#Html.TextBoxFor(model => model.SubmissionId)
</td>
</tr>
<tr>
<td>
#Html.LabelFor(model => model.SubmissionDate)
</td>
<td>
#Html.TextBoxFor(model => model.SubmissionId)
</td>
</tr>
</table>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Here's my controller. The button click doesn't trigger the http post method of the submissions controller . By the way, my controller is "SubmissionsController"
public ActionResult Create()
{
return View();
}
[HttpPost]
public ActionResult Create(Submissions submission)
{
try
{
// TODO: Add insert logic here
// my logic
return RedirectToAction("Index");
}
catch
{
return View();
}
}
}
Thanks..! Help Appreciated

Seems you're trying to include jquery validation for the form as well, so my humble guess would be, that your client-side validation prevents postback to the server due to a validation error. Try to disable that validation and try again. Can't provide more info, because I don't know what exactly does your javascript do, but I think you should be able to fix it yourself now.
And as Jonesy correctly pointed out, you have a typo in your code. The second textbox should be model.SubmissionDate. That is probably causing the validation error I've mentioned earlier.

Related

Showing partial-view, only after search has been submitted Asp.Net MVC

I am new to Asp.Net Mvc. I couldn't find a solution that worked for me here, if I am blind just redirect me.
I am trying to make a web-app where i can search through clients, without displaying the entire table of clients. Only after the user presses search, the search result should show as a partial view. I understand that using Ajax is the most popular way of handling something like this.
Any pointers on how to accomplish this?
My first thought was to just make a display: block/none script connected to the submit button but the page updates each time you search rendering this idea useless. That's why i could use some help with how to asynchronously update the web page with the search result.
HomeController:
using testForAutofill.Models;
//Search Functionality
[HttpPost]
public PartialViewResult Index(string searchTerm)
{
test_Db_Context db = test_Db_Context();
List<ViewNewOrderSum> orderSums;
if (string.IsNullOrEmpty(searchTerm))//Fix this.
{
orderSums = db.ViewNewOrderSum.ToList();
}
else
{
orderSums = db.ViewNewOrderSum.Where(x =>
x.ClientName.Equals(searchTerm)).ToList();
}
return PartialView(orderSums);
}
Index View:
#model IEnumerable<testForAutofill.Models.ViewNewOrderSum>
#using (Html.BeginForm())
{
<b>Kundenavn:</b>
#Html.TextBox("searchTerm", null, new { id = "txtSearch" })
<input type="submit" value="🔍 Search" class="btn btn-primary" id="btn-search" />
}
<div id="posts-wrapper"></div>
<div class="client-div" runat="server" style="max-width: 20rem;">
<div class="card-header">Header</div>
<div class="card-body" id="client-Card">
<h4 class="card-title">Client info</h4>
<table id="client-table">
<tr>
<th>
#Html.DisplayNameFor(model => model.ClientName)
</th>
</tr>
#foreach (var item in Model)
{
#Html.Partial("_OrderSum", item)
}
</table>
</div>
</div>
Partial View:
#model testForAutofill.Models.ViewNewOrderSum
<tr>
<td>
#Html.DisplayFor(modelItem => Model.ClientName)
</td>
</tr>
No need of using Ajax. You can submit search text in Form Post. Fetch your data and filter based on your searchTerm retun to View with model. If your model is not null or empty show table else do not display table.
Checkout the below code :
View :
#model List<testForAutofill.Models.ViewNewOrderSum>
#using (Html.BeginForm()) {
<b>Kundenavn:</b>
#Html.TextBox("searchTerm", null, new { id = "txtSearch" })
<input type="submit" value="🔍 Search" class="btn btn-primary" id="btn-search" />
}
#if (Model != null && Model.Count() > 0) {
<div class="client-div" runat="server" style="max-width: 20rem;">
<div class="card-header">Header</div>
<div class="card-body" id="client-Card">
<h4 class="card-title">Client info</h4>
<table id="client-table">
<tr>
<th>
ClientName
</th>
</tr>
#foreach (var item in Model) {
#Html.Partial("_OrderSum", item)
}
</table>
</div>
</div>
}
Controller :
public ActionResult Index()
{
//if you want to load all the clients by default
test_Db_Context db = test_Db_Context();
List<ViewNewOrderSum> orderSums;
orderSums = db.ViewNewOrderSum.ToList();
return View(orderSums);
}
[HttpPost]
public ActionResult Index(string searchTerm) {
test_Db_Context db = test_Db_Context();
List<ViewNewOrderSum> orderSums;
if (!string.IsNullOrEmpty(searchTerm))
{
orderSums = db.ViewNewOrderSum.Where(x =>
x.ClientName.Equals(searchTerm)).ToList();
}
return View(result);
}
My first thought was to just make a display: block/none script
connected to the submit button but the page updates each time you
search rendering this idea useless.
You can prevent the page from updating using something like the following (using jQuery):
<script type="text/javascript">
$('form').submit(function (evt) {
evt.preventDefault();
... your code
});
</script>
Then you can make your ajax POST call, get the data, unhide table headers and append the html results from your partial view.

Why is my model and its variables not passing from View to Method inside of my Controller?

My application searches for the files that contains a string the user is looking for. So far it does that perfectly. The last thing I need to do is to export it to an excel file so I added a method inside of my controller that is called by the Result page after I press a button.
The results are stored in a List of type Result which is a class with four variables.
The method ExportToExcel currently returns string so that I can test if the list of results is null. Every single time it has come out as "No Data", therefore it is null. It perfectly prints out a table with the information in the Results page but does not have the information when i want to export it.
Why is my model not passing from view to method?
At first I wanted to pass my model so that I can access the information in the List but now I am wondering if it would be better to save the List data in the controller so that I can directly pass it to my method.
Either way would be fine and I am open to any other ways to do this.
Model
namespace Final.Models
{
public class InputModel:Result
{
public List<Result> Results { get; set; }
}
}
Controller
This controller is just showing how I am passing the InputModel between the views and method. Maybe I am doing something wrong here?
public ActionResult Index()
{
var input = new InputModel();
return View(input);
}
[HttpPost]
public ActionResult Index(InputModel input)
{
//Finds files that contain string.
//send model to Result
return View("Result", input);
}
public ActionResult Result(InputModel input)
{
return View(input);
}
[HttpPost]
public string Result(InputModel input,string export)
{
return ExportToExcel(input);
}
public string ExportToExcel(InputModel input)
{
if (input.Results!=null)
{
//Run excel code here
return "Excel Exported";
}
else
{
return "No Data";
}
}
View for Result
This is part of the view, not the whole thing. I didn't think the full view was necessary but I posted it in the bottom just in case.
#foreach(var result in Model.Results)
{
<tr>
//Return graph of information received
</tr>
}
</table>
<form action="Find/Result" method="POST">
<input type="submit" value="Export" name="export" class="btn btn-default">
</form>
Output
Occurs after pressing the "Export" Button
"No Data"
This is my first MVC applications so once again please let me know if there is any other area I can improve in.
Full View For Result
Changed the form to enclose the entire view as suggested by Wubbly but I get the same output.
#model Final.Models.InputModel
#{
ViewBag.Title = "Result";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<br />
<h4>Result</h4>
<hr />
#using (Html.BeginForm("Result", "Find", FormMethod.Post))
{
<p>The <b>#Model.SelectedText</b> files that contain <b>"#Model.Find"</b> are: </p>
<div>
<table class="table table-bordered table-responsive table-hover">
<tr>
//HEADERS
</tr>
#foreach (var result in Model.Results)
{
// int i = 1;
<tr>
<td>#result.SelectedText</td>
<td>#result.FileName</td>
<td>#result.Line</td>
<td>#result.LineCode</td>
</tr>
}
</table>
<div class="form-group">
<div class="col-md-offset-2 ">
<input type="submit" value="Export" name="export" class="btn btn-default">
</div>
</div>
</div>
}
<p>
#Html.ActionLink("Back to List", "Index")
</p>
Use for loop with hidden property which takes your property value to model.
#using (Html.BeginForm("Result", "Find", FormMethod.Post))
{
<p>The <b>#Model.SelectedText</b> files that contain <b>"#Model.Find"</b> are: </p>
<div>
<table class="table table-bordered table-responsive table-hover">
<tr>
//HEADERS
</tr>
#for (int i = 0; i < Model.Results.Count; i++)
{
// int i = 1;
<tr>
<td>
#Html.HiddenFor(r => r.Model.Results[i].SelectedText)
#Html.HiddenFor(r => r.Model.Results[i].FileName)
#Html.HiddenFor(r => r.Model.Results[i].Line)
#Html.HiddenFor(r => r.Model.Results[i].LineCode)
#Html.DisplayFor(r => r.Model.Results[i].SelectedText)
</td>
<td>#Html.DisplayFor(r => r.Model.Results[i].FileName)</td>
<td>#Html.DisplayFor(r => r.Model.Results[i].Line)</td>
<td>#Html.DisplayFor(r => r.Model.Results[i].LineCode)</td>
</tr>
}
</table>
<div class="form-group">
<div class="col-md-offset-2 ">
<input type="submit" value="Export" name="export" class="btn btn-default">
</div>
</div>
</div>
}
<p>
#Html.ActionLink("Back to List", "Index")
</p>
To anyone who might need an answer and is in a similar situation I figured my problem out. Many of you might not think it is the right way to fix it but it is what worked for me. Either way any feedback would be appreciated to improve my abilities.
First, I did change my foreach to a for loop as recommended by StephenMuecke and ShailendraKumar.
The way I transferred the data from my HTTPGet to my HTTPPostis with TempData. I used it to store my model with the user's input inside my HTTPPost Index and called it in my HTTPPost Result.
Here's how I changed my controller.
public ActionResult Index()
{
var input = new InputModel();
input.Type = input.FillType(input.Type);
return View(input);
}
[HttpPost]
public ActionResult Index(InputModel input)
{
input.FileType = input.ValueConvert();
input.FileFind();
TempData["model"] = input
return View("Result", input);
}
public ActionResult Result(InputModel input)
{
return View(input);
}
[HttpPost]
public void Result()
{
InputModel model = new InputModel();
model = (InputModel)TempData["model"];
model.ExportToExcel();
}

asp.net mvc 4 [HttpPost] not working

I am new to asp.net MVC 4. i have some problems dealing with attributs
i use [httppost] attribut in my controller but it's not working
it's not even invoked
my controller
public ActionResult Inscription()
{
return View();
}
[HttpPost]
public ActionResult Inscription(Candidat candidat)
{
if (!ModelState.IsValid)
{
return View(candidat);
}
return RedirectToAction("Index");
}
my view
#model ProcRec.Models.Candidat
#{
ViewBag.Title = "Inscription";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#Html.ValidationSummary(true)
<div class="form_settings">
#using (Html.BeginForm("Inscription", "CandidatController"))
{
<table ="#FFFFFF">
<tr>
<td>#*<span >Nom :</span>*# #Html.LabelFor(model => model.nom_candidat)</td>
<td> #Html.TextBoxFor(model => model.nom_candidat)
#Html.ValidationMessageFor(Model => Model.nom_candidat)
.
.
</table>
}
<input type="submit" class="submit right" value="Inscription" />
think you for your help
Just correct beginform as :
#using (Html.BeginForm("Inscription", "CandidatController",FormMethod.Post))
{
........
<input type="submit" class="submit right" value="Inscription" />
}
Put submit button inside BeginForm() and give BeginForm() FormMethod as Post.
Thankzz..
Put your <submit> element inside the form:
#using (Html.BeginForm())
{
...
<input type="submit" class="submit right" value="Inscription" />
}
Don't need to change Html.BeginForm. By default it's POST.
Check : FormExtensions.BeginForm
Only issue is with the submit button, it should be inside form as mentioned in Andy Refuerzo's answer. Don't know why it is down-voted.

Ajax form not submitting and updating a partialview

I'm going crazy on this... I've been trying to figure out how to use ajax to update a partial view for quite some time... I've got to be missing something simple and easy.
I'm in VS2012, MVC4.
First, I do have these bundles loaded:
#Styles.Render("~/css")
#Styles.Render("~/Content/themes/base/css")
#Scripts.Render("~/js" )
#Scripts.Render("~/bundles/jqueryui")
#Scripts.Render("~/bundles/jqueryval")
I have also tried to specify the unobtrusive script manually as well...
Then I have this in my view:
#using (Ajax.BeginForm("Index_AddGroup", new AjaxOptions { UpdateTargetId = "AddGroupList" }))
{
<div>
#Html.LabelFor(model => Model.NewGroups.GroupName)
</div>
<div>
#Html.DropDownListFor(model => Model.AllGroups.nSelectGroupID, Model.AllGroups.GroupList, "Select Group to Add")
<input type="submit" value="Add Group" />
</div>
}
Then I load a partial view:
<div id="AddGroupList">
#if(Model.Groups != null)
{
#Html.Partial("_AddGroups", Model.Groups);
}
</div>
In that partial view I do the following:
#model IEnumerable<MyApp.ViewModels.Group>
#{
ViewBag.Title = "Added Groups";
}
<h2>Groups to be Added</h2>
<table>
<tr>
<th>Group Name</th>
<th>Added until</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>#Html.DisplayFor(model=>item.GroupName)</td>
<td>#Html.DisplayFor(model=>item.EndDate)</td>
</tr>
}
Controller:
[HttpPost]
public ActionResult Index_AddGroup(SearchedUser viewModel)
{
AddGroupsContext db = new AddGroupsContext();
Group NewGroup = new Group();
NewGroup.GroupName = "test";//viewModel.
db.Groups.Add(NewGroup);
db.SaveChanges();
return PartialView("_AddGroups", db.Groups);
}
I loaded up fiddler and clicked on the button but no request was being sent. Why isn't that javascript/ajax code running?
I think you need a submit button. try:
<input type="submit" value="Add Group" />
Also i think you will need to add a reference to as it doesn't look like it is included anywhere:
jquery.unobtrusive-ajax.js
I think you can get it through nuget if you dont have it already.
otherwise here is a script tag that includes a CDN link:
<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.unobtrusive-ajax.js"></script>

Getting response as null in http post method

I am using the following code:
Controller:
public ActionResult Update(int studentId = 0, int subjectId = 0)
{
Engine engine = new Engine(studentId, subjectId);
List<Chapter> chapterList = engine.GetChapters();
return View(chapterList);
}
[HttpPost]
public ActionResult Update(List<Chapter> model)
{
return View(model);
}
Update.cshtml:
#model IEnumerable<Chapter>
#{
ViewBag.Title = "Update";
}
<h2>
Update</h2>
#using (Html.BeginForm("Update", "StudyPlan", FormMethod.Post))
{
<fieldset>
<table>
#foreach (var item in Model)
{
<tr>
<td>
#item.name
</td>
<td>
#Html.CheckBoxFor(chapterItem => item.included)
</td>
</tr>
}
</table>
<input type="submit" value="submit" />
</fieldset>
}
I want when a user selects checkboxes, the response should come in httppost method of controller. But I am getting null value Update method. Am I doing something wrong
You need to use for instead of foreach. In that case checkbox will be rendered as
<input type='checkbox' name='Model[0].included'/>
<input type='checkbox' name='Model[1].included'/>
...
and then ModelBinder will successfully create model
Example:
#model List<Chapter>
#{
ViewBag.Title = "Update";
}
<h2>
Update</h2>
#using (Html.BeginForm("Update", "StudyPlan", FormMethod.Post))
{
<fieldset>
<table>
#for (int i =0;i<Model.Count;i++)
{
<tr>
<td>
#Model[i].name
</td>
<td>
#Html.CheckBoxFor(chapterItem => Model[i].included)
</td>
</tr>
}
</table>
<input type="submit" value="submit" />
</fieldset>
}
PS. in that example Model changed to List<> from IEnumerable
It happens because MVC analyze expression in CheckBoxFor method. And it this expression is array accessor, then it generates different control name. And based on Name ModelBinder successfully creates List<>
As Sergey suggested, use a for loop, but try this:
#for (int i =0;i<Model.Count;i++)
{
<tr>
<td>
#Html.HiddenFor(m => m[i].id)
#Html.DisplayFor(m => m[i].name)
</td>
<td>
#Html.CheckBoxFor(m => m[i].included)
</td>
</tr>
}

Categories

Resources