views:

1491

answers:

5

I'm looking for a really generic way to "fill out" a form based on a parameter string using javascript.

for example, if i have this form:

<form id="someform">
  <select name="option1">
    <option value="1">1</option>
    <option value="2">2</option>
  </select>
  <select name="option2">
    <option value="1">1</option>
    <option value="2">2</option>
  </select>
</form>

I'd like to be able to take a param string like this: option1=2&option2=1

And then have the correct things selected based on the options in the query string.

I have a sort of ugly solution where I go through children of the form and check if they match the various keys, then set the values, but I really don't like it.

I'd like a cleaner, generic way of doing it that would work for any form (assuming the param string had all the right keys).

I'm using the prototype javascript library, so I'd welcome suggestions that take advantage of it.

EDIT: this is what I've come up with so far (using prototype for Form.getElements(form))

function setFormOptions(formId, params) {
  params = params.split('&');
  params.each(function(pair) {
    pair = pair.split('=');
    var key = pair[0];
    var val = pair[1];
    Form.getElements(form).each(function(element) {
      if(element.name == key) {
        element.value = val;
      }
    });
  });
}

I feel that it could still be faster/cleaner however.

+1  A: 

You said you're already going through the elements and setting the values. However, maybe this is cleaner that what you have?

function setFormSelectValues(form, dataset) {
    var sel = form.getElementsByTagName("select");
    dataset.replace(/([^=&]+)=([^&]*)/g, function(match, name, value){
        for (var i = 0; i < sel.length; ++i) {
            if (sel[i].name == name) {
                sel[i].value = value;
            }
        }
    });                
}

You could then adapt that to more than just select elements if needed.

Shadow2531
Cleaner than what I had in a way, since you are getting the keys/values in a much better fashion, but I'm hoping for something more generic. I only used selects in my example but many forms have other elements.
TM
+3  A: 
Stephen
+5  A: 

If you're using Prototype, this is easy. First, you can use the toQueryParams method on the String object to get a Javascript object with name/value pairs for each parameter.

Second, you can use the Form.Elements.setValue method (doesn't seem to be documented) to translate each query string value to an actual form input state (e.g. check a checkbox when the query string value is "on"). Using the name.value=value technique only works for text and select (one, not many) inputs. Using the Prototype method adds support for checkbox and select (multiple) inputs.

As for a simple function to populate what you have, this works well and it isn't complicated.

function populateForm(queryString) {
    var params = queryString.toQueryParams();
    Object.keys(params).each(function(key) {
        Form.Element.setValue($("someform")[key], params[key]);
    });
}

This uses the Object.keys and the each methods to iterate over each query string parameter and set the matching form input (using the input name attribute) to the matching value in the query params object.

Edit: Note that you do not need to have id attributes on your form elements for this solution to work.

zwerd328
+1 I had absolutely no clue of that method. That's going to be a huge time-saver in the future. Thanks.
Stephen
Ended up changing `document.someform` to `$(formId)` and this is just what I was looking for. Thanks again!
TM
You could shorten the code by using the Hash.each method to access key value pairs:$H(queryString.toQueryParams()).each(function(pair) { Form.Element.setValue($("someform")[pair.key], params[pair.value]);});
aemkei
A: 

Three lines of code in prototype.js:

$H(query.toQueryParams()).each(function(pair) {
    $("form")[pair.key].setValue(pair.value);
});
aemkei
A: 

U can use this to fill up and to get key value pairs for fillup use $("form).fillUpForm(disabledFields); where disabledFields are fields you dont want to show

to get values from in key values pair use $("form").validateForm(); if any field attribute set as mandatory="true" and field is empty then it return false;

(function($){
 $.fn.validateForm = function(){
    var $this =$(this);
    var valid = true;
    var  formArray = $this.serializeArray();
    var list = $this[0];
    for(var i =0,len = list.length;i<len;i++){
        if (list[i].getAttribute("mandatory") && list[i].value == "") {
            var elem = list[i];
            $(elem).bind("click", function () {
                    $(this).css("border", "1px solid #cccccc");
                }
            ).css("border", "1px solid red");
            valid = false;
        }
    }
    if (valid){ 
    return splitDot(formArray);
    }
    return false;
}
function splitDot(formArray){
    var ParamString = {};
    for (var i = 0, len = formArray.length; i < len; i++) {
       var temp = namespace(ParamString,formArray[i].name);
        temp[0][temp[1]] = formArray[i].value;

    }
    return ParamString;
}
$.fn.fillUpForm = function( fields, disabledFields) {
    if(!fields)return false;
    var $this = $(this);
    if(!disabledFields) disabledFields =[];
    var self = $this[0];
    var disabled = false;
    var temp1, temp2;
    for (var k in fields) {
        temp1 = k;
        temp2 = fields[k];
        disabled = false;
        fillThisField(temp1, temp2,disabled);
    }
    function fillThisField(temp1,temp2,disabled) {
        if (typeof temp2 == "object") {
            if(disabledFields[temp1] === false)disabled = true;
            for (var i in temp2) {
                var temp3 = temp1 + "." + i;
                fillThisField(temp3, temp2[i],disabled);
            }
        }
        else if(typeof temp2 != "function"){
            var temp3 = self[temp1];
            if (!temp3) return;
            var tempreplacer = temp1.split(".");
            var tempName =  disabledFields;
            for (var k = 0, innerlen = tempreplacer.length; k < innerlen - 1; k++) {
                if (!tempName[tempreplacer[k]])
                     break;
                tempName = tempName[tempreplacer[k]];
            }
            if(disabled || tempName[tempreplacer[k]] === false){
                $(temp3).parentsUntil("tbody").hide();
                 $(temp3).attr("disabled",true);
            }
            if (temp3.type == "checkbox")
                temp3.checked = temp2;
            else if (temp3.type == undefined && typeof temp3 == "object") {
                for(var key=0;key<temp3.length;key++){
                    if(temp3[key].value == temp2)
                        temp3[key].checked = true;
               }
            }
            else temp3.value = temp2;
            return;
        }
    }
}})(jQuery);
Shusl