%META:TOPICINFO{author="ProjectContributor" date="1645517959" format="1.1" version="1"}%
%META:TOPICPARENT{name="JQueryPlugin"}%
---+!! %TOPIC%
%JQREQUIRE{"chili, ui, ui::autocomplete" warn="off"}%

This page contains a set of example JQueryPlugin helpers that can be used in
wiki applications. The examples demonstrate how you can
dynamically populate autocomplete enabled input boxes using JQueryUIAutocomplete.

Examples are in two parts; a *Client* section and a *Server* section.
The *Client* section is designed to be included into your topics using
=[[VarINCLUDE][%<nop>INCLUDE]]=. The *Server* section is expanded in
response to an AJAX request from a jQuery plugin.

This page also acts as a library of some commonly-used form inputs. For
example, the [[#Topic_selector][Topic selector]] example can be used
in your own topics to define an HTML form input with the name =newtopic=
by putting this in your topic:
<verbatim class="tml">
%JQREQUIRE{"ui::autocomplete"}%
%INCLUDE{
 "%SYSTEMWEB%.JQueryAjaxHelper"
 section="topicselector"
 INPUT_NAME="newtopic"
 EXCLUDE="Web*"
}%
</verbatim>

%TOC%

Note that the examples below are implemented
using base Foswiki functionality. There are a range of plugins, such as
Foswiki:Extensions.RenderPlugin, Foswiki:Extensions.FlexWebListPlugin and
Foswiki:Extensions.DBCachePlugin that can be used to simplify or improve
these sections when building up your own library of input types. Some
examples of the use of these plugins are given at the end of this topic.

---++ Topic selector
Select a topic in the current web. JQueryUIAutocomplete is given a url that
loads the =topic= section of this topic, which expands to the topic list.

---+++ Client section
*INCLUDE Parameters*
   * =INPUT_NAME=: name (and id) of HTML input field
   * =INPUT_VALUE=: preselected value
   * =PLACEHOLDER=: example value
   * =EXCLUDE=: exclude expression to filter out unwanted topics, see the
     =excludetopic= parameter in VarSEARCH
<verbatim class="tml">
%STARTSECTION{"topicselector"}%<!-- topicselector  -->
<input type="text" class="foswikiInputField" name="%INPUT_NAME%" id="%INPUT_NAME%" %IF{"defined PLACEHOLDER" then="placeholder=\"%PLACEHOLDER%\""}% autocomplete="%SCRIPTURL{"view"}%/%SYSTEMWEB%/JQueryAjaxHelper?section=topic;skin=text;contenttype=application/json;baseweb=%BASEWEB%;%IF{"defined EXCLUDE" then="exclude=%EXCLUDE%"}%" size="60" value="%IF{"defined INPUT_VALUE" then="%INPUT_VALUE%"}%" />
<!-- //topicselector -->%ENDSECTION{"topicselector"}%
</verbatim>

---+++ Server section
*URL parameters*
   * =term=: search term substring typed so far
   * =limit=: number of search results to return, defaults to 10
   * =baseweb=: the web where to search for topics
   * =exclude=: exclude expression to filter out unwanted topics
<verbatim class="tml">
%STARTSECTION{"topic"}%[%SEARCH{
  "^%URLPARAM{"term" default="does not exist"}%.*"
  type="regex"
  scope="topic"
  format="<nop>%URLPARAM{"format" encode="safe,quote" default="{\\"label\\":\\"$topic\\", \\"value\\":\\"$topic\\"}"}%"
  separator=","
  limit="%URLPARAM{"limit" default="10"}%"
  nonoise="on"
  excludetopic="%URLPARAM{"exclude"}%"
  web="%URLPARAM{"baseweb" default="%BASEWEB%"}%"
}%]%ENDSECTION{"topic"}%
</verbatim>

---+++ Example
<form>
<div class="foswikiFormSteps">
<div class="foswikiFormStep">
<h3 >Select a topic:</h3>
%INCLUDE{"%TOPIC%" section="topicselector" INPUT_NAME="newtopic" EXCLUDE="FamFamFamMint*" PLACEHOLDER="(Begin typing topic name)" }%
</div>
</div>
</form>

---++ Web selector
Select from a list of webs, using autocomplete

<div class="foswikiHelp">%X% __Note:__ there is currently no way to filter a list of webs in the
default Foswiki core. %IF{"context FlexWebListPluginEnabled" then="This
example uses the FlexWebListPlugin to obtain the list of webs."
else="!FlexWeblist Plugin is *not* installed.  To use this example you will have to install
Foswiki:Extensions.FlexWebListPlugin. "}% </div>

---+++ Client section
*INCLUDE Parameters*
   * =INPUT_NAME=: name of text input field
   * =INPUT_VALUE=: preselected value
   * =PLACEHOLDER=: example value
<verbatim class="tml">
%STARTSECTION{"webselector"}%<!-- webselector  -->
<input type="text" class="foswikiInputField" name="%INPUT_NAME%" id="%INPUT_NAME%" %IF{"defined PLACEHOLDER" then="placeholder=\"%PLACEHOLDER%\""}% autocomplete="%SCRIPTURL{"view"}%/%SYSTEMWEB%/JQueryAjaxHelper?section=web;skin=text;contenttype=application/json;%IF{"defined EXCLUDE" then="exclude=%EXCLUDE%"}%" size="60" value="%IF{"defined INPUT_VALUE" then="%INPUT_VALUE%"}%" />
<!-- //webselector -->%ENDSECTION{"webselector"}%
</verbatim>

---+++ Server section
*URL parameters*
   * =term=: search term substring typed so far
   * =limit=: number of search results to return, defaults to 10
<verbatim class="tml">
%STARTSECTION{"web"}%[%FLEXWEBLIST{
  include="^%URLPARAM{"term" default="does not exist"}%.*"
  ignorecase="on"
  limit="%URLPARAM{"limit" default="10"}%"
  format="\"<nop>$web\""
  separator=", "
  subheader=", "
  subfooter=" "
}%]%ENDSECTION{"web"}%
</verbatim>

---+++ Example
<form>
<div class="foswikiFormSteps">
<div class="foswikiFormStep">
<h3 >Select a web:</h3>
%IF{"context FlexWebListPluginEnabled" then="$percntINCLUDE{\"%TOPIC%\" section=\"webselector\" INPUT_NAME=\"newweb\"}$percnt" else="Install Foswiki:Extensions.FlexWebListPlugin to use this example"}%
</div>
</div>
</form>

---++ Jump box
Jump to specific topics.

---+++ Client section
*INCLUDE Parameters*
   * =GLOBAL=: toggle search for topics in all webs on/off, defaults to off
   * =PLACEHOLDER=: Example text
<verbatim class="tml">
%STARTSECTION{"jumpbox"}%<!-- jumpbox -->
<input type="text" class="foswikiInputField jqJumpBox {%IF{
  "$GLOBAL = 'on'"
  then="global: true, baseweb:'all, -%TRASHWEB%'"
  else="global: false, baseweb:'%BASEWEB%'"
}%}" name="topic" %IF{"defined PLACEHOLDER" then="placeholder=\"%PLACEHOLDER%\""}% autocomplete="off" size="60" />
%ADDTOZONE{"script"
  tag="jumpbox::js"
  section="jumpbox::js"
  requires="JQUERYPLUGIN::UI::AUTOCOMPLETE"
}%
<!-- //jumpbox -->%ENDSECTION{"jumpbox"}%
</verbatim>
The following section is used by the section above; it adds a special Javascript function to the page.
<verbatim class="tml">
%STARTSECTION{"jumpbox::js"}%<literal>
<script>
jQuery(function($){
  $(".jqJumpBox").each(function() {
    var $this = $(this), 
        opts = $.extend({}, $this.metadata());
    $this.autocomplete({
      source: foswiki.getScriptUrl('view', foswiki.getPreference('SYSTEMWEB'), 'JQueryAjaxHelper', {
        section: 'topic',
        skin: 'text',
        contenttype: 'application/json',
        baseweb: opts.baseweb,
      }),
      select: function(event, ui) {
        window.location.href = foswiki.getScriptUrl('view', undefined, ui.item.value);
      }
    });
  });
});
</script>
</literal>%ENDSECTION{"jumpbox::js"}%
</verbatim>
---+++ Server section
Uses the =[[#Topic_selector][topic]]= server section, defined above.

---+++ Examples
---++++ Jump to a topic in the current web
<form>
<div class="foswikiFormSteps">
<div class="foswikiFormStep">
<h3 >Local Jump:</h3>
%INCLUDE{"%TOPIC%" section="jumpbox" PLACEHOLDER="(Begin typing topic name)" }%
</div>
</div>
</form>
---++++ Jump to a topic in any web
<form>
<div class="foswikiFormSteps">
<div class="foswikiFormStep">
<h3 >Global Jump:</h3>
%INCLUDE{"%TOPIC%" section="jumpbox" PLACEHOLDER="(Begin typing topic name)" GLOBAL="on"}%
</div>
</div>
</form>

---++ User selector 
<div class="foswikiHelp">%X% *Note:* This example obtains user information with the %<nop>USERINFO% macro.   If the wiki is configured to hide user details (=$Foswiki::cfg{AntiSpam}{HideUserDetails}=), then this example will not work unless you are an administrator.</div>

---+++ Client section
*INCLUDE Parameters*
   * =INPUT_NAME=: name of text input field
   * =INPUT_VALUE=: preselected user
   * =PLACEHOLDER=: example value 
<verbatim class="tml">
%STARTSECTION{"userselector"}%<!-- userselector -->
<input type="text" class="foswikiInputField jqUserSelector" name="%INPUT_NAME%" id="%INPUT_NAME%" %IF{"defined PLACEHOLDER" then="placeholder=\"%PLACEHOLDER%\""}% autocomplete="%SCRIPTURL{"view"}%/%SYSTEMWEB%/JQueryAjaxHelper?section=user;skin=text;contenttype=application/json" size="60" value="%IF{"defined INPUT_VALUE" then="%INPUT_VALUE%"}%" />
%ADDTOZONE{"script"
  tag="userselector::js"
  section="userselector::js"
  requires="JQUERYPLUGIN::UI::AUTOCOMPLETE"
}%
<!-- //userselector -->%ENDSECTION{"userselector"}%
</verbatim>
The following section is used by the section above; it adds a special Javascript function to the page.
<verbatim class="tml">
%STARTSECTION{"userselector::js"}%<literal>
<script>
jQuery(function($){
  $(".jqUserSelector").data("ui-autocomplete")._renderItem = function(ul, item) {
    if (typeof(item.label) !== 'undefined') {
      return $("<li></li>")
        .data("item.autocomplete", item)
        .append("<a><table width='100%'><tr><td width='60px'><img width='50' src='"+item.img+"' /></td><td>"+item.label+"<br />"+item.email+"</td></tr></table></a>")
        .appendTo(ul);
    }
  };
});
</script>
</literal>%ENDSECTION{"userselector::js"}%
</verbatim>
---+++ Server section
*URL parameters*
   * =term=: search term substring typed so far
   * =limit=: number of search results to return, defaults to 10
<verbatim class="tml">
%STARTSECTION{"user"}%<literal>[%FORMAT{
  "%SEARCH{
     ".*%URLPARAM{"term" default="does not exist"}%.*"
     type="regex"
     scope="topic"
     format="$percntIF{\"'$percntGROUPINFO{\"$topic\" format=\"$dollarname, \" limit=\"1\"}$percnt'=''\"
          then=\"$percntUSERINFO{\"$topic\" format=\"$dollarwikiname, \"}$percnt\"
          else=\"$percntGROUPINFO{\"$topic\" format=\"$dollarname, \" limit=\"1\"}$percnt\"
        }$percnt"
     separator=""
     limit="%URLPARAM{"limit" default="10"}%"
     nonoise="on"
     web="%USERSWEB%"
  }%"
  type="string"
  format="  {\"label\":\"<nop>$item\", 
    \"email\":\"$percntUSERINFO{\"$item\" format=\"$emails\"}$percnt\", 
    \"img\":\"$percntFORMFIELD{\"Photo\" 
      topic=\"%USERSWEB%.$item\" 
      default=\"%PUBURLPATH%/%SYSTEMWEB%/JQueryPlugin/images/nobody.gif\" 
      alttext=\"%PUBURLPATH%/%SYSTEMWEB%/JQueryPlugin/images/nobody.gif\" 
    }$percnt\"
  }"
  separator=",$n"
}%]</literal>%ENDSECTION{"user"}%
</verbatim>

