cross
New Foswiki release 2.1.6 is available with important security fixes.
Sourceforge foswiki email lists being discontinued. Subscribe to the new Foswiki announce and discuss lists at MailingLists
This question about Using an extension: Answered

Jump/Search with multiple autocompletes as the default

How can I make a combined Jump/Search box in WebTopBar that gives the following results (in order):
  1. Exact topic title in this web, formatted as $topic
  2. Strict substring topic title in this web, formatted as $topic
  3. Exact topic title in other webs, formatted as $web/$topic
  4. Strict substring topic title in other webs, formatted as $web/$topic
  5. Text search results in this web, formatted as $topic - $summary(searchcontext)
  6. Text search results in other webs, formatted as $web/$topic - $summary(searchcontext)
Why doesn't Foswiki ship with an autocompleting Jump by default?

-- JayenAshar - 29 Nov 2011

See this page for the code. Caveats:
  1. Uses JQuery directly
  2. Not yet answered: getting $summary(searchcontext) (Can get summary easily, but need to figure out why searchcontext doesn't work.)
  3. The JQuery Autocompleter cache in 1.1.3 seems to have some problems with subsets (eg. WebTop [pause] ic), so it is disabled.
  4. The JQuery UI Autocompleter in 1.1.4 expects a JSON response, and I don't know how to concatenate multiple SEARCHes to be valid JSON, so I catch the error, remove a comma, and reparse...

Working with Foswiki 1.1.3

No such plugin autocomplete
%STARTSECTION{"topic"}%%SEARCH{ 
  "^%URLPARAM{"q" encode="quote" default="does not exist"}%" 
  type="regex" 
  scope="topic" 
  format="<nop>$topic$n" 
  nofinalnewline="off"
  separator="" 
  limit="10" 
  nonoise="on" 
  web="%URLPARAM{"baseweb" default="none"}%" 
}%%SEARCH{ 
  ".+%URLPARAM{"q" encode="quote" default="does not exist"}%" 
  type="regex" 
  scope="topic" 
  format="<nop>$topic$n" 
  nofinalnewline="off"
  separator="" 
  limit="10" 
  nonoise="on" 
  web="%URLPARAM{"baseweb" default="none"}%" 
}%%SEARCH{ 
  "^%URLPARAM{"q" encode="quote" default="does not exist"}%" 
  type="regex" 
  scope="topic" 
  format="<nop>$web/<nop>$topic$n" 
  nofinalnewline="off"
  separator="" 
  limit="10" 
  nonoise="on" 
  web="all,-%URLPARAM{"baseweb" default="none"}%" 
}%%SEARCH{ 
  ".+%URLPARAM{"q" encode="quote" default="does not exist"}%" 
  type="regex" 
  scope="topic" 
  format="<nop>$web/<nop>$topic$n" 
  nofinalnewline="off"
  separator="" 
  limit="10" 
  nonoise="on" 
  web="all,-%URLPARAM{"baseweb" default="none"}%" 
}%%SEARCH{ 
  "%URLPARAM{"q" encode="quote" default="does not exist"}%" 
  type="keyword" 
  scope="text" 
  format="<nop>$topic$n" 
  nofinalnewline="off"
  separator="" 
  limit="10" 
  nonoise="on" 
  web="%URLPARAM{"baseweb" default="none"}%" 
}%%SEARCH{ 
  "%URLPARAM{"q" encode="quote" default="does not exist"}%" 
  type="keyword" 
  scope="text" 
  format="<nop>$web/<nop>$topic$n" 
  nofinalnewline="off"
  separator="" 
  limit="10" 
  nonoise="on" 
  web="all,-%URLPARAM{"baseweb" default="none"}%" 
}%
%ENDSECTION{"topic"}%

%STARTSECTION{"jumpbox::js"}%<literal>
<script type="text/javascript">
jQuery(function($){
  $(".jqJumpBox").each(function() {
    var $this = $(this);
    $this.autocomplete(
      "%SCRIPTURL{"view"}%/%WEB%/%TOPIC%?section=topic;skin=text&baseweb=%BASEWEB%",
      {
        matchSubset: false,
        selectFirst: false,
        width: $this.width() * 2
      }
    ).result(function(event, item) {
      window.location.href="%SCRIPTURLPATH{"view"}%/"+(item[0].indexOf('/') == -1 ? '%BASEWEB%/' : '')+item;
    });
  });
});
</script>
</literal>%ENDSECTION{"jumpbox::js"}%

-- JayenAshar - 01 Dec 2011

If you are using KinoSearchPlugin, you may consider adding the following snippets:
%KINOSEARCH{ 
  "%<nop>URLPARAM{"q" encode="quote" default="does not exist"}% +attachment:yes" 
  format="<nop>$icon <nop>$match
<nop>" 
}%
result(function(event, item) {
      var matches = item[0].match(new RegExp('href="(.*?)"','i'));
      if(matches && matches.length > 1)
        window.location.href=matches[1];
      else
        window.location.href="%SCRIPTURLPATH{"view"}%/"+(item[0].indexOf('/') == -1 ? '%BASEWEB%/' : '')+item;
    });

-- JayenAshar - 02 Dec 2011

Dodgy hack with Foswiki 1.1.4

%STARTSECTION{"jumpuibox::js"}%<literal>
<script type="text/javascript">
var requestIndex = 0;
jQuery(function($){
  $(".jqUIJumpBox").each(function() {
    var self = this;
    var $this = $(this);
    $this.autocomplete({
      search: function(event, ui) {
        ;
      },
      select: function(event, ui) {
        window.location.href="%SCRIPTURLPATH{"view"}%/"+(ui.item.value.indexOf('/') == -1 ? '%BASEWEB%/' : '')+ui.item.value;
      },
//      source: "%SCRIPTURL{"view"}%/%WEB%/%TOPIC%?section=topicui;skin=text&baseweb=%BASEWEB%",//parser error due to trailing comma
      source: function( request, response ) { //taken from jquery.ui.autocomplete.js
            if ( self.xhr ) {
               self.xhr.abort();
            }
            self.xhr = $.ajax({
               url: "%SCRIPTURL{"view"}%/%WEB%/%TOPIC%?section=topicui;skin=text&baseweb=%BASEWEB%",
               data: request,
               dataType: "json",
               autocompleteRequest: ++requestIndex,
               success: function( data, status ) {
                  if ( this.autocompleteRequest === requestIndex ) {
                     response( data );
                  }
               },
               error: function( xhr, status, errorThrown ) {
                  if ( this.autocompleteRequest === requestIndex ) {
                     //parser error due to trailing comma, so this is a dodgy hack
                     if ( status == "parsererror") {
                        var resultsText = xhr.responseText.replace(/,\s*]/m,']');
                        var resultsArray = $.parseJSON(resultsText);
                        response(resultsArray);
                     } else {
                        response( [] );
                     }
                  }
               }
            });
      },
//      source: ["a","b","ab",],//this works even though it has a trailing comma because it's javascript and not json
    });
  });
});
</script>
</literal>%ENDSECTION{"jumpuibox::js"}%

