Latest topics
» "Edit this page" feature
by skouliki Today at 01:36

» [GAME] Count to 1000 using even numbers Van-Helsing Edition
by Van-Helsing Tue 17 Oct 2017, 15:07

» Dark Mode + Another Question
by Ace 1 Tue 17 Oct 2017, 12:42

» [GAME] What are you thinking right now?
by Ace 1 Tue 17 Oct 2017, 08:09

» [GAME] Count to One Million!
by Ace 1 Tue 17 Oct 2017, 08:07

» [GAME] Last Letter Game
by Ace 1 Tue 17 Oct 2017, 08:06

» [GAME] World Snake
by Ace 1 Tue 17 Oct 2017, 08:06

» [GAME] Never have I ever..
by Ace 1 Tue 17 Oct 2017, 08:06

» [GAME] Animal Game
by universecat Mon 16 Oct 2017, 21:43

» [GAME] Post a random picture
by SLGray Mon 16 Oct 2017, 16:28

» Hi everyone!
by skouliki Mon 16 Oct 2017, 02:01

» Hai Guys~
by skouliki Mon 16 Oct 2017, 01:59

» Add a login popup for the toolbar
by Ape Sun 15 Oct 2017, 13:51

» Mobile Usability Test
by Ange Tuteur Sat 14 Oct 2017, 11:20

» Chit Chat Thread
by Ange Tuteur Sat 14 Oct 2017, 11:20

Recent Tutorials
Who is online?
In total there are 12 users online :: 0 Registered, 0 Hidden and 12 Guests :: 2 Bots

None

[ View the whole list ]


Most users ever online was 172 on Fri 19 Feb 2016, 05:17

Auto-suggest @mentions as You Type

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

View previous topic View next topic Go down

avatar
Ange Tuteur
Administrator
Title :
Coffee Addict
Gender : Male
Age : 21
Posts : 4698
Points : 9536
Reputation : 2337
Location : Macungie, PA
Language : EN10, FR5
Browser : Browser : Brave Forum Version : Forum Version : Forumactif Edge
Awards :
View all awards
View user profile https://github.com/SethClydesdale https://twitter.com/sethc1995

PostAnge Tuteur on Fri 19 Aug 2016, 12:50

