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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/**
* Question Choice Collection
*
* @since 3.16.0
* @version 3.16.0
*/
define( [ 'Models/QuestionChoice' ], function( model ) {
return Backbone.Collection.extend( {
/**
* Model for collection items
*
* @type obj
*/
model: model,
initialize: function() {
// reorder called by QuestionList view when sortable drops occur
this.on( 'reorder', this.update_order );
// when a choice is added or removed, update order
this.on( 'add', this.update_order );
this.on( 'remove', this.update_order );
// when a choice is added or remove, ensure min/max correct answers exist
this.on( 'add', this.update_correct );
this.on( 'remove', this.update_correct );
// when a choice is toggled, ensure min/max correct exist
this.on( 'correct-update', this.update_correct );
},
/**
* Retrieve the number of correct choices in the collection
*
* @return int
* @since 3.16.0
* @version 3.16.0
*/
count_correct: function() {
return _.size( this.get_correct() );
},
/**
* Retrieve the collection reduced to only correct choices
*
* @return obj
* @since 3.16.0
* @version 3.16.0
*/
get_correct: function() {
return this.filter( function( choice ) {
return choice.get( 'correct' );
} );
},
/**
* Ensure min/max correct choices exist in the collection based on the question's settings
*
* @param obj choice model of the choice that was toggled
* @return void
* @since 3.16.0
* @version 3.16.0
*/
update_correct: function( choice ) {
if ( ! this.parent.get( 'question_type' ).get_choice_selectable() ) {
return;
}
var siblings = this.without( choice ), // exclude the toggled choice from loops
question = this.parent;
// if multiple choices aren't enabled turn all other choices to incorrect
if ( 'no' === question.get( 'multi_choices' ) ) {
_.each( siblings, function( model ) {
model.set( 'correct', false );
} );
}
// if we don't have a single correct answer & the question has points, set one
// allows users to create quizzes / questions with no points and therefore no correct answers are allowed
if ( 0 === this.count_correct() && question.get( 'points' ) > 0 ) {
var models = 1 === this.size() ? this.models : siblings;
_.first( models ).set( 'correct', true );
}
},
/**
* Update the marker attr of each choice in the list to reflect the order of the collection
*
* @return void
* @since 3.16.0
* @version 3.16.0
*/
update_order: function() {
var self = this,
question = this.parent;
this.each( function( choice ) {
choice.set( 'marker', question.get( 'question_type' ).get_choice_markers()[ self.indexOf( choice ) ] );
} );
},
} );
} );