%STARTSECTION{"topicui"}%[%SEARCH{ 
  "^%URLPARAM{"term" encode="quote" default="does not exist"}%" 
  type="regex" 
  scope="topic" 
  format="\"<nop>$topic\",$n" 
  nofinalnewline="off"
  separator="" 
  limit="10" 
  nonoise="on" 
  web="%URLPARAM{"baseweb" default="none"}%" 
}%%SEARCH{ 
  ".+%URLPARAM{"term" encode="quote" default="does not exist"}%" 
  type="regex" 
  scope="topic" 
  format="\"<nop>$topic\",$n" 
  nofinalnewline="off"
  separator="" 
  limit="10" 
  nonoise="on" 
  web="%URLPARAM{"baseweb" default="none"}%" 
}%%SEARCH{ 
  "^%URLPARAM{"term" encode="quote" default="does not exist"}%" 
  type="regex" 
  scope="topic" 
  format="\"<nop>$web/<nop>$topic\",$n" 
  nofinalnewline="off"
  separator="" 
  limit="10" 
  nonoise="on" 
  web="all,-%URLPARAM{"baseweb" default="none"}%" 
}%%SEARCH{ 
  ".+%URLPARAM{"term" encode="quote" default="does not exist"}%" 
  type="regex" 
  scope="topic" 
  format="\"<nop>$web/<nop>$topic\",$n" 
  nofinalnewline="off"
  separator="" 
  limit="10" 
  nonoise="on" 
  web="all,-%URLPARAM{"baseweb" default="none"}%" 
}%%SEARCH{ 
  "%URLPARAM{"term" encode="quote" default="does not exist"}%" 
  type="keyword" 
  scope="text" 
  format="\"<nop>$topic\",$n" 
  nofinalnewline="off"
  separator="" 
  limit="10" 
  nonoise="on" 
  web="%URLPARAM{"baseweb" default="none"}%" 
}%%SEARCH{ 
  "%URLPARAM{"term" encode="quote" default="does not exist"}%" 
  type="keyword" 
  scope="text" 
  format="\"<nop>$web/<nop>$topic\",$n" 
  nofinalnewline="off"
  separator="" 
  limit="10" 
  nonoise="on" 
  web="all,-%URLPARAM{"baseweb" default="none"}%" 
}%]
%ENDSECTION{"topicui"}%