First topic message reminder :

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 !

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, '<')
            .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 = $(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 Wed 29 Mar 2017, 13:04; edited 5 times in total

avatar
Guest
Guest
View all awards

PostGuest on Mon 22 Aug 2016, 15:22

skouliki wrote:@Ange Tuteur solved as usual thanks for you time
@Samantha thanks for the information

No problem. Anytime.
avatar
Rhino.Freak

Title :
Lord of the 7 kingdoms and protector of the realm
Gender : Male
Age : 21
Posts : 275
Points : 1876
Reputation : 86
Location : India!
Language : English, Hindi
Browser : Browser : Google Chrome Forum Version : Forum Version : phpBB3
Awards :
View all awards
View user profile http://tokyoghoular.foruns.com.pt/

PostRhino.Freak on Tue 23 Aug 2016, 11:12

aha I see! Not only is it technically challenging but from what I remember, the problem faced in the making of this extension for phpBB was slow downs.
Catching and storing the name and avatar of so many members is a challenging task.

Do you think this script will be able to handle a forum with say 30-50K members?
avatar
Ange Tuteur
Administrator
Title :
Coffee Addict
Gender : Male
Age : 21
Posts : 4698
Points : 9536
Reputation : 2337
Location : Macungie, PA
Language : EN10, FR5
Browser : Browser : Brave Forum Version : Forum Version : Forumactif Edge
Awards :
View all awards
View user profile https://github.com/SethClydesdale https://twitter.com/sethc1995

PostAnge Tuteur on Tue 23 Aug 2016, 14:34

@Rhino.Freak I believe there may be some minor slowdowns depending on how many results are displayed per page and maybe even member count. On this forum there's 50 results on the memberlist page so that no doubt is a bit slower. These are the results I gathered from a few forums using just the "@" symbol :

1. FM Design
Results : 50
Members : 223
Response time : about 800-1000ms

2. Demoactif
Results : 10
Members : 10
Response time : about 200ms

3. Forumotion Support Forum
Results : 30
Members : 100,000+
Response time : about 600-800ms

It doesn't seem like member count has too much of an impact, although I'm certain there's at least some margin of impact. The results perpage seems to have the highest impact from what I can tell, because reducing that number does reduce the response time by a few hundred milliseconds.. Think
avatar
omarpop23

Title :
Gender : Male
Age : 22
Posts : 136
Points : 855
Reputation : 24
Location : Egypt
Language : Arabic , English
Browser : Browser : Google Chrome Forum Version : Forum Version : Forumactif Edge
Awards :
View all awards
View user profile https://www.facebook.com/omarpop23

Postomarpop23 on Wed 24 Aug 2016, 14:30

i have problem,
look at this pic

you can test it Go to this URL New Topic
avatar
Guest
Guest
View all awards

PostGuest on Wed 24 Aug 2016, 14:31

omarpop23 wrote:i have problem,
look at this pic

you can test it Go to this URL New Topic

Seems like that's on mobile, right?
avatar
omarpop23

Title :
Gender : Male
Age : 22
Posts : 136
Points : 855
Reputation : 24
Location : Egypt
Language : Arabic , English
Browser : Browser : Google Chrome Forum Version : Forum Version : Forumactif Edge
Awards :
View all awards
View user profile https://www.facebook.com/omarpop23

Postomarpop23 on Wed 24 Aug 2016, 14:36

and my PC because my screen is 15 inch i think
avatar
Guest
Guest
View all awards

PostGuest on Wed 24 Aug 2016, 14:41

Odd. I'm using a laptop with nearly the same screen size. I don't see any issues:



Perhaps your window isn't full size?
avatar
omarpop23

Title :
Gender : Male
Age : 22
Posts : 136
Points : 855
Reputation : 24
Location : Egypt
Language : Arabic , English
Browser : Browser : Google Chrome Forum Version : Forum Version : Forumactif Edge
Awards :
View all awards
View user profile https://www.facebook.com/omarpop23

Postomarpop23 on Wed 24 Aug 2016, 14:51

it's full size, my minitor is 15 inch, that's the problem
and i have on my same the problem mobile
avatar
Guest
Guest
View all awards

PostGuest on Wed 24 Aug 2016, 14:56

omarpop23 wrote:it's full size, my minitor is 15 inch, that's the problem
and i have on my same the problem mobile

Alright. Then we need to wait for Ange...
avatar
Ange Tuteur
Administrator
Title :
Coffee Addict
Gender : Male
Age : 21
Posts : 4698
Points : 9536
Reputation : 2337
Location : Macungie, PA
Language : EN10, FR5
Browser : Browser : Brave Forum Version : Forum Version : Forumactif Edge
Awards :
View all awards
View user profile https://github.com/SethClydesdale https://twitter.com/sethc1995

PostAnge Tuteur on Wed 24 Aug 2016, 15:46

@omarpop23 for RTL forums ( and small screens ), try adding this CSS rule to your stylesheet :
Code:
@media (min-width:0px) and (max-width:768px) {
  #fa_mention_suggestions {
    margin-left:-100px;
  }
}
It'll offset the position of the suggestion list by 100px if the screen is too small.
avatar
Luffy

Title :
Information Master
Gender : Male
Age : 23
Posts : 291
Points : 1666
Reputation : 64
Language : Greek, English
Browser : Browser : Google Chrome Forum Version : Forum Version : phpBB3
Awards :
View all awards
View user profile https://www.inforumgr.com/ https://www.facebook.com/inforumgr https://twitter.com/inforumgr

PostLuffy on Thu 25 Aug 2016, 07:27

