Top forms Questions

List of Tags
445
One Crayon

This is one of the minor CSS problems that plagues me constantly. How do folks around StackOverflow vertically align checkboxes and their labels consistently cross-browser? Whenever I align them correctly in Safari (usually using vertical-align: baseline on the input), they're completely off in Firefox and IE. Fix it in Firefox, and Safari and IE are inevitably messed up. I waste time on this every time I code a form.

Here's the standard code that I work with:

<form>
    <div>
        <label><input type="checkbox" /> Label text</label>
    </div>
</form>

I usually use Eric Meyer's reset, so form elements are relatively clean of overrides. Looking forward to any tips or tricks that you have to offer!

Answered By: One Crayon ( 354)

After over an hour of tweaking, testing, and trying different styles of markup, I think I may have a decent solution. The requirements for this particular project were:

  1. Inputs must be on their own line
  2. Checkbox inputs need to align vertically with the label text similarly (if not identically) across all browsers
  3. If the label text wraps, it needs to be indented (so no wrapping down underneath the checkbox)

Before I get into any explanation, I'll just give you the code:

<form>
    <div>
        <label><input type="checkbox" /> Label text</label>
    </div>
</form>

<style type="text/css">
label {
    display: block;
    padding-left: 15px;
    text-indent: -15px;
}
input {
    width: 13px;
    height: 13px;
    padding: 0;
    margin:0;
    vertical-align: bottom;
    position: relative;
    top: -1px;
    *overflow: hidden;
}
</style>

Here is the working example in JSFiddle: http://jsfiddle.net/t8EGn/6/

This code assumes that you're using a reset like Eric Meyer's that doesn't override form input margins and padding (hence putting margin and padding resets in the input CSS). Obviously in a live environment you'll probably be nesting/overriding stuff to support other input elements, but I wanted to keep things simple.

Things to note:

  • The *overflow declaration is an inline IE hack (the star-property hack). Both IE 6 and 7 will notice it, but Safari and Firefox will properly ignore it. I think it might be valid CSS, but you're still better off with conditional comments; just used it for simplicity.
  • As best I can tell, the only vertical-align statement that was consistent across browsers was vertical-align: bottom. Setting this and then relatively positioning upwards behaved almost identically in Safari, Firefox and IE with only a pixel or two of discrepancy.
  • The major problem in working with alignment is that IE sticks a bunch of mysterious space around input elements. It isn't padding or margin, and it's damned persistent. Setting a width and height on the checkbox and then overflow: hidden for some reason cuts off the extra space and allows IE's positioning to act very similarly to Safari and Firefox.
  • Depending on your text sizing, you'll no doubt need to adjust the relative positioning, width, height, and so forth to get things looking right.

Hope this helps someone else! I haven't tried this specific technique on any projects other than the one I was working on this morning, so definitely pipe up if you find something that works more consistently.

302
Joseph Holsten

I'm trying to direct a browser to a different page. If I wanted a GET request, I might say

document.location.href = 'http://example.com/q=a';

But the resource I'm trying to access won't respond properly unless I use a POST request. If this were not dynamically generated, I might use the HTML

<form action="http://example.com/" method="POST">
  <input type="hidden" name="q" value="a">
</form>

Then I would just submit the form from the DOM.

But really I would like JavaScript code that allows me to say

post_to_url('http://example.com/', {'q':'a'});

What's the best cross browser implementation?

Edit

I'm sorry I was not clear. I need a solution that changes the location of the browser, just like submitting a form. If this is possible with XMLHttpRequest, it is not obvious. And this should not be asynchronous, nor use XML, so Ajax is not the answer.

Answered By: Rakesh Pai ( 461)
function post_to_url(path, params, method) {
    method = method || "post"; // Set method to post by default, if not specified.

    // The rest of this code assumes you are not using a library.
    // It can be made less wordy if you use one.
    var form = document.createElement("form");
    form.setAttribute("method", method);
    form.setAttribute("action", path);

    for(var key in params) {
        if(params.hasOwnProperty(key)) {
            var hiddenField = document.createElement("input");
            hiddenField.setAttribute("type", "hidden");
            hiddenField.setAttribute("name", key);
            hiddenField.setAttribute("value", params[key]);

            form.appendChild(hiddenField);
         }
    }

    document.body.appendChild(form);
    form.submit();
}

EDIT: Since this has gotten upvoted so much, I'm guessing people will be copy-pasting this a lot. So I added the hasOwnProperty check to fix any inadvertent bugs.

221
da5id

I have a form with a standard reset button coded thusly:

<input type="reset" class="button standard" value="Clear" />

Trouble is, said form is of the multi-stage sort, so if a user fills out a stage & then returns later, the 'remembered' values for the various fields won't reset when the Clear button is clicked.

I'm thinking that attaching a jQuery function to loop over all the fields and clear them 'manually' would do the trick. I'm already using jQuery within the form, but am only just getting up to speed & so am not sure how to go about this, other than individually referencing each field by ID, which doesn't seem very efficient.

TIA for any help.

Answered By: Paolo Bergantino ( 329)

updated on March 2012.

So, two years after I originally answered this question I come back to see that it has pretty much turned into a big mess. I feel it's about time I come back to it and make my answer truly correct since it is the most upvoted + accepted.

For the record, Titi's answer is wrong as it is not what the original poster asked for - it is correct that it is possible to reset a form using the native reset() method, but this question is trying to clear a form off of remembered values that would remain in the form if you reset it this way. This is why a "manual" reset is needed. I assume most people ended up in this question from a Google search and are truly looking for the reset() method, but it does not work for the specific case the OP is talking about.

My original answer was this:

// not correct, use answer below
$(':input','#myform')
.not(':button, :submit, :reset, :hidden')
.val('')
.removeAttr('checked')
.removeAttr('selected');

Which might work for a lot of cases, including for the OP, but as pointed out in the comments and in other answers, will clear radio/checkbox elements from any value attributes.

A more correct answer (but not perfect) is:

function resetForm($form) {
    $form.find('input:text, input:password, input:file, select, textarea').val('');
    $form.find('input:radio, input:checkbox')
         .removeAttr('checked').removeAttr('selected');
}

// to call, use:
resetForm($('#myform')); // by id, recommended
resetForm($('form[name=myName]')); // by name

Using the :text, :radio, etc. selectors by themselves is considered bad practice by jQuery as they end up evaluating to *:text which makes it take much longer than it should. I do prefer the whitelist approach and wish I had used it in my original answer. Anyhow, by specifying the input part of the selector, plus the cache of the form element, this should make it the best performing answer here.

This answer might still have some flaws if people's default for select elements is not an option that has a blank value, but it is certainly as generic as it is going to get and this would need to be handled on a case-by-case basis.

197
Eggs McLaren

I'm new to C# and I want to use a track-bar to change a form's opacity.

This is my code:

decimal trans = trackBar1.Value / 5000;
this.Opacity = trans;

When I try to build it, I get this error:

Cannot implicitly convert type 'decimal' to 'double'.

I tried making trans a double, but then the control doesn't work. This code has worked fine for me in VB.NET in the past.

Answered By: Kevin Dente ( 156)

An explicit cast to double isn't necessary.

double trans = (double)trackBar1.Value / 5000.0;

Identifying the constant as 5000.0 (or as 5000d) is sufficient:

double trans = trackBar1.Value / 5000.0;
double trans = trackBar1.Value / 5000d;

This seems a bit bizarre to me, but as far as I can tell, this is how you do it.

I have a collection of objects, and I want users to select one or more of them. This says to me "form with checkboxes." My objects don't have any concept of "selected" (they're rudimentary POCO's formed by deserializing a wcf call). So, I do the following:

public class SampleObject{
  public Guid Id {get;set;}
  public string Name {get;set;}
}

In the view:

<%
    using (Html.BeginForm())
    {
%>
  <%foreach (var o in ViewData.Model) {%>
    <%=Html.CheckBox(o.Id)%>&nbsp;<%= o.Name %>
  <%}%>
  <input type="submit" value="Submit" />
<%}%>

And, in the controller, this is the only way I can see to figure out what objects the user checked:

public ActionResult ThisLooksWeird(FormCollection result)
{
  var winnars = from x in result.AllKeys
          where result[x] != "false"
          select x;
  // yadda
}

Its freaky in the first place, and secondly, for those items the user checked, the FormCollection lists its value as "true false" rather than just true.

Obviously, I'm missing something. I think this is built with the idea in mind that the objects in the collection that are acted upon within the html form are updated using UpdateModel() or through a ModelBinder.

But my objects aren't set up for this; does that mean that this is the only way? Is there another way to do it?

Answered By: Dylan Beattie ( 208)

Html.CheckBox is doing something weird - if you view source on the resulting page, you'll see there's an <input type="hidden" /> being generated alongside each checkbox, which explains the "true false" values you're seeing for each form element.

Try this, which definitely works on ASP.NET MVC Beta because I've just tried it.

Put this in the view instead of using Html.CheckBox():

<% using (Html.BeginForm("ShowData", "Home")) {  %>
  <% foreach (var o in ViewData.Model) { %>
    <input type="checkbox" name="selectedObjects" value="<%=o.Id%>">
    <%= o.Name %>
  <%}%>
  <input type="submit" value="Submit" />
<%}%>

Your checkboxes are all called selectedObjects, and the value of each checkbox is the GUID of the corresponding object.

Then post to the following controller action (or something similar that does something useful instead of Response.Write())

public ActionResult ShowData(Guid[] selectedObjects) {
    foreach (Guid guid in selectedObjects) {
        Response.Write(guid.ToString());
    }
    Response.End();
    return (new EmptyResult());
}

This example will just write the GUIDs of the boxes you checked; ASP.NET MVC maps the GUID values of the selected checkboxes into the Guid[] selectedObjects parameter for you, and even parses the strings from the Request.Form collection into instantied GUID objects, which I think is rather nice.

152
matt b

When using the xhtml1-transitional.dtd doctype, collecting a credit card number with the following HTML

<input type="text" id="cardNumber" name="cardNumber" autocomplete='off'/>

will flag a warning on the W3C validator:

there is no attribute "autocomplete".

Is there a W3C / standards way to disable browser auto-complete on sensitive fields in a form?

Answered By: Nick Presta ( 166)

'autocomplete' is a non-standard attribute, I'm afraid.

Here is a good article from the MDC which explains the problems (and solutions) to form autocompletion. Microsoft has published something similar here, as well.

To be honest, if this is something important to your users, 'breaking' standards in this way seems appropriate. For example, Amazon uses the 'autocomplete' attribute quite a bit, and it seems to work well.

If you want to remove the warning entirely, you can use JavaScript to apply the attribute to browsers that support it (IE and Firefox are the important browsers) using someForm.setAttribute( "autocomplete", "off" ); someFormElm.setAttribute( "autocomplete", "off" );

Finally, if your site is using HTTPS, IE automatically turns off autocompletion (as do some other browsers, as far as I know).

Update

As this answer still gets quite a few upvotes, I just wanted to point out that in HTML5, you can use the 'autocomplete' attribute on your form element. See the documentation on W3C for it.