Edit: Turns out my JavaScript function is not working as I thought, but please help with the ASP issue whilst I fix the JavaScript.
Edit 2:
Using alert(JSON.stringify(sales)) to see the object I get this:
{"712":{"KR":1,"LR":0},"713":{"KR":1,"LR":0}}
Edit 3:
Need to re-write my sales script, i'm trying to use objects but it doesn't seem to be working as I don't have much experience with this part of JS.
var products = {
"KR" : 4,
"LR" : 6
};
var sale = [ ];
function sale(id,product,value)
{
this.id = function prod(product,value)
{
this.product = product;
this.value = value;
}
}
sale("N51","KR",0);
Hopefully you can see what i'm trying to do, but it is probably very wrong.
And thanks for that long post, it is very helpful, I will work on all of that as soon as the above code works
Okay, I have this JavaScript script that will sort out the sales for individual images.
712 and 713 is the image ID. Then KR and LR are the products, it only adds them to the URL variable if there is actually a sale for them.
function submitSales()
{
//URL Variable
var urlVariable = "?sales=";
for (x in sales)
{
urlVariable = urlVariable + x + "-";
for (s in sales[x])
{
if (sales[x][s] > 0)
{
urlVariable = urlVariable + s + ":" + sales[x][s] + ",";
}
}
}
urlVariable = urlVariable.substring(0, urlVariable.length - 1);
}
If I add sales for 3 products I get left with the following string:
?sales=712-KR:1,LR:1,713-KR:1
Now what would the best way of first of all separating the two images sales, so I will be left with:
712-KR:1,LR:1
713-KR:1
Then really I need to have them in a array that would look something like:
image(0) = 712 = product(0) = KR = 1
product(1) = LR = 1
image(1) = 713 = product(0) = KR = 1
I don't really know how ASP array's work that well, from what I read they actually suck.
I don't really know how ASP array's work that well, from what I read they actually suck.
They do, but in this case it does not matter.
General Stuff
First off, your JavaScript is wrong.
x
and s
are never declared, thus they are global. Don't do this, always declare all variables with var
.
- You are not properly encoding your URL parameters. This is bound to blow up, always use proper encoding (
encodeURIComponent()
in this case).
- Avoid relying on global variables. Pass in the
sales
variable as an argument.
- Avoid a naked
for .. in
to iterate an object. Use hasOwnProperty()
as a security precaution. This is good practice to defend against the case where the Object prototype has been extended. Alternatively, use one of the many JS librarys that give you a universal each()
function. Underscore.js, Sugar.js, jQuery, all provide such a function. Or write one yourself, like I did below.
Secondly, ASP already solves this problem very nicely.
If you pass multiple parameters with the same name in your query string, the server puts them in a collection for you. (In fact, the Request
object always contains collections, even if you pass in an URL-parameter only once.)
So when you query
http://foo/bar?sale=712-KR%3A1&sale=712-LR%3A1&sale=713-KR%3A1
Note the encoded :
then the ASP engine will deliver three distinct values, in one collection, like this:
"712-KR:1", "712-LR:1", "713-KR:1"
- This collection is 1-based, so that
Request("sale")(1)
will be "712-KR:1"
and so on.
- You can use
Request("sale").Count
to find out how many parameters with any given name there are.
At this point I suggest two things.
- Rewrite your client code so that it sends multiple parameters with the same name.
- Switch to dictionaries on the ASP side instead of trying to use arrays.
Client
js Helper (this might actually be unnecessary if you are using a library already)
function each(obj, callback) {
var key;
for (key in obj) {
if (obj.hasOwnProperty(key)) {
callback(key, obj[key]);
}
}
}
js
function submitSales(sales) {
var urlVariable, params = [];
each(sales, function (saleId, sale) {
each(sale, function (itemId, val) {
var param = saleId + "-" + itemId + ":" + val;
if (val > 0) {
params.push( encodeURIComponent(param) );
}
});
});
urlVariable = "?sale=" + params.join("&sale=");
// ...
}
Server
ASP helpers
Function NewDict()
Set NewDict = Server.CreateObject("Scripting.Dictionary")
End Function
Function Count(ary)
If IsArray(ary) Then
Count = UBound(ary) - LBound(ary) + 1
Else
Count = vbEmpty
End If
End Function
ASP
Function ParseSales(params)
Dim sales, sale, parts, saleId, value, product
Set sales = NewDict()
For Each sale In params
parts = Split(sale, "-")
saleId = parts(0)
' let's be careful and do a sanity check
If Count(parts) = 2 and IsNumeric(saleId) Then
product = Split(parts(1), ":")
If Count(product) = 2 Then
If Not sales.Exists(saleId) Then
sales.Add saleId, NewDict()
End If
sales(saleId).Add product(0), product(1)
Else
' Invalid parameter format, react accordingly
End If
Else
' Invalid parameter format, react accordingly
End If
Next
Set ParseSales = sales
End Function
Now you can do all kinds of things on the server side
Dim sales, saleId
Set sales = ParseSales(Request("sales"))
Response.Write sales.Exists("712") ' -> True
Response.Write sales.Exists("714") ' -> False
Response.Write sales("712").Count ' -> 2
Response.Write sales("712")("KR") ' -> 1
Response.Write sales("712").Exists("XR") ' -> False
Response.Write Join(sales.Keys(), "; ") ' -> 712; 713
Response.Write Join(sales("712").Keys(), "; ") ' -> KR; LR
For Each saleId In sales
' saleId will be "712" and so on, use sales(saleId) to get the
' actual object and do something with it
Next