Community & Support

Styling a Form Entry... WHY is this so complex?

Please. I must be missing the obvious. I have been working for seven solid hours trying to make ANY style change to a Form Entry page with NO success. I've been trying now maybe 12 different thread suggestions and this is just ridiculous.

This seemed the most promising... about 2.5 hours ago...:
http://drupal.org/node/101092

Ok, I have a Content Type that I built from CCK fields, maybe 60 fields long. As every field presents itself (layout) one beneath the last, this entry form is ridiculously long and full page width wide for no good reason. While building I just assumed I'd hit the cosmetic cleanup of styling it towards he end of my project and now this... OMG is this complex?

Bottom line, is I want to shorten the default full-page width of text fields and set fields side by side where it is reasonable, to shorten this long form vertically.

Zen theme, drupal v5.10. CCK, Views.

Help? Please? Anyone?
sob sob sob.... weeping

Thanks in advance for any lighthouses,
iansears

Comments

I guess we can help you, but

I guess we can help you, but it's hard if we can't see the code.
The best method for styling forms probably depends on the design you want to achieve. Before you start with .tpl.php files, I would try if CSS alone can do the trick. If you don't use Firefox and the Firebug addon yet, this is the time to start using it. Just select the element you want to style, see which styling applies and add/change css rules. Keep in mind that styling the form elements alone may not be enough, because they can be wrapped in full-width div's, i.e. <div class="form-item">.

Thank

Thank you.
http://iansears.com/form_rebuild/before.png
http://iansears.com/form_rebuild/after.png
These two png file show why I absolutely must be able to tighten up the form entry layout.

CSS:
While each form field does indeed have it's own css "id" that I can apply style to,

