summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--demos/quickstart/protected/pages/JuiControls/Home.page4
-rw-r--r--demos/quickstart/protected/pages/JuiControls/Samples/TJuiAutoComplete/Home.page45
-rw-r--r--demos/quickstart/protected/pages/JuiControls/Samples/TJuiAutoComplete/Home.php39
-rw-r--r--demos/quickstart/protected/pages/JuiControls/Widgets.page25
-rw-r--r--framework/Web/Javascripts/source/prado/activecontrols/activecontrols3.js29
-rw-r--r--framework/Web/UI/JuiControls/TJuiAutoComplete.php67
-rwxr-xr-xtests/FunctionalTests/quickstart/JuiControls/JuiAutoCompleteTestCase.php50
7 files changed, 244 insertions, 15 deletions
diff --git a/demos/quickstart/protected/pages/JuiControls/Home.page b/demos/quickstart/protected/pages/JuiControls/Home.page
index 2573b162..68765faa 100644
--- a/demos/quickstart/protected/pages/JuiControls/Home.page
+++ b/demos/quickstart/protected/pages/JuiControls/Home.page
@@ -80,6 +80,10 @@ For informations of the specific options of each interaction, follow jQuery-UI I
<a href="?page=JuiControls.Widgets#TJuiProgressbar">TJuiProgressbar</a>
displays a progress bar.
</li>
+ <li>
+ <a href="?page=JuiControls.Widgets#TJuiAutoComplete">TJuiProgressbar</a>
+ provides a list of suggestions on the current partial word typed in the textbox
+ </li>
</ul>
</com:TContent>
diff --git a/demos/quickstart/protected/pages/JuiControls/Samples/TJuiAutoComplete/Home.page b/demos/quickstart/protected/pages/JuiControls/Samples/TJuiAutoComplete/Home.page
new file mode 100644
index 00000000..1338b651
--- /dev/null
+++ b/demos/quickstart/protected/pages/JuiControls/Samples/TJuiAutoComplete/Home.page
@@ -0,0 +1,45 @@
+<com:TContent ID="body">
+<h1>TJuiAutoComplete Samples</h1>
+
+
+<table class="sampletable">
+
+<tr><td class="samplenote">
+Simple Autocompleter:
+</td><td class="sampleaction">
+<com:TJuiAutoComplete
+ ID="AutoComplete"
+ OnSuggest="suggestNames"
+ OnSuggestionSelected="suggestionSelected1"
+ ResultPanel.CssClass="acomplete"
+ Suggestions.DataKeyField="id" >
+
+ <prop:Suggestions.ItemTemplate>
+ <li><%# $this->Data['name'] %></li>
+ </prop:Suggestions.ItemTemplate>
+</com:TJuiAutoComplete>
+<com:TActiveLabel ID="Selection1" />
+</td></tr>
+
+<tr><td class="samplenote">
+Autocompleter with multiple selection:
+</td><td class="sampleaction">
+<com:TJuiAutoComplete
+ ID="AutoComplete2"
+ OnSuggest="suggestNames"
+ OnSuggestionSelected="suggestionSelected2"
+ Separator=","
+ ResultPanel.CssClass="acomplete"
+ Suggestions.DataKeyField="id" >
+
+ <prop:Suggestions.ItemTemplate>
+ <li><%# $this->Data['name'] %></li>
+ </prop:Suggestions.ItemTemplate>
+</com:TJuiAutoComplete>
+(Use ',' to separate the selected suggestions)
+<com:TActiveLabel ID="Selection2" />
+</td></tr>
+
+</table>
+
+</com:TContent>
diff --git a/demos/quickstart/protected/pages/JuiControls/Samples/TJuiAutoComplete/Home.php b/demos/quickstart/protected/pages/JuiControls/Samples/TJuiAutoComplete/Home.php
new file mode 100644
index 00000000..c3fba3a9
--- /dev/null
+++ b/demos/quickstart/protected/pages/JuiControls/Samples/TJuiAutoComplete/Home.php
@@ -0,0 +1,39 @@
+<?php
+
+class Home extends TPage
+{
+ public function suggestNames($sender,$param) {
+ // Get the token
+ $token=$param->getToken();
+ // Sender is the Suggestions repeater
+ $sender->DataSource=$this->suggestionsForName($token);
+ $sender->dataBind();
+ }
+
+ public function suggestionSelected1($sender,$param) {
+ $id=$sender->Suggestions->DataKeys[ $param->selectedIndex ];
+ $this->Selection1->Text='Selected ID: '.$id;
+ }
+
+ public function suggestionSelected2($sender,$param) {
+ $id=$sender->Suggestions->DataKeys[ $param->selectedIndex ];
+ $this->Selection2->Text='Selected ID: '.$id;
+ }
+
+ public function suggestionsForName($name) {
+ $allChoices = array(
+ array('id'=>1, 'name'=>'John'),
+ array('id'=>2, 'name'=>'Paul'),
+ array('id'=>3, 'name'=>'George'),
+ array('id'=>4, 'name'=>'Ringo')
+ );
+
+ if($name) {
+ return array_filter($allChoices, function ($el) use ($name) {
+ return stripos($el['name'], $name) !== false;
+ });
+ } else
+ return $allChoices;
+ }
+
+} \ No newline at end of file
diff --git a/demos/quickstart/protected/pages/JuiControls/Widgets.page b/demos/quickstart/protected/pages/JuiControls/Widgets.page
index cf72d41d..cedec675 100644
--- a/demos/quickstart/protected/pages/JuiControls/Widgets.page
+++ b/demos/quickstart/protected/pages/JuiControls/Widgets.page
@@ -10,7 +10,7 @@ PRADO Jui widgets controls can be divided in two groups:
For informations of the specific options of each widget, follow jQuery-UI Widget <a href="http://api.jqueryui.com/category/widgets/">API Documentation</a> for the specific interaction.
</p>
-<a name="TJuiProgressbar"></a>
+<a name="TJuiProgressbar" />
<h2>TJuiProgressbar</h2>
<com:DocLink ClassPath="System.Web.UI.JuiControls.TJuiProgressbar" /> - <a href="http://api.jqueryui.com/progressbar/">jQuery UI API</a>
@@ -25,4 +25,27 @@ The panel takes the aspect of a progressbar ranging from a value of 0 to the val
<com:RunBar PagePath="JuiControls.Samples.TJuiProgressbar.Home" />
<br/>
+<a name="TJuiAutoComplete" />
+<h2>TJuiAutoComplete</h2>
+<com:DocLink ClassPath="System.Web.UI.JuiControls.TJuiAutoComplete" /> - <a href="http://api.jqueryui.com/autocomplete/">jQuery UI API</a>
+
+<p class="block-content">
+<tt>TJuiAutoComplete</tt> is an extension to <a href="?page=ActiveControls.ActiveTextBox">TActiveTextBox</a> based on jQuery-UI's <a href="http://jqueryui.com/autocomplete/">autocomplete</a> widget.
+</p>
+
+<p class="block-content">
+TJuiAutoComplete is an extended ActiveTextBox that provides a list of suggestions on the current partial word typed in the textbox. The suggestions are requested using callbacks. The <tt>Frequency</tt> and <tt>MinChars</tt> properties sets the delay and minimum number of characters typed, respectively, before requesting for sugggestions. An embedded <tt>TRepeater</tt> is used to Display the list of suggestions. It can be accessed and styled through the Suggestions property and its sub-properties.
+</p>
+
+<p class="block-content">
+On each request for suggestions, the <tt>OnSuggestion</tt> event will be raised. The event handler receives the entered token that can be used to build the list of suggestions and to <tt>dataBind()</tt> it to the Suggestions repeater.
+</p>
+
+<p class="block-content">
+When a suggestion is selected the <tt>OnSuggestionSelected</tt> event is raised, with the index of the selected suggestion contained in the parameter. Multiple selections can be performed in the same textbox. The selections must be separated by any characters specified with the <tt>Separator</tt> property.
+</p>
+
+<com:RunBar PagePath="JuiControls.Samples.TJuiAutoComplete.Home" />
+<br/>
+
</com:TContent>
diff --git a/framework/Web/Javascripts/source/prado/activecontrols/activecontrols3.js b/framework/Web/Javascripts/source/prado/activecontrols/activecontrols3.js
index 0a7511c1..5d4beef8 100644
--- a/framework/Web/Javascripts/source/prado/activecontrols/activecontrols3.js
+++ b/framework/Web/Javascripts/source/prado/activecontrols/activecontrols3.js
@@ -103,7 +103,12 @@ Prado.WebUI.TJuiAutoComplete = jQuery.klass(Prado.WebUI.TActiveTextBox,
this.hasResults = false;
jQuery.extend(this.options, {
source: this.getUpdatedChoices.bind(this),
- select: this.selectEntry.bind(this)
+ select: this.selectEntry.bind(this),
+ focus: function () {
+ return false;
+ },
+ minLength: this.options.minLength,
+ frequency: this.options.frequency
});
jQuery('#'+options.ID).autocomplete(this.options)
.data( "ui-autocomplete")._renderItem = function( ul, item ) {
@@ -131,22 +136,38 @@ Prado.WebUI.TJuiAutoComplete = jQuery.klass(Prado.WebUI.TActiveTextBox,
getUpdatedChoices : function(request, callback)
{
- var params = new Array(request.term,"__TJuiAutoComplete_onSuggest__");
+ var lastTerm = this.extractLastTerm(request.term);
+ var params = new Array(lastTerm, "__TJuiAutoComplete_onSuggest__");
var options = jQuery.extend(this.options, {
'autocompleteCallback' : callback
});
Prado.Callback(this.options.EventTarget, params, this.onComplete.bind(this), this.options);
},
+ extractLastTerm: function(string)
+ {
+ var re = new RegExp("[" + this.options.Separators + "]");
+ return string.split(re).pop().trim();
+ },
+
/**
* Overrides parent implements, don't update if no results.
*/
- selectEntry: function(event, ui)
- {
+ selectEntry: function(event, ui) {
+ var value = event.target.value;
+ var lastTerm = this.extractLastTerm(value);
+
+ // strip (possibly) incomplete last part
+ var previousTerms = value.substr(0, value.length - lastTerm.length);
+ // and append selected value
+ ui.item.value = previousTerms + ui.item.value;
+
+ //ui.item.value = event.target.value;
var options = [ui.item.id, "__TJuiAutoComplete_onSuggestionSelected__"];
Prado.Callback(this.options.EventTarget, options, null, this.options);
},
+
onComplete : function(request, result)
{
var that = this;
diff --git a/framework/Web/UI/JuiControls/TJuiAutoComplete.php b/framework/Web/UI/JuiControls/TJuiAutoComplete.php
index 115969c5..f6663057 100644
--- a/framework/Web/UI/JuiControls/TJuiAutoComplete.php
+++ b/framework/Web/UI/JuiControls/TJuiAutoComplete.php
@@ -147,6 +147,57 @@ class TJuiAutoComplete extends TActiveTextBox implements INamingContainer, IJuiO
return $this->getViewState('TextCssClass');
}
+
+ /**
+ * @return string word or token separators (delimiters).
+ */
+ public function getSeparator()
+ {
+ return $this->getViewState('separator', '');
+ }
+
+ /**
+ * @param string word or token separators (delimiters).
+ */
+ public function setSeparator($value)
+ {
+ $this->setViewState('separator', TPropertyValue::ensureString($value), '');
+ }
+
+ /**
+ * @return float maximum delay (in seconds) before requesting a suggestion.
+ */
+ public function getFrequency()
+ {
+ return $this->getViewState('frequency', 0.4);
+ }
+
+ /**
+ * @param float maximum delay (in seconds) before requesting a suggestion.
+ * Default is 0.4.
+ */
+ public function setFrequency($value)
+ {
+ $this->setViewState('frequency', TPropertyValue::ensureFloat($value), 0.4);
+ }
+
+ /**
+ * @return integer minimum number of characters before requesting a suggestion.
+ */
+ public function getMinChars()
+ {
+ return $this->getViewState('minChars','');
+ }
+
+ /**
+ * @param integer minimum number of characters before requesting a suggestion.
+ * Default is 1
+ */
+ public function setMinChars($value)
+ {
+ $this->setViewState('minChars', TPropertyValue::ensureInteger($value), 1);
+ }
+
/**
* Raises the callback event. This method is overrides the parent implementation.
* If {@link setAutoPostBack AutoPostBack} is enabled it will raise
@@ -316,17 +367,11 @@ class TJuiAutoComplete extends TActiveTextBox implements INamingContainer, IJuiO
*/
protected function getPostBackOptions()
{
- //disallow page state update ?
- //$this->getActiveControl()->getClientSide()->setEnablePageStateUpdate(false);
$options = $this->getOptions()->toArray();
- /*
- if(strlen($string = $this->getSeparator()))
- {
- $string = strtr($string,array('\t'=>"\t",'\n'=>"\n",'\r'=>"\r"));
- $token = preg_split('//', $string, -1, PREG_SPLIT_NO_EMPTY);
- $options['tokens'] = $token;
- }
- */
+
+ if(strlen($separator = $this->getSeparator()))
+ $options['Separators'] = $separator;
+
if($this->getAutoPostBack())
{
$options = array_merge($options,parent::getPostBackOptions());
@@ -334,6 +379,8 @@ class TJuiAutoComplete extends TActiveTextBox implements INamingContainer, IJuiO
}
if(strlen($textCssClass = $this->getTextCssClass()))
$options['textCssClass'] = $textCssClass;
+ $options['minLength'] = $this->getMinChars();
+ $options['delay'] = $this->getFrequency()/1000.0;
$options['appendTo'] = '#'.$this->getResultPanel()->getClientID();
$options['ID'] = $this->getClientID();
$options['EventTarget'] = $this->getUniqueID();
diff --git a/tests/FunctionalTests/quickstart/JuiControls/JuiAutoCompleteTestCase.php b/tests/FunctionalTests/quickstart/JuiControls/JuiAutoCompleteTestCase.php
new file mode 100755
index 00000000..a3c1ff78
--- /dev/null
+++ b/tests/FunctionalTests/quickstart/JuiControls/JuiAutoCompleteTestCase.php
@@ -0,0 +1,50 @@
+<?php
+
+
+/**
+ * Testcase for TJuiAutoComplete
+ */
+class JuiAutoCompleteTestCase extends PradoGenericSelenium2Test
+{
+ function test ()
+ {
+ $this->url("../../demos/quickstart/index.php?page=JuiControls.Samples.TJuiAutoComplete.Home&amp;notheme=true&amp;lang=en");
+
+ $this->assertEquals("PRADO QuickStart Sample", $this->title());
+
+ $this->assertContains('TJuiAutoComplete Samples', $this->source());
+
+ $base = 'ctl0_body_';
+
+
+ $this->assertText("{$base}Selection1", "");
+
+ $this->byId("{$base}AutoComplete")->click();
+ $this->keys('J');
+ $this->pause(800);
+ $this->assertContains('John', $this->source());
+
+ $this->byCssSelector("#{$base}AutoComplete_result ul li")->click();
+ $this->pause(800);
+ $this->assertValue("{$base}AutoComplete", "John");
+ $this->assertText("{$base}Selection1", "Selected ID: 1");
+
+
+ $this->byId("{$base}AutoComplete2")->click();
+ $this->keys('Joh');
+ $this->pause(800);
+ $this->byCssSelector("#{$base}AutoComplete2_result ul li")->click();
+ $this->pause(800);
+ $this->assertValue("{$base}AutoComplete2", "John");
+ $this->assertText("{$base}Selection2", "Selected ID: 1");
+
+ //$this->keys(PHPUnit_Extensions_Selenium2TestCase_Keys::END);
+ $this->keys(',Ge');
+ $this->pause(800);
+ $this->byCssSelector("#{$base}AutoComplete2_result ul li")->click();
+ $this->pause(500);
+ $this->assertValue("{$base}AutoComplete2", "John,George");
+ $this->assertText("{$base}Selection2", "Selected ID: 3");
+
+ }
+}