• This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.

AutoComplete for Other Data?

LiquidPro

Active member
#1
I would like to create an autocomplete dropdown for things other than username (i.e. Forum Title). I noticed that the AutoComplete function only allows you to use username, since it is including the username and avatar URL. How would I go about doing this? Do I need to write my own AutoComplete function, or is there something I am overlooking? Thanks!
 

Fuhrmann

Well-known member
#2
I think at the moment this is only to auto complete users. In the file xenforo.js:


Code:
if ($('html').hasClass('Admin'))
                {
                    XenForo.AutoComplete.defaultUrl = 'admin.php?users/search-name&_xfResponseType=json';
                }
                else
                {
                    XenForo.AutoComplete.defaultUrl = 'index.php?members/find&_xfResponseType=json';
                }
 

Fuhrmann

Well-known member
#3
Actually you can set your own path to the AutoComplete function using this:

Code:
<input type="search" name="my_search" value="{$my_search}" placeholder="{xen:phrase my_search}..." results="0" class="textCtrl AutoComplete AcSingle" data-acurl="{xen:link mysearch/find}" data-acextrafields="#ctrl_search_type" />

If you want to use the AutoComplete with ForumTitles you could extend the XenForo_ControllerPublic_Forum, create your own action "actionFindTitle" (or something) and then set this in the input:


Code:
<input type="search" name="my_search" value="{$my_search}" placeholder="{xen:phrase my_search}..." results="0" class="textCtrl AutoComplete AcSingle" data-acurl="{xen:link forum/findtitle}" data-acextrafields="#ctrl_search_type" />
I really dont know if it works.
 

LiquidPro

Active member
#4
Yeah, I found that in a previous post on here. The only problem is, username is hardcoded.

Code:
for(e in a)c("<li />").css("cursor","pointer").data("autoComplete",e).click(c.context(this,"resultClick")).mouseenter(c.context(this,"resultMouseEnter")).html(a[e].username.replace(g,"<strong>$1</strong>")).appendTo(this.$results).prepend(c('<img class="autoCompleteAvatar" />').attr("src",
a[e].avatar));
 

LiquidPro

Active member
#5
There are a few extra properties that can be used, that I'm not sure what they're for though. For example acExtraFields and acOptions.
 

Fuhrmann

Well-known member
#6
Well that's true...it has some custom data to only works with users:

Code:
.html(results[i]['username'].replace(filterRegex, '<strong>$1</strong>'))
 

LiquidPro

Active member
#8
I got it, I will post how I did it in a few minutes. I'm in the process of making it a little more flexible to be used with more than just a forum.
 

Fuhrmann

Well-known member
#10
That's what I did, we do not have to edit any core file of XenForo. Just do it a little dirt trick setting the key "title" to "username"...

I have extended the XenForo_ControllerPublic_Forum and inside I created this method:

PHP:
public function actionFindTitle()
    {
        $q = $this->_input->filterSingle('q', XenForo_Input::STRING);
     
        if ($q !== '' && utf8_strlen($q) >= 2)
        {
            $forums = $this->getModelFromCache('XenForo_Model_Node')->getNodesForAdminQuickSearch($q);         
        }
        else
        {
            $forums = array();
        }
     
        $viewParams = array(
            'forums' => $forums
        );
 
        return $this->responseView(
            'XenForo_ViewPublic_Forum_Find',
            'forum_autocomplete',
            $viewParams
        );
    }

Then, created a file called Find, in ViewPublic/Forum and inside:


PHP:
<?php
 
class XenForo_ViewPublic_Forum_Find extends XenForo_ViewPublic_Base
{
    public function renderJson()
    {
     
        $results = array();
        foreach ($this->_params['forums'] AS $forum)
        {
            $results[$forum['title']] = array(             
                'username' => htmlspecialchars($forum['title'])
            );
        }
     
        return array(
            'results' => $results
        );
    }
}


Then, in my template I put this:

Code:
<input type="search" name="search_user" value="{$search_forum}" placeholder="Forum Title..." results="0" class="textCtrl AutoComplete" data-acurl="{xen:link forums/FindTitle, $forum}"/>
Since this is just for a little test and to have an answer to your question, works...But maybe there is an more easy way to do it, of course...
 

LiquidPro

Active member
#11
Here's what I ended up doing, something very similar to you, except reusable for all of my stuff.

Extended XenForo_ControllerAdmin_Forum to add a searchTitle function.
Created the associated JSON view.
Added the attached javascript to my page.

This allows me to do something like this...
HTML:
<input type="search" name="search_forum" data-acDisplay="title" data-acUrl="admin.php?forms/search-title" class="AutoCompleteGeneric AcSingle" />
 

Attachments

Fuhrmann

Well-known member
#12
Here's what I ended up doing, something very similar to you, except reusable for all of my stuff.

Extended XenForo_ControllerAdmin_Forum to add a searchTitle function.
Created the associated JSON view.
Added the attached javascript to my page.

This allows me to do something like this...
HTML:
<input type="search" name="search_forum" data-acDisplay="title" data-acUrl="admin.php?forms/search-title" class="AutoCompleteGeneric AcSingle" />

Really good to know that you just found a solution!
 

LiquidPro

Active member
#13
Yes, thank you for the help! I wish there was an easier way, but this will definitely do. Not as hard as I was imaging, which is usually the case with most things XenForo (y)
 

simbolo

Well-known member
#14
Very helpful post, I'll add the function that I used to get the info that I was returning as it might help someone.
PHP:
 /**
    * Get Tags for quick search. With pre or postfix
    * @param $searchText
    * @return array
    */
    public function getTagsForQuickSearch($searchText)
    {
        $quotedString = XenForo_Db::quoteLike($searchText, 'lr', $this->_getDb());
 
        return $this->fetchAllKeyed('
            SELECT * FROM ContentTags_tag as tag
            WHERE tag.name LIKE ' . $quotedString . '
            OR tag.slug LIKE ' . $quotedString . '
            ORDER BY tag.name
        ', 'tag_id');
    }