---+++ Example
<form>
<div class="foswikiFormSteps">
<div class="foswikiFormStep">
<h3 >Find user:</h3>
%INCLUDE{"%TOPIC%" section="userselector" INPUT_NAME="user" MULTI="true"
%PLACEHOLDER="(Begin typing wikiname)"}%
</div>
</div>
</form>

---++ Query fetcher
Perform a =[[VarQUERY][%<nop>QUERY]]= asynchronously (requires Foswiki 1.1
or later).

---+++ Client section
*INCLUDE Parameters*
   * =ID=: id of an element to bind an onclick event to
   * =SOURCE=: topic to get the field from
   * =QUERY=: query to perform
<verbatim class="tml">
%STARTSECTION{"queryfetcher"}%%ADDTOZONE{"script"
  tag="query::js"
  requires="JQUERYPLUGIN"
  text ="<literal>
<script>
jQuery(function($){
  $(\"#%ID%\").click(function() {
     $.get(foswiki.getScriptUrl('view', foswiki.getPreference('SYSTEMWEB'), 'JQueryAjaxHelper', {
          section: 'query',
          source: '%SOURCE%',
          query: '%QUERY%',
          skin: 'text'
         }),
         function(data) {
             // This is the function that will be executed when the
             // data is fetched
             alert('%QUERY% is ' + data);
         });
  });
});
</script></literal>
"}%%ENDSECTION{"queryfetcher"}%
</verbatim>

