开发者

Delete empty values from form's params before submitting it

I开发者_如何转开发 have some javascript which catches changes to a form then calls the form's regular submit function. The form is a GET form (for a search) and i have lots of empty attributes come through in the params. What i'd like to do is to delete any empty attributes before submitting, to get a cleaner url: for example, if someone changes the 'subject' select to 'english' i want their search url to be

http://localhost:3000/quizzes?subject=English

rather than

http://localhost:3000/quizzes?term=&subject=English&topic=&age_group_id=&difficulty_id=&made_by=&order=&style=

as it is at the moment. This is just purely for the purpose of having a cleaner and more meaningful url to link to and for people's bookmarks etc. So, what i need is something along these lines, but this isn't right as i'm not editing the actual form but a js object made from the form's params:

  quizSearchForm = jQuery("#searchForm");
  formParams = quizSearchForm.serializeArray();
  //remove any empty fields from the form params before submitting, for a cleaner url
  //this won't work as we're not changing the form, just an object made from it.
  for (i in formParams) {
    if (formParams[i] === null || formParams[i] === "") {
      delete formParams[i];
    }
  }
  //submit the form

I think i'm close with this, but i'm missing the step of how to edit the actual form's attributes rather than make another object and edit that.

grateful for any advice - max

EDIT - SOLVED - thanks to the many people who posted about this. Here's what i have, which seems to work perfectly.

function submitSearchForm(){
  quizSearchForm = jQuery("#searchForm");
  //disable empty fields so they don't clutter up the url
  quizSearchForm.find(':input[value=""]').attr('disabled', true);
  quizSearchForm.submit();
}


The inputs with attribute disabled set to true won't be submitted with the form. So in one jQuery line:

$(':input[value=""]').attr('disabled', true);


$('form#searchForm').submit(function() {
    $(':input', this).each(function() {
        this.disabled = !($(this).val());
    });
});


You can't do it that way if you call the form's submit method; that will submit the entire form, not the array you've had jQuery create for you.

What you can do is disable the form fields that are empty prior to submitting the form; disabled fields are omitted from form submission. So walk through the form's elements and for each one that's empty, disable it, and then call the submit method on the form. (If its target is another window, you'll then want to go back and re-enable the fields. If its target is the current window, it doesn't matter, the page will be replaced anyway.)


Well one thing you could do would be to disable the empty inputs before calling "serializeArray"

$('#searchForm').find('input, textarea, select').each(function(_, inp) {
  if ($(inp).val() === '' || $(inp).val() === null)
    inp.disabled = true;
  }
});

The "serializeArray()" routine will not include those in its results. Now, you may need to go back and re-enable those if the form post is not going to result in a completely refreshed page.


Maybe some of the proposed solutions worked at the moment the question was made (March 2010) but today, August 2014, the solution of disabling empty inputs is just not working. The disabled fields are sended too in my Google Chrome. However, I tried removing the "name" attribute and it worked fine!

$('form').submit(function(){
    $(this).find('input[name], select[name]').each(function(){
        if (!$(this).val()){
            $(this).removeAttr('name');
        }
    });
});

Update: Ok, probably the reason because disabling fields doesn't worked to me is not that something changed since 2010. But still not working in my Google Chrome. I don't know, maybe is just in the linux version. Anyway, I think that removing the name attr is better since, despite what policy takes the browser about disabled fields, there is no way to send the parameters if the name attr is missing. Another advantage is that usually disabling fields implies some style changes, and is not nice to see a style change in the form a second before the form is finally submited. There is also a drawback, as Max Williams mentioned in the comments, since the remove name attr solution is not toggleable. Here is a way to avoid this problem:

$('form').submit(function(){
    $(this).find('input[name], select[name]').each(function(){
        if (!$(this).val()){
            $(this).data('name', $(this).attr('name'));
            $(this).removeAttr('name');
        }
    });
});

function recoverNames(){
    $(this).find('input[name], select[name]').each(function(){
        if ($(this).data('name')){
            $(this).attr('name', $(this).data('name'));
        }
    });
}

However, I think this is not a very common case since we are submitting the form so it is assumed that there is no need to recover the missing name attrs.


Your problem helped me figure out my situation, which is a bit different - so maybe someone else can benefit from it. Instead of directly submitting a form, I needed to prevent empty form elements from being collected into a serialized array which is then posted via AJAX.

In my case, I simply needed to loop through the form elements and disable all that were empty, and then collect the leftovers into an array like so:

// Loop through empty fields and disable them to prevent inclusion in array
$('#OptionB input, select').each(function(){
    if($(this).val()==''){
        $(this).attr('disabled', true); 
    }
});

// Collect active fields into array to submit
var updateData = $('#OptionB input, select').serializeArray();


Or serialize, clear empty key=value pairs with regex and call window.location:

$("#form").submit( function(e){
    e.preventDefault();
    //convert form to query string, i.e. a=1&b=&c=, then cleanup with regex
    var q = $(this).serialize().replace(/&?[\w\-\d_]+=&|&?[\w\-\d_]+=$/gi,""),
    url = this.getAttribute('action')+ (q.length > 0 ? "?"+q : "");
    window.location.href = url;
});


Another approach I always recommend is to do that on server side, so you are able to:

  1. Validate the input data correctly
  2. Set default values
  3. Change input values if needed
  4. Have a clean URL or a friendly URL such as "/quizzes/english/level-1/"

Otherwise you will have to deal with text input, select, radio etc...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