Use the Rails highlight
helper to wrap search result matches in <mark>
tags.
Highlight the search term “comment” in a list of notifcations
Usage
Pass the search term to your controller via params (e.g. params[:search]
) and use that to filter down your results.
# app/controllers/inbox_controller.rb class InboxController < ApplicationController def index @notifications = Current.user.notifications.for_search(params[:search]) end end # app/models/notification.rb class Notification < ApplicationRecord belongs_to :recipient, class_name: "User" validates :message, presence: true def self.for_search(term) if term.present? # Implement searching however you'd like where("message ILIKE ?", "%#{term}%") else all end end end
Render the notifications and use TextHelper#highlight
on the message to emphasis the matching query.
<% @notifications.each do |notification| %> <%= link_to highlight(notification.message, params[:search]), notification %> <% end %>
You can style the <mark>
tag however you’d like.
mark { background-color: yellow; }
Options
You can pass either a string, array, or a regex as the phrase to match. Matches are case-insensitive.
highlight('Boring Rails is the best', 'rails') # => Boring <mark>Rails</mark> is the best highlight('Boring Rails is the best', /rails|best/) # => Boring <mark>Rails</mark> is the <mark>best</mark> highlight('Boring Rails is the best', ['is', 'best']) # => Boring Rails <mark>is</mark> the <mark>best</mark>
If there are no matches or you leave the phrase blank, everything still works fine.
highlight('Boring Rails is the best', 'JavaScript') # => Boring Rails is the best highlight('Boring Rails is the best', '') # nil works too # => Boring Rails is the best
You can also override the HTML markup wrapped around the matches using the highlighter
option. Use \1
to reference the match. The output is sanitized by default
highlight('Boring is best', 'best', highlight: '<b>\1</b>') # => Boring is <b>best</b> highlight('Boring is best', 'best', highlight: '<a href="tagged?q=\1">\1</a>') # => Boring is <b>best</b>
If you need to run additional code, you can pass a block to render instead.
highlight('Blog: Boring Rails', 'rails') do |match| link_to(match, public_share_path(term: match)) end # => Blog: Boring <a href="/public/share?term=Rails">Rails</a>
Additional Resources
Rails API Docs: TextHelper#highlight
Top comments (0)