PlaceHolder + #Html.TextBox issue - c#

The goal
Apply, with success, the placeholder attribute for #Html.Textbox method.
The problem
There is the following syntax on my application;
#Html.TextBox("term", new { placeholder = "What are you searching for?" })
But, when the TextBox is rendered, the value attribute of the input is placeholder = "What are you searching for?". In other words, the placeholder attribute isn't applied as an attribute, but as an input's value.
Knowledge
I already searched about this question on Google and Stack Overflow, but until now, without success.
This link has a solution with the same syntax that I'm using, but when I pass the second parameter to TextBox(), it is rendered as a value and nothing happens with the third parameter (in our case, new { placeholder = "something" }).

You're calling the string name, object value overload of that method, so the second parameter is being taken as the value, not as htmlAttributes. You should use a different overload of the method, probably string name, object value, object htmlAttributes by specifying an empty value:
#Html.TextBox("term", "", new { placeholder = "What are you searching for?" })

try this for an empty #Html.TextBox
#Html.TextBox("CustomarName" ,null, new { #class = "form-control" , #placeholder = "Search With Customar Name" })

There is a third param you need:
#Html.TextBox("term", Model.SomeProperty, new { placeholder = "What are you searching for?" })
The third param are any attributes you wish to include in the HTML output of the input field.

Related

How can I add a class to an html element through a controller?

I'm busy with an mvc 5 application. I have a list of names from a database which are displayed in html. I filter the names alphabetically using html.actionlink for A, B, C, D ...Z. Through each html.actionlink I pass through each letter as an Id parameter and then in my controller I filter which names are returned using .ToList() by finding .Where() the first letter of my names match the Id parameter.
That is all working well. What I need to do now is that if there are no names which begin with a certain letter then that letter must be grayed out in the view.
How can I add a class to an html element through my controller? I need to make sure that if there are no names with a certain letter then my html link must have css class with color: grey. I don't know which names there will be because the database is populated by an administrator.
You can define your CSS class and apply your class in html helpers. Like this:
.yourClassName
{
color:grey;
}
Applying your class:
#Html.ActionLink("Name", "{Controller}", null,new { #class ="yourClassName" })
Not too sure I follow the design flow in your question but I think this code may help you.
#if(model.Names.Where(x => x.StartsWith("L").Count() != 0)
{
#Html.ActionLink("L", "{Controller}", "{Action}", null, new {} { #class = "{NOT GRAY}"})
}
#else
{
#Html.ActionLink("L", "{Controller}", "{Action}", null, new {} { #class = "grayed"})
}
Basically, you can write an IF statement in Razor syntax and then check and see if the incoming data is empty by doing a Count and then styling the element differently for each case.
Because I don't know what name you are using for your model, what classes your applying to your not grayed elements, controller names, action names, then you will need to edit to this code to get it to work.
Using ActionLink function you can pass an anonymous object with entries corresponding to Html attributes.
Look at the parameter of type object, called htmlAttributes in the ActionLink function.
Here is an example (note that class is prefixed with # because it is a keyword) :
#Html.ActionLink(
"Portfolio",
"Index",
"Portfolio",
routeValues: null,
htmlAttributes: new { #class = "grayed" }
)

Add HtmlAttributes to Html EditorFor()

That is a tricky question because I want to add Html Attributes to the EditorFor() but do not want to replace the ones that was already created. Let me explain:
I have a default Editor Template for string.cshtml with the following code:
#{
var htmlAttributes = ViewData;
htmlAttributes["class"] = "text-box single-line form-control";
htmlAttributes["placeholder"] = ViewData.ModelMetadata.Watermark ?? ViewData.ModelMetadata.DisplayName;
htmlAttributes["title"] = ViewData.ModelMetadata.Watermark ?? ViewData.ModelMetadata.DisplayName;
}
#Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, htmlAttributes)
It is used to always add the following class, placeholder and title, based on the DisplayName DataAnnotation, for the Form Inputs, it is quite handy!
But the problem is that I'm having trouble adding the disable attribute for one specific Form Input with the common code:
#Html.EditorFor(x => x.Field, new { htmlAttributes = new { disabled = "" } })
When the Form Input is with a field that is not a string, it will not follow the created EditorTemplate and it will work with this exactly code, but when it is a string, the EditorTemplate replaces the Html Attributes.
Does anyone has any clue on this?
Turns out there was a few dumb errors, first of all the declaration on the EditorFor() field was wrong, the correct one is this:
#Html.EditorFor(x => x.Field, new { #disabled = "" })
The second point is to keep using the incoming htmlAttributes in the string.cshtml EditorTemplate, replacing the class property definition:
htmlAttributes["class"] = "text-box single-line form-control";
For:
htmlAttributes["class"] = htmlAttributes["class"] + "text-box single-line form-control";
In this way, the incoming html attributes is just concatenated with the new default ones.

Provide value to htmlAttributes where keys contain dash in their name in MVC view (e.g. "data-bind")

