Jump to content
snobjorn

Live search with results on new page

Recommended Posts

Not sure whether this is actually API, template, dev talk or module talk … I am looking for a starting point on a wanted functionality, which I have never setup before, and am hoping for some references and ProcessWire insight that might help me on the way.

I am looking for to make a search box / live search. Which I am thinking might work like this:

1) You start typing in the search box, i.e. when you're on the front page (home.php - http://example.com/)

2) Once you have typed more than 3 letters, you are redirected to a "live and updated as you type search result" on search.php http://example.com/search/?q=queryhere. Where also the url is reloading as you type. Maybe with some delay on refreshing (when you have stopped typing for 2-3 seconds).

The refreshing and redirecting should be "ajax" smooth. And the search result is on a full page view, not just a dropdown or overlay. It might be advanced, counterintuitive, not API-related. I'm just looking for a nod in the right direction. This is for a hobby project anyway.

Share this post


Link to post
Share on other sites

Hello Laban, 

This is quite easy with ProcessWire, however it's not easy to explain over the forum. You need to use AJAX searching and it will mostly be driven by javascript. 

Just send me an inbox and we will discuss.

Thanks,

Tom

Share this post


Link to post
Share on other sites

Hey gentlemen! I just happen to need this kind of js on a project of my own and am experiencing some trouble with implementing it. So please post the solution here if it is possible. Or just do not go private :P.

  • Like 3

Share this post


Link to post
Share on other sites

you are redirected to a "live and updated as you type search result" on search.php http://example.com/search/?q=queryhere. Where also the url is reloading as you type.

The redirection is probably the most problematic part of this plan, because the new page load will interrupt the visitor’s typing. What you would want to do is keep the search box and simply change the rest of the page using javascript. If the browser supports it, you can use history.pushState() to do manipulate the address bar, so visitors can have bookmarkable links to their search results. Here is a crude solution using jQuery. As you can see, JavaScript does most of the work:

Normal page looks somewhat like this. There is a search box and some unrelated content.

<body>
    <form id="searchform" method="GET">
        <input type="text" name="s" value="purple unicorns" />
    </form>
    <div id="content">
        <!--
            Your regular content stuff goes here.
            If the user starts typing, we replace all of this
            with a placeholder, do the search, then replace it
            with the results.
            Of course you would want to do something a bit more
            sophisticated and pretty in real life.
        -->
    </div>
</body>

Some JavaScript that runs on the above page and requires jQuery.

$(document).ready(function() {
    $('#searchform :input').on('input', function() {
        $("#content").html('<h2>Loading…</h2>');
       
        loadSearchResults(function(result) {
            if (result === false){
                result = '<h2>An error occurred.</h2>';
            }
           
            if (result == '')
                result = '<h2>No results found.</h2>';           

            $("#content").html(result);
        });
    });

    function loadSearchResults(callback) {
        var form = $('#searchform :input[value!=""]');
        var serialized_form = form.serialize(); //if your search field is named “s” this will be “s=search words”
       
        if (serialized_form !== '') {
            var new_url = '/search/?'+serialized_form; //consequently, this will be „/search/?s=search words“
            if (/* IE9 needs this check */ history.pushState) history.pushState({}, '', new_url); //your address bar now shows www.example.com/search/?s=search words
       
            $.ajax({
                type: form.attr('method'),
                url: '/search/',
                data: serialized_form,
                success: function(result) {
                    if (callback && typeof(callback) === 'function') {
                        callback(result);
                    }
                },
                error: function() {
                    if (callback && typeof(callback) === 'function') {
                        callback(false);
                    }
                }
            });
        }
    }
}

The search page /search/ handles a GET parameter called s and either serves a full results page, or just the markup necessary to inject it into existing pages.

<?php
    $s = $input->get->text('s');
    
    $results = $pages->find("title%={$s}, limit=100");
    
    $results_markup = "<h2>{$results->count} results found for “{$s}”:</h2>";
    $results_markup .= "<ul>";
    foreach($results as $r) {
        $results_markup .= "<li><a href='{$r->url}'>{$r->title}</a></li>";
    }
    $results_markup .= "</ul>";

    //if we’re live-searching, output only the results markup,
    //without <html>, <body> etc.
    if($config->ajax) {
        echo results_markup;
        return $this->halt();
    }
    
    
    //now do your regular markup
    include('head.inc');
    
    echo $results_markup;
    
    include('foot.inc');
?>

IRL you would probably serve JSON instead of full markup, but this keeps the JavaScript part short. You would also want to handle cases where users use the live search and then hit their browser’s back button.

  • Like 5

Share this post


Link to post
Share on other sites

Hey gentlemen! I just happen to need this kind of js on a project of my own and am experiencing some trouble with implementing it. So please post the solution here if it is possible. Or just do not go private :P.

Apologies, I wanted to be more direct with the code examples I gave him so he could just drop it in. The guy above is the same approach I used.

Share this post


Link to post
Share on other sites

Sorry to bring this post back up but I'm having a slight issue implementing this.

I have something almost identical to @Jan Romero and in the console I can see the specific term being returned as I type (see screenshot) BUT the variable, in this example $s = $input->get->text('q'); isn't being returned so all the results are just searching an empty string.

<form id="projects__search" method="get">
	<input type="text" name="q" placeholder="Search" />
</form>

Any thoughts?

Share this post


Link to post
Share on other sites

Ah it's because the URL in the JS was search to url: rootURL + 'search/', (rootURL being declared as var rootURL = config.urls.root;) but I have multi languages set up on the site so the URL was wrong.

  • Like 1

Share this post


Link to post
Share on other sites

@Jan Romero, I tried your code on a website.

I do see the url change on typing in the searchbox, tracy also shows the search term. If I press enter I get to the search page with the correct results.

I just miss the live search part.

 

My setup is a _main.php with the search form and the javascript code.

A search template with url /search/ with the code for the actual search.

If have set it up on this test site.

meibergen.webhoes.nl

Do you have any clue why I don't have the live search?

 

Share this post


Link to post
Share on other sites

@webhoes yeah, your javascript wants to put the search results into the element #content, and you don’t have one. If you add id="content" to your container div, it works. The search is doing something weird though. It will only find whole words, so if I look for guitars, the “g” gives me “Marshall MG 10 G Combo”, then everything disappears until I finish “guitar”.

Share this post


Link to post
Share on other sites

@Jan Romero, thanks. I found the same issue. I renamed that div as I already use content for template strategy. I made this

<div id="live-search"></div>

Yes, I changed the % to ~, not sure it that is correct either. If using % it will also give me a lot of unrelated results as it searches in both title and body.

 Currently I trying to fix that the div with results does not grow downwards but upwards making that you can't see the results.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...