diff --git a/app/assets/javascripts/app/views/publisher/poll_creator_view.js b/app/assets/javascripts/app/views/publisher/poll_creator_view.js
index e7078c2ad..158512e4a 100644
--- a/app/assets/javascripts/app/views/publisher/poll_creator_view.js
+++ b/app/assets/javascripts/app/views/publisher/poll_creator_view.js
@@ -4,17 +4,21 @@ app.views.PublisherPollCreator = app.views.Base.extend({
events: {
'click .add-answer .button': 'clickAddAnswer',
'click .remove-answer': 'removeAnswer',
+ 'blur input': 'validate',
+ 'input input': 'validate'
},
postRenderTemplate: function(){
this.$pollAnswers = this.$('.poll-answers');
- this.inputCount = 1;
+ this.inputCount = 2;
+ this.trigger('change');
},
clickAddAnswer: function(evt){
evt.preventDefault();
this.addAnswerInput();
+ this.trigger('change');
},
addAnswerInput: function(){
@@ -35,6 +39,7 @@ app.views.PublisherPollCreator = app.views.Base.extend({
removeAnswer: function(evt){
evt.stopPropagation();
this.removeAnswerInput(this.$(evt.target));
+ this.trigger('change');
},
removeAnswerInput: function(input){
@@ -44,7 +49,7 @@ app.views.PublisherPollCreator = app.views.Base.extend({
toggleRemoveAnswer: function(){
var inputs = this.$pollAnswers.find('input');
- if(inputs.length < 2){
+ if(inputs.length < 3){
this.$('.remove-answer').removeClass('active');
}
else {
@@ -54,6 +59,46 @@ app.views.PublisherPollCreator = app.views.Base.extend({
clearInputs: function(){
this.$('input').val('');
+ },
+
+ validate: function(evt){
+ var input = $(evt.target);
+ this.validateInput(input);
+ this.trigger('change');
+ },
+
+ validateInput: function(input){
+ var wrapper = input.parents('.control-group');
+ var isValid = this.isValidInput(input);
+
+ if(isValid){
+ wrapper.removeClass('error');
+ return true;
+ }
+ else {
+ wrapper.addClass('error');
+ return false;
+ }
+ },
+
+ isValidInput: function(input){
+ return $.trim(input.val());
+ },
+
+ validatePoll: function() {
+ var _this = this;
+ _.each(this.$('input:visible'), function(input){
+ _this.validateInput($(input));
+ });
+ },
+
+ isValidPoll: function(){
+ var _this = this;
+
+ return _.every(this.$('input:visible'), function(input){
+ if(_this.isValidInput($(input)))
+ return true;
+ });
}
});
diff --git a/app/assets/javascripts/app/views/publisher_view.js b/app/assets/javascripts/app/views/publisher_view.js
index be4037d82..790c53b7a 100644
--- a/app/assets/javascripts/app/views/publisher_view.js
+++ b/app/assets/javascripts/app/views/publisher_view.js
@@ -107,6 +107,7 @@ app.views.Publisher = Backbone.View.extend({
this.view_poll_creator = new app.views.PublisherPollCreator({
el: this.$('#publisher-poll-creator')
});
+ this.view_poll_creator.on('change', this.checkSubmitAvailability, this);
this.view_poll_creator.render();
},
@@ -334,11 +335,6 @@ app.views.Publisher = Backbone.View.extend({
return this;
},
- clearPollForm : function(){
- this.$('#poll_question').val('');
- this.$('.poll_answer_input').val('');
- },
-
tryClose : function(){
// if it is not submittable, close it.
if( !this._submittable() ){
@@ -381,9 +377,13 @@ app.views.Publisher = Backbone.View.extend({
// determine submit availability
_submittable: function() {
var onlyWhitespaces = ($.trim(this.el_input.val()) === ''),
- isPhotoAttached = (this.el_photozone.children().length > 0);
+ isPhotoAttached = (this.el_photozone.children().length > 0),
+ isValidPoll = this.view_poll_creator.isValidPoll();
+
+ // show poll errors
+ this.view_poll_creator.validatePoll();
- return (!onlyWhitespaces || isPhotoAttached);
+ return ((!onlyWhitespaces || isPhotoAttached) && isValidPoll);
},
handleTextchange: function() {
diff --git a/app/assets/stylesheets/publisher_blueprint.css.scss b/app/assets/stylesheets/publisher_blueprint.css.scss
index f038fe875..3cbb468a2 100644
--- a/app/assets/stylesheets/publisher_blueprint.css.scss
+++ b/app/assets/stylesheets/publisher_blueprint.css.scss
@@ -356,6 +356,18 @@
float: none;
z-index: none;
}
+ .control-group {
+ &.error {
+ color: $red;
+ background: transparent;
+ border: none;
+ padding: 0px;
+
+ input {
+ border-color: $red;
+ }
+ }
+ }
.poll-answer {
input {
width: 96%;
diff --git a/app/assets/templates/poll_creator_tpl.jst.hbs b/app/assets/templates/poll_creator_tpl.jst.hbs
index ec33719fd..e8d50a84d 100644
--- a/app/assets/templates/poll_creator_tpl.jst.hbs
+++ b/app/assets/templates/poll_creator_tpl.jst.hbs
@@ -10,6 +10,12 @@
+
diff --git a/app/models/poll.rb b/app/models/poll.rb
index 356e5e980..e2fe845a3 100644
--- a/app/models/poll.rb
+++ b/app/models/poll.rb
@@ -13,6 +13,7 @@ class Poll < ActiveRecord::Base
delegate :author, :author_id, :diaspora_handle, :public?, :subscribers, to: :status_message
validate :enough_poll_answers
+ validates :question, presence: true
self.include_root_in_json = false
diff --git a/app/models/poll_answer.rb b/app/models/poll_answer.rb
index e3cc13269..93aec82ab 100644
--- a/app/models/poll_answer.rb
+++ b/app/models/poll_answer.rb
@@ -8,6 +8,8 @@ class PollAnswer < ActiveRecord::Base
xml_attr :answer
+ validates :answer, presence: true
+
self.include_root_in_json = false
end
diff --git a/features/desktop/post_preview.feature b/features/desktop/post_preview.feature
index 97d97d877..7f537758a 100644
--- a/features/desktop/post_preview.feature
+++ b/features/desktop/post_preview.feature
@@ -76,7 +76,6 @@ Feature: preview posts in the stream
When I fill in the following:
| status_message_fake_text | I am eating yogurt |
And I press the element "#poll_creator"
- And I press the element ".add-answer .button.creation"
When I fill in the following:
| status_message_fake_text | I am eating yogurt |
| poll_question | What kind of yogurt do you like? |
diff --git a/features/desktop/post_with_a_poll.feature b/features/desktop/post_with_a_poll.feature
index c725bcead..f2f64cd67 100644
--- a/features/desktop/post_with_a_poll.feature
+++ b/features/desktop/post_with_a_poll.feature
@@ -24,7 +24,7 @@ Feature: posting with a poll
When I expand the publisher
And I press the element "#poll_creator"
And I press the element ".add-answer .button.creation"
- Then I should see 2 options
+ Then I should see 3 options
Scenario: delete an option
Given "#publisher-poll-creator" is hidden
@@ -32,7 +32,7 @@ Feature: posting with a poll
And I press the element "#poll_creator"
And I press the element ".add-answer .button.creation"
And I delete the last option
- Then I should see 1 option
+ Then I should see 2 option
And I should not see a remove icon
Scenario: post with an attached poll
@@ -41,7 +41,6 @@ Feature: posting with a poll
When I fill in the following:
| status_message_fake_text | I am eating yogurt |
| poll_question | What kind of yogurt do you like? |
- And I press the element ".add-answer .button.creation"
And I fill in the following for the options:
| normal |
| not normal |
@@ -52,7 +51,6 @@ Feature: posting with a poll
Scenario: vote for an option
Given I expand the publisher
And I press the element "#poll_creator"
- And I press the element ".add-answer .button.creation"
When I fill in the following:
| status_message_fake_text | I am eating yogurt |
| poll_question | What kind of yogurt do you like? |
@@ -70,7 +68,6 @@ Feature: posting with a poll
Scenario: click to show result
Given I expand the publisher
And I press the element "#poll_creator"
- And I press the element ".add-answer .button.creation"
When I fill in the following:
| status_message_fake_text | I am eating yogurt |
| poll_question | What kind of yogurt do you like? |
@@ -78,6 +75,18 @@ Feature: posting with a poll
| normal |
| not normal |
And I press "Share"
-
And I press the element ".toggle_result"
Then I should see an element ".percentage"
+
+ Scenario: validate answer input
+ Given I expand the publisher
+ And I press the element "#poll_creator"
+ When I fill in the following:
+ | status_message_fake_text | I am eating yogurt |
+ | poll_question | What kind of yogurt do you like? |
+ And I fill in the following for the options:
+ | normal |
+ | |
+ And I press the element "#publisher-poll-creator"
+ And I press the element "input[type=submit]"
+ Then I should see an element ".poll-answer.error"
diff --git a/spec/javascripts/app/views/publisher_poll_creator_view_spec.js b/spec/javascripts/app/views/publisher_poll_creator_view_spec.js
index e11b8b35e..97334dc99 100644
--- a/spec/javascripts/app/views/publisher_poll_creator_view_spec.js
+++ b/spec/javascripts/app/views/publisher_poll_creator_view_spec.js
@@ -51,4 +51,11 @@ describe('app.views.PublisherPollCreator', function(){
expect(this.view.$(remove_btn).hasClass('active')).toBe(false);
});
});
+ describe('#validateInput', function(){
+ it('should invalid blank value', function(){
+ var input = this.view.$('input');
+ input.val(' ');
+ expect(this.view.validateInput(input)).toBe(false);
+ }):
+ });
});
diff --git a/spec/models/poll_answer_spec.rb b/spec/models/poll_answer_spec.rb
index aa53d5261..2f592fc05 100644
--- a/spec/models/poll_answer_spec.rb
+++ b/spec/models/poll_answer_spec.rb
@@ -18,4 +18,17 @@ describe PollAnswer do
end
-end
\ No newline at end of file
+ describe 'validation' do
+ it 'should validate pressence of answer' do
+ answer = PollAnswer.new
+ answer.valid?
+ answer.errors.should have_key(:answer)
+ end
+ it 'answer should not empty' do
+ answer = PollAnswer.new answer: ' '
+ answer.valid?
+ answer.errors.should have_key(:answer)
+ end
+ end
+
+end
diff --git a/spec/models/poll_spec.rb b/spec/models/poll_spec.rb
index c94c08e33..8970fe0ff 100644
--- a/spec/models/poll_spec.rb
+++ b/spec/models/poll_spec.rb
@@ -16,5 +16,11 @@ describe Poll do
@poll.poll_answers.build(:answer => '2')
@poll.should be_valid
end
+
+ it 'should not create a poll when question in blank' do
+ @poll.question = ' '
+ @poll.valid?
+ @poll.errors.should have_key(:question)
+ end
end
-end
\ No newline at end of file
+end