views:

137

answers:

7

Yes, I am having issues with this very basic (or so it seems) thing. I am pretty new to JS and still trying to get my head around it, but I am pretty familiar with PHP and have never experienced anything like this. I just can not empty this damn array, and stuff keeps getting added to the end every time i run this.

I have no idea why, and i am starting to think that it is somehow related to the way chekbox id's are named, but i may be mistaking....

id="alias[1321-213]", id="alias[1128-397]", id="alias[77-5467]" and so on.

I have tried sticking

checkboxes = []; and checkboxes.length = 0;

In every place possible. Right after the beginning of the function, at the end of the function, even outside, right before the function, but it does not help, and the only way to empty this array is to reload the page. Please tell me what I am doing wrong, or at least point me to a place where i can RTFM. I am completely out of ideas here.

function() {

    var checkboxes = new Array();
    checkboxes = $(':input[name="checkbox"]');

        $.each(checkboxes,
            function(key, value) {
                     console.log(value.id);                            
                     alert(value.id);
          }
        );
     checkboxes.length = 0;                          
}

I have also read Mastering Javascript Arrays 3 times to make sure I am not doing something wrong, but still can't figure it out....

A: 

What about doing this:

checkboxes = new Array();
Cocowalla
Yep. This is the first line in the function... Tried adding it at the end too, didn't help...
solefald
A: 

Try: checkboxes = null;

Abbas
Are you sure that you don't mean `undefined` instead of `null`? :P
Dustin
whatever. both undefined and null will cause a reference to stay in the array and `for(var i in arrayname)` would iterate over it too causing errors.
naugtur
A: 

or

checkboxes.slice(0, checkboxes.length - 1);

Kind Regards

--Andy

jAndy
works, but isn't it hacky? ;)
naugtur
I can't just post "it is!", so, it is !
jAndy
A: 

You can also delete it.

delete checkboxes;
Mendy
`delete` doesn't work for variables declared with the `var` statement, those identifiers are made properties of the [Variable Object](http://bclary.com/2004/11/07/#a-10.1.3), and they are created with the `{ DontDelete }` special attribute, give a look to this article: [Understanding `delete`](http://perfectionkills.com/understanding-delete/)
CMS
+2  A: 

Is setting length even possible? ;)

Any way checkboxes is a jquery object not an array.

When You do checkboxes = $(':input[name="checkbox"]'); it's not an array any more and whatever there was before has no influence. It doesn't matter what was in a variable if You assign something new to it in any language I know.

You are making some jquery related error. Please elaborate more so that I can help

Are You sure You put name="checkbox" in all of them? It doesn't seem to have a lot of sense. Maybe You waned $(':input[type="checkbox"]'); ?

Edit: that's funny. the above selector isn't too good as well. It should be:

$('input:checkbox'); 

as for removing stuff:

delete varname

delete arrname[elem]

is the right way to do it.

assigning null does not change the length but just makes trouble.

naugtur
The data and checkboxes I am getting from a PHP page into jQuery UI modal dialog. The data shows up just fine, and I can inspect the element and see that everything is correct. All of checkboxes have the same `name="checkbox"`, its just that the array does not seem to be getting emptied after each run. Also, i have tried `delete checkboxes`, but it does not seem to work either. Maybe there is a problem elsewhere in my code, but i can only narrow it down to this particular function...
solefald
You have an error somewhere in selecting them. the variable is just fine. first get rid of the `:` at the beginning, and second - get firebug and see if Your site contains only checkboxes You want. I suppose there are some old hidden ones somewhere.
naugtur
Yep, I use Chrome and `console.log(value.id);` logs everything in the console. I can see every checkbox id logged every time i hit OK on the `alert()` dialog, so all elements are there, its just when i close the dialog and open it again, the checkboxes array still has the elements from the previous run in it. Have to run to the meeting, I will report on the progress when i get back. Thank you
solefald
See if the old checkboxes remain in DOM somehow. if `$( )` returns them - they must exist. Maybe You hide the dialog and create a new one while the other remains in the DOM still hidden. To check it quickly add `:visible` to Your selector. If it fixes the problem - You should start cleaning up.
naugtur
+4  A: 

I think there's a lot of confusion coming out of this because you are clearing the array -- just maybe not for the purpose you want, or at the wrong time, etc.

function () {
    var checkboxes = new Array();               // local-scope variable
    checkboxes = $(':input[name="checkbox"]');  // new instance

    $.each(checkboxes, /* ... */);              // (truncated for brevity)

    checkboxes.length = 0;                      // this clears the array
                                                // but, for what...?
                                                // nothing happens now
}

As per your snippet, every call to the function recreates and clears the array. However, all work with the array is done while the array is full (nothing happens after it's cleared).

Also, checkboxes is a private variable to the function. The variable only exists during execution of the function and is forgotten once the function is done.

So, what is the big picture? Why are you trying to clear the array?


To take a guess, it sounds like you're intending on clearing it for the next call of the function.
i.e. (filling in doSomething for function name):

doSomething(); // log all array elements and clears the array
doSomething(); // does nothing, since the array is already empty

To accomplish this, you need to define checkboxes in a single location outside of the function, either as a global variable or using closures (the heavily more recommended, albeit more complex, option):

NOTE: If you haven't dealt with closures before, they may not make much sense after only a single example. But, there are thousands of resources available, including Stack Overflow, to help explain them better than I can here.

// closure (or instantly-called function)
// allows for defining private variables, since they are only known by
// code blocks within this function

(function () {
    // private (closure-scoped) variable(s)
    var checkboxes = $(':input[name="checkbox"]');

    function doSomething() {
        $.each(checkboxes, /* ... */);

        checkboxes.length = 0;
    }
})();

The closure will run once, defining checkboxes as the array of inputs while doSomething will iterate the array before clearing it.

Now, the last step is to expose doSomething -- cause, as with checkboxes, it is also private. You can accomplish exposing it by passing the function reference from the closure to a variable outside the closure:

 var doSomething = (function () {
     /* ... */

     return doSomething;  // note that you DO NOT want parenthesis here
 })();
Jonathan Lonowski
Jonathan, huge thank you for your detailed explanation. I would really like to give you a vote up, but I am 1 point shy of being able to do so. Unfortunately putting new array definition outside of my function did not help. I have tried every singe location I possibly (and logically) could, to no avail. New elements just get added to the old array, and I can't get it to work. Closures seem like an interesting concept, but I don't think i could use it in my code: http://pastebin.com/AFfqKBis Possibly my code is just fundamentally wrong, since this is my first time with JS...
solefald
Your problem is with leaving some mess in DOM and the function You put here is ok. Really.
naugtur
A: 

When you rerun the function it will search for all checkboxes again.

Consider this strategy:

function() {
  var checkboxes = $(':input[name=checkbox]:not(.examined)');
  checkboxes.addClass('examined');

  $.each(checkboxes, function(key, value) {
      // ... stuff
  });
}

You could also use .data() if you don't want to "pollute" the DOM.

wombleton