MultiAutoCompleteTextField for Wicket - autocomplete

I need an AutoCompleteTextField for Wicket which can handle several autocomplete items separated by a comma.
Something like this: http://digitarald.de/project/autocompleter/1-1/showcase/delicious-tags/

Wicket-extensions provides autocomplete features.
Add an AutoCompleteBehavior to the TextArea in the same fashion AutoCompleteTextField uses it.
For instance:
TextArea t = new TextArea("area", new Model());
AutoCompleteBehavior<String> b = new AutoCompleteBehavior<String>(
StringAutoCompleteRenderer.INSTANCE){
#Override
protected Iterator<String> getChoices(String input) {
return getMyListElements().iterator();
}
};
t.setOutputMarkupId(true);
t.add(b);
add(t);
If you are using Maven, just add the following dependency to start using wicket-extensions:
<dependency>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket-extensions</artifactId>
<version>${wicket.version}</version>
</dependency>
EDIT
Seeing that the question is about Multi autocomplete textfields, like the one in this example, you might find the following link useful: Wicket auto-complete text fields. There are a couple of components in there that seem to do just what you need.
You might also find this discussion and this one in the Apache Wicket User list useful. You'll find a couple of links there to projects that seem to also have this component: interwicket and WicketHub

Also see https://github.com/wicketstuff/core/tree/master/jdk-1.5-parent/autocomplete-tagit-parent

I could resolve the problem by Ajax in wicket as the following
TextArea partnersDB = new TextArea("partnersDB");
String partnerKeeper;
public String getPartnerKeeper() {
return partnerKeeper;
}
public void setPartnerKeeper(String partnerKeeper) {
this.partnerKeeper = partnerKeeper;
}
public String getMessageTypeKeeper() {
return messageTypeKeeper;
}
public void setMessageTypeKeeper(String messageTypeKeeper) {
this.messageTypeKeeper = messageTypeKeeper;
}
private void makePartnersAutoCompleter() {
final List<String> allPartners = auditDAO.findAllPartnerIds();
IAutoCompleteRenderer partnerRenderer = new AbstractAutoCompleteRenderer() {
#Override
protected String getTextValue(Object obj) {
return getPartnerKeeper() + ((String) obj);
}
#Override
protected void renderChoice(Object obj, Response r, String str) {
r.write((String) obj);
}
};
AutoCompleteBehavior autoCompleteBehavior = new AutoCompleteBehavior(partnerRenderer) {
#Override
protected Iterator<String> getChoices(String input) {
int lastCommaIndex = input.lastIndexOf(';');
String realInput = "";
if (lastCommaIndex == -1) {
setPartnerKeeper("");
realInput = input;
} else {
setPartnerKeeper(input.substring(0, lastCommaIndex) + ";");
realInput = input.substring(lastCommaIndex + 1);
}
List<String> completions = new ArrayList<String>();
for (int i = 0; i < allPartners.size(); i++) {
String partner = allPartners.get(i);
if (partner.startsWith(realInput.toUpperCase()) || partner.startsWith(realInput.toLowerCase())) {
completions.add(partner + ";");
}
}
return completions.iterator();
}
};
partnersDB.add(autoCompleteBehavior);
}

Related

Wicket 7 - AutoCompleted Text field - to have onSelect method

