AutoComplete for Other Data?

LiquidPro

Active member
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
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
Actually you can set your own path to the AutoComplete function using this:

Rich (BB 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:


Rich (BB 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
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
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
Well that's true...it has some custom data to only works with users:

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

Fuhrmann

Well-known member
Here:

Sem título.png


But I made only one change to the xenforo.js script. (I think this is the only way to work..)
 

LiquidPro

Active member
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
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.

I will be more then glad if you post how you did it so I can compare with what i did.
 

Fuhrmann

Well-known member
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
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

  • AutoCompleteGeneric.zip
    2.4 KB · Views: 49

Fuhrmann

Well-known member
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
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
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');
    }
 

Chris D

XenForo developer
Staff member
The code in this thread is for XF1 but XF2 has a very similar JavaScript framework and so you can achieve a similar thing in a similar way.

HTML:
<xf:textboxrow name="something" data-xf-init="auto-complete" data-single="1" data-acurl="{{ link('your/auto-complete-url') }}" />

You then need to add code reachable at the above data-acurl (whatever URL it might be) similar to the code you'll see at XF\Pub\Controller\Member::actionFind which is where the default user auto-complete code happens.

You'll also likely need a view class and renderJson method similar to XF\Pub\View\Member\Find::renderJson to format the results found by the controller.

Hope that helps but if not then please post a new thread with more details about what you're trying to do.
 

Orit

Member
The code in this thread is for XF1 but XF2 has a very similar JavaScript framework and so you can achieve a similar thing in a similar way.

HTML:
<xf:textboxrow name="something" data-xf-init="auto-complete" data-single="1" data-acurl="{{ link('your/auto-complete-url') }}" />

You then need to add code reachable at the above data-acurl (whatever URL it might be) similar to the code you'll see at XF\Pub\Controller\Member::actionFind which is where the default user auto-complete code happens.

You'll also likely need a view class and renderJson method similar to XF\Pub\View\Member\Find::renderJson to format the results found by the controller.

Hope that helps but if not then please post a new thread with more details about what you're trying to do.
Thank you Chris.
This was just a bit too complex for me to follow...
 
Top