This is amazing! Excellent work @Ange Tuteur!

--------

avatar
Ange Tuteur
Administrator
Title :
Coffee Addict
Gender : Male
Age : 21
Posts : 4698
Points : 9536
Reputation : 2337
Location : Macungie, PA
Language : EN10, FR5
Browser : Browser : Brave Forum Version : Forum Version : Forumactif Edge
Awards :
View all awards
View user profile https://github.com/SethClydesdale https://twitter.com/sethc1995

PostAnge Tuteur on Thu 25 Aug 2016, 13:17

@Luffy thanks ! Mr. Green
avatar
SSYT
Member
Title :
SSYT Codes
Gender : Male
Age : 23
Posts : 19
Points : 1500
Reputation : 13
Language : Romanian, English
Browser : Browser : Opera Forum Version : Forum Version : Forumactif Edge
Awards :
View all awards
View user profile https://www.forumcodes.com

PostSSYT on Fri 26 Aug 2016, 15:40

Very useful code @Ange Tuteur
avatar
Ange Tuteur
Administrator
Title :
Coffee Addict
Gender : Male
Age : 21
Posts : 4698
Points : 9536
Reputation : 2337
Location : Macungie, PA
Language : EN10, FR5
Browser : Browser : Brave Forum Version : Forum Version : Forumactif Edge
Awards :
View all awards
View user profile https://github.com/SethClydesdale https://twitter.com/sethc1995

PostAnge Tuteur on Fri 26 Aug 2016, 16:12

@SSYT thanks, that it is ! Cool
avatar
mrsrz
Member
Title :
Hi!!
Gender : Male
Age : 19
Posts : 12
Points : 431
Reputation : 0
Location : Somewere in Venezuela
Language : Español
Browser : Browser : Google Chrome Forum Version : Forum Version : punBB
Awards :
View all awards
View user profile http://musicinstant.host-es.com/ https://www.facebook.com/caminosyacordes https://twitter.com/Joorge_Suarez

Postmrsrz on Sun 28 Aug 2016, 20:35

I have this problem



and have two editors, zedit for fast questions and the normal editor for the creation of topics...



avatar
Ange Tuteur
Administrator
Title :
Coffee Addict
Gender : Male
Age : 21
Posts : 4698
Points : 9536
Reputation : 2337
Location : Macungie, PA
Language : EN10, FR5
Browser : Browser : Brave Forum Version : Forum Version : Forumactif Edge
Awards :
View all awards
View user profile https://github.com/SethClydesdale https://twitter.com/sethc1995

PostAnge Tuteur on Sun 28 Aug 2016, 20:38

@mrsrz have you modified the memberlist_body template ? If so, please provide an URL to your forum. This plugin is only for the SCEditor btw.
avatar
mrsrz
Member
Title :
Hi!!
Gender : Male
Age : 19
Posts : 12
Points : 431
Reputation : 0
Location : Somewere in Venezuela
Language : Español
Browser : Browser : Google Chrome Forum Version : Forum Version : punBB
Awards :
View all awards
View user profile http://musicinstant.host-es.com/ https://www.facebook.com/caminosyacordes https://twitter.com/Joorge_Suarez

Postmrsrz on Sun 28 Aug 2016, 20:39

http://musicinstant.host-es.com/
oh... I delete the template but not work this tuto..
"
Sorry for my english hahaha"
avatar
Ange Tuteur
Administrator
Title :
Coffee Addict
Gender : Male
Age : 21
Posts : 4698
Points : 9536
Reputation : 2337
Location : Macungie, PA
Language : EN10, FR5
Browser : Browser : Brave Forum Version : Forum Version : Forumactif Edge
Awards :
View all awards
View user profile https://github.com/SethClydesdale https://twitter.com/sethc1995

PostAnge Tuteur on Sun 28 Aug 2016, 20:43