We would like to implement AutoCompleteTextField field, once user has selected the field from AutoComplete result, then system would auto populate on other text field, i have used the component AjaxFormComponentUpdatingBehavior (blur), however this will take effect on every text input from AutoCompleteTextField field, but if i change to AjaxFormComponentUpdatingBehavior (change), it doesnt work.
Below is the sample code:
AutoCompleteTextField<String> field_postcode = new AutoCompleteTextField<String>("field_postcode",
new PropertyModel<String>(getModelObject(), "wAdditionalInfo.postal"), autoCompleteRenderer) {
private static final long serialVersionUID = 1L;
#Override
protected Iterator<String> getChoices(String input) {
if (Strings.isEmpty(input)) {
List<String> emptyList = Collections.emptyList();
return emptyList.iterator();
}
List<String> choices = new ArrayList<String>();
List<Postcode> postcodeList = getProfileManager().findAllPostcodeByPostcode(input);
for (Postcode p : postcodeList) {
String postcode = p.getPostcode();
if (postcode.startsWith(input)) {
choices.add(p.getPostcode());
if (choices.size() == 10) {
break;
}
}
}
return choices.iterator();
}
};
field_postcode.setRequired(true);
field_postcode.add(new AjaxFormComponentUpdatingBehavior("blur"){
private static final long serialVersionUID=-1107858522700306810L;
#Override protected void onUpdate( AjaxRequestTarget target){
Postcode postcode = getProfileManager().findPostcodeByPostcode(field_postcode.getInput());
if (postcode != null) {
City city = postcode.getCity();
State state = city.getState();
field_city.setModelObject(city.getCity());
ddl_state.setModelObject(state);
if (isDisplayTip) {
//isDisplayTip true mean is from widrawal webform
isReadonly = true;
} else {
field_city.setEnabled(false);
}
ddl_state.setEnabled(false);
} else {
if (isDisplayTip) {
isReadonly = false;
} else {
field_city.setEnabled(true);
}
ddl_state.setEnabled(true);
}
target.add(field_city, ddl_state);
}
}
);
Is there any api from wicket to achieve this? We need to have something when user select the option from Auto complete, then it only onUpdate method of AjaxFormComponentUpdatingBehavior
According to https://github.com/apache/wicket/blob/cbc237159c4c6632b4f7db893c28ab39d1b40ed4/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/markup/html/autocomplete/wicket-autocomplete.js#L620 it should trigger change event on the HTMLInputElement and thus notify you on the server side.
Use the browser debugger to see whether https://github.com/apache/wicket/blob/cbc237159c4c6632b4f7db893c28ab39d1b40ed4/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/markup/html/autocomplete/wicket-autocomplete.js#L453 is executed and whether it leads to an Ajax call with the value in the parameters.

Plugin dev: How to search only for interfaces in DLTK/PDT plugin?

I develop extension of PDT plugin. I need dialog with interfaces only (not classes). Basic code looks like it:
OpenTypeSelectionDialog2 dialog = new OpenTypeSelectionDialog2(
DLTKUIPlugin.getActiveWorkbenchShell(),
multi,
PlatformUI.getWorkbench().getProgressService(),
null,
type,
PHPUILanguageToolkit.getInstance());
It's works fine but I get classes and interfaces together (type variables). Is any method to filter it? I can't find this kind of mechanism in PDT but classes and interfaces are recognize correctly (icons next to names).
I don't know if its the best solution but it works.
int falseFlags = 0;
int trueFlags = 0;
IDLTKSearchScope scope = SearchEngine.createSearchScope(getScriptFolder().getScriptProject());
trueFlags = PHPFlags.AccInterface;
OpenTypeSelectionDialog2 dialog = new OpenTypeSelectionDialog2(
DLTKUIPlugin.getActiveWorkbenchShell(),
multi,
PlatformUI.getWorkbench().getProgressService(),
scope,
IDLTKSearchConstants.TYPE,
new PHPTypeSelectionExtension(trueFlags, falseFlags),
PHPUILanguageToolkit.getInstance());
And PHPTypeSelectionExtension looks like this:
public class PHPTypeSelectionExtension extends TypeSelectionExtension {
/**
* #see PHPFlags
*/
private int trueFlags = 0;
private int falseFlags = 0;
public PHPTypeSelectionExtension() {
}
public PHPTypeSelectionExtension(int trueFlags, int falseFlags) {
super();
this.trueFlags = trueFlags;
this.falseFlags = falseFlags;
}
#Override
public ITypeInfoFilterExtension getFilterExtension() {
return new ITypeInfoFilterExtension() {
#Override
public boolean select(ITypeInfoRequestor typeInfoRequestor) {
if (falseFlags != 0 && (falseFlags & typeInfoRequestor.getModifiers()) != 0) {
// Try to filter by black list.
return false;
} else if (trueFlags == 0 || (trueFlags & typeInfoRequestor.getModifiers()) != 0) {
// Try to filter by white list, if trueFlags == 0 this is fine 'couse we pass black list.
return true;
} else {
// Rest is filter out.
return false;
}
}
};
}
#SuppressWarnings("restriction")
#Override
public ISelectionStatusValidator getSelectionValidator() {
return new TypedElementSelectionValidator(new Class[] {IType.class, INamespace.class}, false);
}
}

GWT multiple Activities/Places with one Token

My Site has on the left a GWT-Tree. In the center is a GWT-TabBar.
Both parts are implemented as Views/Activities/Places. I have two tokenizer: "m" for the tree and "t" for the tabs.
If I visit one place (goTo()) only this place will be used to generate the history token. But I would like to see this: <page>#m:sub/sub/sub;t:map
I actually thought that the hole idea of activities&places. I don't see the point to have multiple tokenizer, when only one tokenizer can provide a token at once.
You cannot display two different tokens #m: and #t: at the same time as you cannot be in two places at the same time.
So if both tabs and tree are displaying at the same time, then the state of both must be stored at once in the same place.
This is more or less what you need.
public class ExamplePlace extends Place {
public String treePosition = "/";
public int tabIndex = 0;
public ExamplePlace() {
super();
}
public ExamplePlace(String treePosition, int tabIndex) {
this.treePosition = treePosition;
this.tabIndex = tabIndex;
}
#Prefix("overview")
public static class Tokenizer implements PlaceTokenizer<ExamplePlace> {
/**
* parse token to get state
*
*/
#Override
public ExamplePlace getPlace(String token) {
String treePosition = "";
int tabIndex = 0;
String[] states = token.split(";");
for (String state : states) {
String[] mapping = state.split("=");
if (mapping.length == 2) {
if ("t".equals(mapping[0])) {
treePosition = mapping[1];
}
if ("m".equals(mapping[0])) {
try {
tabIndex = Integer.valueOf(mapping[1]);
} catch (Throwable e) {
}
}
}
}
return new ExamplePlace(treePosition, tabIndex);
}
/**
* store state in token
*
*/
#Override
public String getToken(ExamplePlace place) {
StringBuffer sb = new StringBuffer();
if (place.getTreePosition()!=null) {
sb.append("t").append("=").append(place.getTreePosition());
sb.append(";");
}
sb.append("m=").append(place.getTabIndex());
return sb.toString();
}
}
public String getTreePosition() {
return treePosition;
}
public void setTreePosition(String treePosition) {
this.treePosition = treePosition;
}
public int getTabIndex() {
return tabIndex;
}
public void setTabIndex(int tabIndex) {
this.tabIndex = tabIndex;
}
}
This will give you URLs that look like ;
index.html#overview:t=/subtree/subtree/leaf;m=2
You might run in trouble with the forward slashes in the token, not sure. Change them to some other character if necessary;
The activity receives the incoming place and inject the state into the view;

hyperlink cell in GWT CellTable

I have a cell table in GWT with textcells and buttoncell ,Now i want to add a hyperlinkCell in my celltable , is this possible ?
TextCell jobStatusCell = new TextCell();
jobStatusColumn = new Column<EmployerJobs, String>(jobStatusCell) {
#Override
public String getValue(EmployerJobs object) {
// int status = object.getJobStatusId();
/*
* if(status ==1) { return ""; } else
*/
// return "post job";
return "view";
}
};
I want some thing like this
HyperlinkCell jobStatusCell = new HyperLinkCell();
Thanks
do you mean this HyperlinkCell?
If not, you can write a normal hyperlink (linkCell )and put it as the content of a cell.
Try using the following Cell implementation
Be sure that you provide cell's value as an array of 2 String objects like:
String[] value = new String[2];
value[HyperTextCell.LINK_INDEX] = "http://www.google.com";
value[HyperTextCell.TEXT_INDEX] = "Search on google";
public class HyperTextCell extends AbstractCell<String[]> {
interface Template extends SafeHtmlTemplates {
#Template("<a target=\"_blank\" href=\"{0}\">{1}</a>")
SafeHtml hyperText(SafeUri link, String text);
}
private static Template template;
public static final int LINK_INDEX = 0, URL_INDEX = 1;
/**
* Construct a new ImageCell.
*/
public HyperTextCell() {
if (template == null) {
template = GWT.create(Template.class);
}
}
#Override
public void render(Context context, String[] value, SafeHtmlBuilder sb) {
if (value != null) {
// The template will sanitize the URI.
sb.append(template.hyperText(UriUtils.fromString(value[LINK_INDEX]), value[URL_INDEX]));
}
}
}

How to apply like search on GWT cell table?

I am using GWT 2.3.I which I am using GWT cell table.
Here below is the code for my cell table:
public class FormGrid extends SuperGrid {
List<Form> formList;
#Override
public void setColumns(CellTable table) {
TextColumn<Form> nameColumn = new TextColumn<Form>() {
#Override
public String getValue(Form object) {
return object.getName();
}
};
table.addColumn(nameColumn, "Name");
}
#Override
public void setData() {
if (formList != null && formList.size() > 0) {
AsyncDataProvider<Form> provider = new AsyncDataProvider<Form>() {
#Override
protected void onRangeChanged(HasData<Form> display) {
int start = display.getVisibleRange().getStart();
int end = start + display.getVisibleRange().getLength();
end = end >= formList.size() ? formList.size() : end;
List<Form> sub = formList.subList(start, end);
updateRowData(start, sub);
}
};
provider.addDataDisplay(getTable());
provider.updateRowCount(formList.size(), true);
}
}
public List<Form> getFormList() {
return formList;
}
public void setFormList(List<Form> formList) {
this.formList = formList;
}
}
In this my set column and set data will be called fro super class flow.This cell table is working fine.
Now I want to put a filter type facility (like search) in this cell table.It should be like, there is a texbox above the cell table and what ever written in that text box, it should fire a like query to all form name for that text box value.
for example I have 1000 form in the grid.Now if user writes 'app' in some filter textbox above the cell table the all the form which have 'app' in there name will be filtered and grid has only those forms only.
This is the first case:
Another case is I am only render one column in grid name.I have two more properties in form (description,tag).But I am not rendering them.now for filter if user writes 'app' in filter box then it should make a query to all three (name, description, and tag) and should return if 'app' matched to any of three.
I am not getting how to apply filter in cell table.
Please help me out.Thanks in advance.
You can find an implementation in the expenses sample.
Here is a short summary of the steps
1.) Create a Textbox and a SearchButton.
2.) add a clickHandler to the SearchButton (You can also add KeyUpHandler to the Textbox alternatively)
searchButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
search();
}
});
3.) In the search function retrieve the searchString and store it.
private void search() {
searchString = searchBox.getText();
setData();
}
4.) modify your setdata() function to take searchString into account
#Override
public void setData() {
if (formList != null && formList.size() > 0) {
AsyncDataProvider<Form> provider = new AsyncDataProvider<Form>() {
#Override
protected void onRangeChanged(HasData<Form> display) {
int start = display.getVisibleRange().getStart();
int end = start + display.getVisibleRange().getLength();
//new function if searchString is specified take into account
List<Form> sub = getSubList(start,end);
end = end >= sub.size() ? sub.size() : end;
updateRowData(sub.subList(start, end);, sub);
}
};
provider.addDataDisplay(getTable());
provider.updateRowCount(formList.size(), true);
}
}
private List<Form> getSubList(int start, int end) {
List<Form> filtered_list = null;
if (searchString != null) {
filtered_list= new ArrayList<Form>();
for (Form form : formList) {
if (form.getName().equals(searchString) || form.getTag().equals(searchString) || form.getDescription().equals(searchString))
filtered_list.add(form);
}
}
else
filtered_list = formList;
return filtered_list;
}
can propose another solution what can be used quite easy multiple times.
Idea is to create custom provider for your celltable.
GWT celltable filtering
Video in this post shows it in action.
Here is the part of code of custom list data provider which u have to implement.
#Override
protected void updateRowData(HasData display, int start, List values) {
if (!hasFilter() || filter == null) { // we don't need to filter, so call base class
super.updateRowData(display, start, values);
} else {
int end = start + values.size();
Range range = display.getVisibleRange();
int curStart = range.getStart();
int curLength = range.getLength();
int curEnd = curStart + curLength;
if (start == curStart || (curStart < end && curEnd > start)) {
int realStart = curStart < start ? start : curStart;
int realEnd = curEnd > end ? end : curEnd;
int realLength = realEnd - realStart;
List<t> resulted = new ArrayList<t>(realLength);
for (int i = realStart - start; i < realStart - start + realLength; i++) {
if (filter.isValid((T) values.get(i), getFilter())) {
resulted.add((T) values.get(i));
}
}
display.setRowData(realStart, resulted);
display.setRowCount(resulted.size());
}
}
}