<div id="content-area">
<form action="/node/add/data-entry-1"  accept-charset="UTF-8" method="post" id="node-form" enctype="multipart/form-data">
<div>
<div class="node-form">
<div class="standard">
<fieldset class="group-address-1-info collapsible"><legend>Address #1 Info</legend>
<div class="form-item">
<label for="edit-field-contact-address-type-key">Address Type: <span class="form-required" title="This field is required.">*</span></label>
<select name="field_contact_address_type[key]" class="form-select required" id="edit-field-contact-address-type-key" ><option value="Physical Address">Physical Address</option><option value="Shipping">Shipping</option><option value="Billing">Billing</option></select>
<div class="description">(mailing, shipping, billing, etc)</div>
</div>
<div class="form-item">
<label for="edit-field-contact-address-1-street-0-value">Address: <span class="form-required" title="This field is required.">*</span></label>
<textarea cols="60" rows="4" name="field_contact_address_1_street[0][value]" id="edit-field-contact-address-1-street-0-value"  class="form-textarea resizable required"></textarea>
</div>
<div class="form-item">
<label for="edit-field-contact-address-1-city-0-value">City: <span class="form-required" title="This field is required.">*</span></label>
<input type="text" maxlength="" name="field_contact_address_1_city[0][value]" id="edit-field-contact-address-1-city-0-value"  size="60" value="" class="form-text required" />
</div>
<div class="form-item">
<label for="edit-field-contact-address-1-state-0-value">State: <span class="form-required" title="This field is required.">*</span></label>
<input type="text" maxlength="" name="field_contact_address_1_state[0][value]" id="edit-field-contact-address-1-state-0-value"  size="60" value="" class="form-text required" />
</div>
<div class="form-item">
<label for="edit-field-contact-addrss-1-country-key">Country: <span class="form-required" title="This field is required.">*</span></label>
<select name="field_contact_addrss_1_country[key]" class="form-select required" id="edit-field-contact-addrss-1-country-key" ><option value="UNITED STATES">UNITED STATES</option></select>
</div>
<div class="form-item">
<label for="edit-field-contact-address-1-zip-0-value">Postal Code: <span class="form-required" title="This field is required.">*</span></label>
<input type="text" maxlength="" name="field_contact_address_1_zip[0][value]" id="edit-field-contact-address-1-zip-0-value"  size="60" value="" class="form-text required" />
</div>
</fieldset>
<fieldset class="group-address-2-info collapsible"><legend>Address #2 Info</legend>
<div class="form-item">
<label for="edit-field-contact-address-2-type-key">Address Type: </label>
<select name="field_contact_address_2_type[key]" class="form-select" id="edit-field-contact-address-2-type-key" ><option value="" selected="selected"></option><option value="Home">Home</option><option value="Work">Work</option><option value="Work 2">Work 2</option><option value="Work 3">Work 3</option></select>
</div>
<div class="form-item">
<label for="edit-field-contact-address-2-street-0-value">Address: </label>
<textarea cols="60" rows="4" name="field_contact_address_2_street[0][value]" id="edit-field-contact-address-2-street-0-value"  class="form-textarea resizable"></textarea>
</div>
<div class="form-item">
<label for="edit-field-contract-address-2-city-0-value">City: </label>
<input type="text" maxlength="" name="field_contract_address_2_city[0][value]" id="edit-field-contract-address-2-city-0-value"  size="60" value="" class="form-text" />
</div>
<div class="form-item">
<label for="edit-field-contract-address-2-state-0-value">State: </label>
<input type="text" maxlength="" name="field_contract_address_2_state[0][value]" id="edit-field-contract-address-2-state-0-value"  size="60" value="" class="form-text" />
</div>
<div class="form-item">
<label for="edit-field-contract-address-2-countr-key">Country: </label>
<select name="field_contract_address_2_countr[key]" class="form-select" id="edit-field-contract-address-2-countr-key" ><option value="" selected="selected"></option><option value="UNITED STATES">UNITED STATES</option></select>
</div>
<div class="form-item">
<label for="edit-field-contract-address-2-zip-0-value">Postal Code: </label>
<input type="text" maxlength="" name="field_contract_address_2_zip[0][value]" id="edit-field-contract-address-2-zip-0-value"  size="60" value="" class="form-text" />
</div>
</fieldset>
<fieldset class="group-address-3-info collapsible"><legend>Address #3 Info</legend>
<div class="form-item">
<label for="edit-field-contact-address-3-type-key">Address Type: </label>
<select name="field_contact_address_3_type[key]" class="form-select" id="edit-field-contact-address-3-type-key" ><option value="" selected="selected"></option><option value="Home">Home</option><option value="Work">Work</option><option value="Work 2">Work 2</option><option value="Work 3">Work 3</option></select>
</div>
<div class="form-item">
<label for="edit-field-contact-address-3-street-0-value">Address: </label>
<textarea cols="60" rows="4" name="field_contact_address_3_street[0][value]" id="edit-field-contact-address-3-street-0-value"  class="form-textarea resizable"></textarea>
</div>
<div class="form-item">
<label for="edit-field-contact-address-3-city-0-value">City: </label>
<input type="text" maxlength="" name="field_contact_address_3_city[0][value]" id="edit-field-contact-address-3-city-0-value"  size="60" value="" class="form-text" />
</div>
<div class="form-item">
<label for="edit-field-contact-address-3-state-0-value">State: </label>
<input type="text" maxlength="" name="field_contact_address_3_state[0][value]" id="edit-field-contact-address-3-state-0-value"  size="60" value="" class="form-text" />
</div>
<div class="form-item">
<label for="edit-field-contact-addrss-3-country-key">Country: </label>
<select name="field_contact_addrss_3_country[key]" class="form-select" id="edit-field-contact-addrss-3-country-key" ><option value="" selected="selected"></option><option value="UNITED STATES">UNITED STATES</option></select>
</div>
<div class="form-item">
<label for="edit-field-contact-address-3-zip-0-value">Postal Code: </label>
<input type="text" maxlength="" name="field_contact_address_3_zip[0][value]" id="edit-field-contact-address-3-zip-0-value"  size="60" value="" class="form-text" />
</div>
</fieldset>
<fieldset class="group-phone-1-info collapsible"><legend>Phone #1 Info</legend>
<div class="form-item">
<label for="edit-field-contact-phone-1-type-key">Phone Type: </label>
<select name="field_contact_phone_1_type[key]" class="form-select" id="edit-field-contact-phone-1-type-key" ><option value="" selected="selected"></option><option value="Cell">Cell</option><option value="Work">Work</option><option value="Work 1">Work 1</option><option value="Work 2">Work 2</option></select>
</div>
<div class="form-item">
<label for="edit-field-contact-phone-1-countryco-0-value">Country Code: </label>
<input type="text" maxlength="" name="field_contact_phone_1_countryco[0][value]" id="edit-field-contact-phone-1-countryco-0-value"  size="60" value="" class="form-text" />
</div>
<div class="form-item">
<label for="edit-field-contact-phone-1-citycode-0-value">City Code: </label>
<input type="text" maxlength="" name="field_contact_phone_1_citycode[0][value]" id="edit-field-contact-phone-1-citycode-0-value"  size="60" value="" class="form-text" />
</div>
<div class="form-item">
<label for="edit-field-contact-phone-1-phonenumb-0-value">Phone Number: </label>
<input type="text" maxlength="" name="field_contact_phone_1_phonenumb[0][value]" id="edit-field-contact-phone-1-phonenumb-0-value"  size="60" value="" class="form-text" />
</div>
</fieldset>
<fieldset class="group-phone-2-info collapsible"><legend>Phone #2 Info</legend>
<div class="form-item">
<label for="edit-field-contact-phone-2-type-key">Phone Type:: </label>
<select name="field_contact_phone_2_type[key]" class="form-select" id="edit-field-contact-phone-2-type-key" ><option value="" selected="selected"></option><option value="Cell">Cell</option><option value="Work">Work</option><option value="Work 1">Work 1</option><option value="Work 2">Work 2</option></select>
</div>
<div class="form-item">
<label for="edit-field-contact-phone-2-countryco-0-value">Country Code: </label>
<input type="text" maxlength="" name="field_contact_phone_2_countryco[0][value]" id="edit-field-contact-phone-2-countryco-0-value"  size="60" value="" class="form-text" />
</div>
<div class="form-item">
<label for="edit-field-contact-phone-2-citycode-0-value">City Code: </label>
<input type="text" maxlength="" name="field_contact_phone_2_citycode[0][value]" id="edit-field-contact-phone-2-citycode-0-value"  size="60" value="" class="form-text" />
</div>
<div class="form-item">
<label for="edit-field-contact-phone-2-phonenumb-0-value">Phone Number: </label>
<input type="text" maxlength="" name="field_contact_phone_2_phonenumb[0][value]" id="edit-field-contact-phone-2-phonenumb-0-value"  size="60" value="" class="form-text" />
</div>
</fieldset>
<fieldset class="group-phone-3-info collapsible"><legend>Phone #3 Info</legend>
<div class="form-item">
<label for="edit-field-contact-phone-3-type-key">Phone Type: </label>
<select name="field_contact_phone_3_type[key]" class="form-select" id="edit-field-contact-phone-3-type-key" ><option value="" selected="selected"></option><option value="Cell">Cell</option><option value="Home">Home</option><option value="Work">Work</option><option value="Work 2">Work 2</option></select>
</div>
<div class="form-item">
<label for="edit-field-contact-phone-3-countryco-0-value">Country Code: </label>
<input type="text" maxlength="" name="field_contact_phone_3_countryco[0][value]" id="edit-field-contact-phone-3-countryco-0-value"  size="60" value="" class="form-text" />
</div>
<div class="form-item">
<label for="edit-field-contact-phone-3-citycode-0-value">City Code: </label>
<input type="text" maxlength="" name="field_contact_phone_3_citycode[0][value]" id="edit-field-contact-phone-3-citycode-0-value"  size="60" value="" class="form-text" />
</div>
<div class="form-item">
<label for="edit-field-contact-phone-3-phonenumb-0-value">Phone Number: </label>
<input type="text" maxlength="" name="field_contact_phone_3_phonenumb[0][value]" id="edit-field-contact-phone-3-phonenumb-0-value"  size="60" value="" class="form-text" />
</div>
</fieldset>
</div>
<input type="submit" name="op" id="edit-preview" value="Preview"  class="form-submit" />
<input type="submit" name="op" id="edit-submit" value="Submit"  class="form-submit" />
</div>
</div>
</form>
</div>

