jQuery functie waarden optellen
Ik probeer om verschillende categorieën bij elkaar op te tellen om hier vervolgens een gemiddelde van te berekenen. Dit gemiddelde geef ik weer in een process bar. De basis heb ik reeds werkend:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
$('.avg1').change(function(){
var total = 0;
var counter = 0;
$('.avg1').each(function(i){
if($(this).val() != 'NULL'){
total += parseInt($(this).val());
counter += 1;
}
});
var result = (counter != 0) ? Math.round(total/counter) : 'Geen antwoord';
$("#pb1").progressBar(result);
});
var total = 0;
var counter = 0;
$('.avg1').each(function(i){
if($(this).val() != 'NULL'){
total += parseInt($(this).val());
counter += 1;
}
});
var result = (counter != 0) ? Math.round(total/counter) : 'Geen antwoord';
$("#pb1").progressBar(result);
});
Elk selectveld met de class avg1 wordt onchange (her) berekend. En vervolgens wordt de processbar div met het resultaat veranderd.
Nu is het geval dat ik 4 verschillende onderwerpen heb die ik afzonderlijk wil berekenen.
Onderwerp 1
Vraag 1 (class avg1)
Vraag 2 (class avg1)
Onderwerp 2
Vraag 3 (class avg2)
Vraag 4 (class avg2)
Onderwerp 3
etc
Onderwerp 4
etc
Deze onderwerpen wil ik graag een afzonderlijke weging geven. Op dit moment worden alle antwoorden meegenomen (tenzij deze waarde NULL is: niet van toepassinG).
Dus het zou dan zo zijn dat onderwerp 1, bij alle vragen met avg1 100%, een totaal heeft van 25%. Opzich lijkt me dit niet moeilijk te realiseren met de berekening
TotaalTeHalenOnderwerpA * 100 = 25%
25 / TotaalTeHalenOnderwerpA = 0.083333 weging per vraag bij onderwerp A.
Dan 0.083333 * het opgegeven percentage = score.
Maar hoe vertaal ik dit in jQuery met het gebruiken van de huidige functie? Kan ik de functie 4 keer aanmaken en vervolgens het totaal van de avg's optellen? Heeft iemand een idee hoe ik dit voor elkaar kan boksen?
Gewijzigd op 22/11/2011 11:37:21 door Gammele vraal
Code (php)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
var totalQ = 10
var countA = 0
function ShowProgress(val) {
if (val != 'NULL') {
countA++
}
var result = (countA != 0) ? Math.round(totalQ/countA) : 'Geen antwoord';
$("#pb1").progressBar(result);
}
$('.avg1').change(function(){ ShowProgress($(this).val) });
var countA = 0
function ShowProgress(val) {
if (val != 'NULL') {
countA++
}
var result = (countA != 0) ? Math.round(totalQ/countA) : 'Geen antwoord';
$("#pb1").progressBar(result);
}
$('.avg1').change(function(){ ShowProgress($(this).val) });
Of begrijp ik je verkeerd
Ik heb het reeds wat aangepast, heb voor elk onderwerp een aparte jq change functie gemaakt. Wat ik nu heb werkt op zich prima. Zie hieronder.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
scoreA = '';
scoreB = '';
scoreC = '';
scoreD = '';
scoreT = '';
$('.avg1').change(function(){
var total = 0;
var counter = 0;
$('.avg1').each(function(i){
if($(this).val() != 'NULL'){
total += parseInt($(this).val());
counter += 1;
}
});
var result = (counter != 0) ? Math.round(total/counter) : 'Geen antwoord';
scoreA = result;
if(scoreA != 0 && scoreB != 0 && scoreC != 0 && scoreD != 0){
scoreT = (scoreA + scoreB + scoreC +scoreD) / 4;
}
$("#pb1").progressBar(scoreT);
$("#hiddenscore").val(scoreT);
});
$('.avg2').change(function(){
var total = 0;
var counter = 0;
$('.avg2').each(function(i){
if($(this).val() != 'NULL'){
total += parseInt($(this).val());
counter += 1;
}
});
var result = (counter != 0) ? Math.round(total/counter) : 'Geen antwoord';
scoreB = result;
if(scoreB != 0){
scoreT = (scoreA + scoreB + scoreC +scoreD) / 4;
}else{
scoreT = (scoreA + scoreC +scoreD) / 3;
}
$("#pb1").progressBar(scoreT);
$("#hiddenscore").val(scoreT);
});
$('.avg3').change(function(){
var total = 0;
var counter = 0;
$('.avg3').each(function(i){
if($(this).val() != 'NULL'){
total += parseInt($(this).val());
counter += 1;
}
});
var result = (counter != 0) ? Math.round(total/counter) : 'Geen antwoord';
scoreC = result;
if(result != 0){
scoreT = (scoreA + scoreB + scoreC +scoreD) / 4;
}else{
scoreT = (scoreA + scoreB +scoreD) / 3;
}
$("#pb1").progressBar(scoreT);
$("#hiddenscore").val(scoreT);
});
$('.avg4').change(function(){
var total = 0;
var counter = 0;
$('.avg4').each(function(i){
if($(this).val() != 'NULL'){
total += parseInt($(this).val());
counter += 1;
}
});
var result = (counter != 0) ? Math.round(total/counter) : 'Geen antwoord';
scoreD = result;
if(result != 0){
scoreT = (scoreA + scoreB + scoreC +scoreD) / 4;
}else{
scoreT = (scoreA + scoreB +scoreC) / 3;
}
$("#pb1").progressBar(scoreT);
$("#hiddenscore").val(scoreT);
});
scoreB = '';
scoreC = '';
scoreD = '';
scoreT = '';
$('.avg1').change(function(){
var total = 0;
var counter = 0;
$('.avg1').each(function(i){
if($(this).val() != 'NULL'){
total += parseInt($(this).val());
counter += 1;
}
});
var result = (counter != 0) ? Math.round(total/counter) : 'Geen antwoord';
scoreA = result;
if(scoreA != 0 && scoreB != 0 && scoreC != 0 && scoreD != 0){
scoreT = (scoreA + scoreB + scoreC +scoreD) / 4;
}
$("#pb1").progressBar(scoreT);
$("#hiddenscore").val(scoreT);
});
$('.avg2').change(function(){
var total = 0;
var counter = 0;
$('.avg2').each(function(i){
if($(this).val() != 'NULL'){
total += parseInt($(this).val());
counter += 1;
}
});
var result = (counter != 0) ? Math.round(total/counter) : 'Geen antwoord';
scoreB = result;
if(scoreB != 0){
scoreT = (scoreA + scoreB + scoreC +scoreD) / 4;
}else{
scoreT = (scoreA + scoreC +scoreD) / 3;
}
$("#pb1").progressBar(scoreT);
$("#hiddenscore").val(scoreT);
});
$('.avg3').change(function(){
var total = 0;
var counter = 0;
$('.avg3').each(function(i){
if($(this).val() != 'NULL'){
total += parseInt($(this).val());
counter += 1;
}
});
var result = (counter != 0) ? Math.round(total/counter) : 'Geen antwoord';
scoreC = result;
if(result != 0){
scoreT = (scoreA + scoreB + scoreC +scoreD) / 4;
}else{
scoreT = (scoreA + scoreB +scoreD) / 3;
}
$("#pb1").progressBar(scoreT);
$("#hiddenscore").val(scoreT);
});
$('.avg4').change(function(){
var total = 0;
var counter = 0;
$('.avg4').each(function(i){
if($(this).val() != 'NULL'){
total += parseInt($(this).val());
counter += 1;
}
});
var result = (counter != 0) ? Math.round(total/counter) : 'Geen antwoord';
scoreD = result;
if(result != 0){
scoreT = (scoreA + scoreB + scoreC +scoreD) / 4;
}else{
scoreT = (scoreA + scoreB +scoreC) / 3;
}
$("#pb1").progressBar(scoreT);
$("#hiddenscore").val(scoreT);
});
Het enige waar het nu nog mis loopt, is dat wanneer ik een compleet onderwerp (of meer) op NULL zet, dat de berekening dan niet meer klopt. Deze berekening :
Code (php)
1
2
3
4
5
6
2
3
4
5
6
if(result != 0){
scoreT = (scoreA + scoreB + scoreC +scoreD) / 4;
}else{
scoreT = (scoreA + scoreB +scoreC) / 3;
}
scoreT = (scoreA + scoreB + scoreC +scoreD) / 4;
}else{
scoreT = (scoreA + scoreB +scoreC) / 3;
}
Gewijzigd op 22/11/2011 13:47:36 door gammele vraal
één functie proppen. Ik zou ook de scores voor de diverse blokken in een array zetten, dan kun je met een loopje er doorheen, tellertje eraan en je weet precies door hoeveel je moet delen.
Gewijzigd op 22/11/2011 14:16:59 door Ger van Steenderen
Dat zal waarschijnlijk wel kunnen, waar ik naar op zoek ben is een functie die ook schakelt tussen de onderwerpen. Dus als slechts 1 is ingevuld, dat dit onderwerp dan 100 % totaal score genereert. Dit is toch niet makkelijk in één functie te zetten met een teller?
Wat ik nu kan opmaken uit jouw posts is dat je aantal vragen hebt verdeeld over een aantal onderwerpen, en dat je onderaan het percentage goede antwoorden weergeeft.
Wil je dat dan ook per onderwerp doen?
Een onderwerp heeft onderliggende criteria. De percentages en antwoorden sla ik op in een database, per criteria. Dat gedeelte heb ik al werkend. Ik zou alleen graag dit gedeelte werkend willen hebben zodat je direct kan zien wat de beoordeling is.
Je zou dan afzonderlijk per onderwerp maximaal 25% moeten toekennen. En vervolgens berekenen wat de score over het geheel is. Maar als een vraag, of een onderwerp compleet niet van toepassing is, dan zouden 3 onderwerpen de score moeten bepalen.
Dus dan zou zeg maar elk onderdeel 33% moeten gaan wegen.
Onderwerp 1
Vraag 1 (class avg1)
Vraag 2 (class avg1)
Onderwerp 2
Vraag 3 (class avg2)
Vraag 4 (class avg2)
Onderwerp 3
Vraag 5 (class avg3)
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
var score = new Array(0,0,0,0);
var scoreT = 0;
function DoJudgement(avg, idx) {
var total = 0;
var counter = 0;
$(avg).each(function(i){
if ($(this).val() != 'NULL') {
counter++;
total += parseInt($(this).val());
}
)};
score[idx] = (counter != 0) ? Math.round(total/counter) : 0;
counter = 0;
total = 0;
for (j=0;j<score.length;j++) {
if (score[j] != 0) {
counter++;
total += score(j);
}
}
if (total != 0) scoreT = total/counter;
$("#pb1").progressBar(scoreT);
$("#hiddenscore").val(scoreT);
}
$('.avg1').change(function() { DoJudgement('.avg1', 0) });
var scoreT = 0;
function DoJudgement(avg, idx) {
var total = 0;
var counter = 0;
$(avg).each(function(i){
if ($(this).val() != 'NULL') {
counter++;
total += parseInt($(this).val());
}
)};
score[idx] = (counter != 0) ? Math.round(total/counter) : 0;
counter = 0;
total = 0;
for (j=0;j<score.length;j++) {
if (score[j] != 0) {
counter++;
total += score(j);
}
}
if (total != 0) scoreT = total/counter;
$("#pb1").progressBar(scoreT);
$("#hiddenscore").val(scoreT);
}
$('.avg1').change(function() { DoJudgement('.avg1', 0) });
Gewijzigd op 22/11/2011 17:11:06 door Ger van Steenderen
Toevoeging op 23/11/2011 10:40:19:
Er gaat nog iets mis met het scoren met het scoren en het berekenen van het gemiddelde.
De scores kloppen niet met de input, als ik de eerste 3 vragen van onderwerp A op 100% zet, is de score ook 100%. Terwijl de rest op 0 staat. 0 is de standaardwaarde.
Code (php)
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
<select name="avg[<?php echo $data1['criterium_id'];?>]" id="<?php echo $data1['criterium_id'];?>" class="avg<?php echo $data['onderwerp_id'];?>">
<option value="0">0%</option>
<option value="25">25%</option>
<option value="50">50%</option>
<option value="75">75%</option>
<option value="100">100%</option>
<option value="NULL">N.v.t.</option>
</select>
<option value="0">0%</option>
<option value="25">25%</option>
<option value="50">50%</option>
<option value="75">75%</option>
<option value="100">100%</option>
<option value="NULL">N.v.t.</option>
</select>
Ik heb je functie voor de 4 onderwerp als volgt aan geroepen:
Code (php)
1
2
3
4
2
3
4
$('.avg1').change(function() { DoJudgement('.avg1', 0) });
$('.avg2').change(function() { DoJudgement('.avg2', 0) });
$('.avg3').change(function() { DoJudgement('.avg3', 0) });
$('.avg4').change(function() { DoJudgement('.avg4', 0) });
$('.avg2').change(function() { DoJudgement('.avg2', 0) });
$('.avg3').change(function() { DoJudgement('.avg3', 0) });
$('.avg4').change(function() { DoJudgement('.avg4', 0) });
Als ik één vraag onder onderwerp 4 heb, en ik geef deze 25%, dan wordt de totaalscore 25% en worden de anderen niet meer meegenomen. Als ik hem vervolgens terug zet naar 0% dan blijft die op 25% staan.
De functie heb ik veranderd naar
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function DoJudgement(avg, idx) {
var total = 0;
var counter = 0;
$(avg).each(function(i){
if ($(this).val() != 'NULL') {
counter++;
total += parseInt($(this).val());
}
});
score[idx] = (counter != 0) ? Math.round(total/counter) : 0;
counter = 0;
total = 0;
for (j=0;j<score.length;j++) {
if (score[j] != 0) {
counter++;
total += score[j];
}
}
if (total != 0) scoreT = total/counter;
$("#pb1").progressBar(scoreT);
$("#hiddenscore").val(scoreT);
}
var total = 0;
var counter = 0;
$(avg).each(function(i){
if ($(this).val() != 'NULL') {
counter++;
total += parseInt($(this).val());
}
});
score[idx] = (counter != 0) ? Math.round(total/counter) : 0;
counter = 0;
total = 0;
for (j=0;j<score.length;j++) {
if (score[j] != 0) {
counter++;
total += score[j];
}
}
if (total != 0) scoreT = total/counter;
$("#pb1").progressBar(scoreT);
$("#hiddenscore").val(scoreT);
}
was eerst maar dan wordt er verwezen naar een functie.
Gewijzigd op 23/11/2011 10:51:30 door gammele vraal
Probeer dit eens:
Code (php)
1
2
3
4
2
3
4
$('.avg1').change(function() { DoJudgement('.avg1', 0) });
$('.avg2').change(function() { DoJudgement('.avg2', 1) });
$('.avg3').change(function() { DoJudgement('.avg3', 2) });
$('.avg4').change(function() { DoJudgement('.avg4', 3) });
$('.avg2').change(function() { DoJudgement('.avg2', 1) });
$('.avg3').change(function() { DoJudgement('.avg3', 2) });
$('.avg4').change(function() { DoJudgement('.avg4', 3) });
Het tweede argument in de functie is de index van de score array
Gewijzigd op 23/11/2011 11:52:39 door Ger van Steenderen
Dat werkt inderdaad wel, ik kan nu van 100% naar NVT en andersom schakelen, maar de berekening gaat niet zoals het hoort. 0 geeft het zelfde percentage als NULL. De andere waarden zouden dan zwaarder moeten gaan wegen. Net zo als de andere onderwerpen (als je een compleet onderwerp op NVT zet).
1. Geef alle select boxen dezelfde class en voeg er een rel atribuut aan toe:
2. Geef de n.v.t opties de waarde van -1
3. Laat de onchange functie telkens alle select boxen doorlopen
Je krijgt dan de volgende
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
$('.avg').change(function() {
tmpscore = new Array();
onderwerpen = new Array();
$('.avg').each(function(i){
rel = $(this).attr('rel');
if (onderwerpen.indexOf(rel) == -1) onderwerpen[] = rel;
tmpScore[rel][] = $(this).val();
});
for(var i in onderwerpen) {
counter = 0;
total = 0;
for (j=0; j<tmpscore[onderwerpen[i]].length; j++) {
val = tmpscore[onderwerpen[i]][j]
if (val >= 0) {
total += val;
counter++;
}
}
score[onderwerpen[i]] = (counter != 0) ? Math.round(total/counter) : -1;
}
counter = 0;
total = 0;
for (j=0; j<score.length; j++) {
if (score[j] != -1) {
total += score[j];
counter++
}
}
scoreT = (counter != 0) ? Math.round(total/counter) : -1;
$("#pb1").progressBar(scoreT);
$("#hiddenscore").val(scoreT);
});
tmpscore = new Array();
onderwerpen = new Array();
$('.avg').each(function(i){
rel = $(this).attr('rel');
if (onderwerpen.indexOf(rel) == -1) onderwerpen[] = rel;
tmpScore[rel][] = $(this).val();
});
for(var i in onderwerpen) {
counter = 0;
total = 0;
for (j=0; j<tmpscore[onderwerpen[i]].length; j++) {
val = tmpscore[onderwerpen[i]][j]
if (val >= 0) {
total += val;
counter++;
}
}
score[onderwerpen[i]] = (counter != 0) ? Math.round(total/counter) : -1;
}
counter = 0;
total = 0;
for (j=0; j<score.length; j++) {
if (score[j] != -1) {
total += score[j];
counter++
}
}
scoreT = (counter != 0) ? Math.round(total/counter) : -1;
$("#pb1").progressBar(scoreT);
$("#hiddenscore").val(scoreT);
});
PS. Dreamweaver geeft bij mij een syntax error aan op regel 6, maar ik zie m zo snel niet.
http://www.imagedump.nl/img205/4594/85array.png
Zal ondertussen ook kijken wat een oplossing hiervoor kan zijn. Ik denk dat het niet op deze manier gevuld kan worden. Dat het perse een nummer moet bevatten.
Gewijzigd op 24/11/2011 08:22:26 door gammele vraal
Gammele vraal op 24/11/2011 08:18:49:
Volgens mij ondersteunt javascript deze manier van array vullen niet. Mijn foutconsole geeft aan dat het mis gaat als je de array vult bij [].
http://www.imagedump.nl/img205/4594/85array.png
Zal ondertussen ook kijken wat een oplossing hiervoor kan zijn. Ik denk dat het niet op deze manier gevuld kan worden. Dat het perse een nummer moet bevatten.
http://www.imagedump.nl/img205/4594/85array.png
Zal ondertussen ook kijken wat een oplossing hiervoor kan zijn. Ik denk dat het niet op deze manier gevuld kan worden. Dat het perse een nummer moet bevatten.
Das waar ook, weer in de war geweest met php.
De voeding van mijn test server is stuk, dus ik kon het zelf niet testen.
De oplossing is overigens simpel
Gewijzigd op 24/11/2011 10:20:53 door Ger van Steenderen
Bericht: Deze eigenschap of methode wordt niet ondersteund door dit object
Regel: 78
Teken: 5
Ik heb de functie veranderd naar
Code (php)
1
2
2
if (onderwerpen.indexOf(rel)== -1) onderwerpen[onderwerpen.length] = rel;
tmpScore[rel][onderwerpen.length] = $(this).val();
tmpScore[rel][onderwerpen.length] = $(this).val();
Firefox debugger geeft aan dat tmpScore niet gedefinieerd is, terwijl deze er wel boven staat in de functie. Heb ook tmpscore van kleine letters naar grote gelijk gemaakt, maar krijg ik tmpScore[rel] is niet gedefinieerd.
Gewijzigd op 24/11/2011 10:32:38 door gammele vraal
Dit zou het op moeten lossen:
Foutdetails webpagina
Bericht: Deze eigenschap of methode wordt niet ondersteund door dit object op de regel
Als ik in firefox de waarde van welk veld dan ook verander gaat de processbar op -1.
Ik heb een fiddle aangemaakt, zodat je kan zien wat er gebeurt. Heb de processbar update er even uit gehaald.
Gewijzigd op 24/11/2011 12:36:31 door gammele vraal
Hoef ik dat allemaal niet zelf in te kloppen ;-)
Wat betreft indexOf in IE:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
if (!Array.prototype.indexOf)
{
Array.prototype.indexOf = function(elt /*, from*/)
{
var len = this.length;
var from = Number(arguments[1]) || 0;
from = (from < 0)
? Math.ceil(from)
: Math.floor(from);
if (from < 0)
from += len;
for (; from < len; from++)
{
if (from in this &&
this[from] === elt)
return from;
}
return -1;
};
}
{
Array.prototype.indexOf = function(elt /*, from*/)
{
var len = this.length;
var from = Number(arguments[1]) || 0;
from = (from < 0)
? Math.ceil(from)
: Math.floor(from);
if (from < 0)
from += len;
for (; from < len; from++)
{
if (from in this &&
this[from] === elt)
return from;
}
return -1;
};
}
ik dacht dat al door jquery opgevangen werd, maar blijkbaar dus niet.
http://jsfiddle.net/gammele/EQ4YY/11/
Als ik met de prototype functie van jou weer de IE selectie doe, krijg ik een fout in de for lus dat tmpScore leeg is in:
Gewijzigd op 24/11/2011 12:41:29 door gammele vraal
In FF heb ik hem nu werkend
De laatste loop in de functie moet zijn:
Code (php)
1
2
3
4
5
6
2
3
4
5
6
for (var i in onderwerpen) {
if (score[onderwerpen[i]] != -1) {
total += score[onderwerpen[i]];
counter++
}
}
if (score[onderwerpen[i]] != -1) {
total += score[onderwerpen[i]];
counter++
}
}
Toevoeging op 24/11/2011 14:07:43:
Ik heb trouwens nu wel alle arrays buiten de functie gedeclareerd, en elke keer als de functie aangeroepen wordt leeggemaakt (array = [])
De foutmelding in IE kan ik niet plaatsen
edit; waarschijnlijk komt het daar door, wat is de code die je nu gebruikt?
Gewijzigd op 24/11/2011 14:10:21 door gammele vraal