Asked Mar 4th, 4:33 PM 107 0 1
  • 107 0 1
0

Đổi xuống dòng thành thẻ <br/> và ngược lại trong Rails

Share
  • 107 0 1

Đây là file seed của mình

Song.create(
    name: '千本桜',
    lyric: '千本桜 夜ニ紛レ<br/>君ノ声モ届カナイヨ<br/>青藍(せいらん)の空 遥か彼方<br/>その光線銃で打ち抜いて<br/><br/>大胆不敵にハイカラ革命<br/>磊々落々(らいらいらくらく)反戦国家<br/>日の丸印の二輪車転がし<br/>悪霊退散 ICBM<br/><br/>環状線を走り抜けて 東奔西走なんのその<br/>少年少女戦国無双<br/>浮世の随(まにま)に<br/><br/>千本桜 夜ニ紛レ<br/>君ノ声モ届カナイヨ<br/>此処は宴 鋼の檻 その断頭台で見下ろして<br/><br/>三千世界 常世之闇(とこよのやみ)<br/>嘆ク唄モ聞コエナイヨ<br/>青藍(せいらん)の空 遥か彼方<br/>その光線銃で打ち抜いて<br/><br/>百戦錬磨の見た目は将校<br/>いったりきたりの花魁(おいらん)道中<br/>アイツもコイツも皆で集まれ<br/>聖者の行進 わんっ つー さん しっ<br/><br/>禅定門(ぜんじょうもん)を潜り抜けて<br/>安楽浄土厄払い<br/>きっと終幕(さいご)は大団円 拍手の合間に<br/><br/>千本桜 夜ニ紛レ<br/>君ノ声モ届カナイヨ<br/>此処は宴 鋼の檻 その断頭台で見下ろして<br/><br/>三千世界 常世之闇(とこよのやみ)<br/>嘆ク唄モ聞コエナイヨ<br/>希望の丘 遥か彼方 その閃光弾を打ち上げろ<br/><br/>環状線を走り抜けて<br/>東奔西走なんのその<br/>少年少女戦国無双 浮世の随(まにま)に<br/><br/>千本桜 夜ニ紛レ<br/>君ノ声モ届カナイヨ<br/>此処は宴 鋼の檻<br/>その断頭台を飛び降りて<br/><br/>千本桜 夜ニ紛レ<br/>君が歌い僕は踊る<br/>此処は宴 鋼の檻<br/>さあ光線銃を撃ちまくれ'
)

Mình đã sử dụng html_safe với simple_format để đổi nó ra dạng sau:

Tuy nhiên khi về "edit" thì value tại textarea sẽ trả về chuỗi như trên. Mình đang muốn khi bấm vào edit thì trong textarea thì text trong ấy chuyển dạng như trong ảnh. Sau đó bấm "Update song" thì cả đoạn paragraph kia chuyển thành chuỗi như trong seed.

Tại songs_helper.rb mình đã chuẩn bị như sau:

module SongsHelper

    def newline_to_br(text)
        text.to_s.gsub(/\n/, '<br/>').html_safe
    end

    def br_to_newline(text)
        text.to_s.gsub('<br/>', /\n/)
    end
end

Đây là form edit của mình

<h1>Editing Song</h1>

<%= form_for @song, 
    url: { controller: "songs", action: "update", id: @song.id }, 
    method: :put do |f| %>
    
    <%= f.label :name, "Song name:" %>
    <%= f.text_field :name, :required => true %>

    <%= f.label :lyric, "Lyric:" %>
    <%= f.text_area :lyric, :required => true %>

    <br/>
    <%= f.submit "Update song"%>
<% end %>

<%= link_to 'Show', @song %> |
<%= link_to 'Back', songs_path %>

Làm sao để có thể dùng mixin cho field để có thể thực hiện được ý định trên của mình? Xin mọi người hãy giúp đỡ 🙇

Đây là link git: https://github.com/BlazingRockStorm/nihon-lyrics

Update:

Theo như gợi ý của bạn Phạm Anh Tuấn thì mình đã đổi như sau

# edit.html.erb
<%= f.text_area :lyric, :value => @song.lyric.gsub!(%r~<br\s*\/?>~, "\n"), :required => true %>

Nhưng dù gì thì mình vẫn muốn đưa vào Helper nên để 1 code như sau:

# songs_helper.rb
module SongsHelper

    def newline_to_br(text)
        text.to_s.gsub(/\n/, '<br/>').html_safe
    end

    def br_to_newline(text)
        text.to_s.gsub!(%r~<br\s*\/?>~, "\n")
    end
end

Và ở view của mình

# edit.html.erb
<%= f.text_area :lyric, :value => br_to_newline(@song.lyric), :required => true %>

Và đây là controller

def create
    @song = Song.new(song_params)

    respond_to do |format|
      if @song.save
        format.html { redirect_to @song, notice: 'Song was successfully created.' }
        format.json { render :show, status: :created, location: @song }
      else
        format.html { render :new }
        format.json { render json: @song.errors, status: :unprocessable_entity }
      end
    end
  end
.....
private
   .....
    # Never trust parameters from the scary internet, only allow the white list through.
    def song_params
      params.require(:song).permit(:name, newline_to_br(:lyric)) # xử lý đổi từ đoạn văn có xuống dòng thành html ở đây
    end

Tuy nhiên hiện xảy ra lỗi 😦 Mọi người giúp đỡ tiếp bước này với

Phạm Anh Tuấn @tuanbacyen
Mar 5th, 1:02 AM

Bạn thử thay /\n/ thành \r\n xem bạn.

0
| Reply
Share
Hoàng Đức Quân @devil_boom_129
Mar 5th, 2:02 AM

ý mình ko phải là đổi, mà là dùng mấy hàm trên để xử lý đoạn trong textarea cơ

0
| Reply
Share
Nguyễn Thu Đức Trung @15thofaugust
Mar 5th, 2:40 AM

Lúc hiển thị đoạn lyrics trên textarea thì mình làm như vậy

<%= form_for a_testing_route do |f| %>
   <%= f.text_area :test, value: "千本桜 夜ニ紛レ<br/>君ノ声モ届カナイヨ<br/>青藍(せいらん)".gsub!(%r~<br\s*\/?>~, "\n") %>
<% end %>

Sau đó với giá trị param truyền lên, thì đoạn text sẽ chứa các kí tự "\n" sẽ được xử lý chuyển về thẻ "br" trên server

Screenshot from 2019-03-05 09-39-53.png

Không biết làm vầy có đúng với ý bạn không 😕

+1
| Reply
Share
Hoàng Đức Quân @devil_boom_129
Mar 5th, 2:42 AM

@15thofaugust đúng rồi

0
| Reply
Share
Phạm Anh Tuấn @tuanbacyen
Mar 5th, 2:48 AM

@devil_boom_129 Ảnh trên là bạn đã biến nó thành html thì <br> là xuống dòng. Nhưng nếu muốn edit trong textarea thì bạn phải dùng \r\n chứ ??

0
| Reply
Share
Hoàng Đức Quân @devil_boom_129
Mar 5th, 3:00 AM

@tuanbacyen nhưng khi lưu vào database thì liệu chỗ \r\n có chuyển thành <br/> không? Bạn hiểu ý mình muốn xử lý chứ? Tức là hiển thị trên web thì là bth nhưng db là 1 chuỗi với xuống dòng thay bằng <br/>

0
| Reply
Share
Tất Đạt @dat.hedspi
Mar 5th, 3:16 AM

@devil_boom_129 sao chú không lưu vào db dạng 千本桜 夜ニ紛レ\n君ノ声モ届カナイヨ\n青藍(せいらん)の空 遥か彼方... thay vì 千本桜 夜ニ紛レ<br/>君ノ声モ届カナイヨ<br/>青藍(せいらん)の空 遥か彼方...

0
| Reply
Share
Hoàng Đức Quân @devil_boom_129
Mar 5th, 3:20 AM

@dat.hedspi xong sau in ra cũng vẫn phải. chuyển đổi \n anh ơi. Quả này là em lấy ý tưởng từ cục dữ liệu truyện Kim Dung của ông thầy dạy Thực hành OOP

0
| Reply
Share
Tất Đạt @dat.hedspi
Mar 5th, 3:29 AM

@devil_boom_129 sao ko lưu là \n rồi dùng css để mà đẩy nó hiển thị như em muốn, đỡ phải viết helper ko?

0
| Reply
Share
Hoàng Đức Quân @devil_boom_129
Mar 5th, 4:08 AM

@dat.hedspi thử tăng độ khó tí ạ. với lại nếu giờ lúc edit em xuống dòng thì lưu vào db cũng xuống dòng nốt ấy ạ. em thì thà chọn là dạng chuỗi loằng ngoằng hơn cả đoạn dài

