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!
 
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';
                }
 
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.
 
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));
 
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.
 
Well that's true...it has some custom data to only works with users:

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

Sem título.webp


But I made only one change to the xenforo.js script. (I think this is the only way to work..)
 
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 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.
 
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...
 
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

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!
 
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)
 
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');
    }
 
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.
 
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...
 
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.
This worked like a charm for my custom entity. Thanks for the simple explanation.

This does populate the autocomplete textbox with the labels/titles when clicked, but I was wondering if it would be possible to pass the associated row ids of those selections as well when the parent form is submitted? Right now I don't see any hidden inputs that store this information even though I'm returning the row ids from the renderJson method.
 
Top Bottom