Moving the discourse search box and making it functional - how?


(rymate1234) #1

So I’m working on making the theme of my discourse site fit the theme of my main site more. Part of this involves moving the search to the header of the site. How do I make a search box in the header search the forums?


Search is too hidden to new users
(Jeff Atwood) #2

Can you draw a picture of what you mean and paste it here?

The Discourse search is already in the header at the top right.


(rymate1234) #3

Here’s my custom header so far on

Basically I want to know how I can make the search box in the custom header search the forums, rather than the button in the discourse header (which I’ve hidden so there isn’t two search boxes).


(Ronteras) #4

I prefer to have the search field in more visible place:


#5

+1 for this!
I think Discourse’s search is fantastic, but the UI it is not.
What’s the best way to add a big search bat at the top?


(DanielMorgan) #6

On a related note, has anyone been able to create a search box outside of a Discourse installation completely – with the nice type-ahead results still working? Not interested in using Google Site Search.


(TheLoneCuber) #8

Apologies for the earlier duplicate post @codinghorror.

I too would love to bring Search to the forefront of my Discourse communities. Could this be an option for desktop viewing?


Discourse's search is superb, but far from obvious... especially for new users. I am not new to the online world or the online communities of it, yet I clearly remember my first Discourse experience, and knowing that I could search was no part of it. It wasn't until a number of repeat visits that I discovered the search button. [This new-to-Discourse user video][1] is a constant reminder of what we regulars often forget... that what we deem as obvious can often be far from. (thanks @Sailsman63 for the link)

I think a Super Search box would compliment Discourse’s already super search.


Discussing a topic with repeated official answers
(Luke S) #9

I think the post you are looking for is here:

Though, you may want to read further through the topic and see the eventual response to those issues.


(Angus McLeod) #11

Well, I was trying to add a search bar to the header today and came across this discussion. I didn’t succeed 100%, but I got somewhere…so I thought I’d post my thought process:

//thoughts…

Firstly, we’re going to have to change some templates, so we gotta use a plugin.

Ok, so the existing search button is in the header, so first lets look at the header template, header.hbs.

We can see that there’s a nicely ordered list (the ul/li part) for the navigation icons. One of them looks promising…

