I have a listView which has a single column which needs to be editable only in certain cases. If the user needs to change the column, I want them to click a edit button for the row, then replace the label in the cell with a textField. When I call replace I can see the TextField is now in the place of the label, although it is never rendered. I have a AjaxLink to handle the event. I am using a container to repaint the listView. Here is my listview:
parent = new WebMarkupContainer("emp-table-parent");
parent.add(new AjaxLink<Object>(FIRST_NAME_HEADER_LINK) {
/**
*
*/
private static final long serialVersionUID = -1937727929649333407L;
#Override
public void onClick(AjaxRequestTarget target) {
changeGlyphUpdateList(target, parent.get(FIRST_NAME_HEADER_LINK).get(FIRST_NAME_HEADER_ICON),
parent.get(LAST_NAME_HEADER_LINK).get(LAST_NAME_HEADER_ICON),
parent.get(EMAIL_HEADER_LINK).get(EMAIL_HEADER_ICON), parent.get(ELIGIBILITY_CLASS_HEADER_LINK).get(ELIGIBILITY_CLASS_HEADER_ICON),
parent.get(EMPLOYER_HEADER_LINK).get(EMPLOYER_HEADER_ICON));
}
}.add(new Label("first-name-header-label", Model.of("First Name")), new WebComponent(FIRST_NAME_HEADER_ICON)),
new AjaxLink<Object>(LAST_NAME_HEADER_LINK) {
/**
*
*/
private static final long serialVersionUID = -3438649095509412910L;
#Override
public void onClick(AjaxRequestTarget target) {
changeGlyphUpdateList(target, parent.get(LAST_NAME_HEADER_LINK).get(LAST_NAME_HEADER_ICON),
parent.get(FIRST_NAME_HEADER_LINK).get(FIRST_NAME_HEADER_ICON),
parent.get(EMAIL_HEADER_LINK).get(EMAIL_HEADER_ICON),
parent.get(ELIGIBILITY_CLASS_HEADER_LINK).get(ELIGIBILITY_CLASS_HEADER_ICON),
parent.get(EMPLOYER_HEADER_LINK).get(EMPLOYER_HEADER_ICON));
}
}.add(new Label("last-name-header-label", Model.of("Last Name")), new WebComponent(LAST_NAME_HEADER_ICON)),
new AjaxLink<Object>(EMAIL_HEADER_LINK) {
/**
*
*/
private static final long serialVersionUID = 2890934302751793454L;
#Override
public void onClick(AjaxRequestTarget target) {
changeGlyphUpdateList(target, parent.get(EMAIL_HEADER_LINK).get(EMAIL_HEADER_ICON),
parent.get(LAST_NAME_HEADER_LINK).get(LAST_NAME_HEADER_ICON),
parent.get(FIRST_NAME_HEADER_LINK).get(FIRST_NAME_HEADER_ICON),
parent.get(ELIGIBILITY_CLASS_HEADER_LINK).get(ELIGIBILITY_CLASS_HEADER_ICON),
parent.get(EMPLOYER_HEADER_LINK).get(EMPLOYER_HEADER_ICON));
}
}.add(new Label("email-header-label", Model.of("Email")), new WebComponent(EMAIL_HEADER_ICON)),
new AjaxLink<Object>(ELIGIBILITY_CLASS_HEADER_LINK) {
/**
*
*/
private static final long serialVersionUID = -4022209586109961448L;
#Override
public void onClick(AjaxRequestTarget target) {
changeGlyphUpdateList(target, parent.get(ELIGIBILITY_CLASS_HEADER_LINK).get(ELIGIBILITY_CLASS_HEADER_ICON),
parent.get(EMAIL_HEADER_LINK).get(EMAIL_HEADER_ICON),
parent.get(LAST_NAME_HEADER_LINK).get(LAST_NAME_HEADER_ICON),
parent.get(FIRST_NAME_HEADER_LINK).get(FIRST_NAME_HEADER_ICON),
parent.get(EMPLOYER_HEADER_LINK).get(EMPLOYER_HEADER_ICON));
}
}.add(new Label("eligibility-class-header-label", Model.of("Elig. Class")), new WebComponent(ELIGIBILITY_CLASS_HEADER_ICON)),
new AjaxLink<Object>(EMPLOYER_HEADER_LINK) {
/**
*
*/
private static final long serialVersionUID = -738777257301408437L;
#Override
public void onClick(AjaxRequestTarget target) {
changeGlyphUpdateList(target, parent.get(EMPLOYER_HEADER_LINK).get(EMPLOYER_HEADER_ICON),
parent.get(ELIGIBILITY_CLASS_HEADER_LINK).get(ELIGIBILITY_CLASS_HEADER_ICON),
parent.get(EMAIL_HEADER_LINK).get(EMAIL_HEADER_ICON),
parent.get(LAST_NAME_HEADER_LINK).get(LAST_NAME_HEADER_ICON),
parent.get(FIRST_NAME_HEADER_LINK).get(FIRST_NAME_HEADER_ICON));
}
}.add(new Label("employer-header-label", Model.of("Employer")), new WebComponent(EMPLOYER_HEADER_ICON)),
new PageableListView<EmployeeSummaryPkt>("data", employeeSummaryModel.getObject(), 25) {
/**
*
*/
private static final long serialVersionUID = -1697070076764699904L;
#Override
protected void populateItem(final ListItem<EmployeeSummaryPkt> item) {
item.setDefaultModel(new CompoundPropertyModel<EmployeeSummaryPkt>(item.getModelObject()));
item.add(new Label("firstName"),
new Label("lastName"),
new Label("employeeEmail"),
new Link<Object>("eligibility-class-data-link") {
/**
*
*/
private static final long serialVersionUID = -3842291392813313171L;
#Override
public void onClick() {
//LINK TO ELIGIBILITY CLASS OR MAYBE THE SECTION WITHIN THE EMP?
}
}.add(new Label("employeeEligibilityClassSummaryPkt.name")),
new Link<Object>("employer-data-link") {
/**
*
*/
private static final long serialVersionUID = 6809571267919974106L;
#Override
public void onClick() {
getIndex().getHomePanel().setNewContent(new EmployerDetailPanel("panel-content", item.getModelObject().getEmployerSummaryPkt().getId()));
}
}.add(new Label("employerSummaryPkt.name")),
new Label("employeeDateOfBirth"),
new Label("employee-code", Model.of(item.getModelObject().getEmployeeName())).setOutputMarkupId(true),
new AjaxLink<Object>("edit-employee-link") {
/**
*
*/
private static final long serialVersionUID = 6061544430700059358L;
#Override
public void onClick(AjaxRequestTarget target) {
logr.log(Level.FINER, "onClick for edit employee");
logr.log(Level.FINER, "employee code pre: " + item.get("employee-code").getClass().getSimpleName());
item.get("employee-code").replaceWith(new TextField<String>("employee-code", new Model<String>(item.getModelObject().getEmployeeName())).setOutputMarkupId(true));
logr.log(Level.FINER, "employee code post: " + item.get("employee-code").getClass().getSimpleName());
target.addChildren(parent, TextField.class);
target.add(parent);
}
});
}
As you can see, the label with the id "employee-code" is the label I wish to replace. Inside the AjaxLink onClick, you can see where I am getting the label and replacing it. Nothing is changing. Any direction or help is greatly appreciated.
A ListView recreates each if its items on each render, thus the altered listItem is thrown away immediately.
ListView#setReuseItems(true) should help.
An alternative to svenmeier's answer could also be to add only the specific item that has been changed to the AjaxRequestTarget. That is, replace
target.addChildren(parent, TextField.class);
target.add(parent);
With
target.add(item.get("employee-code"))
Which would cause only the piece of markup that concerns the change to be re-rendered, as opposed to the entire table. If your table is big and contains a lot of elements, whose models involve complicated retrieval mechanisms rendering the entire table would be a much more laborious process, and hence re-rendering only the item would be a better solution.
Having said that, in your particular case svenmeier's solution is better, as otherwise if you implement my solution and later on re-render the entire table, the changes would be lost.
Related
may I ask how to pass the value to other Activity using the code below? This is because I want to pass each value of TextView in my ListView to another Activity. Thank you.
public class MySimpleArrayAdapter extends ArrayAdapter<String> {
private final Context context;
private final ArrayList<String> values;
public MySimpleArrayAdapter(Context context, ArrayList<String> values) {
super(context, R.layout.rowlayout, values);
this.context = context;
this.values = values;
}
/**
* Here we go and get our rowlayout.xml file and set the textview text.
* This happens for every row in your listview.
*/
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.rowlayout, parent, false);
TextView textView = (TextView) rowView.findViewById(R.id.criteriaName);
final TextView textView2 = (TextView)rowView.findViewById(R.id.txtView2);
SeekBar seekBar = (SeekBar)rowView.findViewById(R.id.sbBar);
// Setting the text to display
textView.setText(values.get(position));
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
textView2.setText(""+i);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
return rowView;
}
}
So, how am I going to pass the value in TextView2 to another Activity?
At first convert you Textview to a String then , do this
Intent i = new Intent(CurrentActivity.this,ClassOfNextActivity.class);
i.putExtra("My_String",convertedString);
startActivity(i);
On the next Activty you have to do this, to get your String from your first Activity.
Intent i = getIntent();
String newString = (String) i.getSerializableExtra(My_String):
I'm building a wicket bootsrap web application with the following specs (from pom.xml):
wicket version: 6.15.0
wicket-bootstrap-core.version: 0.9.3-SNAPSHOT
I have a base page which is the father of my other pages and adds to mark up a horizontal navigation bar on top, with key component:
BootstrapBookmarkablePageLink extends BookmarkablePageLink
This is part of my BasePage.java
public abstract class BasePage extends GenericWebPage<Void> {
private static final long serialVersionUID = 1L;
String username;
public WicketApplication getApp() {
return WicketApplication.class.cast(getApplication());
}
public BasePage(final PageParameters parameters) {
super(parameters);
// Read session data
cachedUsername = (String)
BasicAuthenticationSession.get().getAttribute("username");
// create navbar
add(newNavbar("navbar"));
}
/**
* #return application properties
*/
public Properties getProperties() {
return WicketApplication.get().getProperties();
}
/**
* creates a new {#link Navbar} instance
*
* #param markupId
* The components markup id.
* #return a new {#link Navbar} instance
*/
protected Navbar newNavbar(String markupId) {
Navbar navbar = new Navbar(markupId) {
private static final long serialVersionUID = 1L;
#Override
protected TransparentWebMarkupContainer newCollapseContainer(String
componentId) {
TransparentWebMarkupContainer container =
super.newCollapseContainer(componentId);
container.add(new CssClassNameAppender("bs-navbar-collapse"));
return container;
}
};
navbar.setPosition(Navbar.Position.TOP);
// navbar.setInverted(true);
NavbarButton<Void> myTab = new NavbarButton<Void>(MyPage.class, new
PageParameters().add("name", "")
.add("status", "All").add("date", ""), Model.of("My page"));
NavbarButton<Void> myOtherTab = new NavbarButton<Void>
(MyOtherPage.class, new PageParameters().add("status", "initial")
.add("date", ""), Model.of("My other page"));
navbar.addComponents(NavbarComponents.transform(
Navbar.ComponentPosition.LEFT,
myTab, myOtherTab));
return navbar;
}
}
Then, MyPage renders a filter form, an html table, ajaxbuttons and some links, Some of my components are ajax components:
public class MyPage extends BasePage {
private static final long serialVersionUID = 5772520351966806522L;
#SuppressWarnings("unused")
private static final Logger LOG = LoggerFactory.getLogger(MyPage.class);
private static final Integer DAYS = 270;
private DashboardFilteringPageForm filteringForm;
private CityInitialForm ncForm;
private String CityName;
private String startDate;
private CitysTablePanel citysTable;
private WebMarkupContainer numberOfNodes;
public MyPage(PageParameters parameters) throws ParseException {
super(parameters);
// get Citys list from repo
final List<City> repoCitys = (List<City>) methodToGetCities();
// select number of nodes
numberOfNodes = new WebMarkupContainer("numberOfNodes") {
private static final long serialVersionUID = 5772520351966806522L;
};
numberOfNodes.setOutputMarkupId(true);
ncForm = new CityInitialForm("ncForm");
// validation
add(new FeedbackPanel("feedbackPanel")).setOutputMarkupId(true);
ncForm.getNumberField().setRequired(true);
ncForm.add(new AjaxButton("ncButton") {
private static final long serialVersionUID = -6846211690328190809L;
#Override
protected void onInitialize() {
super.onInitialize();
add(newAjaxFormSubmitBehavior("change"));
}
#Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
// redirect to other page
}
#Override
protected void updateAjaxAttributes(AjaxRequestAttributes
attributes) {
super.updateAjaxAttributes(attributes);
attributes.getAjaxCallListeners().add(new
DisableComponentListener(citysTable));
}
});
numberOfNodes.add(ncForm);
// filters
CityName = parameters.get("name").toString() == null ? "" :
parameters.get("name").toString();
startDate = parameters.get("date").toString();
filteringForm = new DashboardFilteringPageForm("filteringForm") {
private static final long serialVersionUID = -1702151172272765464L;
};
// initialize form inputs
filteringForm.setCityName(CityName);
try {
filteringForm.setStartDate(new SimpleDateFormat("EE MMM dd HH:mm:ss
z yyyy", Locale.ENGLISH)
.parse(getStartDate().equals("") ?
CortexWebUtil.subtractDays(new Date(), DAYS).toString() : getStartDate()));
} catch (Exception e) {
setResponsePage(SignInPage.class, new PageParameters());
}
filteringForm.add(new AjaxButton("button") {
private static final long serialVersionUID = -6846211690328190809L;
#Override
protected void onInitialize() {
super.onInitialize();
add(newAjaxFormSubmitBehavior("change"));
}
#Override
protected void onSubmit(AjaxRequestTarget target, Form<?> paForm) {
// retrieve Citys
filterCitysAjax(target, "All");
}
#Override
protected void updateAjaxAttributes(AjaxRequestAttributes
attributes) {
super.updateAjaxAttributes(attributes);
attributes.getAjaxCallListeners().add(new
DisableComponentListener(citysTable));
}
});
filteringForm.getCityNameTextField().add(new OnChangeAjaxBehavior() {
private static final long serialVersionUID = 1468056167693038096L;
#Override
protected void onUpdate(AjaxRequestTarget target) {
try {
filterCitysAjax(target, "All");
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
#Override
protected void updateAjaxAttributes(AjaxRequestAttributes
attributes) {
super.updateAjaxAttributes(attributes);
attributes.getAjaxCallListeners().add(new
DisableComponentListener(citysTable));
}
});
// new City link
AjaxLink<Void> newCityLink = newCityLink("newCity", repoCitys);
// Citys table
citysTable = new CitysTablePanel("CitysTable", repoCitys);
citysTable.setOutputMarkupId(true);
// add components
add(filteringForm, newCityLink, numberOfNodes, citysTable);
}
private void filterCitysAjax(AjaxRequestTarget target, String status) {
methodToFilterResults();
// re-render table component
CitysTablePanel cityTableNew = new CitysTablePanel("CitysTable", citys);
cityTableNew.setOutputMarkupId(true);
cityTableNew.setVisibilityAllowed(true);
cityTableNew.setVisible(true);
citysTable.replaceWith(cityTableNew);
target.add(cityTableNew);
citysTable = cityTableNew;
target.appendJavaScript(CortexWebUtil.TABLE_ODD_EVEN_ROWS);
}
private AjaxLink<Void> newCityLink(String string, final List<City> Citys) {
final AjaxLink<Void> newCityLink = new AjaxLink<Void>(string) {
private static final long serialVersionUID = -5420108740617806989L;
#Override
public void onClick(final AjaxRequestTarget target) {
numberOfNodes.add(new AttributeModifier("style",
"display:block"));
target.add(numberOfNodes);
}
};
// new City image
Image newCityImage = new Image("newCityIcon", new
ContextRelativeResource("/img/new_City_icon.png"));
add(newCityLink);
newCityLink.add(newCityImage);
return newCityLink;
}
}
So MyPage works but when I open MyOtherPage Link in an a new tab and trigger an ajax component in MyPage (e.g the AjaxButton) then I get the page expirtaion error.
Why is that happening?
Do I need to use stateless pages? ( stateless link )
Why would it be so ard in wicket to open links in new tabs and use ajax components? I must be missing sometthing..
Here are few possible reasons:
MyPage fails to serialize
Wicket stores stateful pages in page storage (in the disk, by default). Later when you click a stateful link Wicket tries to load the page. First it looks in the http session where the page is kept in its live form (i.e. not serialized). If it is not found there then Wicket looks in the disk.
Wicket keeps only the page(s) used in the last user request in the Http Session (to keep memory footprint small). By clicking on MyOtherPage link you put an instance of MyOtherPage in the Http session and the old instance (of MyPage) is only in the disk. But: if MyPage fails to serialize to byte[] then it cannot be stored in the disk and thus later requests will fail with PageExpiredException.
Todo: Check your logs for NotSerializableException with nice debug message of the reason.
MyOtherPage is too big
By default Wicket writes up to 10M per user session in the disk. If MyPage is let's say 2M and MyOtherPage is 9M (both sizes are quite big, but I don't know what happens in your app...) then saving MyOtherPage will remove MyPage from the disk. Later attempts to load MyPage will fail with PageExpiredException.
Todo: Review your usage of Wicket Models.
timer= new AbstractAjaxTimerBehavior(Duration.seconds(4)) {
/**
*
*/
private static final long serialVersionUID = 1L;
#Override
protected void onTimer(AjaxRequestTarget target) {
List<Animal> newData = animalDaoImpl.getByCriteriaAndIdsAbove(
animal, lastId);
if (newData != null & newData.size() > 0) {
animals.getObject().addAll(newData);
}
target.add(animalWmc);
this.stop(target);
}
};
add(timer);
add(new AjaxLink<String>("start") {
private static final long serialVersionUID = 1L;
#Override
public void onClick(AjaxRequestTarget target) {
timer.restart(target);
}
});
Hi everyone.
above i have code that sets up a timer and stops it before it has a chance to start.
I then have a link which on click should restart the timer and then the timer should do it's thing.
However on click of the button the timer hits the database twice then stops for no reason. Can anyone shed some light on why this is happening. Thanks
Most simple solution (but sure not the best one):
Execute the code in onTimer depending on a boolean variable
#Override
protected void onTimer(AjaxRequestTarget target) {
if (executeTimer) {
// do your database stuff, ...
target.add(animalWmc);
}
}
and change the value for executeTimer in onClick(AjaxRequestTarget target)
#Override
public void onClick(AjaxRequestTarget target) {
executeTimer = true;
}
I tried all to populate a TableView with data. The next code inserts a new row in table but the data not appear the table. I tried to find an explication for this without success.
Please help. I can't what is wrong.
In controller.java
#FXML private TableView<TempTableData> tempTable;
#FXML private TableColumn<TempTableData,String> columnTime;
#FXML private TableColumn<TempTableData,Float> columnTempOne;
#FXML private TableColumn<TempTableData,Float> columnTempTwo;
#FXML private TableColumn<TempTableData,Float> columnTempThree;
#FXML protected void initialize() {
columnTime = new TableColumn<TempTableData,String>();
columnTime.setCellValueFactory(
new PropertyValueFactory<TempTableData,String>("Time"));
columnTempOne = new TableColumn<TempTableData,Float>();
columnTempOne.setCellValueFactory(
new PropertyValueFactory<TempTableData,Float>("Temp 1"));
columnTempTwo = new TableColumn<TempTableData,Float>();
columnTempTwo.setCellValueFactory(
new PropertyValueFactory<TempTableData,Float>("Temp 2"));
columnTempThree = new TableColumn<TempTableData,Float>();
columnTempThree.setCellValueFactory(
new PropertyValueFactory<TempTableData,Float>("Temp 3"));
tempDataList = FXCollections.observableArrayList();
tempDataList.add(new TempTableData("0",3.0f, 4f, 5f));
tempTable.setItems(tempDataList);
}
TempTableData.java
public class TempTableData {
private final SimpleStringProperty time;
private final SimpleFloatProperty dataSensorOne;
private final SimpleFloatProperty dataSensorTwo;
private final SimpleFloatProperty dataSensorThree;
public TempTableData(String time, float dataSensorOne, float dataSensorTwo, float dataSensorThree){
this.time = new SimpleStringProperty(time);
this.dataSensorOne = new SimpleFloatProperty(dataSensorOne);
this.dataSensorTwo = new SimpleFloatProperty(dataSensorTwo);
this.dataSensorThree = new SimpleFloatProperty(dataSensorThree);
}
public String getTime() {
return time.get();
}
public void setTime(String time) {
this.time.set(time);
}
public float getDataSensorOne() {
return dataSensorOne.get();
}
public void setDataSensorOne(float dataSensorOne) {
this.dataSensorOne.set(dataSensorOne);
}
public float getDataSensorTwo() {
return dataSensorTwo.get();
}
public void setDataSensorTwo(float dataSensorTwo) {
this.dataSensorTwo.set(dataSensorTwo);
}
public float getDataSensorThree() {
return dataSensorThree.get();
}
public void setDataSensorThree(float dataSensorThree) {
this.dataSensorThree.set(dataSensorThree);
}
public String toString(){
String string = String.format("[time: %s | dataSensorOne: %f |dataSensorTwo: %f |dataSensorThree: %f ]",
time.get(), dataSensorOne.get(), dataSensorTwo.get(), dataSensorThree.get());
return string;
}
}
why you creating table columns again ? ,as they already created with #FXML annotation (injection!).
remove column instance creation lines from your code and everything will be fine
// remove these lines
columnTime = new TableColumn<TempTableData,String>();
columnTempTwo = new TableColumn<TempTableData,Float>();
columnTempThree = new TableColumn<TempTableData,Float>();
make sure your cell factory values are spelt exactly as the corresponding model class values.
e.g.
private final .... SimpleStringProperty time;
and
new ...... PropertyValueFactory("time"));
I want to change the content of a DataTable depending on the content of a form (think of it as a searchbar functionality). I used to do that in wicket 1.5.x but I can not seem to make it work in wicket 6.0.0-beta2. It does not seem to enter in the onSubmit method of the AjaxButton. Everything else works just fine, every components render correctly and the dataTable is filled with the correct data when the page load, but when I click the button, nothing happens.
Any help would be greatly appreciated. Here is what my code look like :
The dataTable :
public SubscriberPage(PageParameters parameters) {
super(parameters);
add(new SearchForm("searchForm"));
List<IColumn<Subscriber, String>> columns = new ArrayList<IColumn<Subscriber, String>>();
columns.add(new PropertyColumn<Subscriber, String>(new Model<String>("Telephone Number"),
"tn",
"tn"));
[...]
columns.add(new PropertyColumn<Subscriber, String>(new Model<String>("Initialized MB"),
"initializedMB"));
table = new AjaxFallbackDefaultDataTable<Subscriber, String>("table",
columns,
subscriberDataProvider,
40);
table.setOutputMarkupId(true);
add(table);
}
and here is the form with the AjaxButton:
private class SearchForm extends Form<String> {
private static final long serialVersionUID = 1L;
private String tnModel;
private Label tnLabel = new Label("tnLabel", "Telephone Number :");
private TextField<String> tn;
public SearchForm(String id) {
super(id);
tn = new TextField<String>("tnTextField", new PropertyModel<String>(this, "tnModel"));
tn.setOutputMarkupId(true);
add(tnLabel);
add(tn);
AjaxButton lSearchButton = new AjaxButton("searchButton") {
private static final long serialVersionUID = 1L;
#Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
SubscriberFilter filter = new SubscriberFilter();
target.add(table);
if (!(tn.getValue() == null) && !tn.getValue().isEmpty()) {
filter.setTn(tn.getValue());
}
// giving the new filter to the dataProvider
subscriberDataProvider.setFilterState(filter);
}
#Override
protected void onError(AjaxRequestTarget target, Form<?> form) {
// TODO Implement onError(..)
throw new UnsupportedOperationException("Not yet implemented.");
}
};
lSearchButton.setOutputMarkupId(true);
this.setDefaultButton(lSearchButton);
add(lSearchButton);
}
}
The components that you want to refresh need to be added in a container. When you submit, the container needs to be added to target. This way your components will be refreshed. Something like:
WebMarkupContainer outputContainer = new WebMarkupContainer("searchResult");
outputContainer.setOutputMarkupId(true);
outputContainer.add(table);
add(outputContainer);
#Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
//change table ..... stuff ..... ...
//refresh container
target.add(outputContainer);
}
<div wicket:id="searchResult"></div>