DmitryEfimenko / TwitterBootstrapMvc

Fluent implementation of ASP.NET-MVC HTML helpers for Twitter Bootstrap.
Apache License 2.0
224 stars 79 forks source link

Extension class for controls #434

Closed markusgud closed 7 years ago

markusgud commented 7 years ago

Is there a way to create an extension class so that Bootstrap widths can be set dynamically on the controls?

As an example, instead of doing this @f.FormGroup().TextBox("Value").WidthXs(3),WidthSm(3),WidthMd(3).WidthLg(3).Value(Model.Value)

I would like to have the widths set on my control by using this interface:

public interface IBootstrapWidths
{
  int? Xs;
  int? Sm;
  int? Md;
  int? Lg;
}

and then do something like this on the textbox (or other MVC controls) which would only set each width parameter if it is specified, where widthSettings is a parameter of this interface: @f.FormGroup().TextBox("Value").GridWidths(widthSettings).Value(Model.Value)

What is the most flexible way of doing this, so that it works for other controls as well?

DmitryEfimenko commented 7 years ago

In order to address this better, I need to understand the underlying reason for this request. What is the purpose of this? Is it that you'd prefer to shorten HTML code or is there another reason?

If the reason is that you'd like to avoid duplication of the code, I'd like to point out that you can call these methods once on the FormBuilder rather than on each FormGroup.

markusgud commented 7 years ago

Yes, to shorten code and simplify it. In my case I am creating the controls dynamically, so in fact I have properties on the model class (which would be implementing this interface).

I can't see how I can call these methods on the FormBuilder, neither FormGroup nor FormBuilder have these WidthXs, etc. functions.

DmitryEfimenko commented 7 years ago

check this piece of docs out. You'd write something like:

@using (var f = Html.Bootstrap().Begin(
    new Form().Type(FormType.Horizontal)
        .InputWidthLg(3)
        .InputWidthMd(3)
        .InputWidthSm(3)
        .InputWidthXs(3)
))
{
    ...
}

It's a bit more code when initializing form, but you don't have to specify widths on every control. Let me know if this is OK.

markusgud commented 7 years ago

Sorry, I am mixing up a bit the sizing on the input groups vs. the sizing of grid cell containers. Seems like one has to be careful to change the sizing of the labels and widths of input boxes.

I see that you don't have support for grid cell sizing, do you? (within

inside a
) I guess I have to add the col-x-x classes manually to the divs.

DmitryEfimenko commented 7 years ago

within what? I don't think some of your code got through in your last post. not sure if this will be helpful, but there is also Div helper that has same extension methods for manipulating widths:

@Html.Bootstrap().Div("my Html here").WidthXs(3)
markusgud commented 7 years ago

Thank you perhaps it would work if there was a BeginDiv and EndDiv functions.

However, I am still eager to replace code like this: @f.FormGroup().TextBox("fieldName").WidthXs(6).WidthSm(8).WidthMd(10).Label().WidthXs(6).WidthMd(4).WidthSm(2).LabelText("Label")

with something like this since I am generating this dynamically: @f.FormGroup().TextBox("fieldName").SetWidths(a).Label().SetWidths(b).LabelText("Label")

where class instances a and b had information about the xs, sm,md and lg widths.

So my question really is, will I need to write fluent extension methods for all controls that I am using, like for the following two for this case, or is there a base class that I can use to make it more general? BootstrapControlTextBoxBase<TModel> and BootstrapLabel<TModel>

Also, is there a way to assign hidden-xs, etc. by setting the widths? I did not see it documented.

DmitryEfimenko commented 7 years ago

I've updated BMVC with new method Widths(): View:

@f.FormGroup().TextBoxFor(x => x.Title).Widths(Model.Widths).Label().Widths(Model.Widths)

Model:

using TwitterBootstrapMVC;
public class BootstrapWidths : IBootstrapWidths
{
    public int? Xs { get; set; }
    public int? Sm { get; set; }
    public int? Md { get; set; }
    public int? Lg { get; set; }
}

public class MyViewModel
{
    public MyViewModel()
    {
        Widths = new BootstrapWidths{ Lg = 3, Md = 3, Sm = 3, Xs = 3 };
    }
    public IBootstrapWidths Widths { get; set; }
}

Please get latest and let me know if that works better for you.

markusgud commented 7 years ago

Thank you, I like this implementation.

Shouldn't one be able to to the following though? @f.FormGroup().DisplayTextFor(x => x.Value).Widths(Model.FieldWidths).Label().Widths(Model.LabelWidths).LabelText(Model.Label)

I want the "preview rendering" of the submitted data to be set up using the same form groups (and widths) and rather than use a read-only textbox I want only the text to be rendered. Seems like it is not possible to assign the Widths functions with DisplayTextFor and the accompanying label.

Also, I think when I set widths to 0 (zero) it should not be rendered like col-xs-0. but rather as hidden-xs.

DmitryEfimenko commented 7 years ago

I have addressed both issues. Please get latest and let me know how it works for you.

DmitryEfimenko commented 7 years ago

I assume this works as expected. Closing issue

markusgud commented 7 years ago

This has worked extremely well for me. Could it be that the Widthsfunction is missing from radio button lists?

I can not do this: var rbl = f.FormGroup().RadioButtonListFor(m => m.Value, Model.ListItems, item => item.Value, item => item.Text).Label().Widths(Model.LabelWidths);

markusgud commented 7 years ago

In addition, shouldn't there be a support for a tooltip on radio button lists?

Can not do this either: var rbl = f.FormGroup().RadioButtonListFor(m => m.Value, Model.ListItems, item => item.Value, item => item.Text).Tooltip("my tooltip");

DmitryEfimenko commented 7 years ago

It's possible that I forgot to add .Width on RadioButtonListFor. I'll check both of your inquiries.

markusgud commented 7 years ago

Thank you. Is an updated version with these updates expected any soon? I don't see it in v3.17.5 which I believe is the latest version.

DmitryEfimenko commented 7 years ago

Sorry it took a while. I got carried away with another project. This is done. Please get latest.