CF-Slayer
CF-Slayer

Reputation: 169

ColdFusion Array And Struct

I have a shopping cart array stored in a session:Screen Shot of Shopping Cart Array

I give my user the ability to select all items to delete or select individual items via a checkbox.

I am sending the array index via form post to arrayDeleteAt.

Now if I select the bottom 3 items, it does not delete it.

Here is my delete code:

<cfif isDefined("form.leadId") AND  listLen(form.leadId)>
  <cfloop from="#listLen(form.leadId)#" to="1" step="-1" index="i">
    <cfset temp = arrayDeleteAt(session.shoppingcart, #i#)>
  </cfloop> 
</cfif>

Upvotes: 1

Views: 2092

Answers (3)

Russ
Russ

Reputation: 1951

In CF 10 or Railo 4, this can be done using the most recent version of the Underscore.cfc library:

<cfscript>
if (structKeyExists(form, 'leadId') && listlen(form.leadId)) {
    _ = new Underscore();

    variables.shoppingCart = duplicate(session.shoppingCart);

    variables.newCart = _.reject(variables.shoppingCart, function(val, index){
        return _.include(form.leadId, index);
    });
}
</cfscript>

<cfif structKeyExists(variables, "newCart") >
    <cflock scope="session" type="exclusive" timeout="10">
        <cfset session.shoppingCart = variables.newCart>
    </cflock>
</cfif>

You'll see that I'm copying the shopping cart into the variables scope, editing it, then copying it back (with a lock) if necessary. I would've done this all in cfscript if it were possible to write cflocks in cfscript.

(Disclaimer: I wrote Underscore.cfc)

Upvotes: 0

Dan Short
Dan Short

Reputation: 9616

The problem is that you're deleting at the position of the counter, and not the form field that's being passed in. Try this instead:

<cfset temp = arrayDeleteAt(session.shoppingcart, ListGetAt(FORM.leadID, i) />

UPDATE: To get around the issue Tyler mentioned, you can convert your list of indexes from FORM.leadID to an Array using ListToArray and then ArraySort to get them in the order necessary to make sure your deletes are correct.

While my answer does fix your immediate problem, you would definitely be better off following Tyler's advice and using a key for each item in the cart to make sure you're managing the one you actually think you're supposed to be managing :)

Upvotes: 5

Tyler Clendenin
Tyler Clendenin

Reputation: 1489

You are going to have more issues with this method of managing your cart. After using ArrayDeleteAt the array's indexes will be recalculated, so when you will most likely delete the wrong item from the array, or you can get an error when you try and delete an item that is out of bounds.

Is see that you are trying to get around this by working backwards through your list, and Dan is right for what your issue is with the code above, but if the list is passed in in an incorrect order then you are in a world of hurt.

I would suggest instead of using an array, use a struct with a surrogate key, such as a UUID, then delete items by that key.

Upvotes: 7

Related Questions