Questo codice consente agli utenti di vedere un elenco di argomenti simili mentre stanno scrivendo il titolo. È ideale per i forum di supporto in cui quasi tutte le risposte sono già state risolte. Ecco un esempio di come appare:
Tutti possono adattare il codice in base al proprio forum. Può anche essere possibile adattare il codice a qualsiasi altra versione, sebbene ciò dipenda dall'utilizzatore e questo adattamento non è supportato. Di default il codice funziona per phpBB3.
InstallazionePannello di amministrazione ► Moduli ► HTML & JAVASCRIPT ► Gestione dei codici Javascript - Creare un nuovo Javascript Posizionamento: In tutte le pagine
- Codice:
/* The following code is DOM-dependent. It may not work if you modify the posting structure in the forum templates */ var FLRX = FLRX || {}; FLRX.similarTopics = (function () { 'use strict'; let settings = { // default settings forums : [], searchIn : false, maxTopics : 5, wordMinLength: 4, autocomplete: false, // disable browser autocomplete from subject input /* Advanced settings */ excludedCharacters : new RegExp(/[.,\/#!$%\^&\*¿?!¡;:{}\\=\-_`~"«“‘’”»()\[\]]/, 'g'), // The ignored characters from the topic title. dom : { // default settings (should work if left like this with unmodified templates) /* Search page */ topicscontainer : '.forabg', topic : 'dd.dterm', infocontainer : '.span-tab', titlelink : '.topictitle', userlink : 'a[href^="/u"]', forumlink : 'a[href^="/f"]', topicicon : 'dl.icon', /* structure */ visible : 'visible', /* posting page */ titleinput : '#postingbox input[name="subject"]', inputcontainer : 'dl', /* created elements */ maincontainer : $('<div />', { id : 'similarTopics' }), similartopiccont : $('<div />', { class : 'topic-container' }), loadingelm : $('<div />', { class : 'spinner' }) .append($('<div/>', { class:'double-bounce1' })) .append($('<div/>', { class:'double-bounce2' })), topicelmcont : $('<div />', { class: 'topic' }), topicelmtitle : $('<div />', { class: 'topic-title' }), topicdatacont : $('<div />', { class: 'topic-data' }), topicflags : $('<div />', { class: 'topic-flags' }), topiciconcont : $('<div />', { class: 'topic-icon' }), topicstatus : $('<div />', { class: 'topic-status' }), topicelminfo : $('<div />', { class: 'topic-info' }), topicauthor : $('<span />', { class: 'topic-author', text: 'by ' }), topicforum : $('<span />', { class: 'topic-forum', text: ' in ' }), similarstitle : $('<h4 />', { class: 'similarTopics-title', text: 'You may be interested in checking this topics before opening a new one' }), }, }, structure = {}, request, debounce = function(cb, delay) { let timeout; return function(...a) { clearTimeout(timeout); timeout = setTimeout( _ => { timeout = null; cb.call(this, ...a); }, delay); }; }, /* transforms a UTF8-encoded URI into Windows-1252 */ sanitizeURI = function(uri) { /* For some reason Forumotion uses Windows-1252 encoding in search URIs. This workaround will only fix issues with Spanish characters */ return uri.replace(/%C3%91/g, '%D1') // Ñ .replace(/%C3%B1/g, '%F1') // ñ .replace(/%C3%81/g, '%C1') // Á .replace(/%C3%89/g, '%C9') // É .replace(/%C3%8D/g, '%CD') // Í .replace(/%C3%93/g, '%D3') // Ó .replace(/%C3%9A/g, '%DA') // Ú .replace(/%C3%9C/g, '%DC') // Ü .replace(/%C3%A1/g, '%E1') // á .replace(/%C3%A9/g, '%E9') // é .replace(/%C3%AD/g, '%ED') // í .replace(/%C3%B3/g, '%F3') // ó .replace(/%C3%BA/g, '%FA') // ú .replace(/%C3%BC/g, '%FC'); // ü }, /* returns an object array (representation of topics) from a search URL synchronously */ searchTopics = function(url, cb) { $.ajax({ url : url, }).done(function(data) { let relatedTopics = [], $forabg = $(settings.dom.topicscontainer, data); if($forabg.length) { $forabg.find(settings.dom.topic).slice(0, settings.maxTopics).each(function() { let $this = $(this), $topictitle = $this.find(settings.dom.titlelink), $spantab = $this.find(settings.dom.infocontainer), $forumlink = $spantab.find(settings.dom.forumlink), $userlink = $spantab.find(settings.dom.userlink), $topicicon = $this.closest(settings.dom.topicicon); relatedTopics.push({ title : $topictitle.text().trim(), url : $topictitle.attr('href'), icon : $this.css('background-image').slice(4, -1), status : $topicicon.css('background-image').length ? $topicicon.css('background-image').slice(4, -1) : false, forum : { name : $forumlink.text(), url : $forumlink.attr('href'), }, user : { name : $userlink.text(), url : $userlink.attr('href'), }, }); }); } cb.call(this, relatedTopics); }).fail(_ => {let up; throw up || false}); }, /* returns an array with the words of a string that fulfil conditions of settings.excludedCharacters */ getWords = function(str) { return str.trim().replace(settings.excludedCharacters, '').split(' ').filter(elm => elm.length >= settings.wordMinLength); }, /* updates the similar topics DOM structure with the ones in the input array */ updateDOM = function(arr) { structure.topiccontainer.empty(); if(arr.length) { let docfrag = document.createDocumentFragment(); $.each(arr, function(index, topic) { let $topicTitle = settings.dom.topicelmtitle.clone(), $topicContainer = settings.dom.topicelmcont.clone(), $topicInfo = settings.dom.topicelminfo.clone(), $topicauthor = settings.dom.topicauthor.clone(), $topicstatus = settings.dom.topicstatus.clone(), $topicforum = settings.dom.topicforum.clone(), $topicflags = settings.dom.topicflags.clone(), $topicdata = settings.dom.topicdatacont.clone(), $topicicon = settings.dom.topiciconcont.clone(), /* link creation */ $topicLink = $('<a />', { href: topic.url, text: topic.title }), $forumlink = $('<a />', { href: topic.forum.url, text: topic.forum.name }), $authorlink = $('<a />', { href: topic.user.url, text: topic.user.name }); $topicicon.css('background-image', `url('${ topic.icon }')`); topic.status && $topicstatus.css('background-image', `url('${ topic.status }')`); $topicauthor.append($authorlink); $topicforum.append($forumlink); $topicTitle.append($topicLink); $topicInfo.append($topicauthor, $topicforum); $topicdata.append($topicTitle, $topicInfo); $topicflags.append($topicstatus, $topicicon); $topicContainer.append($topicflags, $topicdata); docfrag.append($topicContainer[0]); }); structure.topiccontainer[0].appendChild(docfrag); } else structure.maincontainer.removeClass(settings.dom.visible); }, setLoadingStatus = function() { structure.loadingcontainer.addClass(settings.dom.visible); structure.recentstitle.removeClass(settings.dom.visible); structure.topiccontainer.removeClass(settings.dom.visible); }, topicsRetrieved = function (){ structure.loadingcontainer.removeClass(settings.dom.visible); structure.recentstitle.addClass(settings.dom.visible); structure.topiccontainer.addClass(settings.dom.visible); }, searchAlgorithm = function(words, cb) { let params = { search_where : settings.searchIn || `f${/\?f=(\d+)/.exec(location.search)[1]}`, show_results : 'topics', sort_by : 0, sort_dir : 'DESC', search_terms : 'all', search_keywords : words.join(' '), }; searchTopics(`/search?${sanitizeURI($.param(params))}`, function(arr) { let relatedTopics = arr; if(relatedTopics.length < settings.maxTopics) { params.search_terms = 'any'; searchTopics(`/search?${sanitizeURI($.param(params))}`, function(arr) { let searchAnyWord = arr, neededElms = settings.maxTopics - relatedTopics.length; searchAnyWord = searchAnyWord.filter(elm => relatedTopics.find(e => e.url == elm.url) === undefined); // Ignore duplicates relatedTopics = [...relatedTopics, ...searchAnyWord.slice(0, neededElms)]; cb.call(this, relatedTopics); }); } cb.call(this, relatedTopics); }); }, /* main function */ searchSimilarTopics = function($title) { let words = getWords($title.val()); if(words.length == 0) return; // for the first time, if it was hidden structure.maincontainer.addClass(settings.dom.visible); setLoadingStatus(); searchAlgorithm(words, function(arr) { updateDOM(arr); topicsRetrieved(); }); }, generateStructure = function($title) { let $similarTopics = settings.dom.maincontainer.clone(), $spinner = settings.dom.loadingelm.clone(), $topicsContainer = settings.dom.similartopiccont.clone(), $recentsTitle = settings.dom.similarstitle.clone(); structure = { maincontainer : $similarTopics, loadingcontainer : $spinner, topiccontainer : $topicsContainer, recentstitle : $recentsTitle, }; $similarTopics.append($spinner, $recentsTitle, $topicsContainer); $title.closest(settings.dom.inputcontainer).after($similarTopics); }, init = function(options) { $.extend(true, settings, options); let timeout, $title = $(settings.dom.titleinput); if(!settings.autocomplete) $title.attr('autocomplete', 'off'); // append the basic dom structure (should be hidden by default with CSS) generateStructure($title); $title.on('keypress', debounce(function(e) { if(e.which !== 0) searchSimilarTopics($title); }, 500)); }; /* API :-) */ return { init : init, }; })(); !function() { const settings = { forums : [1,2,3,4,5,6,7], // Forum IDs (separated by comma) where the "Similar Topics" feature will be enabled. Set to true to enable the feature everywhere (not recommended). searchIn : '-1', // Where the searches will take place. Use -1 to search everywhere. If not set, it will search the forum where the topic is being created maxTopics : 5, // Maximum amount of topics shown }; location.pathname == '/post' && location.search.indexOf('&mode=newtopic') > -1 && (settings.forums === true || settings.forums.some(id => location.search.indexOf(`?f=${id}`) > -1)) && $(function() { FLRX.similarTopics.init(settings); }); }();
Ora aggiungi questo codice CSS al tuo forum:
- Codice:
#similarTopics { width: 500px; background: #E1EBF2; padding: 5px 10px; border-radius: 5px; margin: 5px 0 0 10em; } #similarTopics, #similarTopics .spinner, #similarTopics .topic-container, #similarTopics .similarTopics-title { display: none; } #similarTopics.visible, #similarTopics .spinner.visible, #similarTopics .similarTopics-title.visible, #similarTopics .topic-container.visible { display: block; } #similarTopics .topic { display: flex; border-bottom: 1px solid white; padding: 5px 0; margin: 5px 0; } #similarTopics .topic:last-child { border-bottom: none; } #similarTopics .topic-data { flex: 1; } #similarTopics .topic-flags { align-items: center; margin-right: 10px; position: relative; } #similarTopics .topic-icon { position: absolute; top: 0; left: 0; bottom: 0; right: 0; background: transparent 50% 50% no-repeat; } #similarTopics .similarTopics-title { border-bottom: 1px solid #0076b1; color: #0076b1; font-size: .9em; margin: .5em 0; text-transform: uppercase; } #similarTopics .topic-status { width: 27px; height: 27px; background: transparent 0 0 no-repeat; }
|