Question

I have a text box created using

@Html.TextBoxFor(m => m.Model1.field1, new { @class = "login-input", @name="Name",  @Value = "test" })

I want to change the default value of this textbox from "text" to a value stored in a model field. How do i set a model field as the the value attribute? Say the Name of the model to be called is Model2 and the attribute is field2. How do I set the value of the textbox to field2?

Était-ce utile?

La solution

You must first write an Extension Method like this:

public class ObjectExtensions
{
    public static string Item<TItem, TMember>(this TItem obj, Expression<Func<TItem, TMember>> expression)
    {
        if (expression.Body is MemberExpression)
        {
            return ((MemberExpression)(expression.Body)).Member.Name;
        }
        if (expression.Body is UnaryExpression)
        {
            return ((MemberExpression)((UnaryExpression)(expression.Body)).Operand).Member.Name;
        }
        if (expression.Body is ParameterExpression)
        {
            return expression.Body.Type.Name;
        }
        throw new InvalidOperationException();
    }
 }

It will extract the Name of property when you write sth like this: @Html.TextBoxFor(m => m.Model1.field1)

then you can use it like this:

Html.TextBoxFor(m => m.Model1.field1, 
  new { @class = "login-input", 
        @name="Name",  
        @value = Model.Item(m => m.Model1.field1) })

If you don't want to call m => m.Model1.field1 again, you must declare your version of TextBoxFor method which is more complicate, but If you want I can provide you the details.

This is a sample from my code base on Github:

public static class HtmlHelperExtensionForEditorForDateTime
{

    public static MvcHtmlString Editor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
    {
        ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);


        string propname = html.ViewData.Model.Item(expression);
        string incomingValue = null;
        var httpCookie = html.ViewContext.RequestContext.HttpContext.Request.Cookies["lang"];
        if (metadata.Model is DateTime && (httpCookie.IsNull() || httpCookie.Value == Cultures.Persian))
            incomingValue = PersianCalendarUtility.ConvertToPersian(((DateTime)metadata.Model).ToShortDateString());
        if (string.IsNullOrEmpty(incomingValue))
            return html.TextBox(propname, null, new { @class = "datepicker TextField" });

        return html.TextBox(propname, incomingValue, new { @class = "datepicker TextField"});
    }

}

Autres conseils

In your controller, set the value of field1 before passing it to the view... and that will set the value automatically. If you have the value in another field, just do:

model.field1 = model.field2;

in your controller... and that way the models have consistent data.

If you don't need/want that the default value being actually the value of the textbox, you could also use a PlaceHolder... and that way the user could see a value as a hint, but it will be not count as textbox content once you post the form.

@Html.TextBoxFor(m => m.Model1.field1, new { @class = "login-input", @name="Name",  placeholder= "test" })

Remember that not all fieldnames in the HtmlAttributes need a "@"... @class is correct, but the others I don't think are needed.

You can set the default value inside your controller action just before passing the model to the view:

model.field1 = "Test"
return View(model)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top