-- JayenAshar - 04 Dec 2011

Super-dodgy hack with Foswiki 1.1.4 and KinoSearch

%STARTSECTION{"topicuikino"}%[%SEARCH{ 
  "^%URLPARAM{"term" encode="quote" default="does not exist"}%" 
  type="regex" 
  scope="topic" 
  format="{ \"value\": \"<nop>$web/<nop>$topic\", \"label\": \"<nop>$topic\" },$n" 
  nofinalnewline="off"
  separator="" 
  limit="10" 
  nonoise="on" 
  web="%URLPARAM{"baseweb" default="none"}%" 
}%%SEARCH{ 
  ".+%URLPARAM{"term" encode="quote" default="does not exist"}%" 
  type="regex" 
  scope="topic" 
  format="{ \"value\": \"<nop>$web/<nop>$topic\", \"label\": \"<nop>$topic\" },$n" 
  nofinalnewline="off"
  separator="" 
  limit="10" 
  nonoise="on" 
  web="%URLPARAM{"baseweb" default="none"}%" 
}%%SEARCH{ 
  "^%URLPARAM{"term" encode="quote" default="does not exist"}%" 
  type="regex" 
  scope="topic" 
  format="{ \"value\": \"<nop>$web/<nop>$topic\", \"label\": \"<nop>$web/<nop>$topic\" },$n" 
  nofinalnewline="off"
  separator="" 
  limit="10" 
  nonoise="on" 
  web="all,-%URLPARAM{"baseweb" default="none"}%" 
}%%SEARCH{ 
  ".+%URLPARAM{"term" encode="quote" default="does not exist"}%" 
  type="regex" 
  scope="topic" 
  format="{ \"value\": \"<nop>$web/<nop>$topic\", \"label\": \"<nop>$web/<nop>$topic\" },$n" 
  nofinalnewline="off"
  separator="" 
  limit="10" 
  nonoise="on" 
  web="all,-%URLPARAM{"baseweb" default="none"}%" 
}%%SEARCH{ 
  "%URLPARAM{"term" encode="quote" default="does not exist"}%" 
  type="keyword" 
  scope="text" 
  format="{ \"value\": \"<nop>$web/<nop>$topic\", \"label\": \"<nop>$topic\" },$n" 
  nofinalnewline="off"
  separator="" 
  limit="10" 
  nonoise="on" 
  web="%URLPARAM{"baseweb" default="none"}%" 
}%%SEARCH{ 
  "%URLPARAM{"term" encode="quote" default="does not exist"}%" 
  type="keyword" 
  scope="text" 
  format="{ \"value\": \"<nop>$web/<nop>$topic\", \"label\": \"<nop>$web/<nop>$topic\" },$n" 
  nofinalnewline="off"
  separator="" 
  limit="10" 
  nonoise="on" 
  web="all,-%URLPARAM{"baseweb" default="none"}%" 
}%%KINOSEARCH{ 
  "%URLPARAM{"term" encode="quote" default="does not exist"}% +attachment:yes" 
  format="\"<nop>$icon <nop>$match\",
<nop>" 
}%]
%ENDSECTION{"topicuikino"}%

