Yêu cầu thg 3 4, 2019 4:33 CH 739 0 1
  • 739 0 1
0

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

Chia sẻ
  • 739 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

thg 3 5, 2019 1:02 SA

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

Avatar Hoàng Đức Quân @devil_boom_129
thg 3 5, 2019 2:02 SA

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

thg 3 5, 2019 2:40 SA

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 😕

Avatar Hoàng Đức Quân @devil_boom_129
thg 3 5, 2019 2:42 SA

@15thofaugust đúng rồi

thg 3 5, 2019 2:48 SA

@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ứ ??

Avatar Hoàng Đức Quân @devil_boom_129
thg 3 5, 2019 3:00 SA

@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/>

Avatar Tất Đạt @dat.hedspi
thg 3 5, 2019 3:16 SA

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

Avatar Hoàng Đức Quân @devil_boom_129
thg 3 5, 2019 3:20 SA

@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

Avatar Tất Đạt @dat.hedspi
thg 3 5, 2019 3:29 SA

@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?

Avatar Hoàng Đức Quân @devil_boom_129
thg 3 5, 2019 4:08 SA

@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

Avatar Hoàng Đức Quân @devil_boom_129
thg 3 5, 2019 4:11 SA

@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

Avatar Tất Đạt @dat.hedspi
thg 3 5, 2019 4:28 SA

@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à

thg 3 5, 2019 6:10 SA

@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.🤔🤔

Avatar Hoàng Đức Quân @devil_boom_129
thg 3 5, 2019 7:13 SA
Avatar Hoàng Đức Quân @devil_boom_129
thg 3 5, 2019 7:39 SA

@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

Avatar Hoàng Đức Quân @devil_boom_129
thg 3 5, 2019 9:17 SA

@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
Avatar Tất Đạt @dat.hedspi
thg 3 5, 2019 9:29 SA
thg 3 6, 2019 2:02 SA

@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))

thg 3 6, 2019 2:26 SA

@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.

Avatar Hoàng Đức Quân @devil_boom_129
thg 3 6, 2019 3:03 SA
Avatar Hoàng Đức Quân @devil_boom_129
thg 3 6, 2019 3:38 SA

@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

thg 3 6, 2019 4:04 SA

@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.

Avatar Hoàng Đức Quân @devil_boom_129
thg 3 6, 2019 4:07 SA

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

Avatar Tất Đạt @dat.hedspi
thg 3 6, 2019 4:57 SA

@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.

thg 3 6, 2019 5:52 SA

@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)
Avatar Hoàng Đức Quân @devil_boom_129
thg 3 6, 2019 6:04 SA

@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é

Avatar Hoàng Đức Quân @devil_boom_129
thg 3 6, 2019 6:18 SA

1 CÂU TRẢ LỜI


Đã trả lời thg 3 6, 2019 6:27 SA
Đã được chấp nhận
+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 %>
Chia sẻ
thg 3 6, 2019 8:35 SA

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

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí