0

I'm trying to build an array/object based on user-input to a form that has radios, checkboxs with radios, textfields with radios, and selects. I want the final array/object to be consolidated such that activated form-elements with repeated names are collapsed into a single object:

data = {
    name0 = (value0,value4), // checkbox
    name1 = (value2), // radio
    name2 = (value5), // select>option
    name4 = (''), // non-response
    name5 = (NULL) // form element was disabled/hidden
}

Javascript seems to be rather picky, so I'm having some trouble. I've broken it up into 3 pieces (Arr1,Arr2,Arr3), but it seems like the first bit only retains the last form element and the second bit stops for each name after it's been encountered.

Code in JSfiddle: http://jsfiddle.net/jshado1/5Y7sn/12/

EDIT: What I want the final array to look like for the example in the fiddle is:
(with all alphas unchecked, beta=1 checked, beta=2 checked, and delta=3 selected)

data : {
    { 'alpha'    : '' },
    { 'beta'     : '1','2' },
    { 'delta'    : '3' },
    { 'continue' : 'continue' }
}

(eventually I'll filter out [continue] using a more precise jQuery selector and put the button outside of a div)

1
  • 1
    It's really hard to understand what exactly you wont to archive with your fiddle but I'm still trying... Commented Dec 28, 2011 at 0:15

2 Answers 2

4

I'm not quite sure about your goal here, but I can see some problems with your code:

  1. You have a global variable I, which is initialised to 0 but never changed so when you use it as an index to Arr1[I] inside your .each() loop you will continuously overwrite array element 0.
  2. You have Arr2[n] = +1; when you probably meant Arr2[n] += 1; or Arr2[n]++;
  3. Your for loop uses an undeclared i index, though that should work (it's just that i is implicitly global, and it's always better to declare all your variables).
  4. In the middle of the switch you have Arr3[nom] += val; but Arr3[nom] is never initialised to 0 so effectively you are saying undefined += val which would give NaN.
  5. In your switch statement you have case ("checkbox" || "radio"):, which is equivalent to case "checkbox" so you never match on "radio". You want a fall-through to cover both values.

Update your switch:

switch(type) {
    case "checkbox":
        // fall-through
    case "radio":
        if (state) {
           if (Arr2[nom] > 1) {
               Arr3[nom] += val;
           } else {
               Arr3[nom] = val;
           }
        }
        break;
    case "text":
        Arr3[nom] = val;
        break;
    default:
        break;
}

It is at this point that I agree with @Matmarbon and give up. I'd suggest you fix all of the above and get back to us.

Sign up to request clarification or add additional context in comments.

6 Comments

Whoops, I++; must have got deleted at some point (it was at the end of the .each()). #3: I thought the for loop declares i and when it does that, i only exists inside the loop? (I'm pretty sure that's how it works in php, shell, and C) #4: I think I need to initialise Arr3[nom] as an array and use push(val). #5: Doesn't the () create a subroutine?
#2, Arr2[n] holds a count of the number of instances of n. ex Arr2["cups"] = 2.
I've fixed those issues, but now I think I have different ones: jsfiddle.net/jshado1/5Y7sn/23
Regarding your comments about the different points I made: #2 yes, I assumed that but you weren't adding 1 to count, you were setting to 1 each time. #3 any variable used without a var declaration has global scope, and JavaScript doesn't have block scope like Java or C#, it only has function and global scope. #4 Your code looked like you were trying to keep a sum of the values, but yes if you want to remember individual values then an array and .push() would work. #5 No, and even if it did it wouldn't make sense for a case.
Regarding your new fiddle, here's an updated one that runs: jsfiddle.net/5Y7sn/27 I fixed a few problems. Lines 22 & 28 - don't use var to create array elements: Arr2 is already declared so you create a new element with Arr2[someindex]=somevalue. Line 38 needed a semicolon rather than a comma (otherwise it tried to treat the if statement that followed as a variable declaration). I think lines 40-44 should be saying if (Arr3[nom] === undefined) Arr3[nom] = []; and then just Arr3[nom].push(val); otherwise you were never actually initialising that array element to be an array.
|
3

Okay.. don't know where to start.. first you should use :s instead of =s to define the objects properties. Then secondly it's really no problem to nest objects. An attribute of an object can ever by another object. So var x = { 'a' : { { 1 : {} } : 'the value' } } is a valid definition.

Further infos when I understood your JSFiddle ^^

EDIT: Here is a possible solution if I understood your question right: http://jsfiddle.net/5Y7sn/8/

2 Comments

oow, that's almost it, but I want names with unchecked elements to be '' instead of 0 (see the new example I added to my question). Thanks!!
I think in both of yours, the values of alpha and beta are being stored as strings instead of arrays/objects: I would expect there to be a comma between beta:"12" (where beta=1 and beta=2 are both checked). Besides that, it looks right.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.