I'm using an AjaxFormComponentUpdatingBehavior to do some stuff when a choice is selected from an AutoCompleteTextField. After that stuff is done I want to clear the field but it's not behaving the way I expected it to.
Here're the relevant bits of code:
final AutoCompleteTextField<String> searchField =
new AutoCompleteTextField<String>(id, model);
searchField.add(new AjaxFormComponentUpdatingBehavior("onchange")
{
#Override
protected void onUpdate(AjaxRequestTarget target)
{
// Do stuff with the selected value here
...
searchField.clearInput();
target.addComponent(searchField);
}
});
I'm putting the value in a ListView and adding that to the target also. It gets updated correctly but the AutoCompleteTextField doesn't.
I think your example doesn't work, because you rerender the component on the client side using the model on the server side. If you reset the model value and repaint the component it has to work.
searchField.setModelObject(null);
target.addComponent(searchField);
However it is not neccessary to render the whole component, just clear the value on server and client side is enough.
The following example clears the model object and reset the field value by javascript (jQuery).
final AutoCompleteTextField<String> searchField =
new AutoCompleteTextField<String>(id, model);
searchField.setOutputMarkupId(true);
searchField.add(new AjaxFormComponentUpdatingBehavior("onchange")
{
#Override
protected void onUpdate(AjaxRequestTarget target)
{
// Do stuff with the selected value here
...
searchField.clearInput();
searchField.setModelObject(null);
target.appendJavascript("$('#" + searchField.getMarkupId() + "').val('');");
}
});
If you are using Wicket prior 6.x then the jQuery is not included. You can use the following JS:
target.appendJavascript("document.getElementById('" + searchField.getMarkupId() + "').value = '';");
Related
I'm changing the sites locale with an AjaxLink:
#Override
public void onClick(AjaxRequestTarget target) {
Session.get().setLocale(newLanguage.getLocale());
// Add whole page to update instead of single components
target.add(getPage());
}
It does work as i expect, every i18n string on the entire page gets updated while form contents are kept. Splendid.
But testing with WicketTester won't work out. Both methods, clickLink and executeAjaxBehavior, do trigger the AjaxLink, but WicketTester doesn't detect any changes for the model value.
#Test
public void check() {
tester.startPage(SwitchLangPage.class);
tester.clickLink("link", true);
tester.assertModelValue("link:label", "English");
}
Am I missing something importent here?
(Wicket 6.19)
Edit: Gist with a simplified panel
I am new with GWT_GXT
I use MVP(model-view-Presenter)
In Presenter, i call RPC to get data From database. After that i get a List data -> I set it for view
In view, code is below
#Override
public void setDeleteAllTest(List<DeleteAllTestModel> deleteAllTests) {
final ListStore<DeleteAllTestModel> listStore = new ListStore<DeleteAllTestModel>();
listStore.add(deleteAllTests);
gridView = new PMTGridDeleteAllTest<DeleteAllTestModel>().getPMTGridDeleteAllTest(listStore);
gridView.setAutoWidth(true);
}
#Override
protected void onRender(Element parent, int pos) {
super.onRender(parent, pos);
ContentPanel cp = new ContentPanel();
cp.setBodyBorder(false);
cp.setHeading("");
cp.setButtonAlign(Style.HorizontalAlignment.CENTER.CENTER);
cp.setLayout(new FitLayout());
cp.setSize(1200, 400);
cp.add(gridView);
verticalPanel.add(cp);
verticalPanel.add(nameField);
verticalPanel.add(cancelButton);
add(verticalPanel);
cancelButton.addSelectionListener(new SelectionListener<ButtonEvent>() {
#Override
public void componentSelected(ButtonEvent buttonEvent) {
PolicyDeleteAllTestDialog.this.hide();
}
});
getButtonById("ok").hide();
}
The Problem is that Gird is not refresh and update new data_ It only displays (the first Grid in the first Call) .. It always keep the first View( I use dialog to show grid)..
Help me!
Thanks
I don't exactly remember how it works and it really is what you need. But there is something like gridView.refresh();. I remember I sometime used to use grid.getView().refresh(true); but it's been a while. Also I think there is a concept named ListLoader that might be useful. I am not sure of myself but if I were you I would have a look at listLoader. I hope this will help you one way or another, sorry if it does not.
I have a problem with validation on form actually sub-form.
In my website I have some kind of table and "Add row" button (BlockingAjaxSubmitLink).
When I try add let say 2 rows, I get validation error (because row in this table has Required=True parameter) and I can't add another row. I tried use simple AjaxLink but it doesn't have reference to form in onClick method and when I complete some rows and click "Add row" this data get lost.
I want to enable validation only after "save" button click.
Any idea how to deal with this problem?
I do something like you want using an AjaxLink.
My AjaxLink:
private AjaxLink addNewRow = new AjaxLink("addNewRow") {
#Override
public void onClick(AjaxRequestTarget target) {
MyEntityObject newTableRowObject = new MyEntityObject(irrelevantParameter);
entityObjectTableService.createNewRowInDB(newTableRowObject );
target.add(listViewContainer);
}
};
In this code the listViewContainer is a WebMarkupContainer which contains a ListView holding the table rows.
When i click this AjaxLink a new object representing a row in my table is added to the database and then the container containing the ListView is being refreshed refreshing the ListView and the new empty object is being fetched from the DB and shown as a new row in my table at the end.
Depending on your structure maybe you are looking after disabling validation using setDefaultFormProcessing(true); - http://ci.apache.org/projects/wicket/apidocs/6.x/org/apache/wicket/markup/html/form/AbstractSubmitLink.html#setDefaultFormProcessing%28boolean%29
For now I write some kind of hack
First I set
addKnowledgeLink.setDefaultFormProcessing(false);
and next
BlockingAjaxSubmitLink<Object> addKnowledgeLink = new BlockingAjaxSubmitLink<Object>(
"link_knowledge_add") {
#Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
ChangeDataForm.this.process(this);
/* some code */
target.add(form.get(MY_CONTAINER_ID));
}
(...)
and my hack...
//HACK
public void process(IFormSubmitter object){
if (!isEnabledInHierarchy() || !isVisibleInHierarchy())
{
return;
}
// run validation
validate();
/*if (hasError())
{
// mark all children as invalid
markFormComponentsInvalid();
// let subclass handle error
callOnError(object);
}
else
{*/
// mark all children as valid
markFormComponentsValid();
// before updating, call the interception method for clients
beforeUpdateFormComponentModels();
// Update model using form data
updateFormComponentModels();
// validate model objects after input values have been bound
onValidateModelObjects();
if (hasError())
{
callOnError(object);
return;
}
// Form has no error
delegateSubmit(object);
//}
}
and I ovveride one method
#Override
protected void onError(){
super.onError();
this.updateFormComponentModels();
}
I know it is ugly solution but I couldn't figure out anything better..
And I couldn't shutdown feedback messages
I'm using GXT 3 to build a GridView that will display "incidents".
What I want to do is that when it renders it, I want some checkboxes to be checked, others to empty, according to the boolean in the database.
Below you have my code:
CheckBoxSelectionModel<IncidentDto> isIncidentCM = new CheckBoxSelectionModel<IncidentDto>(incidentProperties.incident());
allColumns.add(isIncidentCM.getColumn());
ColumnModel<IncidentDto> columnModel = new ColumnModel<IncidentDto>(allColumns);
final Grid<IncidentDto> grid = new Grid<IncidentDto>(store, columnModel);
grid.setSelectionModel(isIncidentCM);
add(grid);
And the IncidentProperties value provider:
IdentityValueProvider<IncidentDto> incident();
I'm not sure if you can bind the selection value to a boolean property, but you could add a listener to the Grid to update the checkboxes based on the boolean condition.
grid.addBeforeShowHandler(BeforeShowEvent event) {
#Override
public void onBeforeShow(BeforeShowEvent event) {
List<IncidentDto> itemsToSelect = new ArrayList<IncidentDto>();
for (IncidentDto incident : store.getAll()) {
if (incident.getBooleanProperty()) { //whatever your property is called
itemsToSelect.add(incident);
}
}
isIncidentCM.setSelection(itemsToSelect);
}
}
There may be other implications in using a BeforeShowEvent depending on how/when you populate your store, render the grid, etc. but assuming your store is fully loaded and the property available from your store objects I believe this should accomplish your goal.
For some Wicket components, if I call setOutputMarkupId(true) they warn when they are rendered.
Markup id set on a component that is usually not rendered into markup.
I'd like to output an id for every component that will actually end up in the HTML in order that I can find them with XPath for testing. How can I predict from class or properties of a Component whether it is sensible to setOutputMarkupId(true)?
More detail - in my Application I'm overriding
protected void init() {
super.init();
addComponentInstantiationListener(new IComponentInstantiationListener() {
public void onInstantiation(Component component) {
if (!(component instanceof WebMarkupContainer)) return;
if (component instanceof WebMarkupContainerWithAssociatedMarkup) return;
if (component instanceof Border.BorderBodyContainer) return;
WebMarkupContainer container = (WebMarkupContainer) component;
if (container.isTransparentResolver()) return;
component.setOutputMarkupId(true);
}});
For a sample of pages, this arbitrary gubbins does the trick, but it does seem pretty arbitrary!
Repeater components like DataView and ListView don't have their own markup, but repeat the markup with Items. You can check if the component is instanceof RepeatingView.
This problem is easily shown by the following, wrong, example:
ListView<Person> people = new ListView<Person>("people", list) {
protected void onPopulateItem(ListItem<Person> item) {
add(new Label("name", item.getModelObject().getName()));
}
}
Here we don't add the label to the list item, but rather the listview. And that fails. The code should've been:
ListView<Person> people = new ListView<Person>("people", list) {
protected void onPopulateItem(ListItem<Person> item) {
item.add(new Label("name", item.getModelObject().getName()));
}
}
Also ignore auto-components (Component.isAuto()).
Such components are for example: <wicket:container>, <wicket:enclosure>, etc.
This is just an idea. I didn't try this ans can't right now...
You could find the components, that will propably be rendered by checking if the are tied to a WicketTag (which are not rendered or at least which are the ones causing this message).
This can be done like this:
boolean isGoingToBeRendered (Component component) {
MarkupStream stream = new MarkupStream(component.getMarkup());
ComponentTag tag = stream.getTag();
return (!tag instanceof WicketTag);
}
Again: This is no tried solution, just some lines of code hacked into this editor. It's indended as a pointer not as a ready to use piece of code.