我尝试使用信息here作为基础并在StackOverflow回答here和here的帮助下,使用Rails教程(第10章,练习7)中的微博字符倒计时。
在屏幕上,它看起来像this,当你接近字符限制时,文本逐渐变红,一旦微博超过限制,Post按钮就会禁用,完成like so。
目前的实施方式如下:
视图/共享/ _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"
资产/ Javascript角/ 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
资产/样式表/ 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;
}
配置/区域设置/ en.yml
en:
...
shared:
...
micropost_form:
compose_micropost: "Compose new micropost..."
post: "Post"
characters_remaining: " characters remaining."
从这里开始,我有两个问题:
首先,如果可能的话,我希望能够对“剩余字符”字符串进行适当的复数化。也许是这样的事情:
视图/共享/ _micropost_form.html.haml
...
%span
.remaining= t('.characters_remaining', count: [[.countdown value]]).html_safe
.countdown
...
配置/区域设置/ en.yml
...
micropost_form:
...
characters_remaining:
one: " character remaining."
other: " characters remaining."
但是,我不知道如何在.countdown
div中检索值,我可以将其传递给count
参数。我怎么能这样做?
假设第一个问题可以解决,我也想摆脱减号字符,而是将“-2个字符剩余”更改为“2个字符以上”。也许在视图中使用某种分支逻辑和一些javascript来将负数更改为正数...?我在这里不太确定,所以任何帮助都会受到赞赏。
视图/共享/ _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
...
配置/区域设置/ en.yml
...
micropost_form:
...
characters_remaining:
one: " character remaining."
other: " characters remaining."
characters_over:
one: " character over."
other: " characters over."
答案 0 :(得分:2)
我也正在阅读本教程并发现这篇文章,虽然我喜欢你添加的css使这看起来一致(我已经把它作为我自己使用:))我认为你的解决方案过于复杂。对我来说,这只是两个变化:js脚本并将脚本添加到我的视图中。
我的JS文件:character_countdown.js
function updateCountdown() {
// 140 characters max
var left = 140 - jQuery('.micropost_text_area').val().length;
if(left == 1) {
var charactersLeft = ' character left.'
}
else if(left < 0){
var charactersLeft = ' characters too many.'
}
else{
var charactersLeft = ' characters left.'
}
jQuery('.countdown').text(Math.abs(left) + charactersLeft);
}
jQuery(document).ready(function($) {
updateCountdown();
$('.micropost_text_area').change(updateCountdown);
$('.micropost_text_area').keyup(updateCountdown);
});
这是我将其添加到视图中的地方
<script src="app/assets/javascripts/character_countdown.js"></script>
<%= form_for(@micropost) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
请让我知道你的想法:)
答案 1 :(得分:1)
我已经找到了解决我的问题(复数化和摆脱所有语言环境中的减号)的解决方案,我觉得这很好,所以我会在这里详细解释,希望有人会觉得它很有用。
如果您希望在深入研究细节之前了解它的样子,可以在my Sample App deployment at Heroku自行试用。
此解决方案使用i18n-js gem,它是“在Javascript上提供Rails I18n翻译的小型库”。宝石很棒,但遗憾的是我并没有像我想的那样和Heroku玩得很好,doesn't seem like it will for the foreseeable future。因此,需要更改以下配置:
<强>配置/ application.rb中强>
# ...
config.assets.initialize_on_precompile = true
这意味着在每次部署到Heroku之前,需要运行rake assets:precompile
,并且一旦确认部署成功,请运行rake assets:clean
以再次开始开发资产。如果这太烦人了,你需要另一个解决方案。
更新:
如果你在Heroku环境中启用
user-env-compile
,你可以让Heroku预先编译你的资产并仍然使用i18n-js gem。有关如何执行此操作的说明是here,我认为只要Heroku支持该功能,它就值得一试。
<强>的Gemfile 强>
# ...
gem 'i18n-js', '2.1.2'
应用/资产/ Javascript角/ application.js中强>
// ...
//= require i18n
//= require i18n/translations
由于上面的Heroku设置,此时我需要运行
$ rake i18n:js:setup
将i18n-js.yml复制到 config 文件夹。
应用/视图/布局/ application.html.haml 强>
%html
%head
# ...
= render 'layouts/i18n_js'
应用/视图/布局/ _i18n_js.html.haml 强>
:javascript
I18n.defaultLocale = "#{I18n.default_locale}";
I18n.locale = "#{I18n.locale}";
应用/视图/共享/ _micropost_form.html.haml 强>
# ...
.field= f.text_area :content, placeholder: t('.compose_micropost')
%span.countdown
= f.submit t('.post'), class: "btn btn-large btn-primary"
应用/资产/样式表/ custom.css.scss 强>
/* Micropost character countdown */
.countdown {
display: inline;
color: $grayLight;
float: right;
}
// ...
app / assets / javascripts / microposts.js.coffee
(我对javascript / coffeescript不太好,所以这里有改进/重构的空间)
updateCountdownString = (remaining) ->
if remaining > 1 or remaining is 0
$(".countdown").text I18n.t('shared.micropost_form.characters_remaining.other',
count: remaining)
else if remaining is 1
$(".countdown").text I18n.t('shared.micropost_form.characters_remaining.one',
count: remaining)
else if remaining is -1
$(".countdown").text I18n.t('shared.micropost_form.characters_over.one',
count: -remaining)
else
$(".countdown").text I18n.t('shared.micropost_form.characters_over.other',
count: -remaining)
takeFromCollection = (collection, className) ->
(collection.filter (attr) -> attr is className).toString()
updateCountdownAttributes = (remaining) ->
toRemove = ["nearlimit", "almostlimit", "overlimit"]
if remaining < 20
toAdd = takeFromCollection(toRemove, "nearlimit")
if remaining < 11
toAdd = takeFromCollection(toRemove, "almostlimit")
if remaining < 0
toAdd = takeFromCollection(toRemove, "overlimit")
if toAdd isnt null
for attr in toRemove
$(".countdown").removeClass attr
$(".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
updateCountdownString(remaining)
updateCountdownAttributes(remaining)
$(document).ready ->
$(".countdown").text I18n.t('shared.micropost_form.characters_remaining.other',
count: 140)
$("#micropost_content").on("change keyup keydown keypress paste drop",
updateCountdown)
config / locales / en.yml (其他语言环境在相同样式中具有相同的键)
shared:
# ...
micropost_form:
characters_remaining:
one: "%{count} character remaining."
other: "%{count} characters remaining."
characters_over:
one: "%{count} character over limit."
other: "%{count} characters over limit."