%STARTSECTION{"jumpuikinobox::js"}%<literal>
<script type="text/javascript">
var requestIndex = 0;
jQuery(function($){
  $(".jqUIKinoJumpBox").each(function() {
    var self = this;
    var $this = $(this);
    $this.autocomplete({
      search: function(event, ui) {
        ;
      },
      select: function(event, ui) {
        var matches = ui.item.value.match(/\/pub/);
        if(matches)
          window.location.href=ui.item.value;
        else
          window.location.href="%SCRIPTURLPATH{"view"}%/" + ui.item.value;
      },
      focus: function(event, ui) {
        return false;
      },
//      source: "%SCRIPTURL{"view"}%/%WEB%/%TOPIC%?section=topicuikino;skin=text&baseweb=%BASEWEB%",//parser error due to trailing comma
      source: function( request, response ) { //taken from jquery.ui.autocomplete.js
            if ( self.xhr ) {
               self.xhr.abort();
            }
            self.xhr = $.ajax({
               url: "%SCRIPTURL{"view"}%/%WEB%/%TOPIC%?section=topicuikino;skin=text&baseweb=%BASEWEB%",
               data: request,
               dataType: "json",
               autocompleteRequest: ++requestIndex,
               success: function( data, status ) {
                  if ( this.autocompleteRequest === requestIndex ) {
                     response( data );
                  }
               },
               error: function( xhr, status, errorThrown ) {
                  if ( this.autocompleteRequest === requestIndex ) {
                     //parser error due to trailing comma, so this is a dodgy hack
                     if ( status == "parsererror") {
                        var resultsText = xhr.responseText.replace(/,\s*]/m,']');
                        //parser error due to kinosearch embedding "
                        //also, just replacing " for \" means $icon and $match are escaped to be text, and are not html
                        //"<span class="foswikiIcon"><img src="/pub/System/DocumentGraphics/pdf.png" width="16" height="16" alt="Wikimedia_and_edirectory.pdf" /></span> <a href="/pub/Main/ITWiki/ThirdPartyInformation/Wikimedia_and_edirectory.pdf">Wikimedia_and_edirectory.pdf</a>",
                        resultsText = resultsText.replace(/".*("\/pub[^"]+").*alt=("[^"]+").*("\/pub[^"]+").*"/g, '{ "value": $3, "label": $2, "icon": $1 }');
                        var resultsArray = $.parseJSON(resultsText);
                        response(resultsArray);
                     } else {
                        response( [] );
                     }
                  }
               }
            });
      },
//      source: ["a","b","ab",],//this works even though it has a trailing comma because it's javascript and not json
    })
//from http://jqueryui.com/demos/autocomplete/#custom-data
      .data( "autocomplete" )._renderItem = function( ul, item ) {
         return $( "<li></li>" )
            .data( "item.autocomplete", item )
            .append( "<a>" + (item.icon ? '<img src="' + item.icon + '" /> ' : '') + item.label + "</a>" )
            .appendTo( ul );
      };
  });
});
</script>
</literal>%ENDSECTION{"jumpuikinobox::js"}%

-- JayenAshar - 23 Dec 2011

We have a better implementation using SolrPlugin now. This is part of NatSkin, or via the solr skin overlay in PatternSkin.

-- MichaelDaum - 12 Jan 2015
 

QuestionForm edit

Subject Using an extension
Extension JQueryPlugin
Version Foswiki 1.1.4
Status Answered
Related Topics
Topic revision: r12 - 12 Jan 2015, MichaelDaum - This page was cached on 22 Jun 2018 - 00:12.

The copyright of the content on this website is held by the contributing authors, except where stated elsewhere. See Copyright Statement. Creative Commons License    Legal Imprint    Privacy Policy