0

I have some sample data like so:

var data = {
    "section": {
        "1": {
            "question": [{
                "id": "1a",
                "num": "1",
                "title": "test"
            }, {
                "id": "1b",
                "num": "2",
                "title": "test"
            }]
        },
        "2": {
            "question": [{
                "id": "2a",
                "num": "1",
                "title": "test"
            }, {
                "id": "2b",
                "num": "2",
                "title": "test"
            }]
        }
    }
}

Using this I'm attempting to count the number of questions. So for this sample of data that would be 4 questions in total...

The plan is to update a progress meter width using this data:

<div id="progress"><div id="bar"></div></div>

Here is the JS code I have started putting together:

var number = 0, numQuestions, total, width;

function updateProgress() {

    number += 1;

    numQuestions = data.question;

    //total =

    width = total / number;

    $('#progress #bar').animate({'width':width});

}

To get the width I'm guessing that I'd need to add BOTH sections and questions together and divide it by the width of the progress bar and then set the width of the progress as the number of that number??

Can anyone give some help and point me in the right direction?

The main issues are:

  • numQuestions is returning undefined, so obviously I'm doing it wrong
  • I'm not sure how to work out the total... should this be the #progress #bar width calculated against the numQuestions? Or something else entirely?
Cameron
  • 27,963
  • 100
  • 281
  • 483

5 Answers5

3

I would recommend modifying your data structure as follows:

var data = {
    "sections": [ // sections is now an array instead of an object
        {
            "question": [{
                "id": "1a",
                "num": "1",
                "title": "test"
            }, {
                "id": "1b",
                "num": "2",
                "title": "test"
            }]
        },
        {
            "question": [{
                "id": "2a",
                "num": "1",
                "title": "test"
            }, {
                "id": "2b",
                "num": "2",
                "title": "test"
            }]
        }
    ]
}

Unless you need to name the sections, there is no need to key them.

You can then grab the number of sections like so:

var numSections = data.sections.length;

To get the total number of questions in all sections, you'll need to create a loop:

var numQuestions = 0;
for (var i = 0; i < data.sections.length; i++){
    var questions = data.sections[i].question;
    for (var j = 0; j < questions.length; j++){
        numQuestions++;
    }
}

Then, to update the progress bar you would:

function updateProgress() {
    number++;
    width = number / numQuestions * 100;
    $('#progress #bar').animate({'width':width + '%'});
}

You'll want #progress to have a set width, and #bar to have a percentage based width ranging from 0 to 100%.

If you need to name the sections, you can count the number of questions like so:

var numQuestions = 0;
for (var sect in data.section){
    var questions = data.section[sect].question;
    for (var j = 0; j < questions.length; j++){
        numQuestions++;
    }
}

You can see all of this working here: http://jsfiddle.net/wAGHS/1/

Shmiddty
  • 13,847
  • 1
  • 35
  • 52
1

Answer to counting questions

If you look at your data object, there is no data.question. The questions are under section and then under 1 or 2 (data.section.1.question and data.section.2.question).

So, start out with setting a var to data.sections. Loop through the sections and check the size of the question object beneath and sum them up to a variable. Then you have the total number of questions.

Now to the next part: You have the total of four questions. What should the progress show? The number of questions answered by the user or what?

Community
  • 1
  • 1
Henrik Ammer
  • 1,889
  • 13
  • 26
  • The number increments every time that function is fired (which is when a user views a question). So basically that function will fire 4 times in this particular example. – Cameron Sep 12 '12 at 15:34
  • Allright. But then you do not need to recalcuate the number of questions, correct? Move that to another function at startup. Then the width in percent should be `(number/total)*100` since if they have seen 0 questions 0/4 = 0 and 1/4 = 0.25 (25%) so on. – Henrik Ammer Sep 12 '12 at 15:36
1

In your object data.question is undefined, as each one of properties of section object has a question property you can count them.

var number = 0;
for (key in data.section) {
   number++
}

http://jsfiddle.net/KuJgN/

Ram
  • 143,282
  • 16
  • 168
  • 197
1

In your updateProgress(), since the data object has no element at key 'question'

data.question

will return undefined.

Assuming: section must be an object and question must be an array

And further assuming data can contain multiple 'sections', to get the total number of questions in data, try:

var total_questions=0;
Object.keys(data).forEach(function(k){
    Object.keys(data[k]).forEach(function(num){
        total_questions+=data[k][num]['question'] 
            ? data[k][num]['question'].length 
            : 0;
    })
});

If data only ever contains one section, the above can be simplified to:

var total_questions=0;
Object.keys(data.section).forEach(function(num){
    total_questions+=data.section[num]['question'] 
        ? data.section[num]['question'].length 
        : 0
});
Rob Raisch
  • 17,040
  • 4
  • 48
  • 58
1

This function does count your "questions" in your data object:

function countquestions(obj) {
   var count = 0;
   for(var prop in obj) {
       if (obj.hasOwnProperty(prop)){
           for(var propp in obj[prop]) {
               if (obj[prop].hasOwnProperty(propp)){
                   ++count;
               }
           }
       }
   }
   return count;
}

it returns 2 for your data object above, but you say it has 4 questions which is confusing to me as it only has two "question" objects. If you are counting each "question" object as two then just multiply by two the returned result of my function.

Nelson
  • 49,283
  • 8
  • 68
  • 81