FM Design
Would you like to react to this message? Create an account in a few clicks or log in to continue.

IMPORTANT

FM Design is in read-only mode, please click here for more information.

Latest topics
» Forumactif Edge - Releases
by Ange Tuteur Tue 03 Sep 2019, 11:49

» GIFActif - Giphy Button for the Editor
by Ange Tuteur Wed 08 May 2019, 17:21

» Forum Closure
by Ange Tuteur Mon 01 Jan 2018, 01:28

» Chit Chat Thread
by Valoish Sun 31 Dec 2017, 19:15

» Font/Text background color.
by Valoish Sun 31 Dec 2017, 19:11

» Forumactif Messenger - Instant Message Application for Forumotion
by Wolfuryo Sun 31 Dec 2017, 18:24

» [GAME] Count to One Million!
by brandon_g Fri 29 Dec 2017, 18:58

» Post Cards
by manikbiradar Wed 20 Dec 2017, 07:50

» [GAME] Countdown from 200,000
by Valoish Wed 13 Dec 2017, 23:22

» GeekPolice Tech Support Forums - GeekPolice.net
by Dr Jay Mon 11 Dec 2017, 19:12

» Asking about some plugin for Forumotion
by Dr Jay Mon 11 Dec 2017, 19:10

» [GAME] What are you thinking right now?
by Van-Helsing Sat 09 Dec 2017, 14:51

» Widget : Similar topics
by ranbac Wed 06 Dec 2017, 18:11

» Change the Background of the Forum and put an image and how to make prefixs?
by Clement Wed 06 Dec 2017, 15:19

» Hello from Western Australia
by SarkZKalie Wed 06 Dec 2017, 05:34

Recent Tutorials
Top posting users this month

Who is online?
In total there are 8 users online :: 0 Registered, 0 Hidden and 8 Guests :: 1 Bot

None

[ View the whole list ]


Most users ever online was 515 on Tue 14 Sep 2021, 15:24

Auto-suggest @mentions as You Type

Page 1 of 4 1, 2, 3, 4  Next

View previous topic View next topic Go down

Ange Tuteur
Ange Tuteur
Administrator
Gender : Male
Posts : 4741
Points : 12042
Reputation : 2375
Location : Pennsylvania
Language : EN, JA, FR
Browser : Browser : Brave Forum Version : Forum Version : Forumactif Edge
https://sethclydesdale.github.io/ https://twitter.com/sethc1995

PostAnge Tuteur Fri 19 Aug 2016, 12:50

This plugin for the editor auto-suggests you usernames while you're typing a @handle ( mention ). Clicking the suggestions or pressing enter will automatically complete the @handle so you can save time typing ! Plus to make the mentioning system more user-friendly this plugin auto-inserts quotes, so you don't have to worry about failing to tag anyone ever again !

Auto-suggest @mentions as You Type Fament10
Click to view demo

How does it work ?

  • Typing only the at symbol "@" in the editor will bring up a list of the recently connected users.
  • Typing "@" with a letter after the symbol such as "@a" will bring up a list of users who begin with the letter "a". As you continue typing the results will narrow down !
  • When the suggestion list pops up, you can move through the suggestions using the UP and DOWN arrow keys, pressing ENTER will auto-complete the @handle. You can also select mentions with the mouse.
  • To cancel the suggestion list simply press the SPACE bar.

This plugin is optimized for all existing forum versions, so if you like what you hear above then it's time to move on to the installation ! Wink


Note : If you've modified the memberlist_body templates this plugin may not work for you. Please leave a reply with a link to your forum if this is the case.


Installation


To install this plugin go to Admin Panel > Modules > JavaScript codes management and create a new script with the following settings.

