自動完成插件作爲道場AMD模塊(根據AMD規則放入/gefc/dijit/AutoComplete.js):
//
// AutoComplete style widget which works together with an ItemFileReadStore
//
// It will re-query the server whenever necessary.
//
define([
"dojo/_base/declare",
"dijit/form/FilteringSelect"
],
function(declare, _FilteringSelect) {
return declare(
[_FilteringSelect], {
// minimum number of input characters to trigger search
minKeyCount: 2,
// the term for which we have queried the server for the last time
lastServerQueryTerm: null,
// The query URL which will be set on the store when a server query
// is needed
queryURL: null,
//------------------------------------------------------------------------
postCreate: function() {
this.inherited(arguments);
// Setting defaults
if (this.searchDelay == null)
this.searchDelay = 500;
if (this.searchAttr == null)
this.searchAttr = "label";
if (this.autoComplete == null)
this.autoComplete = true;
if (this.minKeyCount == null)
this.minKeyCount = 2;
},
escapeRegExp: function (str) {
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
},
replaceAll: function (find, replace, str) {
return str.replace(new RegExp(this.escapeRegExp(find), 'g'), replace);
},
startsWith: function (longStr, shortStr) {
return (longStr.match("^" + shortStr) == shortStr)
},
// override search method, count the input length
_startSearch: function (/*String*/ key) {
// If there is not enough text entered, we won't start querying
if (!key || key.length < this.minKeyCount) {
this.closeDropDown();
return;
}
// Deciding if the server needs to be queried
var serverQueryNeeded = false;
if (this.lastServerQueryTerm == null)
serverQueryNeeded = true;
else if (!this.startsWith(key, this.lastServerQueryTerm)) {
// the key does not start with the server queryterm
serverQueryNeeded = true;
}
if (serverQueryNeeded) {
// Creating a query url templated with the autocomplete term
var url = this.replaceAll('${autoCompleteTerm}', key, this.queryURL);
this.store.url = url
// We need to close the store in order to allow the FilteringSelect
// to re-open it with the new query term
this.store.close();
this.lastServerQueryTerm = key;
}
// Calling the super start search
this.inherited(arguments);
}
}
);
});
注:
- 我包括一些串函數使其獨立,這些應該去你的JS庫中的適當位置。
中的JavaScript嵌入到其使用德自動完成插件的頁面:
require([
"dojo/ready",
"dojo/data/ItemFileReadStore",
"gefc/dijit/AutoComplete",
"dojo/parser"
],
function(ready, ItemFileReadStore, AutoComplete) {
ready(function() {
// The initially displayed data (current value, possibly null)
// This makes it possible that the widget does not fire a query against
// the server immediately after initialization for getting a label for
// its current value
var dt = null;
<g:if test="${tenantInstance.technicalContact != null}">
dt = {identifier:"id", items:[
{id: "${tenantInstance.technicalContact.id}",
label:"${tenantInstance.technicalContact.name}"
}
]};
</g:if>
// If there is no current value, this will have no data
var partnerStore = new ItemFileReadStore(
{ data: dt,
urlPreventCache: true,
clearOnClose: true
}
);
var partnerSelect = new AutoComplete({
id: "technicalContactAC",
name: "technicalContact.id",
value: "${tenantInstance?.technicalContact?.id}",
displayValue: "${tenantInstance?.technicalContact?.name}",
queryURL: '<g:createLink controller="partner"
action="listForAutoComplete"
absolute="true"/>?term=\$\{autoCompleteTerm\}',
store: partnerStore,
searchAttr: "label",
autoComplete: true
},
"technicalContactAC"
);
})
})
注:
- 這不是獨立JavaScript,但產生與在服務器端的Grails,因此您在代碼中看到
<g:if...
和其他服務器端標記)。用你自己的標記替換這些部分。
<g:createLink
將導致服務器端頁面生成後是這樣的:/Limes/partner/listForAutoComplete?term=${autoCompleteTerm}