I just finished up writing a simplistic/trivial framework using ReactJS using which one could quickly create online quizzes. The code for this could be found on github on following page named as ReactJS-Quiz. I would like to take this opportunity to share AngularJS-Quiz that I wrote sometime back. I must say that I found writing quiz framework using ReactJS more fulfilling as it got aligned to my OOP oriented thinking and I was not required to envisage templates etc as in case of AngularJS. That said, both frameworks are cool and have their own pluses and minuses. Please feel free to suggest if I missed on mentioning one or more key aspects. Also, sorry for typos.
I shall be presenting some of the following key concepts of ReactJS while explaining the functionality of Quiz framework.
To make use of this framework, all that is required to be done is define JSON data model (or retrieve from server) as shown later in this article and that is it! In this blog, I will explain the design aspect of UI using ReactJS. Before that, let me quickly define this Quiz framework. Following are some of the features of first version of this quiz framework:
As a starter, I would recommend you to quickly read the ReactJS page on thinking in terms of components. Briefly speaking, when designing UI, one has to do following:
When designing UI for tests/quiz, following are some of key components as shown above:
The relationship between the components depicted below represents following:
React is all about modular, composable components.
var test = {
name: "Sample Test",
description: "This is a sample test paper to demonstrate the ReactJS UI design by components.",
passCutoff: 0.33,
applyNegativeMarking: false,
questions: [
{
id: "1",
qtext:"California is in which part of USA?",
options:[
{text:"East"},
{text:"Mid"},
{text:"West"},
{text:"South"}
],
ans:"West",
marks: 3
},
{
id: "2",
qtext:"Who is Prime Minister of India?",
options:[
{text:"Sonia Gandhi"},
{text:"Narendra Modi"},
{text:"Manmohan Singh"},
{text:"Rahul Gandhi"}
],
ans:"Narendra Modi",
marks: 2
},
{
id: "3",
qtext:"Which of the following is most popular Search Engine Company?",
options:[
{text:"Microsoft"},
{text:"Facebook"},
{text:"Google"},
{text:"Yahoo"}
],
ans:"Google",
marks: 1
},
]
};
In the above JSON data model, you would find “test” consisting of an array of questions which is modeled using “QuestionPaper” consisting of a list of “Question”s.
var Test = React.createClass({
getInitialState: function() {
return {totalscore : 0, testSubmitted: false};
},
handleChange: function(result) {
this.setState({totalscore: result.totalscore, testSubmitted: true});
},
render: function(){
var totalmarks = 0;
this.props.details.questions.map(function(question){
totalmarks += question.marks;
});
return(
<div>
<h1>{this.props.details.name}</h1>
<hr className="divider"/>
<div>{this.props.details.description}</div>
<table className="table">
<tr>
<td className="col-md-9">
<QuestionPaper questions={this.props.details.questions} applyNegativeMarking={this.props.details.applyNegativeMarking}
onSubmitted={this.handleChange}/>
</td>
<td className="col-md-3">
<Scorecard score={this.state.totalscore} testSubmitted={this.state.testSubmitted} percentage={Math.round(this.state.totalscore*100/totalmarks)}/>
</td>
</tr>
</table>
</div>
);
}
});
var QuestionPaper = React.createClass({
getInitialState: function() {
return {totalscore : 0};
},
handleChange: function(score) {
this.setState({totalscore: this.state.totalscore + score});
},
handleSubmitted: function(event) {
var result = {totalscore: this.state.totalscore};
this.props.onSubmitted( result );
},
render: function(){
var questionAnswers = this.props.questions.map(function(question){
return(
<tr><td><Question question={question.qtext} number={question.no} options={question.options} answer={question.ans} marks={question.marks} applyNegativeMarking={this.props.applyNegativeMarking} onAnswered={this.handleChange}/></td></tr>
);
}, this);
return(
<div>
<table className="table table-striped">{questionAnswers}</table>
<div><input type="button" className="btn btn-primary" value="Submit" onClick={this.handleSubmitted}/></div>
</div>
);
}
});
var Question = React.createClass({
getInitialState: function() {
return {
correctAnswerRecorded: false,
negativeAnswerRecorded: false
};
},
handleChange: function(event) {
var score = 0;
if( event.target.value == this.props.answer) {
if( this.state.correctAnswerRecorded === false ) {
if( this.props.applyNegativeMarking === true && this.state.negativeAnswerRecorded === true ) {
score = 1 + this.props.marks;
} else {
score = this.props.marks;
}
}
this.state.correctAnswerRecorded = true;
this.state.negativeAnswerRecorded = false;
} else {
if( this.props.applyNegativeMarking === true && this.state.negativeAnswerRecorded === false ) {
if( this.state.correctAnswerRecorded === true ) {
score = -1 - this.props.marks;
} else {
score = -1;
}
} else {
if( this.state.correctAnswerRecorded === true ) {
score = -this.props.marks;
}
}
this.state.negativeAnswerRecorded = true;
this.state.correctAnswerRecorded = false;
}
this.props.onAnswered(score);
},
render: function(){
var qname = "option" + this.props.number;
var qoptions = this.props.options.map(function(option){
return (
<div><input type="radio" name={qname} value={option.text} onChange={this.handleChange}/> {option.text}</div>
);
}, this);
return(
<div>
<div><strong>Q</strong>: {this.props.question}</div>
<div>{qoptions}</div>
<br/>
</div>
);
}
});
var Scorecard = React.createClass({
render: function(){
var status = "Test not submitted!";
if( this.props.testSubmitted == true ) {
if( this.props.percentage < 33 ) {
status = "Sorry, you could not pass the test. Try again later!"
} else {
status = "Congratulations!! You passed the test.";
}
}
return(
<div className="list-group">
<div className="list-group-item active">Test Result</div>
<div className="list-group-item">Score: <strong>{this.props.score}</strong></div>
<div className="list-group-item">Percentage: <strong>{this.props.percentage} %</strong></div>
<div className="list-group-item">Status: <strong>{status}</strong></div>
</div>
);
}
});
Please feel free to share any comments/suggestions that you may have. I would extend this framework with other features soon.
Last updated: 26th April, 2024 In this blog post, we will discuss the logistic regression…
Last updated: 22nd April, 2024 As data scientists, we navigate a sea of metrics to…
Last updated: 22nd April, 2024 This post will teach you about the gradient descent algorithm…
Last updated: 19th April, 2024 Among the terminologies used in training machine learning models, the…
Last updated: 19th April, 2024 Model parallelism and data parallelism are two strategies used to…
Last updated: 4th April, 2024 In machine learning, model complexity, and overfitting are related in…