0
| Reply
Share
Hoàng Đức Quân @devil_boom_129
Mar 5th, 4:11 AM

@dat.hedspi còn hiển thị ở show thì html_safe với simple_format thoải mái. helper là em dùng với form

0
| Reply
Share
Tất Đạt @dat.hedspi
Mar 5th, 4:28 AM

@devil_boom_129 ừ thì anh đang hỏi là sao ko làm cách dễ, chú cứ ném string dạng \n ra rồi ở view làm css cho cái đoạn text đấy là white-space: pre thì nó cũng hiển thị dạng xuống dòng thôi mà. Edit thế nào đi nữa có dấu xuống dòng là trong db nó cũng lưu vào là \n mà

0
| Reply
Share
Phạm Anh Tuấn @tuanbacyen
Mar 5th, 6:10 AM

@devil_boom_129 Mình chưa hiểu ý bạn lắm. Nhưng khi bạn lưu trong DB dạng \r\n thì mặc định khi edit hay làm gì đó với textarea thì nó tự động nhận xuống dọng. Đây là sự không đồng bộ của html khi xuống dòng phải dùng
. Nên nếu bạn đang lưu dạng <br> trong DB mà muốn hiển thị lên textarea mà có xuống dòng thì thực hiện một bước convert từ <br> xang \n bằng cách xet cho value của trường text đó thôi.🤔🤔

0
| Reply
Share
Hoàng Đức Quân @devil_boom_129
Mar 5th, 7:13 AM
Hoàng Đức Quân @devil_boom_129
Mar 5th, 7:39 AM

@tuanbacyen Theo như gợi ý của bạn thì mình đã đổi như sau

# edit.html.erb
<%= f.text_area :lyric, :value => @song.lyric.gsub!(%r~<br\s*\/?>~, "\n"), :required => true %>

Nhưng dù gì thì mình vẫn muốn đưa vào Helper nên để 1 code như sau:

# songs_helper.rb
module SongsHelper

    ......

    def br_to_newline(text)
        text.to_s.gsub!(%r~<br\s*\/?>~, "\n")
    end
end

Và ở view của mình

# edit.html.erb
<%= f.text_area :lyric, :value => br_to_newline(@song.lyric), :required => true %>

Đây là ý mình muốn làm. Vấn đề là chỗ từ :value ra là có vẻ chưa đúng lắm

Update: nó ra đúng như mình mong muốn, vấn đề là giờ làm thế nào để sau khi bấm edit, db của mình lưu vào là <br/>, không phải newline

0
| Reply
Share
Hoàng Đức Quân @devil_boom_129
Mar 5th, 9:17 AM

@tuanbacyen

def create
    @song = Song.new(song_params)

    respond_to do |format|
      if @song.save
        format.html { redirect_to @song, notice: 'Song was successfully created.' }
        format.json { render :show, status: :created, location: @song }
      else
        format.html { render :new }
        format.json { render json: @song.errors, status: :unprocessable_entity }
      end
    end
  end
.....
private
   .....
    # Never trust parameters from the scary internet, only allow the white list through.
    def song_params
      params.require(:song).permit(:name, newline_to_br(:lyric)) # xử lý đổi từ đoạn văn có xuống dòng thành html ở đây
    end

Hiện mình code đoạn đổi từ newline về <br/> nhưng không hiểu sao lại lỗi trên. Helper đầy đủ của mình đây

# songs_helper.rb
module SongsHelper
    
    def newline_to_br(text)
        text.to_s.gsub(/\n/, '<br/>').html_safe
    end

    def br_to_newline(text)
        text.to_s.gsub!(%r~<br\s*\/?>~, "\n")
    end
end
0
| Reply
Share
Tất Đạt @dat.hedspi
Mar 5th, 9:29 AM
Nguyễn Thu Đức Trung @15thofaugust
Mar 6th, 2:02 AM

@devil_boom_129

b = "千本桜 夜ニ紛レ\n" + "君ノ声モ届カナイヨ\n" + "青藍(せいらん)"
=> "千本桜 夜ニ紛レ\n" + "君ノ声モ届カナイヨ\n" + "青藍(せいらん)"
b.gsub!(/(?:\n\r?|\r\n?)/, '<br>')
=> "千本桜 夜ニ紛レ<br>君ノ声モ届カナイヨ<br>青藍(せいらん)"

