Asp.Net MVC3 (Razor Viewport), ValidationMessageFor? - asp.net

I need to know whether there is ValidationMessage or not. Because I want to add to " tag into the error message.
like
#if (Html.ValidationMessageFor(m => m.UserId)){
Html.ValidationMessageFor(m => m.UserId) + "<br />
}
the above code does not work, anybody know how it make work?
Thank you!

You need to check the ModelState for that particular error. For example:
#if (ModelState["UserId"].Errors.Count > 0) {
Html.ValidationMessageFor(m => m.UserId) #:<br/>
}
This could get really ugly if you have it everywhere though. If you need to do this a lot, then create a custom Html Helper extension.

if you need to add some markup at your validation message I would suggest you to create a custom one.
All you need to to is create a new helper and encapsulate that logic in the helper itself
somethig like the below
public MvcHtmlString MyValidationMessageFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression)
{
//your logic here
}

Your question is very unclear. Please clarify what you want to achieve.
If you would like to show an error if there is one and do not show an error if there is not, you do not need to write separate "if()" logic like Mystere Man suggests.
Just having Html.ValidationMessageFor(m => m.UserId) in a properly formatted by css html and having all proper references to scripts required for validation will do the trick.
By properly formatted html I mean having validation blocks next to the inputs in the div tags so that you do not have to have <br>s for the new lines.

Related

How to render HTML string in ASP.NET MVC?

On my main page, I have the code #{Html.RenderPartial("_Partial1.cshtml");}, and on my Partial, I have an HTML string:
#{
// The string is actually dynamic, not static. This is here for simplicity
string abc="<div class=\"error\">abc</div>";
}
#abc
I want to output abc with some CSS error styles, but I actually got <div class="error">abc</div> - of course, no styles there. How do I make it interpreted as HTML source code and not a string?
You can use the Html.Raw() method for that.
And if you are using model in your view than use:
#model YourApp.Models.YourModel
....
#Html.Raw(#Model.NameOfYourProperty)

PartialView as HtmlHelper?

Ok.. here we go.. the weirdest and most confusing question of the month :)
I would like to create a HtmlHelper that some how renders html, but uses a partial view for its template of how the html should be rendered, so to put it more simple.. I would like to do exactly the same as a "normal" Controller and view does.. get some data, pass it to the view and then render the html, but in this case I would like to pass some data to a partial view, and then get the returned html as a string and then return that html from a HtmlHelper method...
In this way I would like to be able to write for instance #Html.HeadMenu, that then would return the html for the headmenu, but I would also be able to at anytime without recompiling be able to change the html.. since its all in a partial view.. and I wont have to worry about any server-side things.. and I will also get the benefit of the intellisense since my method will show up in #Html.
I hope you will understand this..since its kind of hard to explain..
Thanks in advance!
How about the Partial HTML-extension method, it sounds like what you are trying to achive right?
#{
var htmlString = Html.Partial("YourPartialViewName").ToString();
}
It also has an overload so that you can pass a model to the partial view:
#{
var htmlString = Html.Partial("YourPartialViewName", partialViewModel).ToString();
}
You could be looking for the Html.RenderAction(actionName, controllerName, routeValues) method.
I would do it this way
Define data that you imagine to pass to your htmlhelper
public class HeadMenuViewModel
{
public string SomeProperty {get;set;}
}
Define view named HeadMenuViewModel.cshtml in Views/Shared/DisplayTemplates
#model HeadMenuViewModel
<div>
////
</div>
From now, you can display your data using
#Html.DisplayFor(model => model.HeadMenu)
And you could write named shortcut-extension for it
using System.Web.Mvc.Html;
...
public static MvcHtmlString HeadMenu<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression)
{
return helper.DisplayFor(expression);
}
Now, change your HeadMenuViewModel.cshtml everytime you need to

ASP.NET MVC3 Obtaining Auto-generated Form Element Id's