Now I created this entry form by:
1) Creating a Content Type (I call it "Data Entry", data_entry_1)
2) Using "Add Fields tab" to create CCK Groups and CCK Fields as I go
3) Then doing a "Create Content" menu selection and choosing type "Data Entry"
4) Feint as I watch this long list print to the screen waiting for data entry.

So, of course I viewed it in FireBug (FireFox) to get some id's that I could then hook into from the theme's style.css and layout.css (this theme is the "zen" theme, couldn't be simpler....). So.... um.. WHERE are the id tags int he divs of this form? There are none, or not enough anyway. There are classes, but I'm only trying to do a SIMPLE layout edit of this one page, not EVERY instance of a form class="form-item". Know what I mean there?

I may be WAY off base stealing second here, but shouldn;t we make CCK field generation produce a unique style "id" for a field when we produce that field? Just to be able to hook into it stylisticly down the road?

No way could we be forced to make this a static page JUST to re-lay it out with stylesheets....

What code would best help you to gleen better insight into my dilemma here?

Frustrated and way way WAY out of time to turn this around for my client here. Who knew Drupal would be so disconnected at this stage?
Sorry, I AM grateful for any help anyone can offer here.
Sincerely
Ian

CSS hooks insufficent to style via CSS

I'm helping on this project as well. I already use the Web Developer's plugin for Firefox to assist with styling via CSS but as you can see from the code in Ian's replay, the only element with an ID is the containing div <div id="content-area">. The form fields and labels are either marked with classes or nothing at all. If there were a way to add IDs to these div elements (or if they were IDed to start with) there would be no problem.

We've poured over the documentation here: http://drupal.org/node/101092 but unfortunately were not able to make it work for us. Any help with this or another approach would be greatly appreciated.

EDIT: OK I lied. The select/input tags do have IDs, but it's useless unless the label and/or containing divs are IDed as well. I just didn't want anyone to accuse me of speaking untruths.

It doesn't look that hard to

It doesn't look that hard to at least come close to what you need... Please tell me if I'm missing something, but suppose that you add to your stylesheet:

.form-item {
  float: left;
}

And then use the input id's to change the widths of the fields.
Finally change the weight of the 'Address Type' dropdown to make it float to the right of 'City'...
Isn't that all you need to do?

Close but...

Thanks for the suggestion. I got hopeful there for a little while since I'd basically written it off without trying it, but unfortunately I was right to start with. It's kind of an unreasonable request, but our client want us to fit this large form all on one page 1024x768. I don't know if I could even do that with full control over all these elements, but I think I could, or at least come really close.

Original: http://www.mattsmessyroom.com/drupalform_original.gif
Float: http://www.mattsmessyroom.com/drupalform_float.gif
Display: inline: http://www.mattsmessyroom.com/drupalform_inline.gif

What I'd really like to do is set a width and height for a containing element, and then absolutely position the form elements inside of that. Floating or display: inline will help tighten up the form, but it does not allow the kind of control that I'm used to when hand coding. I have to believe there is a way to take that sort of control here.

There is a way to take that

There is a way to take that control and the article here -> http://drupal.org/node/101092 (which you have seen) gives the basic idea of how to do it. However, it is a more complex solution than a pure css solution because it requires you to change the output of the form.

Everything you need to do can be achieved with css. You need to understand css floats to make it work.
let me try to give an example:

/* floats all form item wrapping divs left and shrinks them to fit their contents */
div.form-item {
  float: left;
}
/* floats all text inputs left and makes them 50px wide */
.form-item .form-text {
  float: left;
  width: 50px;
}
/* 50px is too narrow for the street address so we make it 75px wide */
#edit-field-contact-address-1-street-0-value {
  width: 75px;
}

