1

The Problem

I've got a problem where I'm trying to create rows of form inputs. This works OK, however, once the width of the total inputs gets too large, everything starts to wrap. What I would like is for a horizontal scroll-bar to appear inside the field-set and for all form elements for a single service-item div to remain on a single line.

<div style="display: inline-block;" class="horizontal-fields service-item">
    <button class="horizontal-fields remove-service-item" style="float: left; margin-right: 5px;">-</button>
    <label for="service_name">Name:</label>
    <input name="service_name[]" id="service_name" value="" type="text">

    <label for="service_description">Description:</label>
    <input id="service_description" name="service_description[]" value="" type="text">

    <!-- Additional form fields are dynamically inserted here. -->
    <div class="service-additional-fields">
        <!-- Additional fields for DSL Tails -->
        <label for="service_dsl_fnn[]">FNN:</label>
        <input id="service_dsl_fnn" name="service_dsl_fnn[]" size="10" value="" type="text">
        <button class="horizontal-fields new-service-item" style="display: inline-block;">+</button>
    </div>
    <br>
 </div>

Current Results

Here is a JSFiddle showing the form in it's current state, I've included all the bare-bones CSS/HTML that I think are relevant: http://jsfiddle.net/FjxqG/3/

You will see that I've managed to get what I want by specifying width: 300% in the horizontal-fields class. However, this is of course not optimal because the width is essentially fixed and not automatically fitting the width of the service-item div.

Of course, this leaves the width much larger than it needs to be, but also always showing a horizontal-scroll, even when it isn't needed.

What I've tried

I've tried using display: inline-block; and whitespace: no-wrap;. However, the former did not seem to do much for me, and the latter only worked for the first few form items, not those inside the service-additional-fields div.

Unfortunately, I've got those latter items in the service-additional-fields div as they are dynamically inserted using jQuery, so although it's possible to take them out, I'd rather leave them in there, as it keeps the JavaScript simpler.

I've tried adapting the solution found here, with little success: http://www.css-lab.com/demos/image-display/side-scroll-gallery.html

Ended up with a similar situation in which the latter form elements were still wrapping.

I've also considered doing something like the jQuery solution found here: Horizontal scroll in DIV with many small DIV's inside (no text)

I guess this would work for me, because I already know that setting the width on horizontal-fields works OK, so using jQuery to find out what that width should be would probably work. However, it feels like I shouldn't need jQuery and it would be kind of a hack. So I'd like to avoid it if reasonably possible.

Thanks!

Community
  • 1
  • 1
Geekman
  • 599
  • 7
  • 18
  • Would it be be possible to loop through the dynamically inserted fields (and what not) to get their widths and then set the outer width using javascript? – qooplmao Nov 12 '12 at 11:41
  • Yes. As I linked to under "What I've tried", I could do this. But I would like to avoid it because it seems like I shouldn't need to rely on jQuery for this. I'd like an all-CSS solution if reasonable to do so. – Geekman Nov 12 '12 at 11:45
  • 1
    Sorry about that, thinking when I should have been reading. How about removing the floats and having inline-blocks with auto widths, And then for the .service-additional-fields as inline-block too? http://jsfiddle.net/UjbBM/ – qooplmao Nov 12 '12 at 12:03
  • Thanks! That seems to work. Going to try it on the actual code-base now. – Geekman Nov 12 '12 at 12:17
  • Can you avoid appearing of scrollbars at all in such containers that have inside all the form elements? I think it would be better. Have you seen at someone's site the behaviour like you want? It's good to use common usability approaches. – starikovs Nov 12 '12 at 11:25
  • The JSFiddle link pretty much shows what I'm trying to do. As I say though, it's fixed with, not adapting to the width of the form elements. I'm quite sure I've seen this done before, but have no specific examples (though I can look for some). If you have any good ideas though, I'm open to it. I just don't want the form elements to wrap because it looks like a mess. – Geekman Nov 12 '12 at 11:42
  • @Qoop Just tested this in my code, and got it working. Thanks! Did you want to post it as an answer so I can accept? – Geekman Nov 12 '12 at 13:07

2 Answers2

2

Try this approach:

HTML:

<div id="slide-wrap">
    <!-- + First row -->
    <div class="row">
      <!-- All elements here -->
    </div>
    <!-- - First row --> 

    <!-- + Second row -->        
    <div class="row">
      <!-- All elements here -->
    </div>
    <!-- - Second row -->  
</div>

CSS:

#slide-wrap {
  margin:0 auto;
  overflow: auto; 
  background:#BCC5E1;
  border:1px solid #000;
  width: 400px; /*  for example */
  padding-left:20px;
}

div.row {
  float:left;
  white-space: nowrap;
}

Take it easy, I was really getting confused of inner styles, so I removed them. JsBin demo

Hashem Qolami
  • 97,268
  • 26
  • 150
  • 164
  • Thanks. But as soon as I put the other form elements into the "service-additional-fields" div, I can't get it working. And this is where I keep running into problems. I'd prefer to keep these fields in there because they are dynamically inserted and it's harder to work with them if all form items are in a single div. :-( – Geekman Nov 12 '12 at 12:12
  • @Geekman There's no problem that can not be solved. could you put some sample elements in `service-additional-fields` div to let me know what exactly happens? – Hashem Qolami Nov 12 '12 at 12:19
2

For some reason the other answer has been deleted and I can't get it back so having to answer again.

Previous answer was -

How about removing the floats and having inline-blocks with auto widths, And then for the .service-additional-fields as inline-block too?

Edited for a fuller answer.

HTML

<fieldset>
        <legend>Fourth: Add Services</legend>
        <div id="slide-wrap">
            <div id="inner-wrap">
                <div class="horizontal-fields service-item">
                    <button class="addField">+</button>
                    <label>Text Box:</label>
                    <input type="text">
                    <label>Text Box:</label>
                    <input type="text">
                    <!-- Additional form fields are dynamically inserted here. -->
                    <div class="service-additional-fields">
                        <!-- Additional fields for DSL Tails -->
                        <label>Text Box:</label>
                        <input type="text">
                        <label>Text Box:</label>
                        <input type="text">
                    </div>
                </div>
                <div class="horizontal-fields service-item">
                    <button class="addField">+</button>
                    <label>Text Box:</label>
                    <input type="text">
                    <label>Text Box:</label>
                    <input type="text">
                    <!-- Additional form fields are dynamically inserted here. -->
                    <div class="service-additional-fields">
                        <!-- Additional fields for DSL Tails -->
                        <label>Text Box:</label>
                        <input type="text">
                        <label>Text Box:</label>
                        <input type="text">
                        <label>Text Box:</label>
                        <input type="text">
                    </div>
                </div>
           </div>
        </div>
    </fieldset>

CSS

#slide-wrap {
    margin:0 auto;
    overflow: auto; 
    background:#BCC5E1;
    border:1px solid #000;
}
#inner-wrap {
    float:left;
    margin-right:-30000px;/*Be safe with Opera's limited negative margin of 32695px     (-999em could cause problems with large font sizes)*/
    padding-left:20px;        
    width: auto;
}

div.horizontal-fields input,
div.horizontal-fields textarea,
div.horizontal-fields select,
div.horizontal-fields label {
    width: auto;
}

/* Horizontal fields is the class which is not re-sizing it's with correctly */
.horizontal-fields {
    display: block;
}

.service-additional-fields {
    display:inline-block;
}​

DEMO

http://jsfiddle.net/aLKHJ/1/

qooplmao
  • 17,622
  • 2
  • 44
  • 69