backdrop-contrib / fast_token_browser

An improved user interface for Backdrop CMS's Token browser
https://backdropcms.org/project/fast_token_browser
GNU General Public License v2.0
1 stars 4 forks source link

Insert token at cursor or over selection rather than at end #14

Closed yorkshire-pudding closed 2 months ago

yorkshire-pudding commented 1 year ago

In this ticket which is about replacing the core token browser with Fast Token Browser, @klonos said:

Not sure whether the way the tokens are being inserted in FTB is ideal 🤔 ...the token seems to always be appended to the end of the existing text in the target text field/area, which makes it really cumbersome and annoying when the intention is to add things in the middle or start of the text.

yorkshire-pudding commented 1 year ago

Core does this here:

Backdrop.behaviors.tokenInsert ```js Backdrop.behaviors.tokenInsert = { attach: function (context, settings) { // Keep track of which textfield was last selected/focused. $(context).find('textarea, input[type="text"]').focus(function() { Backdrop.settings.tokenFocusedField = this; }); $(context).find('.token-click-insert .token-key').once('token-click-insert', function() { var newThis = $('' + $(this).html() + '').click(function(){ if (typeof Backdrop.settings.tokenFocusedField == 'undefined') { alert(Backdrop.t('First click a text field into which the token should be inserted.')); } else { var myField = Backdrop.settings.tokenFocusedField; var myValue = $(this).text(); // IE support. if (document.selection) { myField.focus(); var sel = document.selection.createRange(); sel.text = myValue; } // Mozilla/Webkit. else if (myField.selectionStart || myField.selectionStart == '0') { var startPos = myField.selectionStart; var endPos = myField.selectionEnd; myField.value = myField.value.substring(0, startPos) + myValue + myField.value.substring(endPos, myField.value.length); } // Otherwise just tack to the end. else { myField.value += myValue; } } return false; }); $(this).html(newThis); }); var more = '▸ ' + Backdrop.t('more'); var less = '▾ ' + Backdrop.t('less'); var $link = $('' + more + ' '); var toggleDescription = function() { if ($(this).toggleClass('open').hasClass('open')) { $(this).html(less).siblings('.token-description').css('display', 'block'); } else { $(this).html(more).siblings('.token-description').css('display', 'none'); } return false; } $(context).find('.token-description').each(function() { var $moreLink = $link.clone(); $moreLink.click(toggleDescription); $(this).css('display', 'none').before(' ').before($moreLink); }); } }; ```

Fast Token Browser currently does this here:

function insert(event) ```js function insert(event) { var $input = $(event.target); if (window.selectedToken) { $input.val($input.val() + window.selectedToken.text()); window.selectedToken.removeClass('selected-token'); window.selectedToken.removeAttr('aria-selected'); window.selectedToken = null; } } ```

It would be better to keep as a javascript to avoid re-writing the rest or having inconsistent methods

argiepiano commented 2 months ago

PR #17 submitted.

Basically, this mimics core's token browser's behavior, but keeps some of the behaviors from this module:

yorkshire-pudding commented 2 months ago

@argiepiano - WOW!!! This works brilliantly. Thank you so much.