Rewrite poll creation inputs

This commit is contained in:
Hincu Petru 2014-04-05 20:42:10 +00:00
parent f356ae7216
commit 2d3933ccd8
11 changed files with 213 additions and 137 deletions

View file

@ -0,0 +1,59 @@
app.views.PublisherPollCreator = app.views.Base.extend({
templateName: "poll_creator",
events: {
'click .add-answer .button': 'clickAddAnswer',
'click .remove-answer': 'removeAnswer',
},
postRenderTemplate: function(){
this.$pollAnswers = this.$('.poll-answers');
this.inputCount = 1;
},
clickAddAnswer: function(evt){
evt.preventDefault();
this.addAnswerInput();
},
addAnswerInput: function(){
this.inputCount++;
var input_wrapper = this.$('.poll-answer:first').clone();
var input = input_wrapper.find('input');
var text = Diaspora.I18n.t('publisher.option', {
nr: this.inputCount
});
input.attr('placeholder', text);
input.val('');
this.$pollAnswers.append(input_wrapper);
this.toggleRemoveAnswer();
},
removeAnswer: function(evt){
evt.stopPropagation();
this.removeAnswerInput(this.$(evt.target));
},
removeAnswerInput: function(input){
input.parents('.poll-answer').remove();
this.toggleRemoveAnswer();
},
toggleRemoveAnswer: function(){
var inputs = this.$pollAnswers.find('input');
if(inputs.length < 2){
this.$('.remove-answer').removeClass('active');
}
else {
this.$('.remove-answer').addClass('active');
}
},
clearInputs: function(){
this.$('input').val('');
}
});

View file

