In View i have following error helper
#Html.ValidationSummary(true)
Which, if some property is not validated, show following html
<div class="validation-summary-errors">
<ul>
<li style="display:none"></li>
</ul>
</div>
I have custom css for this class with red border background and problem is that even no error text is shown to user, red border is still displayed.
Can i somehow prevent showing following error html ? Like
#if (Html.ModelState.ContainsNonPropertyErrors() == true)
{
Html.ValidationSummary(true)
}
// or to check if ModelState Error array contains empty keys, becase these are custom messages.
also, can i somehow check if form was submitted to display successfull message ?
for example
#if (Html.ModelState.FormWasSubmitted() == true)
{
if (Html.ModelState.ContainsNonPropertyErrors() == true)
{
Html.ValidationSummary(true)
} else {
Html.Raw("Operation was successfull.")
}
}
or it is a good practice to have model.successfullMessage property in the ViewModel ? (and in view something like #if(ModelState.IsValid) {#Model.successfullMessage} )
How do you do it ?
Ok i think i have working solution
#if (ViewData.ModelState.Keys.Contains(string.Empty))
{
#Html.ValidationSummary(true)
}
Related
I am having difficulties trying to render a checkBox on my Partial View. Basically, what I want is to render the checkBox based on a value extracted from the database. Please see my code below:
<div class="editor-label">
#Html.LabelFor(model => model.Active)
</div>
<div class="editor-field">
#{if (Model.Active == 'Y')
{ Html.CheckBox("Active", true); }
else
{ Html.CheckBox("Active", true); }
}
</div>
In this code block, I am checking for the value inside the Active field from my model and renders the isChecked property of the checkBox to true or false based on that value.
I have debugged this code and used a breakpoint. I have a value of 'Y' from my database and it did went through the if statement. However, when the form pops up, the checkBox didn't render.
Can someone please help me? Thanks!
I think your main problem may be because you have #{ instead of just # before the if.. try remove that.
also, to make things easier.. create a new property on your view model:
public bool IsActive
{
get { return Active == "Y"; }
}
then on your view, use Html.CheckBoxFor(m=> m.IsActive)
Following Brad Wilson's excellent series on using and customizing editor templates, I tried adding an Object.cshtml to the Shared\EditorTemplates folder. The template renders, but the [HiddenInput(DisplayValue = false)] on a model property doesn't render a hidden <input type="hidden" ... /> as expected. Using [HiddenInput(DisplayValue = true)] renders both the hidden and visible elements as expected.
I have verified that the default template for Object works fine and renders the hidden inputs. It's only a problem when building a custom template based on Brad's series above.
Looks like something has changed. Inspecting the MVC 3 source, I found that prop.HideSurroundingHtml is used to determine when to print the surrounding HTML, not to print only the hidden element. The following template allows several levels of rendering an editor for an object graph:
#if (ViewData.TemplateInfo.TemplateDepth > 2)
{
#(ViewData.ModelMetadata.Model != null ?
ViewData.ModelMetadata.SimpleDisplayText :
ViewData.ModelMetadata.NullDisplayText)
}
else
{
foreach (var prop in ViewData.ModelMetadata.Properties.Where(pm => pm.ShowForEdit && !ViewData.TemplateInfo.Visited(pm)))
{
if (!prop.HideSurroundingHtml)
{
if (!String.IsNullOrEmpty(Html.Label(prop.PropertyName).ToHtmlString()))
{
<div class="editor-label">#Html.Label(prop.PropertyName)</div>
}
#Html.Raw("<div class=\"editor-field\">")
}
#Html.Editor(prop.PropertyName)
if (!prop.HideSurroundingHtml)
{
#Html.ValidationMessage(prop.PropertyName, "*")
#Html.Raw("</div>")
}
}
}
I tidied my version of that up a bit for anyone who cares:
#foreach (var modelMetadata in ViewData.ModelMetadata.Properties)
{
if (modelMetadata.HideSurroundingHtml == false)
{
if (!string.IsNullOrEmpty(Html.Label(modelMetadata.PropertyName).ToHtmlString()))
{
<div class="editor-label">
#Html.Label(modelMetadata.PropertyName)
</div>
}
<div class="editor-field">
#Html.Editor(modelMetadata.PropertyName)
</div>
}
}
I want to define this section only if some property (Model.ReadOnly) is false.
#section toolbar {
<div class="tool">
<div class="row">
#Html.ActionLink( Resources.Strings.Edit, "Edit", "Profile" )
</div>
<div class="row">
#Html.ActionLink( Resources.Strings.Delete, "Delete", "Profile" )
</div>
</div >
}
I tried wrapping it up in #if ( !Model.ReadOnly ) {} but it doesn't work.
Is there a way to do this?
I do not want to define an empty section (as #itsmatt suggests), the layout of my page changes whether the section is defined or not (using IsSectionDefined( "toolbar" )).
This should work.
#if (!Model.ReadOnly)
{
<text>
#section toolbar {
}
</text>
}
I never said it would be pretty ;-)
This works for me:
#section SomeSection {
#if (!Model.ReadOnly)
{
}
}
Essentially flipping where the conditional is. This essentially results in an empty section if Model.ReadOnly is true.
Update:
So, what about moving that section to a PartialView and doing something like:
#Html.Partial("MyAction")
in your View and then let the MyAction return you the appropriate PartialView based on the ReadOnly value? Something like:
public PartialViewResult MyAction()
{
...
// determine readonly status - could have passed this to the action I suppose
if (ReadOnly)
{
return PartialView("TheOneThatDefinesTheSection");
}
else
{
return PartialView("TheOneThatDoesNotDefineTheSection");
}
}
Seems like that would work just fine.
Bertrand,
See:
Razor If/Else conditional operator syntax
basically (para-phrasing), ... Razor currently supports a subset of C# expressions without using #() and unfortunately, ternary operators are not part of that set.
also, this may be a way around the issue:
conditional logic in mvc view vs htmlhelper vs action
basically, use the if logic to call a partialview to satisfy your criteria.
[edit] this was my basic thinking (where your #section code is defined in that partial):
#if(!Model.ReadOnly)
{
#Html.Partial("toolbar")
}
I am using one controller which is inserting values in the database. I want to display alert message from controller when the values insertesd in the database successfully.
Is it possible. If yes then how?
You can add the result to ViewData. For example:
if (SaveToDbOK)
{
ViewData["Success"] = "Data was saved successfully.";
// Do other things or return view
}
In your view you can place anywhere:
MVC2:
<% if (ViewData["Success"] != null) { %>
<div id="successMessage">
<%: ViewData["Success"] %>
</div>
<% } %>
MVC3:
#if (ViewData["Success"] != null) {
<div id="successMessage">
#ViewData["Success"]
</div>
#}
I used this approach in my last project in order to make the information returned from the server unobtrusive. Checking whether ViewData["Success"] or ViewData["Failure"] are done in the Master page, the divs are formatted using CSS, jQuery code was used to hide the notifications after 5 seconds.
Regards,
Huske
public ActionResult UploadPropertyImage()
{
// Business logic....
return Content("<script language='javascript' type='text/javascript'>alert('Save Successfully');</script>");
}
Basically that depends on how are you inserting the value into the database, as you would need a method to tells you whether the insertion was successful. As there's a few ways to do that now, linq/entity framework/sql/etc.
Then after you know whether did the insertion happens, then you can just assign a value to a variable and then from the code/aspx just check the value and do a simple alert.
<script type="text/javascript">
//i'm using jquery ready event which will call the javascript chunk after the page has completed loading
$(document).ready(function(){
//assuming that your variable name from the code behind is bInsertSuccess
var bSuccess = "<%= bInsertSuccess %>";
if(bSuccess){
alert("Successfully Inserted");
}
});
</script>
You may add below code to tell user
Return Content("Data added successfully");
I have a partial view which has a Ajax.BeginForm, with a UpdateTargetID set. When the validation on the form fails the update target id is replaced with the validation errors, but when there are no validation errors users should be redirected to a new page.
The code in my Partial view is
<div id="div_UID">
<% using (Ajax.BeginForm("FindChildByUID", new AjaxOptions { UpdateTargetId = "div_UID" } ))
{%>
<p>
<label>UID:</label>
<%= Html.TextBox("UID") %>
</p>
<input type="submit" value="Continue" />
<% } %>
</div>
</pre>
The code in my controller is as follows
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult FindChildByUID(Student student)
{
Student matchingStudent = _studentService.FindChildByUID(student.UID);
if (matchingStudent == null)
{
ModelState.AddModelError("UID", String.Format("No matching child found for the entered UID: {0}", student.UID));
return PartialView();
}
else
{
// full view
return RedirectToAction("ConfirmChildDetails", matchingStudent);
}
}
So, for I have been unsuccessful to display the full view on it's own, as it always seems to dipslay the full view in the UpdateTargetID div specfied in the Ajax.BeginForm.
Any suggestions on how I can get this to work?
Thanks
What your AJAX post is doing is making a request and waiting on a response that contains html to input onto the page. The configuration is such that whatever html is returned will be injected into the div you've named "div_UID".
I typically avoid scenarios like this and use traditional posting if a redirect is required upon a successful outcome of the POST.
I imagine you could do it like this using jQuery to submit rather than the Ajax.BeginForm (or just set a callback function for your Ajax.BeginForm):
function SubmitForm(form) {
$(form).ajaxSubmit({ target: "#div_to_update", success: CheckValidity });
}
function CheckValidity(responseText) {
var value = $("#did_process_succeed").val();
if (value == "True") {
window.location.replace("url_of_new_action_here");
}
}
You just have to have a hidden field in your partial view called "did_process_succeed" and set the value of True or False based on some logic in your controller.
There are likely other ways as well. Perhaps someone else will chime in. I hope this helps for now.