<li>
        {{#if loginRequired}}
          <a id='search-button' class='icon expand' href='#' aria-hidden="true" {{action "showLogin"}}>
            {{fa-icon "search"}}
          </a>
        {{else}}
          <a id='search-button'
             class='icon expand'
             href='#'
             data-dropdown="search-dropdown"
             title='{{i18n 'search.title'}}'>
             {{fa-icon "search" label="search.title"}}
          </a>
        {{/if}}
</li>

Hm, but this is only the button…where’s the search box itself?..

Well at the bottom of header.hbs there’s another clue

{{#if view.renderDropdowns}}
    {{render "search"}}

Ok! Apparently in the header view there is a function called “renderDropdowns” which acts as a trigger for rendering the search view (assuming you know the basics about how ember templates & views work together - if you don’t see here).

If we look a bit closer at the header view we can see it bundles up the functionality of the buttons in the header (remember that list) into various “dropdown” variables, functions and actions…

hm, that’s kinda tricky.

Well, why don’t we just stick “{{render “search”}}” somewhere else in the header and see what happens? This should at least render the search view.

Personally, I don’t want this puppy appearing on mobile web or for those who aren’t logged in so I’m going to enclose it in {{#unless site.mobileView}} and {{#if currentUser}}.

{{#unless site.mobileView}}
  {{#if currentUser}}
    {{render "search" class="d-dropdown header-search"}}
  {{/if}}
{{/unless}}

The class “d-dropdown” contains a bunch of styles for the icon dropdowns so I stuck that in, and I created the class “header-search” to finagle the box a bit.

I only want the existing button to appear in mobile web, so I also popped a “{{#if site.mobileView}}” around the existing button.

{{#if site.mobileView}}
      <li>
        {{#if loginRequired}}
          <a id='search-button' class='icon expand' href='#' aria-hidden="true" {{action "showLogin"}}>
            {{fa-icon "search"}}
          </a>
        {{else}}
          <a id='search-button'
             class='icon expand'
             href='#'
             data-dropdown="search-dropdown"
             title='{{i18n 'search.title'}}'>
             {{fa-icon "search" label="search.title"}}
          </a>
        {{/if}}
      </li>
{{/if}}

Ok…building…

Hey! that works!.. on desktop the box is always there in the header, it searches my content when I type…the normal icon is in mobile web…happy days :smile:

see here: http://quick.as/yavwfQakA

Butttt…the results section doesn’t get destroyed (hidden) like it does with the normal search icon. The results (or “no results”) stay visible after I click elsewhere :frowning:

hm I think this is because that tricky code in header view dealing with creation and destruction is specific to the functionality of the buttons and won’t recognize my new search box…I’ll have to revisit that later…

// end of thoughts…

So there you go. Do what I did and you’ll get a mostly working search box to appear in the header.

As you may have picked up, I’m hardly an expert . But you can figure out a fair bit by just reading the code and the basic ember.js guide.

If anyone knows a better way and/or how to get the results to be destroyed properly, I’m all ears!

(@zogstrip @riking any hints…? :smile: )


(Angus McLeod) #12

I went back to this issue today and figured out how to show/hide the search dropdown, now that it is always showing in the top bar.

After playing around with it a bit, I concluded I essentially wanted to achieve two things.

  1. The dropdown should hide when you click on something else.

  2. The dropdown shouldn’t render on initial load.

It seems that this is roughly what the show / hide stuff in the header view is doing (albeit I probably don’t entirely understand it).

This is what I came up with. This is a js.es6 script that sits in an “/assets/javascripts/discourse/initializers” folder in a plugin:

import ApplicationView from 'discourse/views/application';
import SearchView from 'discourse/views/search';

export default {
  name: 'search-destroyer',
  initialize(){
    ApplicationView.reopen({
      hideDropdownOnClick: function(e) {
        if (!$("#search-term").is(e.target)) {
            $(".search-context").fadeOut('fast');
            $(".results").fadeOut('fast');
        }
      }.on('mouseDown')
    });
    SearchView.reopen({
      setupDropdown: function() {
        $(".search-context").hide();
        $(".results").hide();
      }.on('didInsertElement')
    });
  }
};

The first function attempts to fulfill my first goal. The second function attempts to fulfill my second goal.

Why is this an initializer? I was following this useful explanation on reopening versus extending stuff.

Why did I choose to reopen the application view? Basically, I asked “So what part of the app encompasses “something else” in “The dropdown should hide when you click on something else”? I guess the entire application view”.

Where did I get the properties to listen for (the .on(’’) part of both functions)? From this part of the ember docs.

There’s probably other ways to go about it, but now I have a functioning search bar always in my header that shows/hides its results.


(Angus McLeod) #13

On request (@rewphus), I have turned this feature into a plugin that works with the latest discourse. But I don’t seem to have permissions to post in the plugins category (@sam?).


(Régis Hanol) #14

Just added you to the plugin_authors group :wink:


(Jeremy P) #15

Has there been any update on this topic or a plugin that will make the search box visible instead of the magnifying glass? Our main site has a search box in the header. We found that if we put our Forum into our normal site with usual headers our customers tend to think our site search is the Forum search and get confused and irritated by it. I’d love to have the search box visible from the start so customer know that is where you search for Forum content.


(Sam Saffron) #16

As an enterprise customer we can look at installing the plugin on your instance, though I think a better approach here would be for @angus to turn this into a #plugin:theme component , cause this requires no back-end changes. Perhaps commission the customization to @angus in the #marketplace category?


Header Search Theme
(Angus McLeod) #17

@sam The header search plugin has no backend, but it does require a few changes to some header widgets to function properly. From what I understand about theme components, I’m not sure it would work as one (?). I’ve just updated it to use the latest methods with plugin api 0.8.9, and done a bit of cleaning up.

@Digi-Man Happy to work through any issues you have with the header search plugin. No need to pay me. The plugin already exists / works.


(Sam Saffron) #18

It definitely can work from a theme component, any JS you do in a plugin can be done in a theme component, it has full access to plugin API


(Angus McLeod) #19

Ah k, I’ll dig into it a bit more then.


(Angus McLeod) #20

I’ve ported the Header Search Plugin to the theme format.

I’ve made a new repo for it. There are some situations in which a plugin will be more useful than a theme, so I want to keep the plugin repo.

When Sam adds me to theme_authors I’ll make a new theme topic for it.


(Régis Hanol) #21

Done. You can now make your topic.


(Angus McLeod) #22

@sam @Digi-Man Header Search is now available as a theme (in addition to the plugin). Let me know how it goes if you use it.