width attributes? #140

Closed
fdsanto opened this Issue Oct 29, 2013 · 35 comments

Comments

Projects
None yet
3 participants

fdsanto commented Oct 29, 2013

hi ! this is kind of a basic question but i can't change the controls width, i've tried using WitdhSm/Md/Lg with different int values but it doesn't make any changes, i'm i missing something? also inputSize just changes the inputs height and font but not the width :( should i just use some css class?

thx!

Franco

Owner

DmitryEfimenko commented Oct 29, 2013

InputSize helper is there to accommodate this bootstra's functionality. So that works appropriately.

As to Width change... it all works for me. Show me some code and I'll try to point out the issue.

fdsanto commented Oct 29, 2013

well, for example if i use @f.FormGroup().TextBoxFor(model => model.Venta.Cliente.Nombre).WidthSm(10) nothing happens

Owner

DmitryEfimenko commented Oct 29, 2013

I probably should document this stuff a bit better (or maybe I should change functionality a bit).

Right now Width will only be applied to controls under Form of type Horizontal or Inline. Make sure you specify which one you are using.

If that still does not work for you, please show me more code!

fdsanto commented Oct 29, 2013

Ok, i see how to set the width on different inputs inside a form, but apparently it doesn't work so great on several appended inputs

here, i've a disabled textbox indicating a default client's name, and appended to it two more textbox with typeahead for searching and changing the client's name according to those two parameters.. well the problem is that the appended textboxes' width are too small and i've tried changing them with WidthMd(3) but the styles get broken..
i know it's kind of complex, maybe i should separate each textbox but it was looking great in a single control..

@using (var f = Html.Bootstrap().Begin(new Form().Type(FormType.Horizontal).WidthMd(3)))
{
@(f.FormGroup().TextBoxFor(model => model.Venta.Cliente.Nombre)
.Disabled()
.Append(
f.FormGroup().TextBox(" ").WidthMd(3)
.TypeAhead(new TypeAhead()
.Controller("Cliente")
.Action("CheckClienteByDNI")
.Updater("changeClienteByDNI")
).WidthMd(5).Append(Html.Bootstrap().Label("DNI"))
.Append(
f.FormGroup().TextBox(" ").WidthMd(3)
.TypeAhead(new TypeAhead()
.Controller("Cliente")
.Action("CheckClienteByCUIT")
.Updater("changeClienteByCUIT")
).Append(Html.Bootstrap().Label("CUIT"))
.Append(Html.Bootstrap().Button().Text("Nuevo")
.TriggerModal("clienteModal")
)
)
)
)

Owner

DmitryEfimenko commented Oct 29, 2013

First of all, when you use FormGroup() it will render not only textbox (or other input), but also label for it. So you do not need to have separate label helper appended.
Second, I don't think you are using .Append method as intended. I think what you actually want is to use a .CustomControls method. Though I might be mistaken. It would be easier to tell if you showed me what kind of html output you are looking for.

fdsanto commented Oct 29, 2013

image

I wanted exactly that but with more space for DNI/CUIT textboxes, it's no problem i can take the appended inputs and place them above the main textbox

Owner

DmitryEfimenko commented Oct 29, 2013

I kind of have an alternative:

@using (var f = Html.Bootstrap().Begin(new Form().Type(FormType.Horizontal)))
{
    @(f.FormGroup().TextBoxFor(model => model.Venta.Cliente.Nombre).Disabled()
        .Append(Html.Bootstrap().TextBox("DNI").Placeholder("DNI").Typeahead(...))
        .Append(Html.Bootstrap().TextBox("CUIT").Placeholder("CUIT").Typeahead(...))
        .Append(Html.Bootstrap().Button().Text("Nuevo").TriggerModal("clienteModal")))
}

As you can see you would not need labels since there are placeholders in the inputs.
There is just one issue with this. BMVC does not handle appending inputs quite right. I just noticed it. it wraps inputs into span with class input-group-addon when it should wrap it in the span with class input-group-btn.
There still would be a need to adjust width of these inputs using css, but that will look cleaner.
I'll fix this issue. Let me know if that approach will work for you.

fdsanto commented Oct 29, 2013

it didn't quite fix it, but don't worry maybe i was over-complicating things.. one more thing, i'm trying to place both typeahead txtbox and button above the main txtbox(Nombre), is it possible to place controls in a inline manner inside a horizontal form? (without appending things =P)

thanks for all the help!

EDIT: disregard this, got it working on a horizontal form and it looks great by just placing one input after another. thx!

Owner

DmitryEfimenko commented Oct 30, 2013

I'll give you an idea how this could be done below, but probably some css adjustments will have to be done too:

@using (var f = Html.Bootstrap().Begin(new Form().Type(FormType.Horizontal)))
{
    @(f.FormGroup().CustomControls(
        MvcHtmlString.Create("<div class='form-inline'>"),
        @f.FormGroup().TextBoxFor(x => x.CoolName).Disabled().Label().Class("sr-only"),
        @f.FormGroup().TextBox("DNI").Label(),
        @f.FormGroup().TextBox("CUIT").Label(),
        Html.Bootstrap().Button().Text("Nuevo").TriggerModal("clienteModal"),
        MvcHtmlString.Create("</div>")
    ).LabelFor(x => x.CoolName))
}

fdsanto commented Oct 30, 2013

thanks Dmitry! i'll give it a try as soon as i can

2013/10/30 Dmitry A. Efimenko notifications@github.com

I'll give you an idea how this could be done below, but probably some css
adjustments will have to be done too:

@using (var f = Html.Bootstrap().Begin(new Form().Type(FormType.
Horizontal)))
{
@(f.FormGroup().CustomControls(
MvcHtmlString.Create("

"),
@f.FormGroup().TextBoxFor(x => x.CoolName).Disabled().Label().Class("sr-only"),
@f.FormGroup().TextBox("DNI").Label(),
@f.FormGroup().TextBox("CUIT").Label(),
Html.Bootstrap().Button().Text("Nuevo").TriggerModal("clienteModal"),
MvcHtmlString.Create("
")
).LabelFor(x => x.CoolName))
}


Reply to this email directly or view it on GitHubhttps://github.com/DmitryEfimenko/TwitterBootstrapMvc/issues/140#issuecomment-27411900
.

sgentile commented Dec 5, 2013

I'm having the same issue. Your examples help.

How would you do something like this : http://jsfiddle.net/tdUtX/2/

Owner

DmitryEfimenko commented Dec 5, 2013

well, this one looks to me like a simple Form with just modified input widths:

@using (var f = Html.Bootstrap().Begin(new Form()))
{
    @f.FormGroup().TextBoxFor(x => x.ShortField).WidthXs(6)
    @f.FormGroup().TextBoxFor(x => x.ShortField).WidthXs(6)
    @f.FormGroup().TextBoxFor(x => x.FullWidth)
}

Let me know if I misunderstood something.

sgentile commented Dec 5, 2013

This doesn't work as you need inline or horizontal ? But I'm not wanting either - I want a basic form with the input boxes smaller ?

Owner

DmitryEfimenko commented Dec 5, 2013

If it does not work like that, it's a bug. I'll take a look at it in the evening.

sgentile commented Dec 6, 2013

ok thanks!

Owner

DmitryEfimenko commented Dec 6, 2013

So I see the problem now. I guess the real purpose here is to be able to render multiple inputs in a row like in this fiddle.

Even if I made sure that BMVC renders inputs like in your example - surrounds it with <div class="col-xs-6"> and puts class row on the <div class="form-group">, it would not take care of the root issue because there still would be no way to put multiple inputs in the form group.

So we just need to think of an intuitive BMVC syntax that would allow for this functionality. Here is one possibility:

@using (var f = Html.Bootstrap().Begin(new Form()))
{
    using(f.FormGroup().BeginRow())
    {
        @f.TextBoxFor(x => x.Address).WidthXs(6).Label()
        @f.TextBoxFor(x => x.City).WidthXs(3).Label()
        @f.DropDownListFor(x => x.State).WidthXs(3).Label()
    }
    @f.FormGroup().Row().TextBoxFor(x => x.ShortField).WidthXs(6) // shortcut
    @f.FormGroup().TextBoxFor(x => x.FullWidth) // full widht, so .Row() does not need to be applied
}

For convenience there would also be a short cut .Row() for a single input that needs to be in a row.

Let me know what you think.

sgentile commented Dec 6, 2013

That looks good to me - solves the root issue as well as allows some flexibility on the row layout for multiple inputs

Owner

DmitryEfimenko commented Dec 7, 2013

As I was going through possible use cases with this, I saw that this would really only work for textboxes and dropdowns because they look alike, If you try to put checkbox, radiobutton, listbox, or of course textarea, the layout becomes screwed up.
Your scenario is kind of unique and building helper methods for it like proposed above will introduce confusion. I can already imagine questions asked about this every day. So I propose a different solution, that will be more generic and maybe will cover more situations because I now think it all really comes down to a question "how do I wrap my inputs in the <div class="col-xs-6">?":
Introducing helper .Col():

@using (var f = Html.Bootstrap().Begin(new Form()))
{
    @(f.FormGroup().Class("row").CustomControls(
        f.Col(f.TextBoxFor(x => x.Address).Label()).Xs(6),
        f.Col(f.TextBoxFor(x => x.City).Label()).Xs(3),
        f.Col(f.DropDownListFor(x => x.State).Label()).Xs(3)
    ))
}

So we have here FormGroup().Class() method. That functionality already exists. It just provides a way to slap any class on <div class="form-group">
We have .CustomControls((..). This helper exists as well. It allows to put multiple controls in the form group.
The helper .Col() will take any IHtmlString and essentially wrap it in <div class="col-*-*">
I think with such approach it will be more transparent what is going on and why html is rendered the way it is.

Let me know what you think.

sgentile commented Dec 7, 2013

"I think with such approach it will be more transparent what is going on and why html is rendered the way it is."

I agree - looks good! thanks

Owner

DmitryEfimenko commented Dec 13, 2013

This is done. Changed Col to be Div for even more clarity. This element also has .VisibleDependsOn() method.
the following syntax is now possible:

@using (var f = Html.Bootstrap().Begin(new Form()))
{
    @(f.FormGroup().CustomControls(
        Html.Bootstrap().Div(Html.Bootstrap().TextBox("Address").Label()).Xs(6),
        Html.Bootstrap().Div(Html.Bootstrap().TextBox("State").Label()).Xs(3),
        Html.Bootstrap().Div(Html.Bootstrap().TextBox("Zip").Label()).Xs(3)
    ))
}

thank you - fantastic!

I¹m still having an issue with this ­ can I email you on it ?

From: "Dmitry A. Efimenko" notifications@github.com
Reply-To: DmitryEfimenko/TwitterBootstrapMvc
<reply+i-21778925-fb1e9204704439aafd6fd08d4265c68efafccce7-132404@reply.gith
ub.com>
Date: Friday, December 13, 2013 at 5:03 AM
To: DmitryEfimenko/TwitterBootstrapMvc
TwitterBootstrapMvc@noreply.github.com
Cc: Steve Gentile steven.gentile@gmail.com
Subject: Re: [TwitterBootstrapMvc] width attributes? (#140)

Closed #140
#140 .


Reply to this email directly or view it on GitHub
#140 .

Some problems here:
When I use your example above, it puts the controls inline, even though the form is horizontal.*

Also when I use this:
@(f.FormGroup().CustomControls(
Html.Bootstrap().Div(Html.Bootstrap().DropDownListFor(model => model.General.Sample, new SelectList(Model.Samples, "Id", "Name")).Label()).Xs(4)
))

The width does get set now, however the entire FormGroup is indented.

*also to prevent inline, this means I have to put that entire section each time for every control on the form. ie.

@(f.FormGroup().CustomControls(
Html.Bootstrap().Div(Html.Bootstrap().DropDownListFor(model => model.General.Sample, new SelectList(Model.Samples, "Id", "Name")).Label()).Xs(4)
))
@(f.FormGroup().CustomControls(
Html.Bootstrap().Div(Html.Bootstrap().DropDownListFor(model => model.General.Sample, new SelectList(Model.Samples, "Id", "Name")).Label()).Xs(4)
))
@(f.FormGroup().CustomControls(
Html.Bootstrap().Div(Html.Bootstrap().DropDownListFor(model => model.General.Sample, new SelectList(Model.Samples, "Id", "Name")).Label()).Xs(4)
))

All that is needed with a horizontal form to control the input size is the ability to change the class on the div

ie.
@f.FormGroup().DropDownListFor(model => model.General.Ex, new SelectList(Model.Exs, "ExId", "ExName"))

This produces:

div class=" form-group"
label class="control-label col-lg-2" ...
div class="col-lg-10
    //input here...
div
div

All I need to be able to do is change that div width that wraps the input.

ie. if I'm in chrome and make that

it works perfectly.

I have yet to find the solution that does this

Owner

DmitryEfimenko commented Dec 13, 2013

Looking back at this post - we were talking about a regular form - not horizontal. I was building a way to support example in this fiddle.
I'll take a look what happens when form in horizontal this evening.

As for your last comment, you should be able to change width of that div with something like:

@f.FormGroup().DropDownListFor(model => model.General.Ex, new SelectList(Model.Exs, "ExId", "ExName")).WidthSm(4)

Let me know if this is not the case for you or if I misunderstand the issue.

I call it horizontal because of the label location. In that example, the labels are above the inputs, and the input widths are controlled by setting the class on the wrapping it. I will give that a try and report back

An example

<div class="form-group row">
    <div class="col-xs-6">
        @Html.LabelFor(model => model.General.IncidentTypeId)
        @Html.DropDownListFor(model => model.General.IncidentTypeId, new SelectList(Model.IncidentTypes, "IncidentTypeId", "Name"), new {@class="form-control"})
        @Html.ValidationMessageFor(model => model.General.IncidentSubmissionDate)
    </div>
</div>

That formats exactly how I need it to. It's left justified, and it the exact width.

I keep trying different options with what you provided, it's not formatting at all how this does above.

Owner

DmitryEfimenko commented Dec 13, 2013

I'm not testing this right now. Will be able to take a closer look in the evening, but from the looks of it I just forgot to put class "row" on the FormGroup and render validation message. The below should do it.

@using (var f = Html.Bootstrap().Begin(new Form()))
{
    @(f.FormGroup().Class("row").CustomControls(
        Html.Bootstrap().Div(Html.Bootstrap().TextBox("Address").ShowValidationMessage(true).Label()).Xs(6),
    ))
}

that solved the issue - let me know when you commit with that included (or if you plan on it) and I will update to latest!

Owner

DmitryEfimenko commented Dec 15, 2013

this should be already released. Please get latest and make sure it works as expected.

I have TwitterBootstrapMVC - MVC4 3.9.0 and it requires Class("row") on it to get the result as I posted above

Here is an example of what I have to do :

@(f.FormGroup().Class("row").CustomControls(Html.Bootstrap().Div(Html.Bootstrap().TextBoxFor(model => model.Person.SubscriberNumber).Label()).Xs(6)))
Owner

DmitryEfimenko commented Dec 15, 2013

that looks like exactly what I've posted in my previous comment. Does that work all right for you?

works well, I had misunderstood when you said you forgot to put 'row' on the item - thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment