Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ public JQueryAjaxBehavior(IJQueryAjaxAware source)
* Constructor
*
* @param source {@link Behavior} to which the event - returned by {@link #newEvent()} - will be broadcasted.
* @param duration {@link Duration}. If different than {@link Duration#NONE}, an {@link ThrottlingSettings} will be added with the specified {@link Duration}.
* @param duration {@link Duration}. If different than {@link Duration#ZERO}, an {@link ThrottlingSettings} will be added with the specified {@link Duration}.
*/
public JQueryAjaxBehavior(IJQueryAjaxAware source, Duration duration)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ public static boolean isEmpty(List<StringValue> list)
/**
* Converts a {@link StringValue} to a list of {@code String}
*
* @param value the {@link StringValue}
* @param values the {@link StringValue}
* @return a list of {@code String}
*/
public static List<String> toStringList(StringValue values)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.wicketstuff.jquery.ui.samples.jqueryui.autocomplete.ConverterAutoCompletePage;
import org.wicketstuff.jquery.ui.samples.jqueryui.autocomplete.CustomAutoCompletePage;
import org.wicketstuff.jquery.ui.samples.jqueryui.autocomplete.DefaultAutoCompletePage;
import org.wicketstuff.jquery.ui.samples.jqueryui.autocomplete.IdBasedAutoCompletePage;
import org.wicketstuff.jquery.ui.samples.jqueryui.autocomplete.RendererAutoCompletePage;
import org.wicketstuff.jquery.ui.samples.jqueryui.autocomplete.TemplateAutoCompletePage;
import org.wicketstuff.jquery.ui.samples.jqueryui.button.AjaxButtonPage;
Expand Down Expand Up @@ -191,6 +192,7 @@ public class SiteMapPage extends WebPage
ContextMenuPage.class,
ConverterAutoCompletePage.class,
CustomAutoCompletePage.class,
IdBasedAutoCompletePage.class,
CustomCalendarPage.class,
CustomCalendar6Page.class,
CustomComboBoxPage.class,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ protected List<DemoLink> getDemoLinks()
new DemoLink(CustomAutoCompletePage.class, "Auto-complete: custom beans"), // lf
new DemoLink(TemplateAutoCompletePage.class, "Auto-complete: custom template"), // lf
new DemoLink(RendererAutoCompletePage.class, "Auto-complete: custom renderer"), // lf
new DemoLink(ConverterAutoCompletePage.class, "Auto-complete: form submit") // lf
new DemoLink(ConverterAutoCompletePage.class, "Auto-complete: form submit"), // lf
new DemoLink(IdBasedAutoCompletePage.class, "Auto-complete: id based selection") // lf
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/* Licensed under the Apache License, Version 2.0 (the "License") http://www.apache.org/licenses/LICENSE-2.0 */
table {
width: 400px;
border-spacing: 0;
border-collapse: collapse;
}

th, td {
padding: 5px;
}

.ui-autocomplete {
max-height: 200px;
overflow-y: auto;
overflow-x: hidden;
padding-right: 20px;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<!DOCTYPE html>
<!--
Licensed under the Apache License, Version 2.0 (the "License") http://www.apache.org/licenses/LICENSE-2.0
-->
<html xmlns:wicket="http://wicket.apache.org">
<head>
<wicket:head>
<title>Wicket jQuery UI: auto-complete (custom bean)</title>
</wicket:head>
</head>
<body>
<wicket:extend>
<div id="demo-panel">
<form wicket:id="form">
<table>
<tr>
<td style="width: 300px; vertical-align: top;">
<div>Select a metal genre: (containing any char)</div>
<br/>
<input wicket:id="autocomplete" type="text" size="30" />
</td>
<td wicket:id="container" style="width: 100px;">
<img wicket:id="cover" class="ui-corner-all" />
<div wicket:id="name" style="text-align: center;"></div>
</td>
</tr>
</table>
</form>
</div>
</wicket:extend>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
Licensed under the Apache License, Version 2.0 (the "License") http://www.apache.org/licenses/LICENSE-2.0
*/
package org.wicketstuff.jquery.ui.samples.jqueryui.autocomplete;

import java.util.List;

import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.image.ContextImage;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.wicketstuff.jquery.core.resource.StyleSheetPackageHeaderItem;
import org.wicketstuff.jquery.core.utils.ListUtils;
import org.wicketstuff.jquery.ui.form.autocomplete.AbstractAutoCompleteTextField;
import org.wicketstuff.jquery.ui.form.autocomplete.AutoCompleteTextField;
import org.wicketstuff.jquery.ui.form.autocomplete.IElementSelectionStrategy;
import org.wicketstuff.jquery.ui.form.autocomplete.PropertyBasedElementSelectionStrategy;
import org.wicketstuff.jquery.ui.samples.data.bean.Genre;
import org.wicketstuff.jquery.ui.samples.data.dao.GenresDAO;

public class IdBasedAutoCompletePage extends AbstractAutoCompletePage
{
private static final long serialVersionUID = 1L;

public IdBasedAutoCompletePage()
{
// Model //
final IModel<Genre> model = Model.of(GenresDAO.newGenre());

// Form //
final Form<Void> form = new Form<Void>("form");
this.add(form);

// Container for selected genre (name & cover) //
final WebMarkupContainer container = new WebMarkupContainer("container");
form.add(container.setOutputMarkupId(true));

container.add(new ContextImage("cover", new PropertyModel<String>(model, "cover")));
container.add(new Label("name", new PropertyModel<String>(model, "name")));

// Auto-complete //
form.add(new AbstractAutoCompleteTextField<Genre>("autocomplete", model) {

private static final long serialVersionUID = 1L;

@Override
protected IModel<List<Genre>> getChoicesModel(String input)
{
return new LoadableDetachableModel<>()
{
@Override
protected List<Genre> load()
{
return ListUtils.contains(input, GenresDAO.all());
}
};
}

@Override
protected IElementSelectionStrategy<Genre> newElementSelectionStrategy()
{
return new PropertyBasedElementSelectionStrategy<>("id");
}

@Override
protected void onSelected(AjaxRequestTarget target)
{
target.add(container); // the model has already been updated
}
});
}

// Methods //

@Override
public void renderHead(IHeaderResponse response)
{
super.renderHead(response);

response.render(new StyleSheetPackageHeaderItem(IdBasedAutoCompletePage.class));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ AccordionPanelPage.title=AccordionPanel
# Auto-complete
DefaultAutoCompletePage.title=Auto-complete
CustomAutoCompletePage.title=Auto-complete: custom beans
IdBasedAutoCompletePage.title=Auto-complete: ID based selection
TemplateAutoCompletePage.title=Auto-complete: custom template
RendererAutoCompletePage.title=Auto-complete: custom renderer
ConverterAutoCompletePage.title=Auto-complete: form submit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@
*/
package org.wicketstuff.jquery.ui.form.autocomplete;

import java.util.Collections;
import java.util.List;
import java.util.Locale;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.model.IModel;
import org.apache.wicket.util.convert.IConverter;
import org.apache.wicket.util.lang.Args;
import org.danekja.java.util.function.serializable.SerializableSupplier;
import org.wicketstuff.jquery.core.IJQueryWidget;
import org.wicketstuff.jquery.core.JQueryBehavior;
import org.wicketstuff.jquery.core.renderer.ITextRenderer;
Expand All @@ -40,7 +41,7 @@
* @author Sebastien Briquet - sebfz1
* @author reiern70
*/
public abstract class AbstractAutoCompleteTextField<T> extends TextField<T> implements IJQueryWidget, IAutoCompleteListener // NOSONAR
public abstract class AbstractAutoCompleteTextField<T> extends TextField<T> implements IJQueryWidget, IAutoCompleteListener<T> // NOSONAR
{
private static final long serialVersionUID = 1L;

Expand All @@ -51,6 +52,7 @@ public abstract class AbstractAutoCompleteTextField<T> extends TextField<T> impl

private final ITextRenderer<? super T> renderer;
private final IConverter<T> converter;
private final IElementSelectionStrategy<T> elementSelectionStrategy;

private final IJQueryTemplate template;
private JQueryAbstractTemplateBehavior templateBehavior = null;
Expand Down Expand Up @@ -108,6 +110,7 @@ public AbstractAutoCompleteTextField(String id, ITextRenderer<? super T> rendere
this.renderer = renderer;
this.template = this.newTemplate();
this.converter = this.newConverter();
this.elementSelectionStrategy = this.newElementSelectionStrategy();
}

/**
Expand Down Expand Up @@ -145,7 +148,7 @@ public AbstractAutoCompleteTextField(String id, IModel<T> model, ITextRenderer<?
this(id, model, renderer, null);
}

/**
/**
* Constructor
*
* @param id the markup id
Expand All @@ -160,6 +163,7 @@ public AbstractAutoCompleteTextField(String id, IModel<T> model, ITextRenderer<?
this.renderer = renderer;
this.template = this.newTemplate();
this.converter = this.newConverter();
this.elementSelectionStrategy = this.newElementSelectionStrategy();
}

// Methods //
Expand Down Expand Up @@ -243,6 +247,16 @@ public ITextRenderer<? super T> getRenderer()
return this.renderer;
}

/**
* Gets the {@link IElementSelectionStrategy} used to identify and resolve selected choices.
*
* @return the selection strategy, never {@code null}
*/
public IElementSelectionStrategy<T> getElementSelectionStrategy()
{
return this.elementSelectionStrategy;
}

// Events //

@Override
Expand Down Expand Up @@ -292,17 +306,30 @@ protected void onComponentTag(final ComponentTag tag)
tag.put("autocomplete", "off"); // disable browser's autocomplete
}

@Override
public final void onSelect(AjaxRequestTarget target, int index)
{
if (-1 < index && index < this.choices.getObject().size())
{
T choice = this.choices.getObject().get(index);

this.setModelObject(choice);
this.onSelected(target);
}
}
@Override
public final void onSelect(AjaxRequestTarget target, T choice, String identifier)
{
this.setModelObject(choice);
if (choice == null)
{
LOG.debug("Cannot select choice with ID: {}", identifier);
onSelectionFailed(target, identifier);
}
else
{
this.onSelected(target);
}
}

/**
* Triggered when it was not possible to find an element to select
*
* @param target the {@link AjaxRequestTarget}
* @param identifier THe id of the Choice that could not be retrieved.
*/
protected void onSelectionFailed(AjaxRequestTarget target, String identifier)
{
}

/**
* Triggered when the user selects an item from results that matched its input
Expand All @@ -318,7 +345,13 @@ protected void onSelected(AjaxRequestTarget target)
@Override
public JQueryBehavior newWidgetBehavior(String selector)
{
return new AutoCompleteBehavior(selector, this) { // NOSONAR
return new AutoCompleteBehavior<T>(selector, this, new SerializableSupplier<List<T>>() {

@Override
public List<T> get() {
return choices != null ? choices.getObject() : Collections.emptyList();
}
}) { // NOSONAR

private static final long serialVersionUID = 1L;

Expand Down Expand Up @@ -394,18 +427,34 @@ public String convertToString(T value, Locale locale)
};
}

/**
* Gets a new {@link IElementSelectionStrategy}. Index-based selection is used by default.
*
* @return the selection strategy
*/
protected IElementSelectionStrategy<T> newElementSelectionStrategy()
{
return IndexBasedElementSelectionStrategy.get();
}

/**
* Gets a new {@link AutoCompleteChoiceModelBehavior}
*
* @return the {@link AutoCompleteChoiceModelBehavior}
*/
private AutoCompleteChoiceModelBehavior<T> newChoiceModelBehavior()
{
return new AutoCompleteChoiceModelBehavior<T>(this.renderer, this.template) { // NOSONAR

return new AutoCompleteChoiceModelBehavior<T>(this.renderer, this.template) // NOSONAR
{
private static final long serialVersionUID = 1L;
private static final String TERM = "term";

@Override
protected IElementSelectionStrategy<T> getElementSelectionStrategy()
{
return AbstractAutoCompleteTextField.this.getElementSelectionStrategy();
}

@Override
public List<T> getChoices()
{
Expand All @@ -415,4 +464,34 @@ public List<T> getChoices()
}
};
}

/**
* Gets the {@link AutoCompleteChoiceModelBehavior} that serves the choices to the widget
*
* @return the {@link AutoCompleteChoiceModelBehavior}, or {@code null} if the component has not been initialized yet
*/
public final AutoCompleteChoiceModelBehavior<T> getChoiceModelBehavior()
{
return this.choiceModelBehavior;
}

/**
* Gets the cached choices of the last query, used to resolve the user selected object
*
* @return the {@link IModel} of choices, or {@code null} if no query has been performed yet
*/
public final IModel<List<T>> getChoices()
{
return this.choices;
}

/**
* Gets the {@link JQueryAbstractTemplateBehavior} supplied by {@link #newTemplate()}
*
* @return the {@link JQueryAbstractTemplateBehavior}, or {@code null} if there is no template
*/
public final JQueryAbstractTemplateBehavior getTemplateBehavior()
{
return this.templateBehavior;
}
}
Loading
Loading