You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2007/11/20 02:12:30 UTC
svn commit: r596506 - in /tapestry/tapestry5/trunk/tapestry-core/src:
main/java/org/apache/tapestry/corelib/components/
main/java/org/apache/tapestry/corelib/mixins/
main/resources/org/apache/tapestry/ site/ site/apt/ site/apt/guide/
test/app1/ test/ja...
Author: hlship
Date: Mon Nov 19 17:12:28 2007
New Revision: 596506
URL: http://svn.apache.org/viewvc?rev=596506&view=rev
Log:
TAPESTRY-1650: Tracking issue for Ajax support
Added:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/Autocomplete.java
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/ajax-loader.gif (with props)
tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/ajax.apt
tapestry/tapestry5/trunk/tapestry-core/src/test/app1/AutocompleteDemo.tml
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/AutocompleteDemo.java
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/DateField.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextArea.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextField.java
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/default.css
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/tapestry.js
tapestry/tapestry5/trunk/tapestry-core/src/site/apt/index.apt
tapestry/tapestry5/trunk/tapestry-core/src/site/site.xml
tapestry/tapestry5/trunk/tapestry-core/src/test/app1/Start.tml
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/AppModule.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/MusicLibrary.java
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/DateField.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/DateField.java?rev=596506&r1=596505&r2=596506&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/DateField.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/DateField.java Mon Nov 19 17:12:28 2007
@@ -188,8 +188,6 @@
configure(setup);
- // TODO: protected method to let subclasses provide more setup.
-
_support.addScript("Calendar.setup(%s);", setup);
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextArea.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextArea.java?rev=596506&r1=596505&r2=596506&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextArea.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextArea.java Mon Nov 19 17:12:28 2007
@@ -15,7 +15,6 @@
package org.apache.tapestry.corelib.components;
import org.apache.tapestry.MarkupWriter;
-import org.apache.tapestry.annotations.AfterRender;
import org.apache.tapestry.corelib.base.AbstractTextField;
/**
@@ -29,20 +28,22 @@
@Override
protected final void writeFieldTag(MarkupWriter writer, String value)
{
- writer.element("textarea", "name", getElementName(), "id", getClientId());
+ writer.element("textarea",
+
+ "name", getElementName(),
+
+ "id", getClientId());
// Save until needed in after()
_value = value;
}
- @AfterRender
- final void after(MarkupWriter writer)
+ final void afterRender(MarkupWriter writer)
{
// TextArea will not have a template.
- if (_value != null)
- writer.write(_value.toString());
+ if (_value != null) writer.write(_value);
writer.end(); // textarea
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextField.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextField.java?rev=596506&r1=596505&r2=596506&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextField.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextField.java Mon Nov 19 17:12:28 2007
@@ -27,16 +27,15 @@
@Override
protected final void writeFieldTag(MarkupWriter writer, String value)
{
- writer.element(
- "input",
- "type",
- "text",
- "name",
- getElementName(),
- "id",
- getClientId(),
- "value",
- value);
+ writer.element("input",
+
+ "type", "text",
+
+ "name", getElementName(),
+
+ "id", getClientId(),
+
+ "value", value);
}
final void afterRender(MarkupWriter writer)
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/Autocomplete.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/Autocomplete.java?rev=596506&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/Autocomplete.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/Autocomplete.java Mon Nov 19 17:12:28 2007
@@ -0,0 +1,195 @@
+package org.apache.tapestry.corelib.mixins;
+
+import org.apache.tapestry.*;
+import org.apache.tapestry.annotations.Environmental;
+import org.apache.tapestry.annotations.InjectContainer;
+import org.apache.tapestry.annotations.Parameter;
+import org.apache.tapestry.annotations.Path;
+import org.apache.tapestry.internal.util.Holder;
+import org.apache.tapestry.ioc.annotations.Inject;
+import org.apache.tapestry.ioc.services.TypeCoercer;
+import org.apache.tapestry.json.JSONArray;
+import org.apache.tapestry.json.JSONObject;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.services.MarkupWriterFactory;
+import org.apache.tapestry.services.Request;
+import org.apache.tapestry.util.TextStreamResponse;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A mixin for a text field that allows for autocompletion of text fields. This is based on Prototype's autocompleter
+ * control.
+ * <p/>
+ * The mixin renders an (initially invisible) progress indicator after the field (it will also be after
+ * the error icon most fields render). The progress indicator is made visible during the request to the server.
+ * The mixin then renders a <div> that will be filled in on the client
+ * side with dynamically obtained selections.
+ * <p/>
+ * Multiple selection on the client is enabled by binding the tokens parameter (however, the mixin doesn't
+ * help split multiple selections up on the server, that is still your code's responsibility).
+ * <p/>
+ * The container is responsible for providing an event handler for event "providecompletions". The context
+ * will be the partial input string sent from the client. The return value should be an array or list of
+ * completions, in presentation order. I.e.
+ * <p/>
+ * <pre>
+ * String[] onProvideCompletionsFromMyField(String input)
+ * {
+ * return . . .;
+ * }
+ * </pre>
+ */
+public class Autocomplete
+{
+ static final String EVENT_NAME = "autocomplete";
+ private static final String PARAM_NAME = "t:input";
+
+ /**
+ * The field component to which this mixin is attached.
+ */
+ @InjectContainer
+ private Field _field;
+
+ @Inject
+ private ComponentResources _resources;
+
+ @Environmental
+ private PageRenderSupport _pageRenderSupport;
+
+ @Inject
+ private Request _request;
+
+ @Inject
+ private TypeCoercer _coercer;
+
+ @Inject
+ private MarkupWriterFactory _factory;
+
+ @Inject
+ @Path("classpath:org/apache/tapestry/ajax-loader.gif")
+ private Asset _loader;
+
+ /**
+ * Overwrites the default minimum characters to trigger a server round trip (the default is 1).
+ */
+ @Parameter(defaultPrefix = "literal")
+ private int _minChars;
+
+
+ /**
+ * Overrides the default check frequency for determining whether to send a server request.
+ * The default is .4 seconds.
+ */
+ @Parameter(defaultPrefix = "literal")
+ private double _frequency;
+
+ /**
+ * If given, then the autocompleter will support multiple input values, seperated by
+ * any of the individual characters in the string.
+ */
+ @Parameter(defaultPrefix = "literal")
+ private String _tokens;
+
+ /**
+ * Mixin afterRender phrase occurs after the component itself. This is where we write the <div>
+ * element and the JavaScript.
+ *
+ * @param writer
+ */
+ void afterRender(MarkupWriter writer)
+ {
+ String id = _field.getClientId();
+
+ String menuId = id + ":menu";
+ String loaderId = id + ":loader";
+
+ // This image is made visible while the request is being processed.
+ // To be honest, I think Prototype hides it too soon, it should wait
+ // until the <div> is fully positioned and updated.
+
+ writer.element("img",
+
+ "src", _loader.toClientURL(),
+
+ "class", "t-invisible",
+
+ "id", loaderId);
+ writer.end();
+
+ writer.element("div",
+
+ "id", menuId,
+
+ "class", "t-autocomplete-menu");
+ writer.end();
+
+ Link link = _resources.createActionLink(EVENT_NAME, false);
+
+
+ JSONObject config = new JSONObject();
+ config.put("paramName", PARAM_NAME);
+ config.put("indicator", loaderId);
+
+ if (_resources.isBound("minChars")) config.put("minChars", _minChars);
+
+ if (_resources.isBound("frequency")) config.put("frequency", _frequency);
+
+ if (_resources.isBound("tokens"))
+ {
+ JSONArray tokens = new JSONArray();
+ for (int i = 0; i < _tokens.length(); i++)
+ {
+ tokens.put(_tokens.substring(i, i + 1));
+ }
+
+ config.put("tokens", tokens);
+ }
+
+ _pageRenderSupport.addScript("new Ajax.Autocompleter('%s', '%s', '%s', %s);", id, menuId, link, config);
+ }
+
+ Object onAutocomplete()
+ {
+ String input = _request.getParameter(PARAM_NAME);
+
+ final Holder<List> matchesHolder = Holder.create();
+
+ // Default it to an empty list.
+
+ matchesHolder.put(Collections.emptyList());
+
+ ComponentEventHandler handler = new ComponentEventHandler()
+ {
+ public boolean handleResult(Object result, Component component, String methodDescription)
+ {
+ List matches = _coercer.coerce(result, List.class);
+
+ matchesHolder.put(matches);
+
+ return true;
+ }
+ };
+
+ _resources.triggerEvent("providecompletions", new Object[]{input}, handler);
+
+ MarkupWriter writer = _factory.newMarkupWriter();
+
+ // T4.1 has more flexibility, it can decorate the options with icons, etc.
+ // But this will do for now.
+
+ writer.element("ul");
+
+ for (Object o : matchesHolder.get())
+ {
+ writer.element("li");
+ writer.write(o.toString());
+ writer.end();
+ }
+
+ writer.end(); // ul
+
+ return new TextStreamResponse("text/html", writer.toString());
+ }
+}
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/ajax-loader.gif
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/ajax-loader.gif?rev=596506&view=auto
==============================================================================
Binary file - no diff available.
Propchange: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/ajax-loader.gif
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/default.css
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/default.css?rev=596506&r1=596505&r2=596506&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/default.css (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/default.css Mon Nov 19 17:12:28 2007
@@ -314,3 +314,26 @@
padding: none;
}
+DIV.t-autocomplete-menu UL {
+ border: 2px outset #cc9933;
+ background-color: #cc9933;
+ magin-left: 12px;
+ padding: 4px 6px;
+ width: 300px;
+ height: 360px;
+ overflow: auto;
+}
+
+DIV.t-autocomplete-menu LI {
+ color: white;
+ list-style-type: none;
+ padding: 0px;
+ margin: 0px;
+ border-bottom: 1px solid black;
+ cursor: pointer;
+}
+
+DIV.t-autocomplete-menu LI.selected {
+ color: black;
+ font-weight: bold;
+}
\ No newline at end of file
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/tapestry.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/tapestry.js?rev=596506&r1=596505&r2=596506&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/tapestry.js (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/tapestry.js Mon Nov 19 17:12:28 2007
@@ -369,5 +369,3 @@
element.removeClassName("t-invisible");
});
});
-
-
\ No newline at end of file
Added: tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/ajax.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/ajax.apt?rev=596506&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/ajax.apt (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/ajax.apt Mon Nov 19 17:12:28 2007
@@ -0,0 +1,145 @@
+ ---
+ Tapestry Ajax Support
+ ---
+
+Tapestry Ajax Support
+
+ Tapestry includes sophisticated JavaScript and Ajax support, based on the
+ {{{http://www.prototypejs.org/}Prototype}} and
+ {{{http://script.aculo.us/}Scriptaculous}} libraries. These libraries are
+ all packaged with Tapestry itself ... no extra download required.
+
+ The goal for Tapestry is to have many basic and useful components available within the
+ application itself, and make it easy for other JavaScript widgets to be encapsulated as
+ Tapestry components.
+
+ Ajax support takes the form of new components and, occasionally,
+ {{{mixins.html}component mixins}}.
+
+Basic JavaScript
+
+ The general strategy in Tapestry is that any significant amount of JavaScript should be packaged up
+ as a static JavaScript library, a .js file that can be downloaded to the client.
+
+ Page specific JavaScript should be in the form of minimal statements to initialize objects, referencing
+ the JavaScript libraries.
+
+ Most of this is accomplished via the
+ {{{../../apidocs/org/apache/tapestry/PageRenderSupport.html}PageRenderSupport}} object.
+
+ PageRenderSupport include a number of methods that will be used by components, or event by
+ services that are called from components.
+
+* addScriptLink()
+
+ <<<void addScriptLink(Asset... scriptAssets);>>>
+
+ This method adds a link to a script file, a JavaScript library. A component can inject such a script and
+ pass one or more of assets to this method. Tapestry will ensure that the necessary \<link\> elements
+ are added to the <top> of the document (just inside the \<head\> element).
+
+ Adding the same asset multiple times does <not> create duplicate links. The subsequent ones are simply
+ ignored. In this way, each component can add the assets it needs, without worrying about conflicts
+ with other components.
+
+ Note that the Prototype, Scriptaculous and the base Tapestry library (which largely consists of
+ support for form input validation) are included automatically.
+
+* addScript()
+
+ <<<void addScript(String format, Object... arguments);>>>
+
+ This method adds some initialization JavaScript to the page. By <initialization> we mean that
+ it goes at the bottom of the document, and will only be executed when the document has finished loading
+ on the client (i.e., from the window.onload event handler).
+
+ When calling the method, the format string can include standard substitutions (such as '%s')
+ for arguments. This saves you the trouble of calling String.format() yourself. In any case, the
+ formatting JavaScript is added to the script block.
+
+* Injecting PageRenderSupport
+
+ PageRenderSupport is an <environmental> object, so you will normally inject it via the
+ {{{../../apidocs/org/apache/tapestry/annotations/Environmental.html}Environmental}} annotation:
+
++---+
+ @Environmental
+ private PageRenderSupport _pageRenderSupport;
++---+
+
+ Environmental only works inside components and occasionally a service may want to
+ inject PageRenderSupport. Fortunately, a proxy of PageRenderSupport has been set up. The upshot of which
+ is, you may also:
+
++---+
+ @Inject
+ private PageRenderSupport _pageRenderSupport;
++----+
+
+ ... or, in a service implementation constructor:
+
++---+
+ public MyServiceImpl(PageRenderSupport support)
+ {
+ . . .
+ }
++---+
+
+ Inside a component, you should use Environmental, to highlight the fact that PageRenderSupport (like most
+ environmental objects) is only available during rendering, not during action requests.
+
+Autocomplete Mixin
+
+ The
+ {{{../../apidocs/org/apache/tapestry/corelib/mixins/Autocomplete.html}Autocomplete}}
+ mixin exists to allow a text field to query the server for completions for a partially
+ entered phrase. It is often used in situations where the field exists to select a single value from
+ a large set, too large to succesfully download to the client as a drop down list; for example, when the
+ number of values to select from is numbered in the thousands.
+
+ Autocomplete can be added to an existing text field:
+
++---+
+ <t:textfield t:id="accountName" t:mixins="autocomplete" size="100"/>
++---+
+
+
+ The mixin can be configured in a number of ways, see the
+ {{{../component-parameters.html}component reference}}.
+
+ When the user types into the field, the client-side JavaScript will send a request to the server to
+ get completions.
+
+ You must write an event handler to provide these completions. The name of the event is "providecompletions".
+ The context is the partial input value, and the return value will be converted into the selections
+ for the user.
+
+ For example:
+
++---+
+ List<String> onProvideCompletionsFromAccountName(String partial)
+ {
+ List<Account> matches = _accountDAO.findByPartialAccountName(partial);
+
+ List<String> result = new ArrayList<String>():
+
+ for (Account a : matches)
+ {
+ result.add(a.getName());
+ }
+
+ return result;
+ }
++---+
+
+ This presumes that <<<findByPartialAccountName()>>> will sort the values, otherwise you will probably
+ want to sort them. Certainly the Autocomplete mixin does <not> do any sorting.
+
+ You can return an object array, a list, even a single object. You may return objects instead of strings ... and
+ <<<toString()>>> will be used to convert them into client-side strings.
+
+ Tapestry's default stylesheet includes entries for controlling the look of the floating popup of selections.
+
+ You may override <<<DIV.t-autocomplete-menu UL>>> to change the main look and feel,
+ <<<DIV.t-autocomplete-menu LI>>> for a normal item in the popup list, and
+ <<<DIV.t-autocomplete-menu LI.selected>>> for the element under the cursor (or selecting using the arrow keys).
\ No newline at end of file
Modified: tapestry/tapestry5/trunk/tapestry-core/src/site/apt/index.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/site/apt/index.apt?rev=596506&r1=596505&r2=596506&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/site/apt/index.apt (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/site/apt/index.apt Mon Nov 19 17:12:28 2007
@@ -13,6 +13,9 @@
Progress on Tapestry 5 is really taking off. This space lists some cool new features that have been added
recently.
+ * We're finally starting to see some Ajax support, beginning with the
+ {{{../apidocs/org/apache/tapestry/corelib/mixins/Autocomplete.html}Autocomplete mixin}}.
+
* You may now customize how the TextField, PasswordField and TextArea component converts between server side values
and client side strings, using specialized events.
@@ -49,68 +52,7 @@
* Explicit \<!DOCTYPE\> declarations inside page and component templates will now be forwarded through to the client
web browser.
- * The mapping from class names to page names (or component types) has been tweaked to remove some redundancy;
- For example,
- class org.example.myapp.pages.edit.EditUser will now have the name "edit/User" rather than "edit/EditUser". This
- results in shorter, clearer, more natural URLs.
-
- * The type of component may now be specified in a template using the element name, rather than the
- t:type attribute (this represents an incompatible change from 5.0.2).
-
- * Form validation now runs on the client side (as well as on the server side) with some basic effects,
- built on {{{http://script.taculo.us}script.taculo.us}}.
-
- * The default ExceptionReport page has been improved to show details of the incoming request,
- to filter out repetitive and unnecessary data,
- and to display file content when an exception includes a location.
-
- * Action request URLs have been shortened and simplified for the common case. They may also include a query
- parameter to identify the page's activation context.
-
- * {{{component-parameters.html}Component Reference Documentation}}, generated via a Maven plugin, is now available.
-
- * The return values for the "after" set of {{{guide/rendering.html}render phase methods}} have changed: all render phase
- methods return true (or void) to progress down the default path, and return false to either skip stages or return to earlier
- stages. This may break some existing code.
-
- * Component event handlers may now return a {{{../apidocs/org/apache/tapestry/StreamResponse.html}StreamResponse}}
- to directly send a stream to the client web browser (this is intended for components that need to render
- images, PDF, or other non-page oriented content).
-
- * The root URL for an application now renders the application's start page (it used to let the
- servlet container render the static welcome page, if any).
-
- * Named-based lookups of messages, resources, etc., are all case-insensitive.
-
- * Fast, smart, fully customizable Grid component for displaying tabular data.
-
- * Validating form components will use the same system as BeanEditForm to determine default validation for fields.
-
- * Select component will automatically provide a ValueEncoder and SelectModel when the value parameter is bound to an Enum type.
-
- * BeanEditForm component that creates a form and related controls to edit the properties of any JavaBean, automatically.
- Inspired by {{{http://www.trailsframework.org/}Trails}} and {{{http://beanform.sourceforge.net/}BeanForm}} (both for Tapestry 4).
-
- * Case insensitve URLs. Tapestry no longer cares about the case of the page names and component ids it puts
- into URLs, and they are now generated in all lower-case for that clean "Web 2.0" look. And they're
- shorter and "prettier", too!
-
- * Initial support for {{{guide/appstate.html}application state objects}}.
-
- * Input validation messages may now be overridden by providing a particular message key in the containing component's message catalog.
-
- * Property expressions may now reference public methods (with no parameters) in addition to traditional property names.
-
- * Page templates are now allowed to be stored in the WEB-INF , as well as on the classpath.
-
- * Invisible instrumentation, hiding Tapestry components inside ordinary HTML elements (a favorite feature of Tapestry 4), has been added to Tapestry 5.
-
- * Component parameter defaults may be computed on the fly.
-
- * Component parameters may have default values.
-
- * The @ComponentClass annotation, seen in the earlier {{{../screencast.html}screencasts}} has been removed.
-
+
Changes from Tapestry 4 to Tapestry 5
Tapestry 5 represents a significant advance over Tapestry 4. The goal is to make Tapestry 5
Modified: tapestry/tapestry5/trunk/tapestry-core/src/site/site.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/site/site.xml?rev=596506&r1=596505&r2=596506&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/site/site.xml (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/site/site.xml Mon Nov 19 17:12:28 2007
@@ -1,20 +1,20 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
- Copyright 2006, 2007 The Apache Software Foundation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
+<!--
+ Copyright 2006, 2007 The Apache Software Foundation
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
<project name="Tapestry Core">
<bannerLeft>
<name>Tapestry 5</name>
@@ -61,6 +61,7 @@
<item name="Input Validation" href="guide/validation.html"/>
<item name="BeanEditForm Guide" href="guide/beaneditform.html"/>
<item name="Component Events" href="guide/event.html"/>
+ <item name="Ajax" href="guide/ajax.html"/>
<item name="Page Lifecycle" href="guide/lifecycle.html"/>
<item name="Component Mixins" href="guide/mixins.html"/>
<item name="Localization" href="guide/localization.html"/>
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/app1/AutocompleteDemo.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app1/AutocompleteDemo.tml?rev=596506&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/app1/AutocompleteDemo.tml (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/app1/AutocompleteDemo.tml Mon Nov 19 17:12:28 2007
@@ -0,0 +1,20 @@
+<t:border xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+ <h1>Autocomplete Mixin Demo</h1>
+
+ <t:form>
+ <t:errors/>
+
+ <div class="t-beaneditor">
+ <div class="t-beaneditor-row">
+ <t:label for="title"/>
+ <t:textfield t:id="title" t:mixins="autocomplete" tokens=",;" size="100"/>
+ </div>
+
+ <div class="t-beaneditor-row">
+ <input type="submit" value="Show Track"/>
+ </div>
+ </div>
+ </t:form>
+
+
+</t:border>
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/app1/Start.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app1/Start.tml?rev=596506&r1=596505&r2=596506&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/app1/Start.tml (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/app1/Start.tml Mon Nov 19 17:12:28 2007
@@ -277,6 +277,11 @@
-- Demo ability to provide toclient and parseclient event handler methods
</li>
+ <li>
+ <t:pagelink page="autocompletedemo">Autocomplete Mixin Demo</t:pagelink>
+ -- Demo the autocomplete mixin for text fields.
+ </li>
+
</ul>
</td>
</tr>
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/AutocompleteDemo.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/AutocompleteDemo.java?rev=596506&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/AutocompleteDemo.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/AutocompleteDemo.java Mon Nov 19 17:12:28 2007
@@ -0,0 +1,45 @@
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotations.Persist;
+import org.apache.tapestry.integration.app1.data.Track;
+import org.apache.tapestry.integration.app1.services.MusicLibrary;
+import org.apache.tapestry.ioc.annotations.Inject;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+
+import java.util.Collections;
+import java.util.List;
+
+public class AutocompleteDemo
+{
+ @Inject
+ private MusicLibrary _library;
+
+ @Persist
+ private String _title;
+
+ List onProvideCompletionsFromTitle(String partialTitle) throws Exception
+ {
+ List<Track> matches = _library.findByMatchingTitle(partialTitle);
+
+ List<String> result = CollectionFactory.newList();
+
+ for (Track t : matches)
+ result.add(t.getTitle());
+
+ Collections.sort(result);
+
+ // Thread.sleep(1000);
+
+ return result;
+ }
+
+ public String getTitle()
+ {
+ return _title;
+ }
+
+ public void setTitle(String title)
+ {
+ _title = title;
+ }
+}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/AppModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/AppModule.java?rev=596506&r1=596505&r2=596506&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/AppModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/AppModule.java Mon Nov 19 17:12:28 2007
@@ -18,6 +18,7 @@
import org.apache.tapestry.ioc.MappedConfiguration;
import org.apache.tapestry.ioc.OrderedConfiguration;
import org.apache.tapestry.ioc.annotations.Marker;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
import org.apache.tapestry.services.Request;
import org.apache.tapestry.services.RequestFilter;
import org.apache.tapestry.services.RequestHandler;
@@ -56,8 +57,7 @@
{
return new RequestFilter()
{
- public boolean service(Request request, Response response, RequestHandler handler)
- throws IOException
+ public boolean service(Request request, Response response, RequestHandler handler) throws IOException
{
long startTime = System.currentTimeMillis();
@@ -77,14 +77,12 @@
public void contributeRequestHandler(OrderedConfiguration<RequestFilter> configuration,
- @Local
- RequestFilter filter)
+ @Local RequestFilter filter)
{
configuration.add("Timing", filter);
}
- public void contributeClasspathAssetAliasManager(
- MappedConfiguration<String, String> configuration)
+ public void contributeClasspathAssetAliasManager(MappedConfiguration<String, String> configuration)
{
configuration.add("app1/", "org/apache/tapestry/integration/app1/");
}
@@ -100,8 +98,7 @@
};
}
- public static void contributeApplicationDefaults(
- MappedConfiguration<String, String> configuration)
+ public static void contributeApplicationDefaults(MappedConfiguration<String, String> configuration)
{
configuration.add("tapestry.supported-locales", "en,fr");
configuration.add("app.injected-symbol", "Symbol contributed to ApplicationDefaults");
@@ -123,6 +120,20 @@
public List<Track> getTracks()
{
return tracks;
+ }
+
+ public List<Track> findByMatchingTitle(String title)
+ {
+ String titleLower = title.toLowerCase();
+
+ List<Track> result = CollectionFactory.newList();
+
+ for (Track t : tracks)
+ {
+ if (t.getTitle().toLowerCase().contains(titleLower)) result.add(t);
+ }
+
+ return result;
}
};
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/MusicLibrary.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/MusicLibrary.java?rev=596506&r1=596505&r2=596506&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/MusicLibrary.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/MusicLibrary.java Mon Nov 19 17:12:28 2007
@@ -24,4 +24,13 @@
* Provides a list of all tracks in an indeterminate order.
*/
List<Track> getTracks();
+
+ /**
+ * Performs a case-insensitive search, finding all tracks whose title
+ * contains the input string (ignoring case).
+ *
+ * @param title a partial title
+ * @return a list of all matches
+ */
+ List<Track> findByMatchingTitle(String title);
}