Get it?

Ok, I see what you mean

Ok. I've started messing with it some more and I think I can get this to work. Like you showed, if I deal with the widths of the fields separately and basically make everything else run together with float, I can at least make something that is compact like the client is looking for. Sorry if I'm being belligerent but this is just a big shift from what I'm used to which is being able to tag elements however you choose. Maybe we'll get that one technique working but this might do it for now. Thanks for talking me though it.

No problem. I understand

No problem. I understand what you are used to, and it would be the advantage of "hand crafted" code. However, when dealing with a large system we get to leverage a lot of power that would take a long time to "hand craft". Because of this we just need to change the way we think about how to do something is all.

Since changing the entire output of the form is involved (I have only one time EVER had to go that route), we need to look at the problem as if there was no way to change the output of the form. Taking this view on it, is it possible to use css rule specificity to isolate the elements we want and style them accordingly? I have found that in virtually all cases it is.

Virtually all output of the core system and contributed modules are wrapped in so many containers with classes and id's that it is almost ridiculous. This however is also another trade off. It is done to provide us with enough possible css rule specificity to style something virtually any way we need to, because neither the core nor a module developer could possibly write code to cover every possible use case of the way someone might want something to look.

And to wrap up my lecture, rofl :-). It is generally recommended to use classes whenever possible and id's only when necessary. That is why most of the output you see is the way it is.

