Carissimi utenti, Oggi vi mostro come un piccolo sistema che si attiverà quando andrete a taggare i vostri utenti ( @ ). Vi è mai capitato di taggare un vostro membro ma, alla fine avete digitato il nome sbagliato e il tag non funziona? Oggi vi mostro come rendere il sistema di tag più semplice
Installazione Pannello di amministrazione ► moduli ► gestione dei Javascript&HTML ► Javascript ► crea un nuovo Javascript
Andiamo dunque a creare un nuovo Javascript:
Nome: a vostra scelta Dove?: in tutte le pagine Codice:
- Codice:
!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'; ; 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 : 'cercando...', not_found : 'Nessuna corrispondenza ' }, // 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 = $(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; }'+ '#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; } }); }})});
salviamo dunque le modifiche
Risultato
Ed ecco fatto! alla prossima |