@mrsrz thanks, try using this script :
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;
      }
    });
  }
})});
avatar
mrsrz
Member
Title :
Hi!!
Gender : Male
Age : 19
Posts : 12
Points : 431
Reputation : 0
Location : Somewere in Venezuela
Language : Español
Browser : Browser : Google Chrome Forum Version : Forum Version : punBB
Awards :
View all awards
View user profile http://musicinstant.host-es.com/ https://www.facebook.com/caminosyacordes https://twitter.com/Joorge_Suarez

Postmrsrz on Sun 28 Aug 2016, 20:48

Thans @Ange Tuteur i have other cuestion, y send my question...
avatar
Ange Tuteur
Administrator
Title :
Coffee Addict
Gender : Male
Age : 21
Posts : 4698
Points : 9536
Reputation : 2337
Location : Macungie, PA
Language : EN10, FR5
Browser : Browser : Brave Forum Version : Forum Version : Forumactif Edge
Awards :
View all awards
View user profile https://github.com/SethClydesdale https://twitter.com/sethc1995

PostAnge Tuteur on Sun 28 Aug 2016, 21:02

You're welcome. Wink
avatar
TroyEccles

Title :
Gender : Unspecified
Posts : 25
Points : 467
Reputation : 1
Language : English
Browser : Browser : Google Chrome Forum Version : Forum Version : phpBB3
Awards :
View all awards
View user profile

PostTroyEccles on Mon 29 Aug 2016, 08:24

Works perfectly on a computer.
Works perfectly in an iPad.
Doesn't work on android phone (although it works for me on THIS site).

What could be the cause of that???

www.bellsareringing.forumotion.com
phpBB3
avatar
SarkZKalie
Member
Title :
Exodia the Forbidden One
Gender : Male
Age : 26
Posts : 22
Points : 1396
Reputation : 11
Language : English
Browser : Browser : Google Chrome Forum Version : Forum Version : punBB
Awards :
View all awards
View user profile

PostSarkZKalie on Mon 29 Aug 2016, 12:28

After installed this plugin, i got duplicated avatar and username, then i changed some line in my heavy modified memberlist_body template. It works perfect now! :3
Thank you @Ange Tuteur!


Last edited by SarkZKalie on Mon 29 Aug 2016, 12:39; edited 1 time in total
avatar
Valoish
Graphic Designer
Title :
Gender : Female
Age : 21
Posts : 3652
Points : 4745
Reputation : 357
Location : NYC
Language : English, Russian, Hebrew
Browser : Browser : Opera Forum Version : Forum Version : phpBB2
Awards :
View all awards
View user profile http://www.canvasforums.com https://twitter.com/Valoishx3

PostValoish on Mon 29 Aug 2016, 12:38

@SarkZKalie Awesome job figuring it out on your own! Thumb right

--------

"I was afraid. And my own insecurity crushed him." - Youku x Boku SS
avatar
SarkZKalie
Member
Title :
Exodia the Forbidden One
Gender : Male
Age : 26
Posts : 22
Points : 1396
Reputation : 11
Language : English
Browser : Browser : Google Chrome Forum Version : Forum Version : punBB
Awards :
View all awards
View user profile

PostSarkZKalie on Mon 29 Aug 2016, 12:43

Wow thank you @Valoish now ya here too :3
avatar
Valoish
Graphic Designer
Title :
Gender : Female
Age : 21
Posts : 3652
Points : 4745
Reputation : 357
Location : NYC
Language : English, Russian, Hebrew
Browser : Browser : Opera Forum Version : Forum Version : phpBB2
Awards :
View all awards
View user profile http://www.canvasforums.com https://twitter.com/Valoishx3

PostValoish on Mon 29 Aug 2016, 13:07

@SarkZKalie Haha yeah xD SLGray introduced me to Ange's forum and I got really into the games on here LOL. Now it's just a part of my daily routine to check up on this forum~

--------

"I was afraid. And my own insecurity crushed him." - Youku x Boku SS

Page 2 of 4 Previous  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