Встроенное редактирование с помощью Rails gem 'best_in_place' - ошибка: новые строки теряются после редактирования на textarea
Я использую best_in_place gem, чтобы сделать некоторое встроенное редактирование в приложении Rails.
Одно из свойств моего объекта имеет тип text
, и я хочу, чтобы он редактировался в текстовой области, поэтому я сделал это:
<%= best_in_place @myobject, :description, :type => :textarea %>
Он работает, но когда он не редактируется, все возвраты (\n) удаляются.
Я попытался использовать simple_format, добавив :display_with => :simple_format
к параметрам, переданным в best_in_place:
<%= best_in_place @myobject, :description, :type => :textarea, :display_with => :simple_format %>
При отсутствии редактирования новые строки отображаются в соответствии с ожиданиями. Но щелчок, чтобы войти в редакцию, сломан, и новая черта добавлена выше. Нажатие на него отображает текстовое поле, но оно пустое, а введенный там текст не сохраняется обратно к моему объекту.
Содержимое, сохраненное в моем свойстве, - это просто текст, он не содержит html.
Эта проблема (и исправление), казалось, была связана с моей проблемой: https://github.com/bernat/best_in_place/pull/111
Однако при применении патча (вручную, в файле .../gems/best_in_place-1.0.6/spec/spec_helper.rb
) у меня все еще есть та же проблема.
Ответы
Ответ 1
У меня была такая же проблема, и я решил ее привязать к событию "ajax: success", как описано в best_in_place documentation и преобразовании нового строк до <br />
.
$('.best_in_place').bind('ajax:success', function(){ this.innerHTML = this.innerHTML.replace(/\n/g, '<br />') });
Вы также можете использовать легкий язык разметки, например, текстиль или уценку вместо простых разрывов строк. Javascript-конвертеры для них можно найти здесь (текстиль) и здесь (уценка).
Я пошел с Textile, так как я мог просто использовать метод textilize в опции best_in_place display_with.
Обновленный javascript:
$('.best_in_place').bind('ajax:success', function(){ $(this).JQtextile('textile', this.innerHTML) });
Кроме того, если вы хотите только этого поведения в текстовых областях best_in_place, вы можете проверить атрибут типа данных:
$('.best_in_place').bind('ajax:success', function(){
if ($(this).attr('data-type') == 'textarea')
$(this).JQtextile('textile', this.innerHTML)
});
Наконец, сопоставьте конверсию со стороны сервера:
:display_with => lambda { |v| textilize(v).html_safe } // the RedCloth gem may be required.
Ответ 2
Нашел полурабочее решение.
В show.html.erb
:
<%= best_in_place @myobject, :description, :type => :textarea, :display_as => 'description_format' %>
и в myobject.rb
:
def description_format
self.description.gsub(/\n/, "<br>")
end
Работает так, как ожидалось. Почти.
Единственная оставшаяся проблема: когда вы редактируете текст, после того, как вы не сфокусировались на текстовом поле, новые строки снова теряются. Если вы обновите страницу, она будет отображаться правильно.
Ответ 3
Если \n
заменяется на <br>
, и пользователь решает сделать больше изменений, пользователь увидит весь текст только на одной строке, что затруднит чтение и редактирование.
Основываясь на ответах выше, я сделал это решение, которое удаляет любой \r
после успеха.
$('.best_in_place').bind('ajax:success', function(){
if ($(this).attr('data-type') == 'textarea') {
this.innerHTML = this.innerHTML.replace(/\r/g, '')
}
});
Это гарантирует, что никакие дополнительные строки не отображаются. Преимущество этого решения состоит в том, что если пользователь снова захочет редактировать поле, все будет показано как раньше.
Ответ 4
Я думаю, что ответы здесь все работают. Это еще одна альтернатива. Вы можете добавить поле best_in_place между тегом <pre>
и позаботиться о добавлении строк. Конечно, потребуется некоторое форматирование и изменение стиля, но оно легко решает проблему.
Ответ 5
В ответ на вопрос ниже о форматировании строки теряется после обновления. После некоторых экспериментов я получил это, чтобы работать. Это пример поля, называемого "комментарий", который используется как текстовое поле и хранится как текст типа в базе данных.
В форме:
div class: "single-spacing", id: "comment_div" do
best_in_place coursedate, :comment, as: :textarea, url: [:admin,coursedate], ok_button: "Uppdatera", cancel_button: "Cancel", class: "editable",
:display_with => lambda { |c| simple_format(c.gsub("<br />", ""), {}, sanitize: false) }
end
В css:
.single-spacing {
ul br {
display: none;
}
ol br {
display: none;
}
div br {
display: none;
}
h3 {
border-bottom: 1px dotted #e8e8e8;
padding-bottom: 15px;
}
blockquote {
border-color: #a7c2d9;
p {
font-size: 14px;
color: #777777;
line-height: 1.5;
}
}
}
CoffeeScript:
# refresh textarea bip on coursedate when edited to reload line breaks after update
$('#comment_div').bind 'ajax:success', ->
$('#comment_div').load(document.URL + ' #comment_div');
return
Ответ 6
Это помогло мне.
$('.best_in_place').bind 'ajax:success', ->
content = $(this).text().replace(/\n/g, "<br>")
$(this).html(content)
или JQuery
$('.best_in_place').bind('ajax:success', function(){
content = $(this).text().replace(/\n/g, "<br>")
$(this).html(content)
});