views:

1631

answers:

4

I know the defined behavior for web forms is to not submit disabled fields... but that's not the definition I want. I want to use ajax to post the form and I want it to get all fields, even if they are disabled. I don't want to build a workaround where I make the field "look disabled"... or have to hack it where I enable the fields -> post -> disable.

is it possible to make ajaxSubmit() or serialize() grab the disabled fields as it's moving through the DOM and grabbing values? or is there another serialize plugin out there that can do this? or does someone have a mod I can make to one of these plugins to make it work?

or am I doomed to hack it?

+4  A: 

You can make your fields readonly, this will disallow changes to the value of your controls.

Edit: You could easily write a "serializeDisabled" function, iterating over the disabled form elements which have a name attribute and using the jQuery.param function at the end, to generate the serialized string:

(function ($) {
  $.fn.serializeDisabled = function () {
    var obj = {};

    $(':disabled[name]', this).each(function () { 
        obj[this.name] = $(this).val(); 
    });
    return $.param(obj);
  }
})(jQuery);
CMS
you can't make a <select> box readonly... yet another hack is required to make that work
Nick Franceschina
Which goes back to the question in my answer: why would you make a select box disabled and still want the value?
Anthony
i want the value because I don't want to have to write special code for certain fields ("this field is a disabled/select so I have to get the value somewhere else"). I want consistent/concise code that puts values in the form and then when those fields are sent back I can use one set of code to read the values and be done. I want it to be generic. This post is not a discussion about concepts... I'm looking for an answer to my question
Nick Franceschina
I can certainly appreciate you not wanting to get too conceptual, but you want to know the answer that will a) not be a hack and b) do something that html doesn't do by default. And you want the answer to be as broad and generic as possible, which, if it was, you know full well that it would be native to HTML and you'd already know the answer. Before mentioning the select box, there was a simple answer (from CMS) yet your problem got more CONCEPTUALLY complicated with the select-box detail. Cool off and read the addendum to my answer.
Anthony
but this isn't HTML... it's jQuery/ajax... and those libraries/plugins are just cycling through the DOM and grabbing fields... which could easily take an extra option which says "grab disabled fields as well". I suppose I should have asked it more specifically: is there an option for those plug-ins to not ignore disabled fields
Nick Franceschina
Well, my 4 line function essentially just says "grab disabled fields as well" by creating the hidden input with the same data. I am legitimately curious if that "unsuccessful" feature did what you wanted. With PHP, at least, POST data is identified by name, and the `select` element is what carries the name, not the `option`. So doesn't it show multiple instances of the same POST data? How do you know which one was selected? If you are giving each option a different name, that would be invalid and, in my opinion, a hack.
Anthony
A: 

First: I really like CMS's answer. Much simpler. But in case it's not the best option...

Why don't you just have a JQuery function tied to the form's onsubmit event that traverses the form and grabs the input for all <input>s in the form and enables them and then submits the form? Do you need to know if the input is disabled? Are you concerned that enabling the input will change the visual appearance in a way that concerns the user?

In either case you could add something to the elements that you are enabling. For styling, add a class that gives disabled inputs the same look as enabled inputs. Of if you need to know which were disabled, add something to either the name or the value itself to indicate the status.