Title : @Mention Auto-suggest
Placement : In all the pages
Paste the following code into the textarea :
Code:
!window.fa_mentionner && !/\/privmsg|\/profile\?mode=editprofile&page_profil=signature/.test(window.location.href) && $(function(){$(function(){
  var container = $('.sceditor-container')[0],
      text_editor = document.getElementById('text_editor_textarea'),
      frame,
      instance;
 
  if (container && text_editor) {
 
    frame = $('iframe', container);
    instance = $(text_editor).sceditor('instance');
 
    window.fa_mentionner = {
      suggest_delay : 100, // delay before suggestions show up (100ms)
 
      // language presets
      lang : {
        placeholder : 'Searching...',
        not_found : 'User not found'
      },
 
      // colors of the suggestion popup
      color : {
              font : '#333',
        hover_font : '#FFF',
        error_font : '#F00',
 
              background : '#FFF',
        hover_background : '#69C',
 
        border : '#CCC',
        shadow : 'rgba(0, 0, 0, 0.176)'
      },
 
      // sceditor instance and rangeHelper
      instance : instance,
      rangeHelper : instance.getRangeHelper(),
 
      // cached nodes for listening and modifications
      frame : frame[0],
      body : frame.contents().find('body')[0],
      textarea : $('textarea', container)[0],
 
      // faux textarea and suggestion list
      faux_textarea : $('<div id="faux_text_editor" />')[0], // helps us mirror the cursor position in source mode
      list : $('<div id="fa_mention_suggestions" style="position:absolute;" />')[0],
 
      // version specific selectors
      selectors : $('.bodyline')[0] ? ['a.gen[href^="/u"]', '.avatar.mini a'] :
                  document.getElementById('ipbwrapper') ? ['.membername', '.mini-avatar'] :
                  null,
 
 
      // adjusts the scroll position of the faux textarea so the caret stays in line
      adjustScroll : function() {
        fa_mentionner.faux_textarea.scrollTop = fa_mentionner.textarea.scrollTop;
      },
 
 
      // updates the content in the faux textarea
      updateFauxTextarea : function(active, key) {
        if (key == 16) { // 16 = SHIFT
          return; // return when specific keys are pressed
        }
 
        // clear suggestion queue when suggestions aren't active
        if (active != true) {
          fa_mentionner.clearSuggestions();
        } else {
          return; // return when interactive keys are pressed while suggesting ; up, down, enter
        }
 
        // use another method if in WYSIWYG mode
        if (!fa_mentionner.instance.inSourceMode()) {
          key != 32 ? fa_mentionner.searchWYSIWYG() : fa_mentionner.clearSuggestions();
          return;
        }
 
        var val = fa_mentionner.instance.val(),
            range = 0,
            selection,
            faux_caret,
            username;
       
        // update the textarea height and width if it's not equal
        if (fa_mentionner.faux_textarea.style.height != fa_mentionner.textarea.style.height || fa_mentionner.faux_textarea.style.width != fa_mentionner.textarea.style.width) {
          fa_mentionner.faux_textarea.style.height = fa_mentionner.textarea.style.height;
          fa_mentionner.faux_textarea.style.width = fa_mentionner.textarea.style.width;
        }
 
        // get the position of the caret
        if (document.selection) {
          selection = document.selection.createRange();
          selection.moveStart('character', -fa_mentionner.textarea.length);
          range = selection.text.length;
        } else if (fa_mentionner.textarea.selectionStart || fa_mentionner.textarea.selectionStart == 0) {
          range = fa_mentionner.textarea.selectionStart;
        }
 
        // set the position of the caret
        val = val.slice(0, range) + '{FAUX_CARET}' + val.slice(range, val.length);
 
        // parse and sanitize the faux textarea content
        $(fa_mentionner.faux_textarea).html(
          val.replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(/@"(.*?)"|@(.*?)(?:\s|\r|\n|$)/g, function(M, $1, $2) {
              var lastChar = M.substr(-1),
                  name = ($1 || $2 || '').replace(/\{FAUX_CARET\}|"/g, '');
 
              return '<a href="#' + name + '">' + (/\s|\r|\n/.test(M) ? M.slice(0, M.length - 1) + '</a>' + lastChar : M + '</a>');
            })
            .replace(/\{FAUX_CARET\}/, '<span id="faux_caret" style="position:absolute;margin-left:-3px;">|</span>')
        );
 
        faux_caret = document.getElementById('faux_caret');
 
        // mentions are parsed as <a>nchors, so when the faux caret is inside one we'll show some suggestions
        if (faux_caret && faux_caret.parentNode.tagName == 'A') {
          fa_mentionner.value = val;
 
          fa_mentionner.delay = window.setTimeout(function() {
            fa_mentionner.suggest(faux_caret.parentNode.href.replace(/.*?#(.*)/, '$1'), $(faux_caret).offset());
          }, fa_mentionner.suggest_delay);
 
        }
 
        fa_mentionner.adjustScroll();
      },
 
 
      // search for active mentions in wysiwyg mode
      searchWYSIWYG : function() {
        var selected = fa_mentionner.rangeHelper.cloneSelected(),
            mentions = selected.startContainer.data && selected.startContainer.data.match(/(@".*?")|(@.*?)(?:\s|\r|\n|$)/g),
            offset,
            offset_marker,
            hit,
            i;
 
            console.log(mentions);
 
        if (mentions && mentions[0]) {
 
          // clean up whitespace
          for (i in mentions) {
            mentions[i] = mentions[i].replace(/\s$/g, '');
          }
 
          // search for the mention that's currently being modified
          for (i in mentions) {
            if (!fa_mentionner.wysiwyg_mentions || (mentions[i] != fa_mentionner.wysiwyg_mentions[i])) {
              hit = true;
 
              fa_mentionner.delay = window.setTimeout(function() {
                fa_mentionner.rangeHelper.insertMarkers(); // insert markers to help get the caret offset
 
                offset = $(fa_mentionner.frame).offset();
                offset_marker = $('#sceditor-end-marker', fa_mentionner.body).show().offset();
 
                // add the marker offsets to the iframe offsets
                offset.left += offset_marker.left;
                offset.top += offset_marker.top - fa_mentionner.body.scrollTop;
 
                fa_mentionner.suggest(mentions[i].slice(1).replace(/^"|"$/g, ''), offset, true);
                fa_mentionner.wysiwyg_active = mentions[i]; // save the active mention for later use in finish()
              }, fa_mentionner.suggest_delay);
 
              break;
            }
          }
 
          // hide the suggestion list if there's no newly modified mentions
          if (!hit) {
            fa_mentionner.list.style.display = 'none';
            fa_mentionner.focused = null;
          }
 
          fa_mentionner.wysiwyg_mentions = mentions; // update the list of mentions
 
        }
      },
 
      // suggest a list of users based on the passed username
      suggest : function(username, offset, wysiwyg) {
 
        // insert the suggestion list to show that it's searching
        fa_mentionner.list.innerHTML = '<span class="fam-info">' + fa_mentionner.lang.placeholder + '</span>';
        $(fa_mentionner.list).css({
          left : offset.left + 'px',
          top : offset.top + 'px',
          display : 'block',
          overflowY : 'auto'
        });
 
        document.body.appendChild(fa_mentionner.list);
 
        // send a query request to the memeberlist to find users who match the typed username
        fa_mentionner.request = $.get('/memberlist?username=' + username, function(d) {
          fa_mentionner.request = null;
 
          var suggestion = $(fa_mentionner.selectors ? fa_mentionner.selectors[0] : '.avatar-mini a', d),
              ava = fa_mentionner.selectors ? $(fa_mentionner.selectors[1], d) : null,
              i = 0,
              j = suggestion.length,
              name;
 
          fa_mentionner.list.innerHTML = '';
 
          if (j) {
            for (; i < j; i++) {
              name = $(suggestion[i]).text().replace(/^\s+|\s+$/g, '');
 
              fa_mentionner.list.insertAdjacentHTML('beforeend',
                '<a href="javascript:fa_mentionner.finish(\'' + name.replace(/'/g, '\\\'') + '\', ' + wysiwyg + ');" class="fa_mention_suggestion">'+
                  '<img class="fa_suggested_avatar" src="' + $(fa_mentionner.selectors ? ava[i] : suggestion[i]).find('img').attr('src') + '"/>'+
                  '<span class="fa_suggested_name">' + name + '</span>'+
                '</a>'
              );
            }
 
            // change overflowY property when it exceeds 7 suggestions -- prevents unsightly scroll bug
            fa_mentionner.list.style.overflowY = j > 7 ? 'scroll' : 'auto';
 
            // update the focused suggestion and scroll it into view
            fa_mentionner.list.firstChild.className += ' fam-focus';
            fa_mentionner.focused = fa_mentionner.list.firstChild;
            fa_mentionner.scrollSuggestions();
 
          } else {
            fa_mentionner.list.innerHTML = '<span class="fam-info" style="color:' + fa_mentionner.color.error_font + ';">' + fa_mentionner.lang.not_found + '</span>';
          }
 
        });
      },
 
 
      // kill the suggestion timeout while typing persists
      clearSuggestions : function() {
        if (fa_mentionner.delay) {
          window.clearTimeout(fa_mentionner.delay);
          fa_mentionner.delay = null;
 
          fa_mentionner.list.style.display = 'none';
          fa_mentionner.focused = null;
        }
 
        if (fa_mentionner.request) {
          fa_mentionner.request.abort();
          fa_mentionner.request = null;
        }
      },
 
 
      // finish the username
      finish : function(username, wysiwyg) {
        var mention, index, i;
 
        // hide and clear suggestions
        fa_mentionner.clearSuggestions();
        fa_mentionner.focused = null;
        fa_mentionner.list.style.display = 'none';
 
        if (!wysiwyg) {
          fa_mentionner.value = fa_mentionner.value.replace(/(?:@".[^"]*?\{FAUX_CARET\}.*?"|@\{FAUX_CARET\}.*?(\s|\n|\r|$)|@.[^"\s]*?\{FAUX_CARET\}.*?(\s|\n|\r|$))/, function(M, $1, $2) {
            mention = '@"' + username + '"';
            return '{MENTION_POSITION}' + ( $1 ? $1 : $2 ? $2 : '' );
          });
 
          // get the index where the mention should be
          index = fa_mentionner.value.indexOf('{MENTION_POSITION}');
          fa_mentionner.value = fa_mentionner.value.replace('{MENTION_POSITION}', '');
 
          // save current scroll position for application after the value has been updated
          fa_mentionner.scrollIndex = fa_mentionner.textarea.scrollTop;
 
          // update the textarea with the completed mention
          fa_mentionner.instance.val('');
          fa_mentionner.instance.insert(fa_mentionner.value.slice(0, index) + mention, fa_mentionner.value.slice(index, fa_mentionner.value.length));
 
          // restore the scroll position for the textareas
          fa_mentionner.textarea.scrollTop = fa_mentionner.scrollIndex;
          fa_mentionner.adjustScroll();
 
          // update the fake textarea
          fa_mentionner.updateFauxTextarea();
 
        } else {
          // save the caret range in WYSIWYG so we can restore it after replacing the HTML
          fa_mentionner.rangeHelper.saveRange();
          fa_mentionner.body.innerHTML = fa_mentionner.body.innerHTML.replace(new RegExp(fa_mentionner.wysiwyg_active.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") + '(<span.*?id="sceditor-end-marker".*?>)'), '@"' + username + '"$1');
          fa_mentionner.body.focus();
          fa_mentionner.rangeHelper.restoreRange();
 
          // update the wysiwyg mention array so no new suggestions appear
          for (i in fa_mentionner.wysiwyg_mentions) {
            if (fa_mentionner.wysiwyg_mentions[i] == fa_mentionner.wysiwyg_active) {
              fa_mentionner.wysiwyg_mentions[i] = '@"' + username + '"';
              break;
            }
          }
        }
      },
 
 
      // scroll the selected suggestion into view
      scrollSuggestions : function() {
        $(fa_mentionner.list).scrollTop(
          (
            $(fa_mentionner.focused).offset().top -
            $(fa_mentionner.list).offset().top +
            $(fa_mentionner.list).scrollTop()
          ) -
 
          (26 * 3) // 26 = the height of the suggestions, so display 3 suggestions above while scrolling
        );
      }
    };
 
    // get computed styles for the textarea and apply them to the faux textarea
    for (var css = window.getComputedStyle(fa_mentionner.textarea, null), i = 0, j = css.length, str = ''; i < j; i++) {
      str += css[i] + ':'  + css.getPropertyValue(css[i]) + ';';
    }
 
    // add styles to the head
    $('head').append('<style type="text/css">'+
      '#faux_text_editor {' + str + '}'+
      '#faux_text_editor { position:absolute; left:0; bottom:0; z-index:-1; visibility:hidden; display:block; overflow-y:auto; width:100%; }'+
      '#fa_mention_suggestions { color:' + fa_mentionner.color.font + '; font-size:10px; font-family:arial, verdana, sans-serif; background:' + fa_mentionner.color.background + '; border:1px solid ' + fa_mentionner.color.border + '; margin-top:20px; z-index:999; max-height:182px; overflow-x:hidden; box-shadow:0 6px 12px ' + fa_mentionner.color.shadow + '; }'+
      'a.fa_mention_suggestion, .fam-info { color:' + fa_mentionner.color.font + '; height:26px; line-height:26px; padding:0 3px; display:block; white-space:nowrap; cursor:pointer; }'+
      'a.fa_mention_suggestion.fam-focus { color:' + fa_mentionner.color.hover_font + '; background:' + fa_mentionner.color.hover_background + '; }'+
      '.fa_suggested_avatar { height:20px; width:20px; vertical-align:middle; margin-right:3px; }'+
      'a.fa_mention_suggestion, .fa_suggested_name { transition:none; }'+ // override transitions, specifically on modernbb
    '</style>');
 
    // insert faux textarea into document
    fa_mentionner.textarea.parentNode.insertBefore(fa_mentionner.faux_textarea, fa_mentionner.textarea);
 
    // apply event handlers
    fa_mentionner.textarea.onclick = fa_mentionner.updateFauxTextarea;
    fa_mentionner.textarea.onscroll = fa_mentionner.adjustScroll;
 
    // update the faux textarea on keyup
    fa_mentionner.instance.keyUp(function(e) {
      if (fa_mentionner.focused && e && (e.keyCode == 13 || e.keyCode == 38 || e.keyCode == 40)) {
        fa_mentionner.updateFauxTextarea(true, e.keyCode);
        return false;
      } else {
        fa_mentionner.updateFauxTextarea(false, e.keyCode);
      }
    });
 
    // key events for the suggested mentions
    $([document, fa_mentionner.body]).on('keydown', function(e) {
      var that = e.target;
 
      if (fa_mentionner.focused && e && e.keyCode && (that.tagName == 'TEXTAREA' || that.tagName == 'BODY')) {
 
        // move selection down
        if (e.keyCode == 40) {
          var next = fa_mentionner.focused.nextSibling;
 
          if (next) {
            $(fa_mentionner.focused).removeClass('fam-focus');
            next.className += ' fam-focus';
            fa_mentionner.focused = next;
 
            fa_mentionner.scrollSuggestions();
          }
 
          return false;
        }
 
        // move selection up
        if (e.keyCode == 38) {
          var prev = fa_mentionner.focused.previousSibling;
 
          if (prev) {
            $(fa_mentionner.focused).removeClass('fam-focus');
            prev.className += ' fam-focus';
            fa_mentionner.focused = prev;
 
            fa_mentionner.scrollSuggestions();
          }
 
          return false;
        }
 
        // apply selection
        if (e.keyCode == 13) {
          fa_mentionner.focused.click();
          return false;
        }
 
      }
    });
 
    // update focused suggestion on hover
    $(document).on('mouseover', function(e) {
      var that = e.target;
 
      if (/fa_mention_suggestion/.test(that.className)) {
        $(fa_mentionner.focused).removeClass('fam-focus');
        that.className += ' fam-focus';
        fa_mentionner.focused = that;
      }
    });
  }
})});

When you're finished, save the script and the auto-suggest plugin for mentions will be installed, and typing "@" should now bring up suggestions in your editor ! Very good

If you want to make any modifications to this plugin please see the following section. Doff


Modifications


Below is a list of the modifications that can be made to this plugin.


1. suggest_delay
This variable determines the delay before the editor starts searching for suggestions after typing the @ symbol. By default the delay is 0.1 seconds, if you want to change it simply modify the delay time.
Code:
suggest_delay : 100, // delay before suggestions show up (100ms)


2. lang
If you want to change any of the texts that appear in this plugin, find the lang object :
Code:
      lang : {
        placeholder : 'Searching...',
        not_found : 'User not found'
      },
and edit any of the texts you want ! Wink


3. color
The last modifiable portion in this plugin is the color object :
Code:
      color : {
              font : '#333',
        hover_font : '#FFF',
        error_font : '#F00',

              background : '#FFF',
        hover_background : '#69C',

        border : '#CCC',
        shadow : 'rgba(0, 0, 0, 0.176)'
      },
Feel free to modify any of the colors in this object to change the default colors of the suggestion list. Artist


That's all the modifications that can be made ! If you have any feedback, suggestions, or a problem with this plugin, feel free to leave a reply below. I hope this plugin makes mentioning members more easy ! Banana


Notice
Tutorial written by Ange Tuteur.
Special thanks to the Beta Testers for testing this plugin.
Reproduction not permitted without consent from the author.


Last edited by Ange Tuteur on Thu 27 Sep 2018, 10:01; edited 6 times in total
Anonymous
Guest
Guest

PostGuest Fri 19 Aug 2016, 14:21

Great plug-in, @Ange Tuteur! Thanks for sharing! Auto-suggest @mentions as You Type 1f496
Ange Tuteur
Ange Tuteur
Administrator
Gender : Male
Posts : 4741
Points : 12042
Reputation : 2375
Location : Pennsylvania
Language : EN, JA, FR
Browser : Browser : Brave Forum Version : Forum Version : Forumactif Edge
https://sethclydesdale.github.io/ https://twitter.com/sethc1995

PostAnge Tuteur Fri 19 Aug 2016, 15:18

@Samantha thanks ! Certainly makes mentioning people a breeze now, no more copy-pasting. Cool
Anonymous
Guest
Guest

PostGuest Fri 19 Aug 2016, 15:22

Ange Tuteur wrote:@Samantha thanks ! Certainly makes mentioning people a breeze now, no more copy-pasting. Cool

And no more faulty mentions Wink
Michael_vx
Michael_vx

Gender : Male
Age : 32
Posts : 302
Points : 4095
Reputation : 76
Language : Arabic
Browser : Browser : Mozilla Firefox Forum Version : Forum Version : Other
http://miccsoft.net https://www.facebook.com/Michaelvx2008

PostMichael_vx Fri 19 Aug 2016, 20:00

that is so great @Ange Tuteur
test and translate is done Smile
Ange Tuteur
Ange Tuteur
Administrator
Gender : Male
Posts : 4741
Points : 12042
Reputation : 2375
Location : Pennsylvania
Language : EN, JA, FR
Browser : Browser : Brave Forum Version : Forum Version : Forumactif Edge
https://sethclydesdale.github.io/ https://twitter.com/sethc1995

PostAnge Tuteur Fri 19 Aug 2016, 21:15

Samantha wrote:And no more faulty mentions Wink
Indeed ! This is something that should have been implemented day one for usability. pirat

Michael_vx wrote:that is so great @Ange Tuteur
test and translate is done Smile
Thanks, I'm glad you like it ! ^^
TroyEccles
TroyEccles

Gender : Unspecified
Posts : 25
Points : 2848
Reputation : 1
Language : English
Browser : Browser : Google Chrome Forum Version : Forum Version : phpBB3

PostTroyEccles Sat 20 Aug 2016, 04:38

This looked SO awesome but didn't work for me. In case I made an error, I did it three times.

I have a few javascripts loaded in already (twitter embedding, emojis, post-in-progress (which is no longer working either) and a couple of others. Is it possible one of them could be causing this new one not to work or do they all work well together?
Ange Tuteur
Ange Tuteur
Administrator
Gender : Male
Posts : 4741
Points : 12042
Reputation : 2375
Location : Pennsylvania
Language : EN, JA, FR
Browser : Browser : Brave Forum Version : Forum Version : Forumactif Edge
https://sethclydesdale.github.io/ https://twitter.com/sethc1995

PostAnge Tuteur Sat 20 Aug 2016, 05:37

TroyEccles wrote:This looked SO awesome but didn't work for me. In case I made an error, I did it three times.

I have a few javascripts loaded in already (twitter embedding, emojis, post-in-progress (which is no longer working either) and a couple of others. Is it possible one of them could be causing this new one not to work or do they all work well together?
Hi @TroyEccles,

I'm happy you like it. Wink

If it's not working on your end, it's most likely a JavaScript related error. You didn't supply a forum URL so I cannot help you debug. Instead try the following method :

1. Disable all other scripts temporarily, by editing them and unticking all their placements.
2. Install this plugin.
3. Test to see if the plugin works.
4. If it does work, try renabling each script you disabled 1-by-1 until you find this plugin doesn't work.
5. Once you've enabled the script that causes the error, either remove or disable it, and post it here for debugging. Thumb right
TroyEccles
TroyEccles

Gender : Unspecified
Posts : 25
Points : 2848
Reputation : 1
Language : English
Browser : Browser : Google Chrome Forum Version : Forum Version : phpBB3

PostTroyEccles Sat 20 Aug 2016, 06:22

Ok, not sure why but it's started working now.

So, er, I'm gonna step back away from the coding bits, say thank you very much, sorry for wasting your time and well....thanks for the awesome plugin!
Ange Tuteur
Ange Tuteur
Administrator
Gender : Male
Posts : 4741
Points : 12042
Reputation : 2375
Location : Pennsylvania
Language : EN, JA, FR
Browser : Browser : Brave Forum Version : Forum Version : Forumactif Edge
https://sethclydesdale.github.io/ https://twitter.com/sethc1995

PostAnge Tuteur Sat 20 Aug 2016, 06:25

lol don't worry about it, as long as it's working, right ? Razz

You're welcome ^^
TroyEccles
TroyEccles

Gender : Unspecified
Posts : 25
Points : 2848
Reputation : 1
Language : English
Browser : Browser : Google Chrome Forum Version : Forum Version : phpBB3

PostTroyEccles Sat 20 Aug 2016, 06:25

EDIT: just found why it's not working. I had a js that when you @tag someone, it shows their avatar. Looks like I removed that and now the auto@ is working. I'll have to hunt down the original js for the one I deleted and put it back in and see what happens.
Ange Tuteur
Ange Tuteur
Administrator
Gender : Male
Posts : 4741
Points : 12042
Reputation : 2375
Location : Pennsylvania
Language : EN, JA, FR
Browser : Browser : Brave Forum Version : Forum Version : Forumactif Edge
https://sethclydesdale.github.io/ https://twitter.com/sethc1995

PostAnge Tuteur Sat 20 Aug 2016, 06:33

Anonymous
Guest
Guest

PostGuest Sat 20 Aug 2016, 06:47

@TroyEccles don't forget I did many of modifications by cleaning up CSS so you may find some of the stuff working now and some of it changed the look of your site.
TroyEccles
TroyEccles

Gender : Unspecified
Posts : 25
Points : 2848
Reputation : 1
Language : English
Browser : Browser : Google Chrome Forum Version : Forum Version : phpBB3

PostTroyEccles Sat 20 Aug 2016, 07:09

Maybe! Thanks again.
Rhino.Freak
Rhino.Freak

Gender : Male
Age : 27
Posts : 275
Points : 4257
Reputation : 86
Location : India!
Language : English, Hindi
Browser : Browser : Google Chrome Forum Version : Forum Version : phpBB3
http://tokyoghoular.foruns.com.pt/

PostRhino.Freak Sat 20 Aug 2016, 13:40

Though I don't understand the technicalities of it, it's impressive you did something that has been a challenge to create for phpBB yet!
Keep up the good work! This is very user friendly!
schiggysboard
schiggysboard

Gender : Male
Posts : 79
Points : 3724
Reputation : 20
Language : German, English
Browser : Browser : Mozilla Firefox Forum Version : Forum Version : phpBB3
http://www.schiggysboard.com/

Postschiggysboard Sun 21 Aug 2016, 04:48

It doesn't work for me. After typing the "@" symbol with one or more letters, the message "User not found" appears.

I didn't modify the script and didn't get any error messages in the console.
jessy
jessy

Gender : Female
Posts : 102
Points : 3139
Reputation : 14
Language : italy
Browser : Browser : Google Chrome Forum Version : Forum Version : Invision
http://ilgiornaledibordo.forumattivo.com/

Postjessy Sun 21 Aug 2016, 05:52

incredible..fantastic,I have no words Auto-suggest @mentions as You Type 1f603
skouliki
skouliki

Gender : Female
Posts : 376
Points : 3707
Reputation : 173
Language : english,greek
Browser : Browser : Google Chrome Forum Version : Forum Version : punBB
http://iconskouliki.forumgreek.com https://www.facebook.com/iconskouliki https://twitter.com/iconskouliki

Postskouliki Sun 21 Aug 2016, 06:51

hello 

invision forum worked perfect cheers english and greek usernames 

i have a problem on my punbb forum http://iconskouliki.forumgreek.com
Auto-suggest @mentions as You Type Screen20  

thanks
Ange Tuteur
Ange Tuteur
Administrator
Gender : Male
Posts : 4741
Points : 12042
Reputation : 2375
Location : Pennsylvania
Language : EN, JA, FR
Browser : Browser : Brave Forum Version : Forum Version : Forumactif Edge
https://sethclydesdale.github.io/ https://twitter.com/sethc1995

PostAnge Tuteur Mon 22 Aug 2016, 14:47

Rhino.Freak wrote:Though I don't understand the technicalities of it, it's impressive you did something that has been a challenge to create for phpBB yet!
Keep up the good work! This is very user friendly!
@Rhino.Freak Thank you ! ^^

It's not hard for regular textareas, all you need to do is create a "faux textarea" which mirrors what is written in the default textarea. What I did for this plugin is find and format the mentions as anchors, then find the cursor ( or caret ) position and insert a "faux caret" into the faux textarea. Once the faux caret entered one of these anchors, I'd get the username/text in the anchor and submit a request with it to the /memberlist page. WYSIWYG mode is bit tricky though, I had to use and cache regular expressions, and then listen for any changes. It's very technical, but you're free to look over the code. Nerd

schiggysboard wrote:It doesn't work for me. After typing the "@" symbol with one or more letters, the message "User not found" appears.

I didn't modify the script and didn't get any error messages in the console.
@schiggysboard if you get "user not found" each time, it means you've modified your memberlist_body template, checking your forum confirms this. You'll need to use this script for your forum :
Code:
!window.fa_mentionner && !/\/privmsg|\/profile\?mode=editprofile&page_profil=signature/.test(window.location.href) && $(function(){$(function(){
  'SCEDITOR @HANDLE AUTO-SUGGEST';
  'DEVELOPED BY ANGE TUTEUR';
  'NO DISTRIBUTION WITHOUT CONSENT OF THE AUTHOR';
  'ORIGIN : http://fmdesign.forumotion.com/t943-auto-suggest-mentions-as-you-type#19157';
 
  var container = $('.sceditor-container')[0],
      text_editor = document.getElementById('text_editor_textarea'),
      frame,
      instance;
 
  if (container && text_editor) {
 
    frame = $('iframe', container);
    instance = $(text_editor).sceditor('instance');
 
    window.fa_mentionner = {
      suggest_delay : 100, // delay before suggestions show up (100ms)
 
      // language presets
      lang : {
        placeholder : 'Searching...',
        not_found : 'User not found'
      },
 
      // colors of the suggestion popup
      color : {
              font : '#333',
        hover_font : '#FFF',
        error_font : '#F00',
 
              background : '#FFF',
        hover_background : '#69C',
 
        border : '#CCC',
        shadow : 'rgba(0, 0, 0, 0.176)'
      },
 
      // sceditor instance and rangeHelper
      instance : instance,
      rangeHelper : instance.getRangeHelper(),
 
      // cached nodes for listening and modifications
      frame : frame[0],
      body : frame.contents().find('body')[0],
      textarea : $('textarea', container)[0],
 
      // faux textarea and suggestion list
      faux_textarea : $('<div id="faux_text_editor" />')[0], // helps us mirror the cursor position in source mode
      list : $('<div id="fa_mention_suggestions" style="position:absolute;" />')[0],
 
      // version specific selectors
      selectors : $('.bodyline')[0] ? ['a.gen[href^="/u"]', '.avatar.mini a'] :
                  document.getElementById('ipbwrapper') ? ['.membername', '.mini-avatar'] :
                  null,
 
 
      // adjusts the scroll position of the faux textarea so the caret stays in line
      adjustScroll : function() {
        fa_mentionner.faux_textarea.scrollTop = fa_mentionner.textarea.scrollTop;
      },
 
 
      // updates the content in the faux textarea
      updateFauxTextarea : function(active, key) {
        if (key == 16) { // 16 = SHIFT
          return; // return when specific keys are pressed
        }
 
        // clear suggestion queue when suggestions aren't active
        if (active != true) {
          fa_mentionner.clearSuggestions();
        } else {
          return; // return when interactive keys are pressed while suggesting ; up, down, enter
        }
 
        // use another method if in WYSIWYG mode
        if (!fa_mentionner.instance.inSourceMode()) {
          key != 32 ? fa_mentionner.searchWYSIWYG() : fa_mentionner.clearSuggestions();
          return;
        }
 
        var val = fa_mentionner.instance.val(),
            range = 0,
            selection,
            faux_caret,
            username;
 
        // get the position of the caret
        if (document.selection) {
          selection = document.selection.createRange();
          selection.moveStart('character', -fa_mentionner.textarea.length);
          range = selection.text.length;
        } else if (fa_mentionner.textarea.selectionStart || fa_mentionner.textarea.selectionStart == 0) {
          range = fa_mentionner.textarea.selectionStart;
        }
 
        // set the position of the caret
        val = val.slice(0, range) + '{FAUX_CARET}' + val.slice(range, val.length);
 
        // parse and sanitize the faux textarea content
        $(fa_mentionner.faux_textarea).html(
          val.replace(/</g, '<')
            .replace(/>/g, '>')
            .replace(/@"(.*?)"|@(.*?)(?:\s|\r|\n|$)/g, function(M, $1, $2) {
              var lastChar = M.substr(-1),
                  name = ($1 || $2 || '').replace(/\{FAUX_CARET\}|"/g, '');
 
              return '<a href="#' + name + '">' + (/\s|\r|\n/.test(M) ? M.slice(0, M.length - 1) + '</a>' + lastChar : M + '</a>');
            })
            .replace(/\{FAUX_CARET\}/, '<span id="faux_caret" style="position:absolute;margin-left:-3px;">|</span>')
        );
 
        faux_caret = document.getElementById('faux_caret');
 
        // mentions are parsed as <a>nchors, so when the faux caret is inside one we'll show some suggestions
        if (faux_caret && faux_caret.parentNode.tagName == 'A') {
          fa_mentionner.value = val;
 
          fa_mentionner.delay = window.setTimeout(function() {
            fa_mentionner.suggest(faux_caret.parentNode.href.replace(/.*?#(.*)/, '$1'), $(faux_caret).offset());
          }, fa_mentionner.suggest_delay);
 
        }
 
        fa_mentionner.adjustScroll();
      },
 
 
      // search for active mentions in wysiwyg mode
      searchWYSIWYG : function() {
        var selected = fa_mentionner.rangeHelper.cloneSelected(),
            mentions = selected.startContainer.data && selected.startContainer.data.match(/(@".*?")|(@.*?)(?:\s|\r|\n|$)/g),
            offset,
            offset_marker,
            hit,
            i;
 
            console.log(mentions);
 
        if (mentions && mentions[0]) {
 
          // clean up whitespace
          for (i in mentions) {
            mentions[i] = mentions[i].replace(/\s$/g, '');
          }
 
          // search for the mention that's currently being modified
          for (i in mentions) {
            if (!fa_mentionner.wysiwyg_mentions || (mentions[i] != fa_mentionner.wysiwyg_mentions[i])) {
              hit = true;
 
              fa_mentionner.delay = window.setTimeout(function() {
                fa_mentionner.rangeHelper.insertMarkers(); // insert markers to help get the caret offset
 
                offset = $(fa_mentionner.frame).offset();
                offset_marker = $('#sceditor-end-marker', fa_mentionner.body).show().offset();
 
                // add the marker offsets to the iframe offsets
                offset.left += offset_marker.left;
                offset.top += offset_marker.top - fa_mentionner.body.scrollTop;
 
                fa_mentionner.suggest(mentions[i].slice(1).replace(/^"|"$/g, ''), offset, true);
                fa_mentionner.wysiwyg_active = mentions[i]; // save the active mention for later use in finish()
              }, fa_mentionner.suggest_delay);
 
              break;
            }
          }
 
          // hide the suggestion list if there's no newly modified mentions
          if (!hit) {
            fa_mentionner.list.style.display = 'none';
            fa_mentionner.focused = null;
          }
 
          fa_mentionner.wysiwyg_mentions = mentions; // update the list of mentions
 
        }
      },
 
      // suggest a list of users based on the passed username
      suggest : function(username, offset, wysiwyg) {
 
        // insert the suggestion list to show that it's searching
        fa_mentionner.list.innerHTML = '<span class="fam-info">' + fa_mentionner.lang.placeholder + '</span>';
        $(fa_mentionner.list).css({
          left : offset.left + 'px',
          top : offset.top + 'px',
          display : 'block',
          overflowY : 'auto'
        });
 
        document.body.appendChild(fa_mentionner.list);
 
        // send a query request to the memeberlist to find users who match the typed username
        fa_mentionner.request = $.get('/memberlist?username=' + username, function(d) {
          fa_mentionner.request = null;
 
          var suggestion = $('.ipsType_subtitle a', d),
              ava = $('.ipsUserPhotoLink', d),
              i = 0,
              j = suggestion.length,
              name;
 
          fa_mentionner.list.innerHTML = '';
 
          if (j) {
            for (; i < j; i++) {
              name = $(suggestion[i]).text().replace(/^\s+|\s+$/g, '');
 
              fa_mentionner.list.insertAdjacentHTML('beforeend',
                '<a href="javascript:fa_mentionner.finish(\'' + name.replace(/'/g, '\\\'') + '\', ' + wysiwyg + ');" class="fa_mention_suggestion">'+
                  '<img class="fa_suggested_avatar" src="' + $(ava[i]).find('img').attr('src') + '"/>'+
                  '<span class="fa_suggested_name">' + name + '</span>'+
                '</a>'
              );
            }
 
            // change overflowY property when it exceeds 7 suggestions -- prevents unsightly scroll bug
            fa_mentionner.list.style.overflowY = j > 7 ? 'scroll' : 'auto';
 
            // update the focused suggestion and scroll it into view
            fa_mentionner.list.firstChild.className += ' fam-focus';
            fa_mentionner.focused = fa_mentionner.list.firstChild;
            fa_mentionner.scrollSuggestions();
 
          } else {
            fa_mentionner.list.innerHTML = '<span class="fam-info" style="color:' + fa_mentionner.color.error_font + ';">' + fa_mentionner.lang.not_found + '</span>';
          }
 
        });
      },
 
 
      // kill the suggestion timeout while typing persists
      clearSuggestions : function() {
        if (fa_mentionner.delay) {
          window.clearTimeout(fa_mentionner.delay);
          fa_mentionner.delay = null;
 
          fa_mentionner.list.style.display = 'none';
          fa_mentionner.focused = null;
        }
 
        if (fa_mentionner.request) {
          fa_mentionner.request.abort();
          fa_mentionner.request = null;
        }
      },
 
 
      // finish the username
      finish : function(username, wysiwyg) {
        var mention, index, i;
 
        // hide and clear suggestions
        fa_mentionner.clearSuggestions();
        fa_mentionner.focused = null;
        fa_mentionner.list.style.display = 'none';
 
        if (!wysiwyg) {
          fa_mentionner.value = fa_mentionner.value.replace(/(?:@".[^"]*?\{FAUX_CARET\}.*?"|@\{FAUX_CARET\}.*?(\s|\n|\r|$)|@.[^"\s]*?\{FAUX_CARET\}.*?(\s|\n|\r|$))/, function(M, $1, $2) {
            mention = '@"' + username + '"';
            return '{MENTION_POSITION}' + ( $1 ? $1 : $2 ? $2 : '' );
          });
 
          // get the index where the mention should be
          index = fa_mentionner.value.indexOf('{MENTION_POSITION}');
          fa_mentionner.value = fa_mentionner.value.replace('{MENTION_POSITION}', '');
 
          // save current scroll position for application after the value has been updated
          fa_mentionner.scrollIndex = fa_mentionner.textarea.scrollTop;
 
          // update the textarea with the completed mention
          fa_mentionner.instance.val('');
          fa_mentionner.instance.insert(fa_mentionner.value.slice(0, index) + mention, fa_mentionner.value.slice(index, fa_mentionner.value.length));
 
          // restore the scroll position for the textareas
          fa_mentionner.textarea.scrollTop = fa_mentionner.scrollIndex;
          fa_mentionner.adjustScroll();
 
          // update the fake textarea
          fa_mentionner.updateFauxTextarea();
 
        } else {
          // save the caret range in WYSIWYG so we can restore it after replacing the HTML
          fa_mentionner.rangeHelper.saveRange();
          fa_mentionner.body.innerHTML = fa_mentionner.body.innerHTML.replace(new RegExp(fa_mentionner.wysiwyg_active.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") + '(<span.*?id="sceditor-end-marker".*?>)'), '@"' + username + '"$1');
          fa_mentionner.body.focus();
          fa_mentionner.rangeHelper.restoreRange();
 
          // update the wysiwyg mention array so no new suggestions appear
          for (i in fa_mentionner.wysiwyg_mentions) {
            if (fa_mentionner.wysiwyg_mentions[i] == fa_mentionner.wysiwyg_active) {
              fa_mentionner.wysiwyg_mentions[i] = '@"' + username + '"';
              break;
            }
          }
        }
      },
 
 
      // scroll the selected suggestion into view
      scrollSuggestions : function() {
        $(fa_mentionner.list).scrollTop(
          (
            $(fa_mentionner.focused).offset().top -
            $(fa_mentionner.list).offset().top +
            $(fa_mentionner.list).scrollTop()
          ) -
 
          (26 * 3) // 26 = the height of the suggestions, so display 3 suggestions above while scrolling
        );
      }
    };
 
    // get computed styles for the textarea and apply them to the faux textarea
    for (var css = window.getComputedStyle(fa_mentionner.textarea, null), i = 0, j = css.length, str = ''; i < j; i++) {
      str += css[i] + ':'  + css.getPropertyValue(css[i]) + ';';
    }
 
    // add styles to the head
    $('head').append('<style type="text/css">'+
      '#faux_text_editor {' + str + '}'+
      '#faux_text_editor { position:absolute; left:0; bottom:0; z-index:-1; visibility:hidden; display:block; overflow-y:auto; }'+
      '#fa_mention_suggestions { color:' + fa_mentionner.color.font + '; font-size:10px; font-family:arial, verdana, sans-serif; background:' + fa_mentionner.color.background + '; border:1px solid ' + fa_mentionner.color.border + '; margin-top:20px; z-index:999; max-height:182px; overflow-x:hidden; box-shadow:0 6px 12px ' + fa_mentionner.color.shadow + '; }'+
      'a.fa_mention_suggestion, .fam-info { color:' + fa_mentionner.color.font + '; height:26px; line-height:26px; padding:0 3px; display:block; white-space:nowrap; cursor:pointer; }'+
      'a.fa_mention_suggestion.fam-focus { color:' + fa_mentionner.color.hover_font + '; background:' + fa_mentionner.color.hover_background + '; }'+
      '.fa_suggested_avatar { height:20px; width:20px; vertical-align:middle; margin-right:3px; }'+
    '</style>');
 
    // insert faux textarea into document
    fa_mentionner.textarea.parentNode.insertBefore(fa_mentionner.faux_textarea, fa_mentionner.textarea);
 
    // apply event handlers
    fa_mentionner.textarea.onclick = fa_mentionner.updateFauxTextarea;
    fa_mentionner.textarea.onscroll = fa_mentionner.adjustScroll;
 
    // update the faux textarea on keyup
    fa_mentionner.instance.keyUp(function(e) {
      if (fa_mentionner.focused && e && (e.keyCode == 13 || e.keyCode == 38 || e.keyCode == 40)) {
        fa_mentionner.updateFauxTextarea(true, e.keyCode);
        return false;
      } else {
        fa_mentionner.updateFauxTextarea(false, e.keyCode);
      }
    });
 
    // key events for the suggested mentions
    $([document, fa_mentionner.body]).on('keydown', function(e) {
      var that = e.target;
 
      if (fa_mentionner.focused && e && e.keyCode && (that.tagName == 'TEXTAREA' || that.tagName == 'BODY')) {
 
        // move selection down
        if (e.keyCode == 40) {
          var next = fa_mentionner.focused.nextSibling;
 
          if (next) {
            $(fa_mentionner.focused).removeClass('fam-focus');
            next.className += ' fam-focus';
            fa_mentionner.focused = next;
 
            fa_mentionner.scrollSuggestions();
          }
 
          return false;
        }
 
        // move selection up
        if (e.keyCode == 38) {
          var prev = fa_mentionner.focused.previousSibling;
 
          if (prev) {
            $(fa_mentionner.focused).removeClass('fam-focus');
            prev.className += ' fam-focus';
            fa_mentionner.focused = prev;
 
            fa_mentionner.scrollSuggestions();
          }
 
          return false;
        }
 
        // apply selection
        if (e.keyCode == 13) {
          fa_mentionner.focused.click();
          return false;
        }
 
      }
    });
 
    // update focused suggestion on hover
    $(document).on('mouseover', function(e) {
      var that = e.target;
 
      if (/fa_mention_suggestion/.test(that.className)) {
        $(fa_mentionner.focused).removeClass('fam-focus');
        that.className += ' fam-focus';
        fa_mentionner.focused = that;
      }
    });
  }
})});
If it doesn't work let me know. Wink


jessy wrote:incredible..fantastic,I have no words Auto-suggest @mentions as You Type 1f603
@jessy Thanks, I'm happy you like it ! ^^

skouliki wrote:hello 

invision forum worked perfect cheers english and greek usernames 

i have a problem on my punbb forum http://iconskouliki.forumgreek.com
Auto-suggest @mentions as You Type Screen20  

thanks
@skouliki your forum has modified templates for the memberlist_body as well. However, I cannot provide a solution currently, because your memberlist page is not visible to guests. Could you provide a test account ?
schiggysboard
schiggysboard

Gender : Male
Posts : 79
Points : 3724
Reputation : 20
Language : German, English
Browser : Browser : Mozilla Firefox Forum Version : Forum Version : phpBB3
http://www.schiggysboard.com/

Postschiggysboard Mon 22 Aug 2016, 15:01

It works! You're the best, thanks. Very Happy
skouliki
skouliki

Gender : Female
Posts : 376
Points : 3707
Reputation : 173
Language : english,greek
Browser : Browser : Google Chrome Forum Version : Forum Version : punBB
http://iconskouliki.forumgreek.com https://www.facebook.com/iconskouliki https://twitter.com/iconskouliki

Postskouliki Mon 22 Aug 2016, 15:02

yes of course

* credentials removed by @Samantha *

thank you in advance
Anonymous
Guest
Guest

PostGuest Mon 22 Aug 2016, 15:06

@skouliki , please keep credentials PRIVATE and rather send them to our staff (in this case Ange) via PM, with a link to the topic involved. Thanks for understanding.
Ange Tuteur
Ange Tuteur
Administrator
Gender : Male
Posts : 4741
Points : 12042
Reputation : 2375
Location : Pennsylvania
Language : EN, JA, FR
Browser : Browser : Brave Forum Version : Forum Version : Forumactif Edge
https://sethclydesdale.github.io/ https://twitter.com/sethc1995

PostAnge Tuteur Mon 22 Aug 2016, 15:14

@skouliki thanks Rose

Try using this script for your forum :
Code:
!window.fa_mentionner && !/\/privmsg|\/profile\?mode=editprofile&page_profil=signature/.test(window.location.href) && $(function(){$(function(){
  'SCEDITOR @HANDLE AUTO-SUGGEST';
  'DEVELOPED BY ANGE TUTEUR';
  'NO DISTRIBUTION WITHOUT CONSENT OF THE AUTHOR';
  'ORIGIN : http://fmdesign.forumotion.com/t943-auto-suggest-mentions-as-you-type#19157';
 
  var container = $('.sceditor-container')[0],
      text_editor = document.getElementById('text_editor_textarea'),
      frame,
      instance;
 
  if (container && text_editor) {
 
    frame = $('iframe', container);
    instance = $(text_editor).sceditor('instance');
 
    window.fa_mentionner = {
      suggest_delay : 100, // delay before suggestions show up (100ms)
 
      // language presets
      lang : {
        placeholder : 'Searching...',
        not_found : 'User not found'
      },
 
      // colors of the suggestion popup
      color : {
              font : '#333',
        hover_font : '#FFF',
        error_font : '#F00',
 
              background : '#FFF',
        hover_background : '#69C',
 
        border : '#CCC',
        shadow : 'rgba(0, 0, 0, 0.176)'
      },
 
      // sceditor instance and rangeHelper
      instance : instance,
      rangeHelper : instance.getRangeHelper(),
 
      // cached nodes for listening and modifications
      frame : frame[0],
      body : frame.contents().find('body')[0],
      textarea : $('textarea', container)[0],
 
      // faux textarea and suggestion list
      faux_textarea : $('<div id="faux_text_editor" />')[0], // helps us mirror the cursor position in source mode
      list : $('<div id="fa_mention_suggestions" style="position:absolute;" />')[0],
 
      // version specific selectors
      selectors : $('.bodyline')[0] ? ['a.gen[href^="/u"]', '.avatar.mini a'] :
                  document.getElementById('ipbwrapper') ? ['.membername', '.mini-avatar'] :
                  null,
 
 
      // adjusts the scroll position of the faux textarea so the caret stays in line
      adjustScroll : function() {
        fa_mentionner.faux_textarea.scrollTop = fa_mentionner.textarea.scrollTop;
      },
 
 
      // updates the content in the faux textarea
      updateFauxTextarea : function(active, key) {
        if (key == 16) { // 16 = SHIFT
          return; // return when specific keys are pressed
        }
 
        // clear suggestion queue when suggestions aren't active
        if (active != true) {
          fa_mentionner.clearSuggestions();
        } else {
          return; // return when interactive keys are pressed while suggesting ; up, down, enter
        }
 
        // use another method if in WYSIWYG mode
        if (!fa_mentionner.instance.inSourceMode()) {
          key != 32 ? fa_mentionner.searchWYSIWYG() : fa_mentionner.clearSuggestions();
          return;
        }
 
        var val = fa_mentionner.instance.val(),
            range = 0,
            selection,
            faux_caret,
            username;
 
        // get the position of the caret
        if (document.selection) {
          selection = document.selection.createRange();
          selection.moveStart('character', -fa_mentionner.textarea.length);
          range = selection.text.length;
        } else if (fa_mentionner.textarea.selectionStart || fa_mentionner.textarea.selectionStart == 0) {
          range = fa_mentionner.textarea.selectionStart;
        }
 
        // set the position of the caret
        val = val.slice(0, range) + '{FAUX_CARET}' + val.slice(range, val.length);
 
        // parse and sanitize the faux textarea content
        $(fa_mentionner.faux_textarea).html(
          val.replace(/</g, '<')
            .replace(/>/g, '>')
            .replace(/@"(.*?)"|@(.*?)(?:\s|\r|\n|$)/g, function(M, $1, $2) {
              var lastChar = M.substr(-1),
                  name = ($1 || $2 || '').replace(/\{FAUX_CARET\}|"/g, '');
 
              return '<a href="#' + name + '">' + (/\s|\r|\n/.test(M) ? M.slice(0, M.length - 1) + '</a>' + lastChar : M + '</a>');
            })
            .replace(/\{FAUX_CARET\}/, '<span id="faux_caret" style="position:absolute;margin-left:-3px;">|</span>')
        );
 
        faux_caret = document.getElementById('faux_caret');
 
        // mentions are parsed as <a>nchors, so when the faux caret is inside one we'll show some suggestions
        if (faux_caret && faux_caret.parentNode.tagName == 'A') {
          fa_mentionner.value = val;
 
          fa_mentionner.delay = window.setTimeout(function() {
            fa_mentionner.suggest(faux_caret.parentNode.href.replace(/.*?#(.*)/, '$1'), $(faux_caret).offset());
          }, fa_mentionner.suggest_delay);
 
        }
 
        fa_mentionner.adjustScroll();
      },
 
 
      // search for active mentions in wysiwyg mode
      searchWYSIWYG : function() {
        var selected = fa_mentionner.rangeHelper.cloneSelected(),
            mentions = selected.startContainer.data && selected.startContainer.data.match(/(@".*?")|(@.*?)(?:\s|\r|\n|$)/g),
            offset,
            offset_marker,
            hit,
            i;
 
            console.log(mentions);
 
        if (mentions && mentions[0]) {
 
          // clean up whitespace
          for (i in mentions) {
            mentions[i] = mentions[i].replace(/\s$/g, '');
          }
 
          // search for the mention that's currently being modified
          for (i in mentions) {
            if (!fa_mentionner.wysiwyg_mentions || (mentions[i] != fa_mentionner.wysiwyg_mentions[i])) {
              hit = true;
 
              fa_mentionner.delay = window.setTimeout(function() {
                fa_mentionner.rangeHelper.insertMarkers(); // insert markers to help get the caret offset
 
                offset = $(fa_mentionner.frame).offset();
                offset_marker = $('#sceditor-end-marker', fa_mentionner.body).show().offset();
 
                // add the marker offsets to the iframe offsets
                offset.left += offset_marker.left;
                offset.top += offset_marker.top - fa_mentionner.body.scrollTop;
 
                fa_mentionner.suggest(mentions[i].slice(1).replace(/^"|"$/g, ''), offset, true);
                fa_mentionner.wysiwyg_active = mentions[i]; // save the active mention for later use in finish()
              }, fa_mentionner.suggest_delay);
 
              break;
            }
          }
 
          // hide the suggestion list if there's no newly modified mentions
          if (!hit) {
            fa_mentionner.list.style.display = 'none';
            fa_mentionner.focused = null;
          }
 
          fa_mentionner.wysiwyg_mentions = mentions; // update the list of mentions
 
        }
      },
 
      // suggest a list of users based on the passed username
      suggest : function(username, offset, wysiwyg) {
 
        // insert the suggestion list to show that it's searching
        fa_mentionner.list.innerHTML = '<span class="fam-info">' + fa_mentionner.lang.placeholder + '</span>';
        $(fa_mentionner.list).css({
          left : offset.left + 'px',
          top : offset.top + 'px',
          display : 'block',
          overflowY : 'auto'
        });
 
        document.body.appendChild(fa_mentionner.list);
 
        // send a query request to the memeberlist to find users who match the typed username
        fa_mentionner.request = $.get('/memberlist?username=' + username, function(d) {
          fa_mentionner.request = null;
 
          var suggestion = $('.avatar-mini a', d),
              i = 0,
              j = suggestion.length,
              name;
 
          fa_mentionner.list.innerHTML = '';
 
          if (j) {
            for (; i < j; i++) {
              name = $(suggestion[i]).text().replace(/^\s+|\s+$/g, '');
 
              fa_mentionner.list.insertAdjacentHTML('beforeend',
                '<a href="javascript:fa_mentionner.finish(\'' + name.replace(/'/g, '\\\'') + '\', ' + wysiwyg + ');" class="fa_mention_suggestion">'+
                  '<img class="fa_suggested_avatar" src="' + $(suggestion[i]).find('img').attr('src') + '"/>'+
                  '<span class="fa_suggested_name">' + name + '</span>'+
                '</a>'
              );
            }
 
            // change overflowY property when it exceeds 7 suggestions -- prevents unsightly scroll bug
            fa_mentionner.list.style.overflowY = j > 7 ? 'scroll' : 'auto';
 
            // update the focused suggestion and scroll it into view
            fa_mentionner.list.firstChild.className += ' fam-focus';
            fa_mentionner.focused = fa_mentionner.list.firstChild;
            fa_mentionner.scrollSuggestions();
 
          } else {
            fa_mentionner.list.innerHTML = '<span class="fam-info" style="color:' + fa_mentionner.color.error_font + ';">' + fa_mentionner.lang.not_found + '</span>';
          }
 
        });
      },
 
 
      // kill the suggestion timeout while typing persists
      clearSuggestions : function() {
        if (fa_mentionner.delay) {
          window.clearTimeout(fa_mentionner.delay);
          fa_mentionner.delay = null;
 
          fa_mentionner.list.style.display = 'none';
          fa_mentionner.focused = null;
        }
 
        if (fa_mentionner.request) {
          fa_mentionner.request.abort();
          fa_mentionner.request = null;
        }
      },
 
 
      // finish the username
      finish : function(username, wysiwyg) {
        var mention, index, i;
 
        // hide and clear suggestions
        fa_mentionner.clearSuggestions();
        fa_mentionner.focused = null;
        fa_mentionner.list.style.display = 'none';
 
        if (!wysiwyg) {
          fa_mentionner.value = fa_mentionner.value.replace(/(?:@".[^"]*?\{FAUX_CARET\}.*?"|@\{FAUX_CARET\}.*?(\s|\n|\r|$)|@.[^"\s]*?\{FAUX_CARET\}.*?(\s|\n|\r|$))/, function(M, $1, $2) {
            mention = '@"' + username + '"';
            return '{MENTION_POSITION}' + ( $1 ? $1 : $2 ? $2 : '' );
          });
 
          // get the index where the mention should be
          index = fa_mentionner.value.indexOf('{MENTION_POSITION}');
          fa_mentionner.value = fa_mentionner.value.replace('{MENTION_POSITION}', '');
 
          // save current scroll position for application after the value has been updated
          fa_mentionner.scrollIndex = fa_mentionner.textarea.scrollTop;
 
          // update the textarea with the completed mention
          fa_mentionner.instance.val('');
          fa_mentionner.instance.insert(fa_mentionner.value.slice(0, index) + mention, fa_mentionner.value.slice(index, fa_mentionner.value.length));
 
          // restore the scroll position for the textareas
          fa_mentionner.textarea.scrollTop = fa_mentionner.scrollIndex;
          fa_mentionner.adjustScroll();
 
          // update the fake textarea
          fa_mentionner.updateFauxTextarea();
 
        } else {
          // save the caret range in WYSIWYG so we can restore it after replacing the HTML
          fa_mentionner.rangeHelper.saveRange();
          fa_mentionner.body.innerHTML = fa_mentionner.body.innerHTML.replace(new RegExp(fa_mentionner.wysiwyg_active.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") + '(<span.*?id="sceditor-end-marker".*?>)'), '@"' + username + '"$1');
          fa_mentionner.body.focus();
          fa_mentionner.rangeHelper.restoreRange();
 
          // update the wysiwyg mention array so no new suggestions appear
          for (i in fa_mentionner.wysiwyg_mentions) {
            if (fa_mentionner.wysiwyg_mentions[i] == fa_mentionner.wysiwyg_active) {
              fa_mentionner.wysiwyg_mentions[i] = '@"' + username + '"';
              break;
            }
          }
        }
      },
 
 
      // scroll the selected suggestion into view
      scrollSuggestions : function() {
        $(fa_mentionner.list).scrollTop(
          (
            $(fa_mentionner.focused).offset().top -
            $(fa_mentionner.list).offset().top +
            $(fa_mentionner.list).scrollTop()
          ) -
 
          (26 * 3) // 26 = the height of the suggestions, so display 3 suggestions above while scrolling
        );
      }
    };
 
    // get computed styles for the textarea and apply them to the faux textarea
    for (var css = window.getComputedStyle(fa_mentionner.textarea, null), i = 0, j = css.length, str = ''; i < j; i++) {
      str += css[i] + ':'  + css.getPropertyValue(css[i]) + ';';
    }
 
    // add styles to the head
    $('head').append('<style type="text/css">'+
      '#faux_text_editor {' + str + '}'+
      '#faux_text_editor { position:absolute; left:0; bottom:0; z-index:-1; visibility:hidden; display:block; overflow-y:auto; }'+
      '#fa_mention_suggestions { color:' + fa_mentionner.color.font + '; font-size:10px; font-family:arial, verdana, sans-serif; background:' + fa_mentionner.color.background + '; border:1px solid ' + fa_mentionner.color.border + '; margin-top:20px; z-index:999; max-height:182px; overflow-x:hidden; box-shadow:0 6px 12px ' + fa_mentionner.color.shadow + '; }'+
      'a.fa_mention_suggestion, .fam-info { color:' + fa_mentionner.color.font + '; height:26px; line-height:26px; padding:0 3px; display:block; white-space:nowrap; cursor:pointer; }'+
      'a.fa_mention_suggestion.fam-focus { color:' + fa_mentionner.color.hover_font + '; background:' + fa_mentionner.color.hover_background + '; }'+
      '.fa_suggested_avatar { height:20px; width:20px; vertical-align:middle; margin-right:3px; }'+
    '</style>');
 
    // insert faux textarea into document
    fa_mentionner.textarea.parentNode.insertBefore(fa_mentionner.faux_textarea, fa_mentionner.textarea);
 
    // apply event handlers
    fa_mentionner.textarea.onclick = fa_mentionner.updateFauxTextarea;
    fa_mentionner.textarea.onscroll = fa_mentionner.adjustScroll;
 
    // update the faux textarea on keyup
    fa_mentionner.instance.keyUp(function(e) {
      if (fa_mentionner.focused && e && (e.keyCode == 13 || e.keyCode == 38 || e.keyCode == 40)) {
        fa_mentionner.updateFauxTextarea(true, e.keyCode);
        return false;
      } else {
        fa_mentionner.updateFauxTextarea(false, e.keyCode);
      }
    });
 
    // key events for the suggested mentions
    $([document, fa_mentionner.body]).on('keydown', function(e) {
      var that = e.target;
 
      if (fa_mentionner.focused && e && e.keyCode && (that.tagName == 'TEXTAREA' || that.tagName == 'BODY')) {
 
        // move selection down
        if (e.keyCode == 40) {
          var next = fa_mentionner.focused.nextSibling;
 
          if (next) {
            $(fa_mentionner.focused).removeClass('fam-focus');
            next.className += ' fam-focus';
            fa_mentionner.focused = next;
 
            fa_mentionner.scrollSuggestions();
          }
 
          return false;
        }
 
        // move selection up
        if (e.keyCode == 38) {
          var prev = fa_mentionner.focused.previousSibling;
 
          if (prev) {
            $(fa_mentionner.focused).removeClass('fam-focus');
            prev.className += ' fam-focus';
            fa_mentionner.focused = prev;
 
            fa_mentionner.scrollSuggestions();
          }
 
          return false;
        }
 
        // apply selection
        if (e.keyCode == 13) {
          fa_mentionner.focused.click();
          return false;
        }
 
      }
    });
 
    // update focused suggestion on hover
    $(document).on('mouseover', function(e) {
      var that = e.target;
 
      if (/fa_mention_suggestion/.test(that.className)) {
        $(fa_mentionner.focused).removeClass('fam-focus');
        that.className += ' fam-focus';
        fa_mentionner.focused = that;
      }
    });
  }
})});
skouliki
skouliki

Gender : Female
Posts : 376
Points : 3707
Reputation : 173
Language : english,greek
Browser : Browser : Google Chrome Forum Version : Forum Version : punBB
http://iconskouliki.forumgreek.com https://www.facebook.com/iconskouliki https://twitter.com/iconskouliki

Postskouliki Mon 22 Aug 2016, 15:21

@Ange Tuteur solved as usual thanks for you time
@Samantha thanks for the information
Ange Tuteur
Ange Tuteur
Administrator
Gender : Male
Posts : 4741
Points : 12042
Reputation : 2375
Location : Pennsylvania
Language : EN, JA, FR
Browser : Browser : Brave Forum Version : Forum Version : Forumactif Edge
https://sethclydesdale.github.io/ https://twitter.com/sethc1995

PostAnge Tuteur Mon 22 Aug 2016, 15:22

No problem, have a good day ! ^^
Sponsored content

PostSponsored content

Page 1 of 4 1, 2, 3, 4  Next

View previous topic View next topic Back to top

Create an account or log in to leave a reply

You need to be a member in order to leave a reply.

Create an account

Join our community by creating a new account. It's easy!


Create a new account

Log in

Already have an account? No problem, log in here.


Log in

 
Permissions in this forum:
You cannot reply to topics in this forum