Ответ 1
Я думаю, мое решение, размещенное здесь в формате SO, теперь немного отличается от вашего, что я могу смиренно разместить его в качестве ответа.
Это упражнение было немного сложным. Понял, что я опубликую свое решение, чтобы узнать, кто-то сделал это по-другому или кто-нибудь, кто знает лучший способ.
Я не уверен в передовом опыте использования Asset Pipline.. например, правильный порядок, чтобы поместить вещи в файл манифеста application.js или когда нужно поместить вещи в lib против приложения. Я просто поставил следующее в lib, чтобы попытаться заставить его работать.
Из Michael Hartl Rails Tutorial 2nd ed Глава 10, Упражнение 7:
(сложный) Добавьте отображение JavaScript на главную страницу, чтобы считать от 140 символов.
Во-первых, я прочитал этот пост о jQuery Twitter-подобных обратных отсчетах, который предоставил код для этого.
Затем я обновил приложение /views/shared/ _micropost_form.html.erb, чтобы выглядеть так:
<%= form_for(@micropost) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field">
<%= f.text_area :content, placeholder: "Compose new micropost..." %>
</div>
<%= f.submit "Post", class: "btn btn-large btn-primary" %>
<span class="countdown"></span>
<% end %>
Затем я создал каталог javascripts в lib и добавил файл
Lib/активы/JavaScripts/microposts.js
function updateCountdown() {
// 140 is the max message length
var remaining = 140 - jQuery('#micropost_content').val().length;
jQuery('.countdown').text(remaining + ' characters remaining');
}
jQuery(document).ready(function($) {
updateCountdown();
$('#micropost_content').change(updateCountdown);
$('#micropost_content').keyup(updateCountdown);
});
Наконец, я добавил крошечный бит CSS
Приложение/активы/таблицы стилей /custom.css.scss
/* micropost jQuery countdown */
.countdown {
display: inline;
padding-left: 30px;
color: $grayLight;
}
Наконец, добавьте директиву в app/assets/javascripts/application.js
//= require jquery
//= require jquery_ujs
//= require bootstrap
//= require microposts
//= require_tree .
ЗАКЛЮЧИТЕЛЬНЫЙ РЕЗУЛЬТАТ выглядит так http://grab.by/dbC6
Вопрос:
Было бы неправильно помещать строки манифеста после //= require_tree .
Например, это работает, но я не уверен, какая разница, или добавив строку над деревом.
//= require jquery
//= require jquery_ujs
//= require bootstrap
//= require_tree .
//= require microposts
Я думаю, мое решение, размещенное здесь в формате SO, теперь немного отличается от вашего, что я могу смиренно разместить его в качестве ответа.
Вы можете упростить его с помощью CoffeeScript:
/app/assets/javascripts/microposts.js.coffee
updateCountdown = -> remaining = 140 - jQuery("#micropost_content").val().length jQuery(".countdown").text remaining + " characters remaining" jQuery -> updateCountdown() $("#micropost_content").change updateCountdown $("#micropost_content").keyup updateCountdown
И как упоминалось jonyamo, вам не нужно прикасаться к application.js, поскольку //= require_tree .
уже выполняет трюк.
Я не знаю почему, но это решение работает только для меня, используя кофе script. Я попытался реализовать его с помощью javascript, но он каким-то образом ничего не отображал: ни обратный отсчет, ни фиксированная часть текста "оставшиеся символы".
Итак, вот что я сделал.
Шаг 1: создайте файл app/javascripts/microposts.js.coffee
updateCountdown = ->
remaining = 140 - jQuery("#micropost_content").val().length
jQuery(".countdown").text remaining + " characters remaining"
jQuery ->
updateCountdown()
$("#micropost_content").change updateCountdown
$("#micropost_content").keyup updateCountdown
NB: будучи помещенным в папку app/javascripts, мне не нужно было обновлять файл application.js.
Шаг 2: обновите часть _micropost_form.html.erb:
<%= form_for(@micropost) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field">
<%= f.text_area :content, placeholder: "Compose new micropost..." %>
</div>
<%= f.submit "Post", class: "btn btn-large btn-primary" %>
<span class="countdown"></span>
<% end %>
шаг 3: реализовать бит css в файле custom_css.css.scss
/* micropost jQuery countdown */
.countdown {
display: inline;
padding-left: 10px;
color: $grayLight;
}
Шаг 4: наслаждайтесь результатом и будьте счастливы, что все это получится:)
My microposts.js.coffee
использует метод jQuery . css, чтобы изменить цвет оставшихся символов в зависимости от значения переменной remaining
чтобы более точно отразить поведение twitter
updateCountdown = ->
remaining = 140 - jQuery("#micropost_content").val().length
jQuery(".countdown").text remaining + " characters remaining"
jQuery(".countdown").css "color", (if (140 >= remaining >= 21) then "gray")
jQuery(".countdown").css "color", (if (21 > remaining >= 11) then "black")
jQuery(".countdown").css "color", (if (11 > remaining) then "red")
jQuery ->
updateCountdown()
$("#micropost_content").change updateCountdown
$("#micropost_content").keyup updateCountdown
Спасибо всем, кто раньше ответил.
Я использовал код Бретта, чтобы получить это упражнение в Rails Tutorial, хотя у меня небольшие изменения. У меня возникли проблемы с текстом, исчезающим из элемента .countdown, когда я перешел на другую страницу, а затем вернулся к Home. С некоторыми незначительными исследованиями и помощь от другого ответа на SO я понял, что причиной является Turbolinks. Мое изменение кода Бретта, привязка к событию page:change
вместо ready
, приведено ниже. Надеюсь, это поможет некоторым другим людям.
function updateCountdown() {
// 140 is the max message length
var remaining = 140 - jQuery('#micropost_content').val().length;
jQuery('.countdown').text(remaining + ' characters remaining');
}
function micropostChange() {
$('#micropost_content').change(updateCountdown);
}
function micropostKeyup() {
$('#micropost_content').keyup(updateCountdown);
}
jQuery(document).ready(function($) {
updateCountdown();
micropostChange();
micropostKeyup();
jQuery(document).on('page:change', function($) {
updateCountdown();
micropostChange();
micropostKeyup();
});
});
Здесь моя версия coffeescript, основанная на решении Adriano. Это игнорирует пробелы, не включает добавление пустых divs в представление, а также добавляет класс ошибки, когда вы попадаете в минус номера.
updateCountdown = ->
text = jQuery('#micropost_content').val()
text = text.replace(/\s/g, '');
remaining = 140 - text.length
jQuery('.countdown').text remaining + ' characters remaining'
jQuery('.countdown').addClass 'alert alert-error' if remaining < 0
jQuery('.countdown').removeClass 'alert alert-error' if remaining > 0
jQuery(document).ready ->
jQuery('#new_micropost').append '<span class="countdown">140 characters remaining</span>'
jQuery('#micropost_content').change updateCountdown
jQuery('#micropost_content').keyup updateCountdown
return
Чтобы избежать минус-символа, я добавил этот предел в _micropost_form.html.erb, поэтому он останавливает вас на 140 символов:
<%= f.text_area :content, maxlength:140, placeholder: "Compose new micropost..." %>