I want to code a custom form component that allows users to edit the
set of tags of
some object. When constructed, the component receives a model for the
current set
of tags. The user can then edit this set using AJAX Add button and
Remove links:
Current tags: Foo (x), Bar (x)
Add tag: [text field] Add
I have implemented the component as a
FormComponentPanel<List<String>>, with
AjaxLink's to realize the remove links (x) and with an AjaxSubmitLink
for
the Add button.
The remove links work but the Add button's onSubmit() always fails
with a
NullPointerException when it tries to get the model object,
getModelObject(),
of the enclosing FormComponentPanel. Does anybody see what I am doing
wrong?
I attach the complete source (heavily cut down).
Thank you in advance for any hint or guidance, and sorry for the
lenghty post,
Kaspar
// File Test.html
<html>
<body>
<form wicket:id="form">
<div wicket:id="selector"></div>
<input type="submit" value="Submit"/>
</form>
</body>
</html>
// File Test.java
package org.test;
import java.util.ArrayList;
import java.util.List;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
public class Test extends WebPage
{
public Test()
{
super();
final Form form = new Form("form");
add(form);
List<String> initialTags = new ArrayList<String>();
initialTags.add("Foo");
IModel<List<String>> tagsModel = Model.of(initialTags);
form.add(new TagSelector("selector", tagsModel));
}
}
// File TagSelector.html
<html xmlns:wicket>
<wicket:panel>
<!-- Feedback -->
<div wicket:id="feedback"></div>
<!-- Currently selected tags -->
Tags:
<ul>
<li wicket:id="tag"><wicket:container wicket:id="tag-name"/> <a
href="#" wicket:id="remove">remove</a></li>
</ul>
<!-- Field and button to add tag -->
Add: <input type="text" wicket:id="input"/> <input value="Add"
wicket:id="add-button" type="submit"/>
</wicket:panel>
</html>
// File TagSelector.java
package org.test;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
import
org
.apache
.wicket.extensions.ajax.markup.html.autocomplete.AutoCompleteTextField;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.FormComponentPanel;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
public class TagSelector extends FormComponentPanel<List<String>>
{
private final static String[] DUMMY_TAGS_ARRAY = {
"Foo", "Bar", "Foobar"
};
private final static List<String> DUMMY_TAGS =
Arrays.asList(DUMMY_TAGS_ARRAY);
public TagSelector(String id, IModel<List<String>> model)
{
super(id, model);
setOutputMarkupId(true);
add(new FeedbackPanel("feedback"));
add(new ListView<String>("tag", model)
{
@Override
protected void populateItem(ListItem<String> item)
{
final String tagName = item.getModelObject();
item.add(new Label("tag-name", tagName));
item.add(new AjaxLink("remove")
{
@Override
public void onClick(AjaxRequestTarget target)
{
// Remove tag from current selection
TagSelector.this.getModelObject().remove(tagName);
// Feedback
getSession().info("Removed tag '" + tagName + "'.");
// AJAX update (including feedback panel)
target.addComponent(TagSelector.this);
}
});
}
});
final AutoCompleteTextField<String> inputField = new
AutoCompleteTextField<String>("input", new Model<String>(""))
{
@Override
protected Iterator<String> getChoices(String input)
{
// For the sake of illustration, return a fixed list here ...
return DUMMY_TAGS.iterator();
}
};
add(inputField.setOutputMarkupId(true));
add(new AjaxSubmitLink("add-button")
{
@Override
protected void onSubmit(AjaxRequestTarget target, Form form)
{
// Get entered tag name
final String tagName =
StringEscapeUtils
.unescapeHtml(inputField.getDefaultModelObjectAsString());
// Verify existence
final boolean exists = DUMMY_TAGS.contains(tagName);
if (!exists)
{
getSession().info("Tag '" + tagName + "' is unknown. Please
try again!");
}
// Add tag
else
{
List<String> currentTags =
TagSelector.this.getModelObject(); // is always null!
if (currentTags.contains(tagName))
{
getSession().info("Tag '" + tagName + "' already
present.");
}
else
{
currentTags.add(tagName);
getSession().info("Added tag '" + tagName + "'.");
}
}
// AJAX update (including feedback panel)
target.addComponent(TagSelector.this);
target.focusComponent(inputField);
}
});
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]