Skip to content

Commit

Permalink
base viewcomponent architecture
Browse files Browse the repository at this point in the history
  • Loading branch information
swalke16 committed Jan 24, 2012
1 parent 51f358e commit 94422f8
Show file tree
Hide file tree
Showing 10 changed files with 101 additions and 128 deletions.
43 changes: 22 additions & 21 deletions public/javascripts/answer_panel.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,29 @@
var Views = (function(ns){

var AnswerPanel = function(container, messageBus){
this.$container = container;
this.messageBus = messageBus;
this.hasSubmitted = false;

this.renderInit();
};

AnswerPanel.prototype = {
bindEvents: function(){
this.messageBus.on("question-changed", _.bind(this.renderAnswers, this));
this.messageBus.on("user-answered", _.bind(this.updatePercentages, this));
this.$submitAnswerButton.on("click", _.bind(this.submitAnswer, this));
this.$answerContainer.on('click', '.possibleAnswer', _.bind(this.selectAnswer, this));
var AnswerPanel = Views.ViewComponent.extend({
id: "answer_panel",
className: "section",
hasSubmitted: false,

events: {
view: {
"click #final_answer" : "submitAnswer",
"click .possibleAnswer" : "selectAnswer"
},
messageBus: {
"question-changed" : "renderAnswers",
"user-answered" : "updatePercentages"
}
},

renderInit: function(data){
this.$container.empty();
var $panel_content = $(Templates.render('answer_panel')).appendTo(this.$container);
this.$answerContainer = $panel_content.find("#possible_answers_container");
this.$submitAnswerButton = $panel_content.find("#final_answer");
render: function(){
var $html = $(Templates.render('answer_panel'));
this.$el.empty().append($html);

this.$answerContainer = this.$("#possible_answers_container");
this.$submitAnswerButton = this.$("#final_answer");

this.bindEvents();
return this;
},

renderAnswers: function(answers){
Expand Down Expand Up @@ -67,7 +68,7 @@ var Views = (function(ns){
this.$submitAnswerButton.toggleClass('disabled', false);
}
}
};
});


ns.AnswerPanel = AnswerPanel;
Expand Down
39 changes: 21 additions & 18 deletions public/javascripts/discussion_panel.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,30 @@
var Views = (function(ns){

var DiscussionPanel = function(container, messageBus){
this.$container = container;
this.messageBus = messageBus;

this.renderInit();
};
var DiscussionPanel = Views.ViewComponent.extend({
id: "discussion_panel",

events: {
view: {
"click input#submit_discussion" : "sendMessage"
},
messageBus: {
"message-new" : "renderMessages"
}
},

DiscussionPanel.prototype = {
bindEvents: function(){
this.messageBus.on("message-new", _.bind(this.renderMessages, this));
this.$discussion_submit_button.on("click", _.bind(this.sendMessage, this));
initialize: function(){
this.render();
},

renderInit: function(){
this.$container.empty();
var $pad_contents = $(Templates.render('discussion_area')).appendTo(this.$container);
render: function(){
var $html = $(Templates.render('discussion_area'));
this.$el.empty().append($html);

this.$discussion_box = $pad_contents.find('textarea.discussion');
this.$discussion_submit_button = $pad_contents.find('input#submit_discussion');
this.$discussion_items = $pad_contents.find('table#discussion_items');
this.$discussion_box = this.$('textarea.discussion');
this.$discussion_submit_button = this.$('input#submit_discussion');
this.$discussion_items = this.$('table#discussion_items');

this.bindEvents();
return this;
},

renderMessages: function(messages) {
Expand All @@ -32,7 +35,7 @@ var Views = (function(ns){
sendMessage: function(){
this.messageBus.emit("message-send", {message: this.$discussion_box.val()});
}
};
});


ns.DiscussionPanel = DiscussionPanel;
Expand Down
29 changes: 10 additions & 19 deletions public/javascripts/question_panel.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,20 @@
var Views = (function(ns) {

var QuestionPanel = Views.ViewComponent.extend({
id: "question_panel",

var QuestionPanel = function(container, messageBus) {
this.$container = container;
this.messageBus = messageBus;

this.bindEvents();
};

QuestionPanel.prototype = {
bindEvents: function(){
this.messageBus.on("question-changed", _.bind(this.render, this));
events: {
messageBus: {
"question-changed" : "renderQuestion"
}
},

render: function(data){
var $templateContent = $(Templates.render('question_panel', data));
this.$container.empty().append($templateContent);

this.$questionPanel = this.$container.find("#question_panel");
this.$answerPanelContainer = this.$container.find("#answer_panel_container");

this.answerPanel = new Views.AnswerPanel(this.$answerPanelContainer, this.messageBus);
renderQuestion: function(data){
var $html = $(Templates.render('question_panel', data));
this.$el.empty().append($html);
}

};
});

ns.QuestionPanel = QuestionPanel;
return ns;
Expand Down
2 changes: 1 addition & 1 deletion public/javascripts/view_component.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ var Views = (function(ns){
_.each(messageBusEvents, this.delegateBusEvent, this);
},

delegateViewEvent : function(key, methodName){
delegateViewEvent : function(methodName, key){
var method = this[methodName];
if (!method) throw new Error('Event "' + methodName + '" does not exist');
var match = key.match(eventSplitter);
Expand Down
37 changes: 16 additions & 21 deletions spec/answer_panel_spec.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
describe("AnswerPanel", function(){
var $container,
answerPanel,
fakeMessageBus,
var answerPanel,
messageBus,
answerData;

describe("#renderAnswers", function(){
beforeEach(function(){
$container = $("<div></div>");
fakeMessageBus = new FakeMessageBus();
answerPanel = new Views.AnswerPanel($container, fakeMessageBus);
messageBus = new FakeMessageBus();
answerPanel = new Views.AnswerPanel({messageBus: messageBus}).render();
answerData = {possibleAnswers:[{value: "undefined", percentageChosen: 35}, {value: "null", percentageChosen: 10}]};
});

Expand All @@ -30,20 +28,19 @@ describe("AnswerPanel", function(){

describe("messages received", function() {
beforeEach(function(){
$container = $("<div></div>");
fakeMessageBus = new FakeMessageBus();
messageBus = new FakeMessageBus();
spyOn(Views.AnswerPanel.prototype, 'renderAnswers').andCallThrough();
answerPanel = new Views.AnswerPanel($container, fakeMessageBus);
answerPanel = new Views.AnswerPanel({messageBus: messageBus}).render();
});

it("renders answers on question-changed", function(){
fakeMessageBus.emit('question-changed', {});
messageBus.emit('question-changed', {});
expect(answerPanel.renderAnswers).toHaveBeenCalled();
});

it("disables the answer submission button on question-changed", function(){
answerPanel.$submitAnswerButton.removeClass('disabled');
fakeMessageBus.emit('question-changed', {});
messageBus.emit('question-changed', {});
expect(answerPanel.$submitAnswerButton).toHaveClass('disabled');
});

Expand All @@ -52,7 +49,7 @@ describe("AnswerPanel", function(){
answerPanel.renderAnswers(answerData);
answerData.possibleAnswers[0].percentageChosen = 15;
answerData.possibleAnswers[1].percentageChosen = 25;
fakeMessageBus.emit('user-answered', answerData);
messageBus.emit('user-answered', answerData);

expect(answerPanel.$answerContainer).toContainText("15%");
expect(answerPanel.$answerContainer).toContainText("25%");
Expand All @@ -64,21 +61,20 @@ describe("AnswerPanel", function(){
var responseData;

beforeEach(function(){
$container = $("<div></div>");
responseData = { correctIndex:1 };
fakeMessageBus = new FakeMessageBus();
fakeMessageBus.fakeResponse(function() { return responseData; });
answerPanel = new Views.AnswerPanel($container, fakeMessageBus);
messageBus = new FakeMessageBus();
messageBus.fakeResponse(function() { return responseData; });
answerPanel = new Views.AnswerPanel({messageBus: messageBus}).render();
answerPanel.renderAnswers({possibleAnswers: ['undefined', 'null']});
});

it("submits the selected answer", function() {
spyOn(fakeMessageBus, 'emit');
spyOn(messageBus, 'emit');
answerPanel.$answerContainer.find('.possibleAnswer input:first').prop('checked', true);

answerPanel.$submitAnswerButton.click();

expect(fakeMessageBus.emit).toHaveBeenCalledWith('answer-submitted', {answerIndex: 0}, jasmine.any(Function));
expect(messageBus.emit).toHaveBeenCalledWith('answer-submitted', {answerIndex: 0}, jasmine.any(Function));
});

it("indicates which is the correct answer", function() {
Expand All @@ -102,9 +98,8 @@ describe("AnswerPanel", function(){

describe("selecting an answer", function() {
beforeEach(function(){
$container = $("<div></div>");
fakeMessageBus = new FakeMessageBus();
answerPanel = new Views.AnswerPanel($container, fakeMessageBus);
messageBus = new FakeMessageBus();
answerPanel = new Views.AnswerPanel({messageBus: messageBus}).render();
answerPanel.renderAnswers({possibleAnswers: ['undefined', 'null']});
});

Expand Down
12 changes: 5 additions & 7 deletions spec/discussion_panel_spec.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
describe("DiscussionPanel", function(){
var $container, discussionPanel, messageBus;
var discussionPanel, messageBus;

describe("#renderMessages", function(){
beforeEach(function () {
$container = $("<div id='discussion_pad'></div>");
messageBus = new FakeMessageBus();
discussionPanel = new Views.DiscussionPanel($container, messageBus);
discussionPanel = new Views.DiscussionPanel({messageBus: messageBus});
});

it("is empty with 0 messages", function(){
discussionPanel.renderMessages({messages:[]});
expect(discussionPanel.$discussion_items.children().length).toBe(0);
});

Expand Down Expand Up @@ -44,10 +44,9 @@ describe("DiscussionPanel", function(){

describe("messages received", function(){
beforeEach(function () {
$container = $("<div id='discussion_pad'></div>");
messageBus = new FakeMessageBus();
spyOn(Views.DiscussionPanel.prototype, 'renderMessages');
discussionPanel = new Views.DiscussionPanel($container, messageBus);
discussionPanel = new Views.DiscussionPanel({messageBus: messageBus});
});

it("renders on message-new event", function(){
Expand All @@ -61,10 +60,9 @@ describe("DiscussionPanel", function(){

describe("sending messages", function(){
beforeEach(function () {
$container = $("<div id='discussion_pad'></div>");
messageBus = new FakeMessageBus();
spyOn(messageBus, 'emit');
discussionPanel = new Views.DiscussionPanel($container, messageBus);
discussionPanel = new Views.DiscussionPanel({messageBus: messageBus});
});

it("emits the message-send event", function(){
Expand Down
40 changes: 15 additions & 25 deletions spec/question_panel_spec.js
Original file line number Diff line number Diff line change
@@ -1,51 +1,41 @@
describe("QuestionPanel", function(){
var $container,
questionPanel,
fakeMessageBus,
example;
var questionPanel,
messageBus,
example = {question:"Does this work?", code:"var example = {};"};

describe("#render", function(){
describe("#renderQuestion", function(){
beforeEach(function(){
$container = $("<div></div>");
fakeMessageBus = new FakeMessageBus();
questionPanel = new Views.QuestionPanel($container, fakeMessageBus);
example = {question:"Does this work?", code:"var example = {};"};
messageBus = new FakeMessageBus();
questionPanel = new Views.QuestionPanel({messageBus: messageBus});
});

it("displays the question", function(){
questionPanel.render(example);
questionPanel.renderQuestion(example);

expect(questionPanel.$questionPanel).toContainText(example.question);
expect(questionPanel.$el).toContainText(example.question);
});

it("displays the prettified code", function() {
var prettyCode = 'this is some damn fine code';
Templates.helpers.prettyPrintCode = function(){ return prettyCode; };

questionPanel.render(example);

expect(questionPanel.$questionPanel).toContainText(prettyCode);
});

it("renders the answer panel", function() {
questionPanel.render(example);
questionPanel.renderQuestion(example);

expect(questionPanel.$answerPanelContainer.children().length).toBeGreaterThan(0);
expect(questionPanel.$el).toContainText(prettyCode);
});

});

describe("messages received", function() {
beforeEach(function(){
$container = $("<div></div>");
spyOn(Views.QuestionPanel.prototype, 'render');
spyOn(Views.QuestionPanel.prototype, 'renderQuestion');
messageBus = new FakeMessageBus();
questionPanel = new Views.QuestionPanel($container, messageBus);
questionPanel = new Views.QuestionPanel({messageBus: messageBus});
});

it("renders on question-changed message", function() {
messageBus.emit('question-changed', {});
expect(questionPanel.render).toHaveBeenCalled();
it("renderQuestions on question-changed message", function() {
messageBus.emit('question-changed', example);
expect(questionPanel.renderQuestion).toHaveBeenCalled();
});

});
Expand Down
10 changes: 4 additions & 6 deletions views/client/answer_panel.hbs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
<div id='answer_panel' class='.section'>
<div id='possible_answers_container'>
</div>
<div id='final_answer_container'>
<a id='final_answer' class='disabled' href='#'>Submit My Final Answer</a>
</div>
<div id='possible_answers_container'>
</div>
<div id='final_answer_container'>
<a id='final_answer' class='disabled' href='#'>Submit My Final Answer</a>
</div>
4 changes: 2 additions & 2 deletions views/client/discussion_area.hbs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<div id='discussion_enter'>
<div id='textarea_container'>
<textarea class='discussion'/>
<div id='textarea_container'>
<textarea class='discussion'/>
</div>
<input type='button' id='submit_discussion' value='Send' class='enabled'/>
</div>
Expand Down
Loading

0 comments on commit 94422f8

Please sign in to comment.