@ -23,16 +23,13 @@ app.views.Publisher = Backbone.View.extend({
"click .post_preview_button" : "createPostPreview",
"textchange #status_message_fake_text": "handleTextchange",
"click #locator" : "showLocation",
"click #poll_creator" : "showPollCreator",
"click #add_poll_answer" : "addPollAnswer",
"click .remove_poll_answer" : "removePollAnswer",
"click #poll_creator" : "togglePollCreator",
"click #hide_location" : "destroyLocation",
"keypress #location_address" : "avoidEnter"
},
initialize : function(opts){
this.standalone = opts ? opts.standalone : false;
this.option_counter = 1;
// init shortcut references to the various elements
this.el_input = this.$('#status_message_fake_text');
@ -41,8 +38,6 @@ app.views.Publisher = Backbone.View.extend({
this.el_submit = this.$('input[type=submit], button#submit');
this.el_preview = this.$('button.post_preview_button');
this.el_photozone = this.$('#photodropzone');
this.el_poll_creator = this.$('#poll_creator_wrapper');
this.el_poll_answer = this.$('#poll_creator_wrapper .poll_answer');
// init mentions plugin
Mentions.initialize(this.el_input);
@ -75,7 +70,6 @@ app.views.Publisher = Backbone.View.extend({
});
this.initSubviews();
this.addPollAnswer();
return this;
},
@ -109,6 +103,11 @@ app.views.Publisher = Backbone.View.extend({
publisher: this
});
this.view_uploader.on('change', this.checkSubmitAvailability, this);
this.view_poll_creator = new app.views.PublisherPollCreator({
el: this.$('#publisher-poll-creator')
});
this.view_poll_creator.render();
},
@ -179,36 +178,11 @@ app.views.Publisher = Backbone.View.extend({
}
},
showPollCreator: function(){
this.el_poll_creator.toggle();
togglePollCreator: function(){
this.view_poll_creator.$el.toggleClass('active');
this.el_input.focus();
},
addPollAnswer: function(){
if($(".poll_answer").size() == 1) {
$(".remove_poll_answer").css("visibility","visible");
}
this.option_counter++;
var clone = this.el_poll_answer.clone();
var answer = clone.find('.poll_answer_input');
answer.val("");
var placeholder = answer.attr("placeholder");
var expression = /[^0-9]+/;
answer.attr("placeholder", expression.exec(placeholder) + this.option_counter);
$('#poll_creator_wrapper .poll_answer').last().after(clone);
},
removePollAnswer: function(evt){
$(evt.currentTarget).parent().remove();
if($(".poll_answer").size() == 1) {
$(".remove_poll_answer").css("visibility","hidden");;
}
return false;
},
// avoid submitting form when pressing Enter key
avoidEnter: function(evt){
if(evt.keyCode == 13)
@ -351,7 +325,7 @@ app.views.Publisher = Backbone.View.extend({
this.destroyLocation();
// clear poll form
this.clearPollForm();
this.view_poll_creator.clearInputs();
// force textchange plugin to update lastValue
this.el_input.data('lastValue', '');
@ -386,7 +360,7 @@ app.views.Publisher = Backbone.View.extend({
$(this.el).addClass("closed");
this.el_wrapper.removeClass("active");
this.el_input.css('height', '');
this.el_poll_creator.hide();
this.view_poll_creator.$el.removeClass('active');
return this;
},

View file

@ -334,50 +334,55 @@
}
}
#poll_creator_wrapper {
display:none;
#publisher-poll-creator {
border: 1px solid $border-dark-grey;
padding:5px;
margin-top:1em;
padding: 5px;
margin-top: 5px;
@include border-radius(2px);
}
display: none;
.remove_poll_answer {
visibility:hidden;
float:right;
display: table-cell;
&.active {
display: block;
}
input {
-moz-box-sizing: border-box;
box-sizing: border-box;
margin-bottom: 0px;
}
.poll-question input {
width: 100%;
}
.controls {
float: none;
z-index: none;
}
.poll-answer {
input {
width: 96%;
display: inline-block;
vertical-align: bottom;
}
.remove-answer {
width: 14px;
height: 14px;
@include opacity(0.4);
cursor: pointer;
vertical-align: top;
margin-top: 7px;
display: none;
.icons-deletelabel {
height: 14px;
width: 14px;
margin-top:5px;
&:hover {
@include opacity(1);
}
&.active {
display: inline-block;
}
}
}
.control-group {
margin-bottom: 5px;
}
.add-answer {
padding-top: 5px;
}
}
.poll_answer_input {
width:100%;
}
#add_poll_answer_wrapper {
padding:5px 0 5px 0;
display:block;
}
#poll_question_wrapper {
}
#poll_question {
width: 100%;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
}
.poll_answer {
display: table;
width: 100%;
}
.poll_answer_input_wrapper {
display: table-cell;
}

View file

@ -0,0 +1,18 @@
<div class="poll-question control-group">
<div class="controls">
<input class="span12" placeholder="{{t 'publisher.question' }}" type="text" name="poll_question">
</div>
</div>
<div class="poll-answers">
<div class="poll-answer control-group">
<div class="controls">
<input type="text" name="poll_answers[]" placeholder="{{t 'publisher.option' nr=1}}">
<div class="remove-answer icons-deletelabel"></div>
</div>
</div>
</div>
<div class="control-group add-answer">
<div href="#" class="button creation">
{{t 'publisher.add_option' }}
</div>
</div>

View file

@ -37,17 +37,7 @@
= image_tag 'icons/camera.png', :alt => t('shared.publisher.upload_photos').titleize, :class => 'publisher_image'
= hidden_field :location, :coords
#location_container
#poll_creator_wrapper
#poll_question_wrapper
%input{:id => 'poll_question', :placeholder => t('shared.publisher.poll.question'), :name => 'poll_question'}
.poll_answer
%span{:class => 'poll_answer_input_wrapper'}
%input{:class => 'poll_answer_input', :placeholder => t('shared.publisher.poll.option'), :name => 'poll_answers[]'}
%a{:class => 'remove_poll_answer', :title => t('shared.publisher.poll.remove_poll_answer')}
.icons-deletelabel
#add_poll_answer_wrapper
#add_poll_answer{:class => 'button creation'}
= t('shared.publisher.poll.add_poll_answer')
#publisher-poll-creator
- if publisher_public
= hidden_field_tag 'aspect_ids[]', "public"

View file

@ -102,6 +102,11 @@ en:
mark_read: "Mark read"
mark_unread: "Mark unread"
publisher:
option: "Option <%= nr %>"
add_option: "Add option"
question: "Question"
stream:
hide: "Hide"
public: "Public"
@ -180,4 +185,4 @@ en:
one: "1 vote so far"
other: "<%=count%> votes so far"
show_result: "Show result"
close_result: "Hide result"
close_result: "Hide result"

View file

@ -76,6 +76,7 @@ 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? |

View file

@ -9,28 +9,29 @@ Feature: posting with a poll
And I am on the home page
Scenario: expanding the publisher
Given "#poll_creator_wrapper" is hidden
Given "#publisher-poll-creator" is hidden
When I expand the publisher
Then I should see an element "#poll_creator"
Scenario: expanding the poll creator
Given "#poll_creator_wrapper" is hidden
Given "#publisher-poll-creator" is hidden
When I expand the publisher
And I press the element "#poll_creator"
Then I should see an element "#poll_creator_wrapper"
Then I should see an element "#publisher-poll-creator"
Scenario: adding option to poll
Given "#poll_creator_wrapper" is hidden
Given "#publisher-poll-creator" is hidden
When I expand the publisher
And I press the element "#poll_creator"
And I press the element "#add_poll_answer"
Then I should see 3 options
And I press the element ".add-answer .button.creation"
Then I should see 2 options
Scenario: delete an option
Given "#poll_creator_wrapper" is hidden
Given "#publisher-poll-creator" is hidden
When I expand the publisher
And I press the element "#poll_creator"
And I delete the first option
And I press the element ".add-answer .button.creation"
And I delete the last option
Then I should see 1 option
And I should not see a remove icon
@ -40,6 +41,7 @@ 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 |
@ -50,6 +52,7 @@ 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? |
@ -67,6 +70,7 @@ 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? |

View file

@ -1,19 +1,19 @@
Then /^I should see ([1-9]+) options?$/ do |number|
find("#poll_creator_wrapper").all(".poll_answer").count.should eql(number.to_i)
find("#publisher-poll-creator").all(".poll-answer").count.should eql(number.to_i)
end
And /^I delete the first option$/ do
find("#poll_creator_wrapper").all(".poll_answer .remove_poll_answer").first.click
And /^I delete the last option$/ do
find("#publisher-poll-creator").all(".poll-answer .remove-answer").first.click
end
And /^I should not see a remove icon$/ do
page.should_not have_css(".remove_poll_answer")
page.should_not have_css(".remove-answer")
end
When /^I fill in the following for the options:$/ do |table|
i = 0
table.raw.flatten.each do |value|
all(".poll_answer_input")[i].set(value)
all(".poll-answer input")[i].set(value)
i+=1
end
end

View file

@ -0,0 +1,54 @@
describe('app.views.PublisherPollCreator', function(){
beforeEach(function(){
this.view = new app.views.PublisherPollCreator();
this.view.render();
this.input_selector = '.poll-answer input';
});
describe('rendering', function(){
it('should have question input', function(){
expect(this.view.$('input[name=poll_question]')).toExist();
});
it('should have answerinput', function(){
expect(this.view.$(this.input_selector)).toExist();
});
});
describe('#addAnswerInput', function(){
it('should add new answer input', function(){
this.view.addAnswerInput();
expect(this.view.$(this.input_selector).length).toBe(2);
});
it('should change input count', function(){
this.view.addAnswerInput();
expect(this.view.inputCount).toBe(2);
});
});
describe('#removeAnswerInput', function(){
it('remove answer input', function(){
var input = this.view.$('input:first');
this.view.removeAnswerInput(input);
expect(this.view.$(this.input_selector).length).toBe(1);
});
});
describe('#clearInputs', function(){
it('clear input', function(){
this.view.$('input').val('Hello word');
this.view.clearInputs();
expect(this.view.$(this.input_selector).val()).toBe('');
});
});
describe('#toggleRemoveAnswer', function(){
var remove_btn = '.poll-answer .remove-answer';
it('show remove button when answer input is greater 1', function(){
this.view.addAnswerInput();
expect(this.view.$(remove_btn).hasClass('active')).toBe(true);
});
it('hide remove button when is only one answer input', function(){
var input = this.view.$(this.input_selector);
this.view.addAnswerInput();
this.view.removeAnswerInput(input);
expect(this.view.$(remove_btn).hasClass('active')).toBe(false);
});
});
});

View file

@ -277,40 +277,6 @@ describe("app.views.Publisher", function() {
});
context("poll", function(){
beforeEach(function() {
loginAs({name: "alice", avatar : {small : "http://avatar.com/photo.jpg"}});
spec.loadFixture("aspects_index");
$("#poll_creator_wrapper").hide(); //css not loaded? :-/
this.view = new app.views.Publisher();
});
describe('#showPollCreator', function(){
it("Shows the poll creator", function(){
expect($("#poll_creator_wrapper").is(":visible")).toBe(false);
this.view.showPollCreator();
expect($("#poll_creator_wrapper").is(":visible")).toBe(true);
})
});
describe("#addPollAnswer", function(){
it("should add a poll answer if clicked", function(){
expect($("#poll_creator_wrapper .poll_answer").length).toBe(2);
this.view.addPollAnswer();
expect($("#poll_creator_wrapper .poll_answer").length).toBe(3);
})
});
describe("#removePollAnswer", function(){
it("should remove a poll answer if clicked", function(){
var answer_count = $('.poll_answer').length;
var evt = {'currentTarget' : $("#poll_creator_wrapper .poll_answer:first .remove_poll_answer")};
this.view.removePollAnswer(evt);
expect($("#poll_creator_wrapper .poll_answer").length).toBe(answer_count-1);
})
});
});
context("locator", function() {
beforeEach(function() {
// should be jasmine helper