Out of curiosity, when would you ever want the disabled info? If the input is always disabled (meaning the user didn't set it that way) don't you already know the value? And if the input is set to disabled by the user, aren't you being a bit deceptive collecting that data?

If the value is disabled because it's something like a "total" field which updates via js based on other non-disabled fields, I'd go with CMS on making it read-only instead.


Based on your response to CMS:

I can only imagine a few scenarios where a select box would be disabled but you'd want that passed back to the script. The main one that comes to my mind is that certain select boxes become enabled when other options are checked, but you would rather have the form pass back the default of the select box rather than have the server script deal with filling in the blanks.

If that's the case, why not set up a toggle between a hidden input and the select box? Have the value and name be the same for both inputs but if one is enabled, the other is disabled. This way the script only sees one of the two inputs, and since they have the same name it doesn't get caught on where the data came from.


$('form').submit(function() {
    $('[disabled]').each(function(i) {
        d_name = $(this).attr("name");
        d_val = $(this).val();
        $(this).after(
        '<input type="hidden" name="' + d_name + '" value="' + d_val + ' />'
        );
    });
return true;
});

Just in case you think I'm being too conceptual, here's a simple function that will run on user submit. Notice how it goes through each disabled element and adds a new hidden input into the DOM which has the same name and value has your hidden input, thus insuring that your server-side script can treat all input generically.

Anthony
thanks for your detailed reply. if we want to talk conceptually about things, then in windows forms you can always get the value of a field whether or not it is enabled/disabled. a field has a value... disabling it has nothing to do with the value it contains... but this is the web... and I have to deal with it. I have a form with fields and those fields have values.. one of which is a drop-down for a relationship that cannot be changed by user. but I want my life to be easy so I can just set the values in all fields and then post them (no hacks/tricks/workarounds). I think I'm doomed tho
Nick Franceschina
Is it really a drop-down if the user can't change it? Do they get one shot at it and then it's disabled, or was it ever something they could interact with? If they can't interact with it, then why not just have it as a normal input that's read-only? Something (I assume) must be setting it, and that something could just as easily fill in a text-input, right?
Anthony
It's frustrating, I'm sure, that HTML doesn't do what you are used to from Windows. I get really annoyed that javascript can't do everything that PHP can. But that doesn't mean getting what you want is simple, nor does it make every solution a hack. You are using selects that, from what I can tell, aren't really selectable at all. Whatever way the drop down becomes selected and then disabled, simply pass the value to a hidden input. Either that or deal with the fact that you have chosen an input that isn't read-only and need to account for it in your server script.
Anthony
I just did a test to be sure and the code in my answer does work. I was a bit nervous that the browser would not include any inputs added after the form was submitted (even though it is held up by the js function), but sure enough, the added inputs do appear as submitted data on the other end. Same name, same value, as promised.
Anthony
A: 

OK... perhaps I didn't ask my question clearly enough... but the answer I was looking for is here:

http://docs.jquery.com/Plugins:Forms#.val.28.29_becomes_.fieldValue.28.29

I mentioned ajaxSubmit() in my question, which comes from the jQuery Form plugin... and inside that plug-in there is a method called fieldValue() which accepts a parameter called "successful". If you pass in "true" then the plug-in only returns what the W3C defines as "successful" controls (which excludes disabled controls). but if you set it to false, then it will get all values, regardless of W3C definition.

I knew this was possible, since the entire submission is controlled by the plug-in and has nothing to do with the HTML standards/definition... I was just asking to see if this option was already available in this plug-in or other plugins. It is available in this plugin, although the default behavior is to act like a standard HTML submit

Nick Franceschina
Wow. Way to figure something out on your own after having other people went to the trouble of trying to offer you legitimate solutions. On an un-bitter note, according to the documentation "unsuccessful" values also include ALL options in a selected (one of the bullets of successful values is "are selected options". How will you know which of your disabled drop-down choices is actually the correct one if all of them are returned?
Anthony
my question had nothing to do with "select options"... so asking me what I'm going to do about that is irrelevant.
Nick Franceschina
Um, first of all, you need to really calm down. Secondly, if ALL options in a drop down menu (which is known as a select element, hence "select options") are considered unsuccessful, and you have all unsuccessful options returned, then how will you determine which of the options in your disabled select was the one it was set to? Or is this just yet another example of how you don't want to hack things but you apparently use the wrong element and still expect to get what you want?
Anthony
I really am perfectly calm :) I wanted to know if there was a way to get those jQuery libraries to submit disabled elements. the answer is "yes" (as posted above), but the default implementation in those libraries isn't going to truly solve my problem (as you've mentioned). yet the question has been answered, and that's what is important. This is not the place for a long debate on the design merits of my particular application
Nick Franceschina
A: 

//jQuery('#container :input').serializeAll()

(function($j) {
  $j.fn.serializeDisabled=function(){
    var obj={};
    $j(this).filter(':input:disabled').each(function(index,domElem){
      var $this=$j(domElem);
      obj[domElem.name]=$this.val(); 
    });
    return $j.param(obj);
  };

  $j.fn.serializeAll=function(){
    $this=$j(this);
    return $this.filter(':input:enabled').serialize()+'&'+$this.serializeDisabled();
  };
})(jQuery);