---+++ Server section
*URL parameters*
   * =source=: source topic 
   * =query=: query to perform
<verbatim class="tml">
%STARTSECTION{"query"}%<noautolink>%QUERY{
  "'%URLPARAM{"source" default="%BASEWEB%.%BASETOPIC%"}%'/%URLPARAM{"query" default="query missing"}%"
  style="json"
}%</noautolink>%ENDSECTION{"query"}%
</verbatim>

---+++ Example
%INCLUDE{"%TOPIC%" section="queryfetcher" ID="jqQueryExample" SOURCE="%WEB%.%TOPIC%" QUERY="parent.name"}%
<input type="button" class="foswikiButton" id="jqQueryExample" value="Click here" /> to get the parent of this topic asynchronously (should be '%QUERY{"parent.name"}%')

---++ Other selectors
Server sections for some other selectors that are common in wiki applications.

---+++ Formfield
Fetch a formfield from a topic asynchronously.
Uses [[VarFORMFIELD][FORMFIELD]], which is deprecated in Foswiki 1.1. Foswiki 1.1 and later should use [[VarQUERY][QUERY]]

*URL Parameters*
   * =source=: source topic 
   * =formfield=: name of formfiled to retrieve

---++++ Server section
<verbatim class="tml">
%STARTSECTION{"formfield"}%%FORMFIELD{
  "%URLPARAM{"formfield" default="does not exist"}%"
  topic="%URLPARAM{"source" default="does not exist"}%"
}%%ENDSECTION{"formfield"}%
</verbatim>

