I added the validation for blank to poll question and poll answer
This commit is contained in:
parent
682a49605e
commit
57de031f6b
11 changed files with 118 additions and 18 deletions
|
|
@ -4,17 +4,21 @@ app.views.PublisherPollCreator = app.views.Base.extend({
|
||||||
events: {
|
events: {
|
||||||
'click .add-answer .button': 'clickAddAnswer',
|
'click .add-answer .button': 'clickAddAnswer',
|
||||||
'click .remove-answer': 'removeAnswer',
|
'click .remove-answer': 'removeAnswer',
|
||||||
|
'blur input': 'validate',
|
||||||
|
'input input': 'validate'
|
||||||
},
|
},
|
||||||
|
|
||||||
postRenderTemplate: function(){
|
postRenderTemplate: function(){
|
||||||
this.$pollAnswers = this.$('.poll-answers');
|
this.$pollAnswers = this.$('.poll-answers');
|
||||||
this.inputCount = 1;
|
this.inputCount = 2;
|
||||||
|
this.trigger('change');
|
||||||
},
|
},
|
||||||
|
|
||||||
clickAddAnswer: function(evt){
|
clickAddAnswer: function(evt){
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
|
|
||||||
this.addAnswerInput();
|
this.addAnswerInput();
|
||||||
|
this.trigger('change');
|
||||||
},
|
},
|
||||||
|
|
||||||
addAnswerInput: function(){
|
addAnswerInput: function(){
|
||||||
|
|
@ -35,6 +39,7 @@ app.views.PublisherPollCreator = app.views.Base.extend({
|
||||||
removeAnswer: function(evt){
|
removeAnswer: function(evt){
|
||||||
evt.stopPropagation();
|
evt.stopPropagation();
|
||||||
this.removeAnswerInput(this.$(evt.target));
|
this.removeAnswerInput(this.$(evt.target));
|
||||||
|
this.trigger('change');
|
||||||
},
|
},
|
||||||
|
|
||||||
removeAnswerInput: function(input){
|
removeAnswerInput: function(input){
|
||||||
|
|
@ -44,7 +49,7 @@ app.views.PublisherPollCreator = app.views.Base.extend({
|
||||||
|
|
||||||
toggleRemoveAnswer: function(){
|
toggleRemoveAnswer: function(){
|
||||||
var inputs = this.$pollAnswers.find('input');
|
var inputs = this.$pollAnswers.find('input');
|
||||||
if(inputs.length < 2){
|
if(inputs.length < 3){
|
||||||
this.$('.remove-answer').removeClass('active');
|
this.$('.remove-answer').removeClass('active');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
@ -54,6 +59,46 @@ app.views.PublisherPollCreator = app.views.Base.extend({
|
||||||
|
|
||||||
clearInputs: function(){
|
clearInputs: function(){
|
||||||
this.$('input').val('');
|
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;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -107,6 +107,7 @@ app.views.Publisher = Backbone.View.extend({
|
||||||
this.view_poll_creator = new app.views.PublisherPollCreator({
|
this.view_poll_creator = new app.views.PublisherPollCreator({
|
||||||
el: this.$('#publisher-poll-creator')
|
el: this.$('#publisher-poll-creator')
|
||||||
});
|
});
|
||||||
|
this.view_poll_creator.on('change', this.checkSubmitAvailability, this);
|
||||||
this.view_poll_creator.render();
|
this.view_poll_creator.render();
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
@ -334,11 +335,6 @@ app.views.Publisher = Backbone.View.extend({
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
clearPollForm : function(){
|
|
||||||
this.$('#poll_question').val('');
|
|
||||||
this.$('.poll_answer_input').val('');
|
|
||||||
},
|
|
||||||
|
|
||||||
tryClose : function(){
|
tryClose : function(){
|
||||||
// if it is not submittable, close it.
|
// if it is not submittable, close it.
|
||||||
if( !this._submittable() ){
|
if( !this._submittable() ){
|
||||||
|
|
@ -381,9 +377,13 @@ app.views.Publisher = Backbone.View.extend({
|
||||||
// determine submit availability
|
// determine submit availability
|
||||||
_submittable: function() {
|
_submittable: function() {
|
||||||
var onlyWhitespaces = ($.trim(this.el_input.val()) === ''),
|
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();
|
||||||
|
|
||||||
return (!onlyWhitespaces || isPhotoAttached);
|
// show poll errors
|
||||||
|
this.view_poll_creator.validatePoll();
|
||||||
|
|
||||||
|
return ((!onlyWhitespaces || isPhotoAttached) && isValidPoll);
|
||||||
},
|
},
|
||||||
|
|
||||||
handleTextchange: function() {
|
handleTextchange: function() {
|
||||||
|
|
|
||||||
|
|
@ -356,6 +356,18 @@
|
||||||
float: none;
|
float: none;
|
||||||
z-index: none;
|
z-index: none;
|
||||||
}
|
}
|
||||||
|
.control-group {
|
||||||
|
&.error {
|
||||||
|
color: $red;
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
padding: 0px;
|
||||||
|
|
||||||
|
input {
|
||||||
|
border-color: $red;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
.poll-answer {
|
.poll-answer {
|
||||||
input {
|
input {
|
||||||
width: 96%;
|
width: 96%;
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,12 @@
|
||||||
<div class="remove-answer icons-deletelabel"></div>
|
<div class="remove-answer icons-deletelabel"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="poll-answer control-group">
|
||||||
|
<div class="controls">
|
||||||
|
<input type="text" name="poll_answers[]" placeholder="{{t 'publisher.option' nr=2}}">
|
||||||
|
<div class="remove-answer icons-deletelabel"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="control-group add-answer">
|
<div class="control-group add-answer">
|
||||||
<div href="#" class="button creation">
|
<div href="#" class="button creation">
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ class Poll < ActiveRecord::Base
|
||||||
delegate :author, :author_id, :diaspora_handle, :public?, :subscribers, to: :status_message
|
delegate :author, :author_id, :diaspora_handle, :public?, :subscribers, to: :status_message
|
||||||
|
|
||||||
validate :enough_poll_answers
|
validate :enough_poll_answers
|
||||||
|
validates :question, presence: true
|
||||||
|
|
||||||
self.include_root_in_json = false
|
self.include_root_in_json = false
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ class PollAnswer < ActiveRecord::Base
|
||||||
|
|
||||||
xml_attr :answer
|
xml_attr :answer
|
||||||
|
|
||||||
|
validates :answer, presence: true
|
||||||
|
|
||||||
self.include_root_in_json = false
|
self.include_root_in_json = false
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,6 @@ Feature: preview posts in the stream
|
||||||
When I fill in the following:
|
When I fill in the following:
|
||||||
| status_message_fake_text | I am eating yogurt |
|
| status_message_fake_text | I am eating yogurt |
|
||||||
And I press the element "#poll_creator"
|
And I press the element "#poll_creator"
|
||||||
And I press the element ".add-answer .button.creation"
|
|
||||||
When I fill in the following:
|
When I fill in the following:
|
||||||
| status_message_fake_text | I am eating yogurt |
|
| status_message_fake_text | I am eating yogurt |
|
||||||
| poll_question | What kind of yogurt do you like? |
|
| poll_question | What kind of yogurt do you like? |
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ Feature: posting with a poll
|
||||||
When I expand the publisher
|
When I expand the publisher
|
||||||
And I press the element "#poll_creator"
|
And I press the element "#poll_creator"
|
||||||
And I press the element ".add-answer .button.creation"
|
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
|
Scenario: delete an option
|
||||||
Given "#publisher-poll-creator" is hidden
|
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 "#poll_creator"
|
||||||
And I press the element ".add-answer .button.creation"
|
And I press the element ".add-answer .button.creation"
|
||||||
And I delete the last option
|
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
|
And I should not see a remove icon
|
||||||
|
|
||||||
Scenario: post with an attached poll
|
Scenario: post with an attached poll
|
||||||
|
|
@ -41,7 +41,6 @@ Feature: posting with a poll
|
||||||
When I fill in the following:
|
When I fill in the following:
|
||||||
| status_message_fake_text | I am eating yogurt |
|
| status_message_fake_text | I am eating yogurt |
|
||||||
| poll_question | What kind of yogurt do you like? |
|
| 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:
|
And I fill in the following for the options:
|
||||||
| normal |
|
| normal |
|
||||||
| not normal |
|
| not normal |
|
||||||
|
|
@ -52,7 +51,6 @@ Feature: posting with a poll
|
||||||
Scenario: vote for an option
|
Scenario: vote for an option
|
||||||
Given I expand the publisher
|
Given I expand the publisher
|
||||||
And I press the element "#poll_creator"
|
And I press the element "#poll_creator"
|
||||||
And I press the element ".add-answer .button.creation"
|
|
||||||
When I fill in the following:
|
When I fill in the following:
|
||||||
| status_message_fake_text | I am eating yogurt |
|
| status_message_fake_text | I am eating yogurt |
|
||||||
| poll_question | What kind of yogurt do you like? |
|
| poll_question | What kind of yogurt do you like? |
|
||||||
|
|
@ -70,7 +68,6 @@ Feature: posting with a poll
|
||||||
Scenario: click to show result
|
Scenario: click to show result
|
||||||
Given I expand the publisher
|
Given I expand the publisher
|
||||||
And I press the element "#poll_creator"
|
And I press the element "#poll_creator"
|
||||||
And I press the element ".add-answer .button.creation"
|
|
||||||
When I fill in the following:
|
When I fill in the following:
|
||||||
| status_message_fake_text | I am eating yogurt |
|
| status_message_fake_text | I am eating yogurt |
|
||||||
| poll_question | What kind of yogurt do you like? |
|
| poll_question | What kind of yogurt do you like? |
|
||||||
|
|
@ -78,6 +75,18 @@ Feature: posting with a poll
|
||||||
| normal |
|
| normal |
|
||||||
| not normal |
|
| not normal |
|
||||||
And I press "Share"
|
And I press "Share"
|
||||||
|
|
||||||
And I press the element ".toggle_result"
|
And I press the element ".toggle_result"
|
||||||
Then I should see an element ".percentage"
|
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"
|
||||||
|
|
|
||||||
|
|
@ -51,4 +51,11 @@ describe('app.views.PublisherPollCreator', function(){
|
||||||
expect(this.view.$(remove_btn).hasClass('active')).toBe(false);
|
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);
|
||||||
|
}):
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -18,4 +18,17 @@ describe PollAnswer do
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
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
|
end
|
||||||
|
|
@ -16,5 +16,11 @@ describe Poll do
|
||||||
@poll.poll_answers.build(:answer => '2')
|
@poll.poll_answers.build(:answer => '2')
|
||||||
@poll.should be_valid
|
@poll.should be_valid
|
||||||
end
|
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
|
||||||
end
|
end
|
||||||
Loading…
Reference in a new issue