Most of the Html helpers available in ASP.Net MVC have overloads with object htmlAttributes. This is used to provide additional attribute values for the outputted tags. While using the anonymous object notation for specifying htmlAttributes value, their property names must be valid c# identifier.
Now the problem arises when you are trying to output a property with a dash - character (for e.g. knockout js's "data-bind" attribute)
So for example lets take the following example:
#Html.TextBox("Title", string.Empty, new { data-bind="text: title" })
Try the above code in your view and at run-time it would show error screen with below message:
Compilation Error
Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.
Compiler Error Message: CS0746: Invalid anonymous type member declarator. Anonymous type members must be declared with a member assignment, simple name or member access.
So the question is, how to provide htmlAttributes with their property keys having dash characters; like "data-bind"?
In your property names, replace all your dash - characters with an underscore _ (as shown in example below):
#Html.TextBox("Title", string.Empty, new { data_bind="text: title" })
This would work because all HTML helpers convert an underscore _ in a property name to a dash - when rendering the HTML; i.e. for your example, data_bind when outputted in html gets converted to data-bind.
This is not always correct. Say you're using parameters in a URL.
#Html.ActionLink("Add Job", "Index", "Home", new { foo_bar = "foobar" }, new { #class = "btn btn-default", data_foo = "bar" })
The data_foo does get rendered as "data-foo", but the parameters stays as a under bar. Your result will be: http://your.domain/yourapp/?foo_bar=foobar
Of course you can't actually use the dash or you get the error specified in the OP.
I have worked around this as follows, but I'd be interested to see if anyone that comes along in the future will have a better way:
#{
var link = Html.ActionLink("Add Job", "Index", "Home", new { foo_bar = "foobar" }, new { #class = "btn btn-default", data_foo = "bar" });
}
#Html.Raw(link.ToString().Replace('_', '-'))
Use the HtmlHelper.AnonymousObjectToHtmlAttributes method. The following code will add a tooltip to the text input box, with the tooltip displaying the data from the DisplayAttribute description for MyIntVal on my model.
#{
var htmlAttributesWithDashes = HtmlHelper.AnonymousObjectToHtmlAttributes(
new
{
id = "myTextBoxId",
data_toggle = "tooltip",
data_position = "left top",
title = ModelMetadata.FromLambdaExpression( m => m.MyIntVal, ViewData ).Description
}
);
}
<div class="col-sm-6">
#Html.TextBoxFor( m => m.MyIntVal, htmlAttributesWithDashes )
</div>

Add Id or other attributes to ASP.NET MVC 3 Html Helper Textbox

How can I add attributes to a html helper textbox.
I've tried this:
#Html.TextBox("username", new { id = "username" })
This seems to put 'id=username' in the value field of the textbox. I want to add an Id to my textbox.
Thanks.
The second parameter (new { id = "username" } in your example) is the initial value (value attribute) of the TextBox. The third parameter is the actual htmlAttributes:
#Html.TextBox("username", Model.Username, new { id = "username" })
while new { id = "username" } as the 2nd parameter is valid, you will need to add # to attributes that are also keywords, like class.

ASP.NET MVC 3: Override "name" attribute with TextBoxFor

Is it possible when using Html.TextBoxFor to override the name attribute?
I have tried with no success. I need to use TextBoxFor to get client side validation to work, however for reasons I won't go into I need the name of the textbox to be different from the generated one.
I have tried the following:
#Html.TextBoxFor(x => x.Data, new { name = Model.Key + "_Data", id = Model.Key + "_Data" })
Which works for ID but not name. Is this possible?
Update: Looking into the code for TextBoxFor. It doesn't look like there is an easy way. Hopefully someone can prove me wrong.
Rob, actually there is a much simpler way. Instead of name, use Name:
#Html.TextBoxFor(x => x.Data, new { Name = Model.Key + "_Data", id = Model.Key + "_Data" })
Are you asking this because you want to apply a prefix to the name? If so, you can do this by setting ViewData.TemplateInfo.HtmlFieldPrefix in your Controller.
I learnt a lot about this stuff from Brad Wilson's blog.
EditorFor has an overload where you can supply the name attribute as a parameter:
#Html.EditorFor(expression, null, name)
Try EditorFor. you can pass string as template name if you want to make sure textbox is rendered even if property type is not string. If property is string already, it does not need templatename explicitly to render textbox, so you can pass null. Note that it does not require id parameter explicitly, it will infer it from element name. And all the validation things are still active with EditorFor
#Html.EditorFor(x => x.Data, "string", Model.Key + "_Data")
It is called Microsoft GOTCHA...
Use the name in caps, like this
#Html.TextBoxFor(m => m.Reply.Answer, new { Name = "Whatyouwant" })
ben's answer got me what I was looking for except you need to wrap in in Html.Raw
#Html.Raw(Html.TextBoxFor(x => x.Data).ToString().Replace("Data", "NewData"))
a little bit "unpretty"=), try:
#Html.TextBoxFor(x => x.Data).ToString().Replace("Data", "NewData")
For me, it works! I hope that help!
#Html.EditorFor(model => model.Nome, new { htmlAttributes = new { #class = "form-control", #maxlength = "80", #id = "NomeFilter", #Name = "NomeFilter" } })
#Html.EditorFor(Model => Model.Something, "name", "name", new {#class = "form-control" })
Not sure which of those two string parameters in the middle do the work, but it worked only when I typed both of them.
For this example, I was disabling form fields based on permissions, but still showing them. I had a hidden field to send the value to the controller, but wanted a different field name in the EditorFor.
First param after model value represents the "name" property, second is the new name.
#Html.EditorFor(m => m.UserName, "name", "UserNameDisabled", new { htmlAttributes = new { #class = "form-control", #disabled = "disabled"} });
Results in:
<input class="form-control text-box single-line" disabled="disabled" id="UserNameDisabled" name="UserNameDisabled" type="text" value="someEnteredValue" />
Keep it simple, your already providing the ID you should simply be able to use the method "TextBox" instead of "TextBoxFor" and it will work fine client side and server side. In addition, although the accepted answer will work but will produce duplicate Name attributes on your tag if you inspect it using a browser. The below solution does not have that problem.
MvcHtmlString Html.TextBox(string name, string value, object htmlAttributes)
#Html.TextBox(Model.Key + "_Data", Model.Key, new { id = Model.Key + "_Data" }

Categories

Resources