MVC 5 Razor handling view when validation fails - c#

I have an MVC Razor layout with a WebGrid.
#Html.ValidationSummary()
<div>
#model List<DelsDTO>
#{
var grid = new WebGrid(Model, defaultSort: "Name");
}
#grid.GetHtml(headerStyle: "webgrid-header", columns: grid.Columns(
grid.Column(header: "Select", format: #<text><input name="checkedDelUnits" type="checkbox" value="#item.delId" /></text>),
grid.Column("DelId", header: "ID"),
grid.Column("Name", style: "nameColLen"),
grid.Column("CRate", header: "C Rate", style: "span1", format: (item) =>
(item.CRate == null) ? String.Empty : String.Format("{0:0.00}", #item.CRate))
)
)
<td><input type="submit" name="saveChanges" value="Save Changes" /></td>
}
</div>
Using a submit button I perform validation checks in a controller method.
If the validation fails I set:
ModelState.AddModelError("", "No records Selected");
return View("Search");
At this point I have no datasource for the view so it is returned with an empty grid.
What is best practice for handling this?
Should I pass the webgrid datasource (model) from the view to the controller only to pass it back if validation fails? If so how do that?

If the validation fails you basically need to create the model once again since it is not saved anywhere. So if on the initial action you were doing something like (just an idea below):
var model = GetGridModel();
return View("Search", model);
You would need to do the same on submit when validation failed:
ModelState.AddModelError("", "No records Selected");
var model = GetGridModel();
return View("Search", model);

Related

How do I call my method in html?

I want to call my method in my mvc view. I have a method called SavePersoon wich has to save the changed data into my database. This is my code from my services:
public bool SavePersoon(PersoonModel persoon)
{
bool result = true;
db.Persoon.AddOrUpdate(persoon.GetPoco());
db.SaveChanges();
return result;
}
This is the button who has to be pressed and then this code above has to deal the work itself.
The view:
<button type="button" id="btnSaveChanges" class="btn btn-primary">Opslaan</button>
Do I have to use something similair like <asp:LinkButton...?
You can make use of Ajax , Something like this
$("#btnSaveChanges").on("click",function(){
$.ajax({
url:"/controllerName/SavePersoon",
data:$("#formName").serialize(),
cache:false,
type:"POST",
error:function(){
alert("Error");
}
});
});
If you use Razor view engaine, you can make your method return an action result and call it from the view using Html.Actionlink.
You can do 2 things:
Use the HTML Helpers that ASP.Net MVC provides to create a form which posts to the required method, something like 'Save' of the controller 'Person':
#using (Html.BeginForm("Save", "Person", FormMethod.Post, new { #class = "form-horizontal" })) {
<div>
<!-- Your HTML, this could for example be a text field for the person its name -->
#Html.TextBoxFor(Model => Model.Name, new { #class = "form-control" })
<input type="submit" class="btn btn-primary" value="Save" />
</div>
}
This will create a form tag for you, something like <form action="person/save" method="post"> ... your HTML & the submit button ... </form>
An alternative is to use Ajax to prevent the page from refreshing as stated in the above post.
$("#btnSaveChanges").on("click",function(){
$.ajax({
url: '#Url.Action("Save", "Person")', // Again an MVC HTML Helper to create a URL
data:$("#Name").val(), // Posts the value of a text field with ID "Name"
cache:false,
type:"POST",
success: funcion(returnValue) {
// Do something with the result.
}
error:function(){
alert("Error");
}
});
});

Redirecting parent page from Html.renderAction child without using Ajax, Java, Jquery or such

