MB34
MB34

Reputation: 4434

Dynamic attributes in HTML.TextBoxFor

I'm trying to build a TextBoxFor with conditional attributes.

If the Model.question doesn't have a CALC_EXPRESSION, I don't even want the data-formula attribute to show.

Is that possible? This doesn't work:

@Html.TextBoxFor(q => question.AnswerFloatString,
    new
    {
        Value = "",
        id = String.Concat("Percent_of_Funding_", i.ToString()),
        Name = "QuestionBasicSection.Questions[" + question.Index+ "].AnswerFloatString",
        @class = "form-control percentMask",
        data_bind = "textInput: sdto.DATE_INACTIVE",
        data_pattern = question.FORMAT_VALIDATION,
        data_cell = "F" + (15 + i).ToString(),
        data_format = (question.FORMAT_VALIDATION == "pecent" ? "0.00%" : (question.FORMAT_VALIDATION == "currency" ? "$0,0.00" : "")),
        (question.CALC_EXPRESSION.Trim() != "" ? data_fomula = question.CALC_EXPRESSION:""),
        @readonly = "readonly",
        tabindex = "-1"
    })

But if I do this:

data_fomula = (question.CALC_EXPRESSION.Trim() != "" ? question.CALC_EXPRESSION:""),

I get and empty attribute in the HTML and if there is no CALC_EXPRESSION in the model, I get an "Object reference not set" exception. I also wouldn't mind not having the data-format attribute if the question.FORMAT_VALIDATION != 'percent' or 'currency'.

Upvotes: 0

Views: 3158

Answers (3)

aarset89
aarset89

Reputation: 59

What I'm trying to do is pass an object from the viewModel to the view and then get them and make an easy if to select what I need:

View Model:

public string FormRoot;

    public string form()
    {
        if (FormRoot == "Edit")
        {
            return ("1");
        }
        else if(FormRoot == "Details")
        {
            return ("2");
        }
        return ("No valido");
    }

Controller:

    var viewModel = new SubCategoryViewModel()
    {
        SubCategory = subCategory,
        Categories = await _context.Categories.ToListAsync(),
        FormRoot = style //Style is the info sent to the method
    };

View:

@Html.TextBoxFor(m => m.SubCategory.Name, "", new {@class = "form-control", @disabled = Model.FormRoot.ToString() == "Edit" ? "false" : "true" })

Dynamic class is working, but in this case, textBox in page keep disable even if it is like "disabled="false".

Upvotes: 0

Chetan
Chetan

Reputation: 6911

Html.TextboxFor takes IDictionary as a parameter to populate html attributes of the textbox.

https://msdn.microsoft.com/en-us/library/system.web.mvc.html.inputextensions.textboxfor(v=vs.118).aspx

You should create a dictionary with all the attributes populated based on the logic of yours and then pass that dictionary to the textboxfor method.

That way you will have better control over which attribute will be present or not with what value.

var attributes = new Dictionary<string,object>();

attributes.Add ("id", String.Concat("Percent_of_Funding_", i.ToString()));
// and so on.... keep adding the attributes based on the logic.
//Have an if block for adding certain attribute only if certain condition is met. 
//That way you will not have the unnecessary attributes. 
@Html.TextBoxFor(q => question.AnswerFloatString, attributes)

Upvotes: 4

Chris Pratt
Chris Pratt

Reputation: 239460

The latter approach is how you should do it, but you want to return null from the ternary rather than an empty string, i.e.:

data_fomula = (question.CALC_EXPRESSION.Trim() != "" ? question.CALC_EXPRESSION : null),

Attributes which are null are not included in the generated HTML.

Upvotes: 1

Related Questions