One other thing. Don't

One other thing. Don't forget that you have classes on your fieldsets. You can use these to isolate groups of form items with css rules. Also remember the clear property. It will be your friend when you want something to not float.

Oh and one last one:
You can set widths on those fieldsets too. If you made the fieldset 800px wide and each input 250px wide then they could only float 3 across with the 4th one underneath the other 3 and no clear necessary.

Changing the output of the form

Hello, I hope you don't mind me posting here, because what I am trying to do is mentioned in this thread as well. I am trying to change the layout of the submitted form or find a way to display the information submitted in the form in the format I specify. So, for example, a picture, which is submitted as an attached file in a form will be displayed in the left top corner of the page and other fields are not just positioned one behind the other, but make it to the title, content, footer, etc. of the page. So far I played with form css, but it doesn't do what I want. I also want to display text within the textfields of the form not as text fields, but as text positioned in some particular place on the page. Any help would be very much appreciated.

The topic here is not

The topic here is not styling the submitted content, but styling the submission form. Those are two different things. So: your question is a little off-topic in the context of this thread... but I'll answer anyway.

In fact the answer to your problem is quite simple: you need the contemplate module. (http://drupal.org/project/contemplate) This module allows you to use all variables available in a node and mix them with html (and php if you need it) to create exactly the output you need.

Thanks for the answer.

Thank you for the answer. I've moved my question to the link here: http://drupal.org/node/305063

Thanks again

Just wanted to follow up and say thanks again. We showed the output to the client recently and they were very pleased. The only trailing issue is a section of grouped fields that in IE only, shift upward when one or more field(s) in a preceding group is left blank. I'm working on some workarounds that should sidestep the issue. Now on to bigger and better things!

Positioning submit button

Hey,

All the help with the float and clear css stuff was awesome. Thanks to all.

This trick applies to custom-written forms.

One thing I had a problem with was positioning the submit button underneath the form in the usual location. The submit button doesn't get the "wrapper" element, so I added it in my module thusly:

function mycustom_form() {
  ...
  $form['submit'] = array(
      '#prefix' => '<div class="form-item" id="edit-submit-wrapper">',
      '#type' => 'submit',
      '#value' => t('Submit'),
      '#suffix' => '</div>'
    );
   ...
}

Note the prefix and suffix items. I copied the naming format that the other form items had. I then added this to my stylesheet:

#edit-submit-wrapper {
  clear: both;
  margin-left: 0;
}

Works perfectly (Drupal 6.15). Tested with Safari 4, Firefox 3 (Mac and WinXP), and IE 8.

nobody click here