Using #Html.TextBoxFor(m => m.MyField) will (normally?) result in <input id="MyField" name="MyField" type="text" value="" /> and if I want to access that element in jquery I do so as follows $("#MyField"). Is there a way to avoid manually typing the ID into the jquery selector? It seems clunky to me to do it this way as I'm coming from a classic asp.net background where you would pull the id of the element using the ClientID property. Therefore if the renderer changed how it generated the ID ones code automatically kept up-to-date. In the above example if I change MyField to MyNewField the compiler will remind me to change all the strongly typed references, but nothing will remind me to change my jquery selector.
Write a simple method that get a property and return it's name with reflection and use it like this:
static string GetVariableName<T>(Expression<Func<T>> expression)
{
var body = expression.Body as MemberExpression;
return body.Member.Name;
}
$('#' + #(GetVariableName(() => Model.MyField)))
Should work.

asp.net mvc c# tooltip

what is the best and most simplest way to create tooltip text for textboxes
With JavaScript and probably with a framework like jQuery that fits very well with ASP.NET MVC. Using the framework means that someone's alread done the hard work and written a plugin for it!
qtip
tooltip
List of some tooltip plugins
There is of course the title attribute on text inputs that shows as a popup tip in some browsers.
I found this to be the simplest and easy to maintain approach:
Create description using data annotation for the property of your model
Example:
[Display(Name="MyTextBox", Description = "Title for your entry")]
public string MyTextBox{ get; set; }
Then in your view access the description above using:
#Html.TextBoxFor(model => model.MyTextBox, new { title = ModelMetadata.FromLambdaExpression(model => model.MyTextBox, ViewData ).Description })
Just use the title tag :
<input type="text" title="Hello I'm the tool-tip"/>
Mvc way :
#Html.TextBoxFor(t => t.NameOfCustomer, new{ title= "Hello I'm the tool-tip" })
It's not fully customizable as is, but it does not require extra javascript nor a framework.
Use the data annotations on your model to put the tooltip in the Description property of the DisplayAttribute.
Then write your own Html Helper function that puts the Description property into the title attribute of the TextBox input field. You can call the helper TextBoxWithTooltipFor
In your view definition you can then replace the call to #(Html.TextBoxFor(...)) with the call to #(Html.TextBoxWithTooltipFor(...))
Here is the code that is tested and works.

Forcing client ids in ASP.NET

I know that in the next version of ASP.NET we'll finally be able to set the clientids on System.Web controls without the framework doing it for us in a quasi-intelligent way e.g:
id="ctl00__loginStatus__profileButton"
Does anyone know a good method in the meantime to force the above id to something like
id="profileButton"
The main reason for this is manipulation of the clientids in jQuery when dynamically adding controls to a page. The problem I can see is changing the ids will break the Viewstate?
You have to use the ClientIDMode attribute:
<asp:xxxx ID="fileselect" runat="server" ClientIDMode="Static"/>
What I tend to do is dynamically generate javascript methods which handle this. You can do this in markup or code behind so for example:
<script language="javascript" type="text/javascript">
function doXYZ()
{
$("#" + getListBoxId()).css(...)
}
function getListBoxId()
{
return "<%=this.myListBox.ClientId>";
}
</script>
You can also build the functions in the code behind and register them.
EDIT
A couple months ago I needed to fix the id of some server controls, I managed to hack it in and I described my method here here.
Basically you need put the controls inside a naming container like a user control, and then override a couple of properties which prevents the child controls from getting their uniqueid.
The performance isn't great, but you can use this selector syntax to match messy ClientIDs:
$("[id$='_profileButton']")
That matches any element ending in _profileButton. Adding the leading underscore ensures that you're matching the desired element and not another element that ends in the substring "profileButton" (e.g. "myprofileButton").
Since it has to iterate over the entire DOM, the performance can be poor if you use it in a loop or several times at once. If you don't overuse it, the performance impact is not very significant.
Another way would be to wrap your control with a div or span with a static id, then access the control through that.
E.g.
<span id="mySpan">
<asp:TextBox id="txtTest" runat="server" />
</span>
You could then target input tags inside MySpan. (though I agree it would be nice to be able to specify a nice name, provided you could handle the naming conflicts...)
I have often run in to this "problem" while developing in asp.net webforms. In most cases I tend to use the css class of the element.
jQuery(".My .Container12")
Before starting to manipulate the id:s, perhaps that is a way you can handle it aswell? It's a simple solution.
There is another solution not mentioned which is to subclass the ASP.NET controls and force the IDs:
public class MyCheckBox : CheckBox
{
public string ForcedId { get;set; }
public override string ID
{
get
{
if (!string.IsNullOrEmpty(ForcedId))
return ForcedId;
else
return base.ID;
}
set
{
base.ID = value;
}
}
public override string ClientID
{
get
{
return ID;
}
}
}
Then use this where you know the IDs will never clash:
<mytag:MyCheckBox ForcedId="_myCheckbox" runat="server" />
If you are using lists you will need to write a ListControlAdapter, and also adapters for each type of list you're using (dropdown,checkbox,radiobutton,listbox). Alternatively cross your legs and wait for .NET 4.0.

Resources