Last active
November 14, 2024 14:26
-
-
Save lawso017/44df47968be36222b874b8c4d94b779b to your computer and use it in GitHub Desktop.
@mentions with trix-editor and selectize.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
window.addEventListener "trix-initialize", (e) => | |
Utility.TrixMentions.prepare($(e.target)) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Filter for use with https://github.com/jch/html-pipeline | |
# to extract mentioned user_ids | |
module HTML | |
class Pipeline | |
class TrixMentionFilter < Filter | |
attr_reader :mentioned_user_ids | |
def initialize(doc, context = nil, result = nil) | |
super doc, context, result | |
@mentioned_user_ids = [] | |
end | |
def call | |
process_attachments! do |attachment| | |
@mentioned_user_ids << attachment["user-id"].to_i | |
end | |
doc | |
end | |
def process_attachments! | |
doc.css("[data-trix-attachment]").each do |attachment_node| | |
attachment = JSON.parse(attachment_node.attribute('data-trix-attachment')) | |
next unless attachment["attachment-type"] == "trix-mention" | |
yield attachment | |
end | |
end | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
window.Utility ||= {} | |
class Utility.TrixMentions | |
MENTIONS_PATH = "mentions-path" | |
MENTIONS_DIV_ID = "#trix-mentions-" | |
MENTIONS_INPUT_ID = MENTIONS_DIV_ID + "input-" | |
@prepare: ($trix) -> | |
mentionsDivForTrix = ($trix) -> | |
$(MENTIONS_DIV_ID + $trix.attr('trix-id')) | |
mentionsInputForTrix = ($trix) -> | |
$(MENTIONS_INPUT_ID + $trix.attr('trix-id')) | |
mentionsSelectizeForTrix = ($trix) -> | |
mentionsInputForTrix($trix).next('.selectize-control') | |
mentionsSelectizeDropdownForTrix = ($trix) -> | |
mentionsInputForTrix($trix).next('.selectize-dropdown') | |
createMentionsDivForTrix = ($trix) -> | |
$trix.after("<trix-mentions id='trix-mentions-"+ $trix.attr('trix-id') + "'><input id='trix-mentions-input-" + $trix.attr('trix-id') + "'></input></trix-mentions>") | |
initializeMentionsSelectize = ($trix) -> | |
$.getJSON $trix.data(MENTIONS_PATH), (result) -> | |
mentionsInputForTrix($trix).selectize | |
create: false | |
valueField: 'id' | |
labelField: 'name' | |
searchField: 'name' | |
sortField: 'name' | |
options: result.data | |
selectOnTab: true | |
onInitialize: -> | |
@.disable() | |
mentionsSelectizeForTrix($trix).css('left', -1000) | |
onItemAdd: (value, $item) -> | |
embed = "<span class='trix-mention'>@" + $item.text() + "</span>" | |
attachment = new Trix.Attachment | |
content: embed | |
'attachment-type': 'trix-mention' | |
'user-id': $item.data('value') | |
$trix[0].editor.setSelectedRange([$trix.data('last-position') - 1, $trix.data('last-position')]) | |
$trix[0].editor.deleteInDirection('forward') | |
$trix[0].editor.insertAttachment attachment | |
mentionsDivForTrix($trix).hide() | |
onBlur: -> | |
mentionsDivForTrix($trix).hide() | |
@.disable() | |
mentionsSelectizeForTrix($trix).css('left', -1000) | |
$trix.focus() | |
if @.items.length == 0 | |
$trix[0].editor.setSelectedRange([$trix.data('last-position') - 1, $trix.data('last-position')]) | |
$trix[0].editor.deleteInDirection('forward') | |
onDropdownClose: -> | |
mentionsDivForTrix($trix).hide() | |
onDropdownOpen: ($dropdown) -> | |
rect = $trix[0].editor.getClientRectAtPosition($trix[0].editor.getPosition()) | |
if rect != undefined | |
$dropdown.css('top', 34) | |
if rect.left + 200 > $trix.offset().left + $trix.width() | |
$dropdown.css('left', $trix.offset().left + $trix.width() - (rect.left + 210)) | |
onType: (str) -> | |
rect = $trix[0].editor.getClientRectAtPosition($trix[0].editor.getPosition()) | |
if rect.left + 200 > $trix.offset().left + $trix.width() | |
mentionsSelectizeDropdownForTrix($trix).css('left', $trix.offset().left + $trix.width() - (rect.left + 210)) | |
openMentionsSelectize = ($trix, editor) -> | |
$trix.data 'last-position', editor.getPosition() | |
mentionsInput = mentionsInputForTrix($trix) | |
mentionsSelectize = mentionsSelectizeForTrix($trix) | |
rect = editor.getClientRectAtPosition(editor.getPosition()) | |
mentionsSelectize.css('left', rect.left - 10) | |
mentionsSelectize.css('top', rect.top - 4) | |
mentionsInput[0].selectize.clear() | |
mentionsInput[0].selectize.enable() | |
mentionsDivForTrix($trix).show() | |
mentionsInput[0].selectize.focus() | |
if $trix.data(MENTIONS_PATH).length > 0 | |
createMentionsDivForTrix($trix) | |
initializeMentionsSelectize($trix) | |
$trix.on 'trix-change', -> | |
editor = @.editor | |
char = editor.getDocument().toString().charAt(editor.getPosition() - 1) | |
openMentionsSelectize($(@), editor) if char == '@' |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[data-trix-attachment] { | |
display: inline-block; | |
} | |
span.trix-mention + figcaption { | |
display: none; | |
} | |
trix-mentions { | |
.selectize-control { | |
position: fixed | |
} | |
.selectize-input { | |
border: none !important; | |
background: none !important; | |
box-shadow: none !important; | |
} | |
.selectize-control, .selectize-dropdown { | |
width: 200px !important; | |
z-index: 9999; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@blimey85, the MENTIONS_PATH constant shouldn't need to be changed in your implementation. It's just defined as a constant to prevent typos in the code... we use the defined value "mentions-path" to identify the data attribute containing the path in the control.
In your case, you just need to ensure that your trix element has the data attribute:
defined.