I have a problem where I have a form in a Html.RenderAction and after submitting the form I have to reload the parent but I keep getting "Child actions can not perform redirect actions". So how can I solve it without Ajax etc.
In my parent I have:
#{
var UserReviewExist = Model.Reviews.FirstOrDefault(x => x.AspNetUser.UserName == Name.AspNetUser.UserName);
}
#{if (UserReviewExist == null)
{
Html.RenderAction("ReviewCreate", "Reviews", new { BookID = Model.Id });
}
}
My RenderAction View contains this:
#model Trigger_Happy_Bunnies.Models.Review
#{
Layout = null;
}
#{
if (true)
{
Trigger_Happy_Bunnies.Models.Review newReview = new Trigger_Happy_Bunnies.Models.Review();
<div style="border:1px black">
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
and ends with
<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>
}
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
And lastly I have this in my controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult ReviewCreate([Bind(Include = "Id,BookId,UserId,Text,Title,Rating,IsActive,IsReported,ReportedBy,ReportReason,ModifiedDate,ModifiedBy,CreatedDate")] Review review)
{
if (ModelState.IsValid)
{
db.Reviews.Add(review);
db.SaveChanges();
return View("~/Views/Reviews/ReviewCreate.cshtml");
}
ViewBag.UserId = new SelectList(db.AspNetUsers, "Id", "Email", review.UserId);
ViewBag.BookId = new SelectList(db.Books, "Id", "UserId", review.BookId);
return PartialView();
}
So how can I update the parent view when submitting the form?
I'm not sure what your issue is here. A child action merely dumps its response into the view. So at the end of the day, whether you used a child action, a partial or just plopped the code right in the view, you just have a one HTML document that includes a form.
Calling Html.BeginForm with no parameters says basically that it should use the current action, but even in the context of child action, that's still going to be the main action being rendered. So, your form will post to that main action, not your child action.
That's how it should be. You cannot post to a child action, because that makes no sense in the context of a web page. Technically, you can as long as it's not marked as [ChildActionOnly], but the entire page will change to the partial view that's returned as the response, sans layout. If you want to replace just the area that was rendered via the child action, you must submit an AJAX request that returns the partial response and manually replace the appropriate node in the DOM with that.
In other words, that's why a child action can't redirect. It's not a true action and it hasn't been routed to. It's not rendered until the response preparation phase, and by that point, there's already data in the response, preventing any changes, like a redirect. If you need to redirect after the post of the form, you should have that already in place, just make sure your main action has a version that handles post, and redirect from there.

Filter records in database according to the selected checkboxes using MVC

I have a Ajax.BeginForm in my razor view. I want to have 3 check boxes.
Begineer
Intemidiate
advance
checkoxes can select for any combination. When I clicked submit button bellow method in my controller will triggered.
public PartialViewResult SearchCourseCriteria(){
var courses = from s in db.CourseCategories
select s;
return PartialView("_Courses", courses);
}
This is my view
#using (Ajax.BeginForm("SearchCourseCriteria", new AjaxOptions
{
UpdateTargetId = "CourseList",
InsertionMode = InsertionMode.Replace,
HttpMethod = "GET"
}))
{
td>
#Html.CheckBoxFor()
</td>
<td>
<input type="submit" value="Search" class="btn " />
</td>
}
In my model there is field called CourseLevel. I want to know How to filter courses according to the selected checkboxes.
EX : If I select begineer and Intermidiate checkboex. I want to get all courseCategories from that levels. I dont know how to get that result. Help please.
In you view, generate 3 checkboxes for each value
<label>
<input type="checkbox" name="courselevel" value="Begineer" /> // Beginner?
<span>Begineer</span>
<label>
<label>
<input type="checkbox" name="courselevel" value="Intemidiate" /> // Intermediate?
<span>Intemidiate</span>
<label>
... // ditto for advance
Then add a parameter to the method
public PartialViewResult SearchCourseCriteria(string[] CourseLevel)
The value of CourseLevel will be an array of the selected checkboxes, for example [ "Begineer", "advance" ] if you checked the first and third checkboxes
You can then modify you query to
var courses = from s in db.CourseCategories
where CourseLevel.Contains(s.CourseLevel)
select s;
or
var courses= db.CourseCategories.Where(c => CourseLevel.Contains(c.CourseLevel));
Side note: I would recommend you use an enum to define the values for CourseLevel

Saving all checkbox values from WebGrid in MVC 4

I am new to MVC 4. I am stuck in a situation and want some suggestions to resolve the problem. The problem scenario is:
I am rendering a WebGrid inside a partial view and the WebGrid format is as follows:
An IEnumerable collection is bound with the WebGrid. The view for binding WebGrid is:
#{
MIS.Areas.AdminModule.Models.AdminModuleViewModels.Module_UserGrp_Permission allPermissions = new MIS.Areas.AdminModule.Models.AdminModuleViewModels.Module_UserGrp_Permission();
}
#{
var grid = new WebGrid(Model, canPage: true, rowsPerPage: 10, selectionFieldName: "selectedRow", ajaxUpdateContainerId: "Title");
grid.Pager(WebGridPagerModes.NextPrevious);}
<div id="gridContent">
#grid.GetHtml(tableStyle: "webGrid",
headerStyle: "header",
alternatingRowStyle: "alt",
selectedRowStyle: "select",
columns: grid.Columns(
grid.Column(header: "Select",
format: #<input class="select" id="assignChkBx" name="assignChkBx" type="checkbox" #allPermissions.intMenuId/>),
grid.Column(header: "MenuId", format: (item) => item.intMenuId, style: "description"),
grid.Column(header: "Menu", format: (item) => item.strMenuName, style: "description", canSort: true),
grid.Column(header: "Add", format: #<text><input name="Add" type="checkbox" #(item.boolAddPer == true ? "Checked" : null) id="chkboxIsActiveAdd" /></text>),
grid.Column(header: "Edit", format: #<text><input name="Edit" type="checkbox" #(item.boolEditPer == true ? "Checked" : null) id="chkboxIsActiveEdit" /></text>),
grid.Column(header: "Delete", format: #<text><input name="Delete" type="checkbox" #(item.boolDeletePer == true ? "Checked" : null) id="chkboxIsActiveDelete" /></text>),
grid.Column(header: "Grant", format: #<text><input name="Grant" type="checkbox" #(item.boolGrantPer == true ? "Checked" : null) id="chkboxIsActiveGrant" /></text>)
))
</div>
And fetching data from database as follows (I am NOT using EntityFramework) :
var result = from column in dt.AsEnumerable()
select new Module_UserGrp_Permission
{
intMenuId = Convert.ToInt32(column["MenuId"]),
intUserGrpId = Convert.ToInt32(column["UserGrpId"]),
strMenuName = Convert.ToString(column["MenuName"]),
boolAddPer = Convert.ToBoolean(column["boolGAdd"]),
boolEditPer = Convert.ToBoolean(column["boolGEdit"]),
boolDeletePer = Convert.ToBoolean(column["boolGDel"]),
boolViewPer = Convert.ToBoolean(column["boolGView"]),
boolGrantPer = Convert.ToBoolean(column["boolGGrant"])
};
return new List<MIS.Areas.AdminModule.Models.AdminModuleViewModels.Module_UserGrp_Permission>(result);
Now the problem is I have to save all the checked/unchecked items from this WebGrid.
What should I do to save all the values after clicking the 'Save' button.
Please suggest possible solutions.
Thank you all.
Since all of your check boxes have the same name you can do a
string result = Request.Form["assignChkBx"].ToString();
on your controller which will give you a list of all of the checked checkboxes. Hopefully this helps.
While it's not a coded worked solution, I've managed to get this working with a single checkbox. Should be simple enough to get it wired up for multiple: ASP.NET MVC Display an HTML Table with Checkboxes to Select Row Items

How to get value entered in a text box from a view

My MVC view has a table with an editable field as follows.
<td>
<div class="view">
<%= Model.device_Url%>
</div>
<div class="edit">
<input type="text" name="deviceurl" id = "deviceurl" value="<%= Model.device_Url%>" />
</div>
</td>
The user has the option to edit then save the value entered in the above text box field.
<td class="options">
<div class="view">
Edit
</div>
<div class="edit">
Save
Cancel
</div>
</td>
I would like to call my controller /Live/Update and pass in the value changed in the text box in the URL.
How would I get the value entered inthe text box.
Do I need java script to do this?
You will need javascript unless you want to use a traditional submit.
The easiest approach would be to use jQuery and get the value with a line of code similar to this:
$("#deviceurl").val()
I would then make an ajax call to submit the value back to your controller's action. You also probably want to use the Url.Action helper to build the Url:
$.ajax(
url: '<%=Url.Action("Update")%>,
data : {deviceUrl : $("#deviceurl").val()},
success : function (result){
// handle logic when the update succeeds
}
);
Hope this helps
My advise will for you to use Html.ActionLink instead of using this Save
like this :
<%=Html.ActionLink("Save",
"Live", // <-- Controller Name.
"Update", // <-- ActionMethod
new { streamurl = deviceurl },
new { #class = "save refresh" }
)
%>

Categories