views:

120

answers:

2

Please, help me to understand the following part of the code from the post http://stackoverflow.com/questions/133925/javascript-post-request-like-a-form-submit/133997#133997

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

    form.appendChild(hiddenField);
}
....

Does this mean that we could pass the Dictionary object to the JavaScript function (calling JavaScript function from Silverlight app) and it will generate the param string in the form of key=value&key2=value2&key3=value3 ?

For example, passing the following Dictionary:

Dictionary<string, decimal> postdata = new Dictionary<string, decimal>();
postdata["productID1"] = 126504;
postdata["productID2"] = 126505;

We get the function output: productId1=126504&productId2=126505 ?

+1  A: 

Depends what you mean by output. The function does not output anything directly. It creates a form and adds an input element for every key-value pair in the object. It then submits that form, and the browser internally generates that parameter string and POSTs it to the URL. If by output you mean "posts to the server," then yes - that is what it does.

Regarding passing in objects from managed code (silverlight), it seems it is possible. Dictionarys will be marshalled to Javascript objects as long as the key is a string. You will be able to access the entries by using the regular javascript property notation (dictionary["key"] or dictionary.key).

More reading regarding Dictionary marshalling.

Also, I may be wrong (my C# is a bit rusty), but wouldn't:

Dictionary<string, decimal> postdata = new Dictionary<string, decimal>();
postdata["productID"] = 126504;
postdata["productID"] = 126505;

be considered invalid? In Dictionarys, like Javascript Objects, all keys must be distinct, no?


If you just want the query string, coming up with a function to create a parameter/query string from a JS object is relatively easy.

For example:

function paramString(object) {
    var strBuilder = [];
    for (var key in object) if (object.hasOwnProperty(key)) {
       strBuilder.push(encodeURIComponent(key)+'='+encodeURIComponent(object[key]));
    }
    return strBuilder.join('&');
}

paramString(postdata)
"productID1=126504&productID2=126505"
CD Sanchez
Yes, Daniel, thanks. I'll correct myself
rem
@rem: If that string is all you want, I've added a function that returns that based on a JS object (or dictionary from SL I guess).
CD Sanchez
@Daniel Thank you for your help and for this example, it will for sure give me more understanding of JavaScript. But in my current case I'd like JavaScript function would generate multiple "input" elements in accordance with the number of elements in the dictionary. Like in case for identical "input name" attributes in the post http://stackoverflow.com/questions/3747222/javascript-post-request/3749631#3749631 then I will get in the output required string
rem
@rem: So you want something to add the input elements to a form, then submit the form, and then return the string? If you submit the form you will leave the page. Would you like to add those to an existing form but do not submit? Please describe what you want in detail so I can help you out.
CD Sanchez
rem
@rem: Oh, well, that's what the function you posted does. The browser will generate the query string internally and send it off with the POST request from the form submission.
CD Sanchez
+1  A: 

Every java-script object is implemented as a dictionary - all properties are name-value pairs. So to pass dictionary to post_to_url function, you can use

var postdata = {};
postdata["name1"] = value1;
postdata["name2"] = value2;
...

post_to_url(url, postdata, "post"

Note that syntax postdata["name1"] and postdata.name1 are equivalent - they refer to same value. You can also use alternate syntax using JS object notation. For example,

var postdata = {
    "name1" = value1,
    "name2" = value2,
    ...
    "namex" = valuex
};

post_to_url(url, postdata, "post"

Now to answer another part of your question - the sighted JS function will only post the data from params. It will not create a url such as productId=126504&productId=126505 for GET method. For that, you need to roll up your own version such as

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 (method.toUpperCase() === "GET") {
       if(path.indexOf("?") < 0) {
           path += "?";
       }
       path += "&" + key + "=" + params["key"];
    }
    else {

       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);    // Not entirely sure if this is necessary
form.submit();

}

VinayC