Bạn thử sửa lại helper như vậy xem sao. Với cả mình chưa bao giờ gọi hàm helper ở trong permit nên không rõ liệu chỗ đấy có vấn đề gì k nữa.

Edit: Mình vừa test lại thì helper của bạn chạy ok, k có vấn đề gì cả, thì có lẽ vấn đề ở đoạn params.require(:song).permit(:name, newline_to_br(:lyric))

0
| Reply
Share
Phạm Anh Tuấn @tuanbacyen
Mar 6th, 2:26 AM

@devil_boom_129 @15thofaugust Hình như bạn ý quên required vào controller nên không gọi được thì phải. Còn hàm trong hellper thì ok r.

0
| Reply
Share
Hoàng Đức Quân @devil_boom_129
Mar 6th, 3:03 AM
Hoàng Đức Quân @devil_boom_129
Mar 6th, 3:38 AM

@tuanbacyen @15thofaugust Hiện tại mình đang sửa như này

params.require(:song).permit(:name, :lyric => :lyric.gsub!(/(?:\n\r?|\r\n?)/, '<br>'))

Nhưng vẫn chưa đúng lắm

0
| Reply
Share
Phạm Anh Tuấn @tuanbacyen
Mar 6th, 4:04 AM

@devil_boom_129 Đây là bạn dùng trực tiếp gsub khi params đc gửi về. Còn ở trên là bạn gọi 1 def ở helper. 2 cái này là hoàn toàn khác nhau nhé. Bạn thử tạo def br_to_newline trong private của application controller rồi gọi bên contrller bạn dùng xem có đc ko.

0
| Reply
Share
Hoàng Đức Quân @devil_boom_129
Mar 6th, 4:07 AM

@tuanbacyen thì mình đang dùng trực tiếp gsub để thử mà. cơ mà khi báo ra vẫn lỗi

0
| Reply
Share
Tất Đạt @dat.hedspi
Mar 6th, 4:57 AM

@devil_boom_129 có 2 chỗ. Một là chú ý cái thẻ <br/> hay <br>. Hai là kiểm tra cái song_params trên controller của em đã đúng chưa. Phần thứ 2 thì anh suggest là em xử lý cái string truyền lên ở trong controller chứ ko phải ở trong permit.

0
| Reply
Share
Phạm Anh Tuấn @tuanbacyen
Mar 6th, 5:52 AM

@devil_boom_129 Trước khi dùng strong param bạn làm 1 bước tiền sử lý string như này xem đc ko ??

params[:song][:lyric] = params[:song][:lyric].gsub!(/(?:\n\r?|\r\n?)/, '<br>')
params.require(:song).permit(:name, :lyric)
+1
| Reply
Share
Hoàng Đức Quân @devil_boom_129
Mar 6th, 6:04 AM

@tuanbacyen ơn giời. đúng nguyện vọng luôn rồi. cảm ơn bạn. bạn post full giải pháp ở dưới để mình accept answer nhé

0
| Reply
Share
Hoàng Đức Quân @devil_boom_129
Mar 6th, 6:18 AM

1 ANSWERS


Answered Mar 6th, 6:27 AM
Accepted
+1

Xin cảm ơn bác @tuanbacyen đã hỗ trợ rất nhiều cho câu trả lời này

Helper được viết như sau:

module SongsHelper
    # change newline from input into br tag in database
    def newline_to_br(text)
        text.to_s.gsub!(/(?:\n\r?|\r\n?)/, '<br/>')
    end

    # change br tag in database into newline when edit
    def br_to_newline(text)
        text.to_s.gsub!(%r~<br\s*\/?>~, "\n")
    end
end

Sau khi có Helper thì tại SongsController, ta sẽ phải thêm các đoạn:

class SongsController < ApplicationController
  extend SongsHelper
  .....
  private
    include SongsHelper
    # Use callbacks to share common setup or constraints between actions.
    def set_song
      @song = Song.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def song_params
      params[:song][:lyric] = newline_to_br(params[:song][:lyric])
      params.require(:song).permit(:name, :lyric)

Và tại views/songs/edit:

  <%= f.text_area :lyric, :value => br_to_newline(@song.lyric), :required => true %>
Share
Phạm Anh Tuấn @tuanbacyen
Mar 6th, 8:35 AM

Cảm ơn bạn nhiều 😃 😍

0
| Reply
Share