I attempted the micropost character countdown in The Rails Tutorial (Chapter 10, Exercise 7) using the information here as a base and with some help from StackOverflow answers here and here.
On screen, it looks like this, and as you get closer to the character limit, the text gradually turns redder, and once the micropost is overlimit, the Post button disables, finishing like so.
The current implementation looks like:
views/shared/_micropost_form.html.haml
= form_for @micropost do |f|
= render 'shared/error_messages', object: f.object
.field= f.text_area :content, placeholder: t('.compose_micropost')
%span
.remaining= t('.characters_remaining').html_safe
.countdown
= f.submit t('.post'), class: "btn btn-large btn-primary"
assets/javascripts/microposts.js.coffee
updateCountdownAttributes = (toRemove, toAdd = null) ->
for attr in toRemove
$(".remaining, .countdown").removeClass attr
if toAdd
$(".remaining, .countdown").addClass toAdd
if toAdd is "overlimit"
$("input.btn.btn-large.btn-primary").attr("disabled", "true")
else
$("input.btn.btn-large.btn-primary").removeAttr("disabled")
updateCountdown = ->
remaining = 140 - $("#micropost_content").val().length
toRemove = ["nearlimit", "almostlimit", "overlimit"]
if remaining > 19
updateCountdownAttributes(toRemove)
if remaining < 20
toAdd = (toRemove.filter (attr) -> attr is "nearlimit").toString()
updateCountdownAttributes(toRemove, toAdd)
if remaining < 11
toAdd = (toRemove.filter (attr) -> attr is "almostlimit").toString()
updateCountdownAttributes(toRemove, toAdd)
if remaining < 0
toAdd = (toRemove.filter (attr) -> attr is "overlimit").toString()
updateCountdownAttributes(toRemove, toAdd)
$(".countdown").text remaining
$(document).ready ->
$(".countdown").text 140
$("#micropost_content").change updateCountdown
$("#micropost_content").keyup updateCountdown
$("#micropost_content").keydown updateCountdown
$("#micropost_content").keypress updateCountdown
assets/stylesheets/custom.css.scss
...
/* Micropost character countdown */
.remaining, .countdown {
display: inline;
color: $grayLight;
float: right;
}
.overlimit {
color: $red;
}
.almostlimit {
color: hsl(360, 57%, 21%);
}
.nearlimit {
color: $gray;
}
config/locales/en.yml
en:
...
shared:
...
micropost_form:
compose_micropost: "Compose new micropost..."
post: "Post"
characters_remaining: " characters remaining."
From here, I have two questions/problems:
The first is, if possible, I want to be able to do proper pluralization of the "characters remaining" string. Perhaps something like:
views/shared/_micropost_form.html.haml
...
%span
.remaining= t('.characters_remaining', count: [[.countdown value]]).html_safe
.countdown
...
config/locales/en.yml
...
micropost_form:
...
characters_remaining:
one: " character remaining."
other: " characters remaining."
However, I don't know how to retrieve the value within the .countdown
div in a way that I can pass it over to the count
parameter. How can I do this?
Assuming the first problem can be solved, I also want to get rid of the minus number of characters and instead change "-2 characters remaining" to "2 characters over". Perhaps using some kind of branching logic in the view and some javascript to change the negative number to a positive number...? I'm not really sure here, so any help would be appreciated.
views/shared/_micropost_form.html.haml
...
%span
- [[ if .countdown value < 0 ]]
.remaining= t('.characters_over',
count: [[positive .countdown value]]).html_safe
- [[ else ]]
.remaining= t('.characters_remaining', count: [[.countdown value]]).html_safe
.countdown
...
config/locales/en.yml
...
micropost_form:
...
characters_remaining:
one: " character remaining."
other: " characters remaining."
characters_over:
one: " character over."
other: " characters over."
See Question&Answers more detail:
os