DmitryEfimenko / TwitterBootstrapMvc

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

How can we specify a width to input controls? #75

Closed Jak3b0 closed 11 years ago

Jak3b0 commented 11 years ago

Hi,

I was wondering how are we suppose to specify a width to the input controls? Reading the Bootstrap documentation, inputs (Inputs, Selects and TextAreas) by default takes 100% of the available width.

They mention that if we want to force a width, we have to wrap the inputs with a div having the proper col-* class to size it.

Is there a way using your library to acheive this? My goal is to have the validation message for a field to appear right next to the input.

Thanks!

DmitryEfimenko commented 11 years ago

BMVC goes hand in hand with Twitter Bootstra's documentation. BMVC does not have a helper to achieve what you want (at least for Bootstrap 3) and I can't think of a way you'd be able to do it cleanly. You'd have to ask this question on the forums of Bootstrap itself. If you find a way, let me know! I'm curious to see what the solution would be.

Jak3b0 commented 11 years ago

Hi,

The documentation of the Twitter Bootstrap 3 mention that if you want to control the width of the inputs, you need to wrap the input with a div having the desired col-lg-* width. Here is what I was doing before migrating my screens with your library: (Note: the ValidationStateFor method will set the "has-error" class if error are found for the property)

     <div class="form-group @Html.ValidationStateFor( m => m.Email )">
        @Html.LabelFor( m => m.Email, new { @class = "col-lg-2 control-label" } )
        <div class="col-lg-5">
           @Html.TextBoxFor( m => m.Email, new { @class = "form-control" } )
        </div>
        <span class="help-block col-lg-5">@Html.ValidationMessageFor( m => m.Email )</span>
     </div>

This was allowing me to control the width of the inputs and have the validation help text on the right instead of underneath.

I think this is pretty easy to implement on your end and it will add a way to customize more easily the layout of a screen.

Will you be interested in adding this to your library?

DmitryEfimenko commented 11 years ago

Absolutely! It does look interesting. Just have to figure out friendly syntax for this.

There are already helpers on Form class and .Label() extension method: .WidthSm() etc. I think it needs to be something similar. For example extension method called: .InlineValidationWidthSm() (a little long, but clear). When used, the form-group elements would be rendered according to your example.

Let me know what you think

Jak3b0 commented 11 years ago

I think that the use of .WidthSm() (and the others) is the right way to do it. The validation message itself is optional. I could want to only have an input smaller than 100%.

I just did some tests and you can just specify the width on the inputs and all should work fine. Therefor, you could expose only extensions methods on the inputs like this one: .TextBoxFor( m => m.Email ).WidthLg( 5 ).ShowValidationMessage( true ).Label()

I don't know if this would be possible with your code but this could be really easy to use! :)

What do you think?

DmitryEfimenko commented 11 years ago

I did a bit of testing as well. It looks like if no grid size class is specified on validation message, then if the message is too long, it does not have a margin on the right and hits the right border of the container.

Jak3b0 commented 11 years ago

Humm... and can you set the remainging width to the message based on what has been set on the form (for the labels) and the inputs?

DmitryEfimenko commented 11 years ago

I can. The reason I do not quite like extension name .WidthLg( 5 ) on .TextBoxFor( m => m.Email ) is that one may get confused into thinking that if this method is used then class col-lg-5 will be applied straight to the input (textbox in this case) when in the reality it will be applied to the containing div and appropriate class would be calculated for validation span. On top of that once this method is used, validation message moves outside the container where input is located.

Basically, a lot of things happen and a simple name WidthLg just does not seem to cut it :) On top of all of that, I'd like same extension method be applied to the Form class so that a developer does not need to apply this to all form groups individually.

Jak3b0 commented 11 years ago

You have a point. The implication are far more than just set a class name on an object. Having the option to set it at the form level is a good idea also.

I do think though that we should have the option to set it to particular inputs. I can easily think of a screen having a description field that should take the whole space and have another input that will have a max input length of 5 which should be smaller, in my opinion.

mikestu commented 11 years ago

I agree with Jak3b0. Setting it on individual inputs is a must, and setting at the form level would be a bonus. For the form level though, you could already do something like surround the form with a container that has a width set on it, so to me, that one isn't as big of a deal.

DmitryEfimenko commented 11 years ago

I never intended not to implement setting on individual inputs. I am only saying that the extension name should be named appropriately and I'm having a hard time thinking of such name.

DmitryEfimenko commented 11 years ago

Ok, so I think I finally figured out how this will be done. I'll introduce methods .WidthLg(5) and similar on .TextBoxFor( m => m.Email ). All that helper will do is set width of the div that contains inputs.

Now, there is already a method:

Html.Bootstrap().Globals().SetValidationMessageBeforeInput();

I'll introduce a new helper method under Globals that is similar to the method above, except that it will be responsible for getting validation message rendered after div that contains inputs. I need some help figuring out the name for this method.

And also I'm thinking about an ability to set width of div containing inputs on the Form level similar to:

Html.Bootstrap().Begin(new Form().WidthMd(2)

However, this method would have to be called something like .InputsWidthMd(8). Given this change, I'm thinking whether I should rename .WidthMd(2) method into .LabelWidthMd(2). That would be a breaking change then, which I would like to avoid.

Need your thoughts guys.

BrettBaggott commented 11 years ago

Renaming is the right way to go IMO. I can't imagine with all the 2.2.3 -> 3.0 changes most of us are dealing with that a breaking change this early can be much of a deal. At least I know it isn't for me. Hopefully others will chime in.

SLOPapa commented 11 years ago

I tend to agree with BrettBaggot - it's likely most of us are still dealing with figuring out 3.0. I know I am.

I think the advantages of the solution you describe outweigh the disadvantages.

phxdev1 commented 11 years ago

Agreed with Brett. Renaming makes the method much more descriptive. With the 3.0 change over, now is the perfect time to include this.

dwelford commented 11 years ago

I vote yes

JustinPierce commented 11 years ago

Agreed with the rest of the bunch. If there were ever an appropriate time to make a breaking change, it's now.

mikestu commented 11 years ago

I like your recommendations. Also, I vote yes on the rename. Just in case, perhaps you could leave the existing version for a little while, but mark it with the obsolete attribute.

Jak3b0 commented 11 years ago

I too vote yes for the renaming. Of course, I only have 1 screen to review so it's not much trouble for me. Maybe you can leave the old name also and set the Obsolete attribute on it (http://msdn.microsoft.com/en-us/library/system.obsoleteattribute.aspx).

MrGorki commented 11 years ago

Html.Bootstrap().Globals().SetValidationMessageBeforeInput();

will be a time saver for me. Because I am dealing with the validation placements nowadays.

JasonRodman commented 11 years ago

When will this feature be done because its really holding me up from completing my upgrade...

DmitryEfimenko commented 11 years ago

Ok, the methods on the Form are renamed (the old once are deprecated). Added .Width[Size](int) methods to almost all input helpers. If you are missing this one a helper, where you believe it needs to be, please let me know.

I didn't yet create a method in Globals to allow html structure for "inline" validation messages. Hopefully will add this tomorrow. Hopefully these changes didn't introduce too many bugs :)

@MrGorki Html.Bootstrap().Globals().SetValidationMessageBeforeInput(); should exist.

Jak3b0 commented 11 years ago

Cool! I'm gonna try it later... thank you very much!

DmitryEfimenko commented 11 years ago

All from this issue is finally taken care of. Added method Html.Bootstrap().Globals().SetValidationMessageInline();

For all changes see Change Log