Hello, I have migrated my application from Wicket 1.4 to 1.7. Everything is working fine except default focus behavior for page with dynamic number of text area. The behavior is working fine with 1.4.
Here is my requirement: On clicking row from the grid, application opens modal window with left and right frame. Left frame has tabs with different panels associated with each tab. Right side frame shows page with list of (radio choice + text area). The number of items in this list is dynamic; based upon number of responses from database. Now when the modal is displayed, I want the default focus set to the first text area component on right side whose radio choice is not yet selected. Once user makes the choice and update the result, the focus should then go to the next unchecked text area component (allowing user to mark the radio choice without manual scroll). The focus is working fine, but issue is that half of the time the page is not scrolled up to that text area, so user needs to manually scroll to that component. This was not the case with 1.4. The focus was set as well as the page was auto scrolled(every time) to the component; making that component visible. Following is the code snippet for reference. The CustomerDetailsModalPage has left and right frame. Right frame contains the CustomerDetailsResponsePage. CustomerDetailsResponsePage has ListView<Responses> which has radio and text area panel (CustomerDetailsResponsePanel inside CollapsiblePanel). CustomerDetailsResponsePanel has TextArea with DefaultFocusBehavior (Behavior class at the bottom). Could anybody please help or guide me here? My apologies if description/code is confusing. Class CustomerDetailsModalPage ================================ public CustomerDetailsModalPage() { super(); CustomerDetailsRequestPage leftFramePage = new CustomerDetailsRequestPage(); getSession().getPageManager().touchPage(leftFramePage); // get the url to that page IRequestHandler leftFrameHandler = new RenderPageRequestHandler(new PageProvider(leftFramePage)); FramePage leftPage = new FramePage("leftFrame", leftFrameHandler); add(leftPage); CustomerDetailsResponsePage rightFramePage = new CustomerDetailsResponsePage(); getSession().getPageManager().touchPage(rightFramePage); // get the url to that page IRequestHandler rightFrameHandler = new RenderPageRequestHandler(new PageProvider(rightFramePage)); FramePage rightPage = new FramePage("rightFrame", rightFrameHandler); add(rightPage); } Class CustomerDetailsResponsePage: ==================================== ListView<Responses> responseList = new ListView<Responses>("object.list") { ..... //Generate TextArea and radio button panel component for each response from the list. @Override protected void populateItem(final ListItem<Responses> item) { final Responses response = item.getModelObject(); //Add Radio choice for Y/N radio buttons RadioChoice matchFlag = new RadioChoice("matchFlag", yesNoList).setSuffix(" "); matchFlag.setMarkupId("matchFlagId".concat(String.valueOf(item.getIndex()))).setOutputMarkupId(true); item.add(matchFlag); //Add Accordion style panel to show Text Area with response text CollapsiblePanel collapsiblePanel = new CollapsiblePanel("collPanel", new Model<String>("Matching Criteria " + matchingContent), true) { @Override protected Panel getInnerPanel(String markupId) { //Set Page focus if needed by checking if response already marked match Y or N. //If nothing selected then set the focus to the associated text area component if (response.getMatchFlag() == null){ response.setMatchFlagIndicator(AppConstants.SET_FOCUS);// SET_FOCUS = 1 } //Reusable Panel with Text Area return new CustomerDetailsResponsePanel(markupId, response.getContent(), response.getMatchFlagIndicator()); } } collapsiblePanel.setOutputMarkupId(true); item.add(collapsiblePanel); } } Class CustomerDetailsResponsePanel =================================== public CustomerDetailsResponsePanel(String id, String responseContent, final int setFocus) { super(id); if (responseContent != null) { responseContent = responseContent.replaceAll("(
)", ""); responseContent = responseContent.replaceAll(";{2,}", ";"); responseContent = responseContent.replaceAll(";", "\n"); } TextArea<String> response = new TextArea<String>("response", new Model<String>(responseContent)); response.setOutputMarkupId(true); if (setFocus == AppConstants.SET_FOCUS) { response.add(new DefaultFocusBehavior()); } add(response); } Class DefaultFocusBehavior =========================== public class DefaultFocusBehavior extends Behavior { private static final long serialVersionUID = -4891399118136854774L; private Component component; String markupId; public DefaultFocusBehavior() { } @Override public void bind(Component component) { if (!(component instanceof FormComponent)) { throw new IllegalArgumentException("DefaultFocusBehavior: component must be instanceof FormComponent"); } this.component = component; component.setOutputMarkupId(true); } @Override public void renderHead(Component component, IHeaderResponse iHeaderResponse) { super.renderHead(component, iHeaderResponse); String focusStr = "setTimeout(function() { document.getElementById('" + component.getMarkupId() + "').focus(); }, 100);"; iHeaderResponse.render(OnLoadHeaderItem.forScript(focusStr)); String ieFocusStr = "if (navigator.appName == 'Microsoft Internet Explorer') setTimeout(function() { document.getElementById('" + component.getMarkupId() + "').focus(); }, 400)"; iHeaderResponse.render(OnLoadHeaderItem.forScript(ieFocusStr)); } }