---+++ User photo
This one returns an =&lt;img...>= to a user's photo. See the User selector example above.

*URL Parameters*
   * =name=: name of user
   * =height=: image height, defaults to 50

---++++ Server section
<verbatim class="tml">
%STARTSECTION{"userphoto"}%<img src='%FORMFIELD{"Photo" topic="%USERINFO{"%URLPARAM{"name" default="does not exist"}%" format="$wikiusername"}%" default="%PUBURLPATH%/%SYSTEMWEB%/JQueryPlugin/images/nobody.gif" alttext="%PUBURLPATH%/%SYSTEMWEB%/JQueryPlugin/images/nobody.gif"}%' alt='%URLPARAM{"name"}%' height='%URLPARAM{"height" default="50"}%' />%ENDSECTION{"userphoto"}%
</verbatim>

---+++ Expand TML
expand a TML expression in the given scope

---++++ Server section
*URL parameters*
   * =expression=: TML to be evaluated; will be wrapped into %...% before executing it
   * =scope=: optionally defines the topic within which the expression is expanded

<verbatim class="tml">
%STARTSECTION{"expand"}%%EXPAND{"$percnt%URLPARAM{"expression"}%$percnt" scope="%URLPARAM{"scope" default="%BASEWEB%.%BASETOPIC%"}%"}%%ENDSECTION{"expand"}%
</verbatim>
%META:PREFERENCE{name="ALLOWTOPICVIEW" title="ALLOWTOPICVIEW" type="Set" value="*"}%
