Open nfranke opened 11 years ago
Can you view the source and tell me what the random element is? Take a look at the generated HTML. This is strange.
I have thought about having an ajax="false" option so that tab changes cause a full page refresh. Would that help you? Then you could use a @PageActivationContext which would remain through the posting of the form.
You can test this by setting the active tab to a @PageActivationContext and then right click on a tab and open in new window. I'm guessing if you do this, the active tab will remain though the form post.
The editor cut out my text. It's an empty input element. I can' easily run your demo, but try putting a t:form around the tab group in your demo. It's in the generated HTML. I can't figure out where it's coming from. I eliminated it by putting the form inside the Tab element.
Disabling AJAX would help some things, I think. I managed to get it working with the @Persist, but I'm not sure if I like that solution. I have a grid in there so stuff is stored in the session anyway.
Ok, how's this for a complex solution. You could add a listener on your page for onTabChange(tabindex) which should "bubble up" from the tabgroup to your page
In the event, use the ajax response renderer to update a hidden field in your form
Then when your form posts, you will have the active tab which you can pass to your onactivate
By the way, the tab group never adds an input. I wonder if it's the form component adding t:formdata
Were you able to reproduce it by inserting a t:form around your example?
I have the same issue. It is no t:formdata hidden input, it is empty <input>
. Html inside form looks like
<form id="form" method="post" action="/page.form"
onsubmit="javascript:return Tapestry.waitForPage(event);">
<div class="" style="display: none;">
<input type="hidden" name="t:formdata"
value="HoIF+WNTWJhH80N9cnOkgjFGj0s=:H4sIAAAAAAAAAFvzloEVAN3OqfcEAAAA">
</div>
<div id="tabsZone" class="t-zone tapestry-zone">
<ul class="nav nav-tabs">
<li class="active"><a href="/page.tabgroup:tabchange/tab1"
onclick="javascript:return Tapestry.waitForPage(event);"
id="eventlink">tab1</a></li>
<li><a href="/page.tabgroup:tabchange/tab2"
onclick="javascript:return Tapestry.waitForPage(event);"
id="eventlink_0">tab2</a></li>
</ul>
<input> tab1Content
</div>
</form>
In it's current state, the tabgroup cannot be used inside a form.
The easiest solution is to add a ajax="false"
option which causes all tabs to be fetched and rendered on page load but only one is visible. With this option, a tab change would not cause an ajax request and would simply toggle the visible tab on the client. This has the added benefit that field changes would not be lost when changing tabs.
To do ajax tab changes in a form would be much more difficult. This would probably need to use FormInjector and you'd also need to record the field changes somewhere before updating the zone (session / cookie / js variable etc).
I made workaround for me in Tab.java. It ugly but works for my needs
@AfterRenderBody
void afterRender(MarkupWriter writer) {
if (renderBody) {
// capture the body markup and remove it from the DOM, it will be rendered by the TabGroup
Element bodyWrapper = writer.getElement();
List<Node> children = bodyWrapper.getChildren();
//workaround. Empty input if tabGroup inside form
if (children.size() > 1 && children.get(0) instanceof Element) {
Element element = ((Element) children.get(0));
if ("input".equals(element.getName()) && element.getAttributes().size() == 0 && element.getChildren().size() == 0) {
element.remove();
}
}
//***workaround
writer.end();
TabModel tabModel = (TabModel) request.getAttribute(TabGroup.ATTRIBUTE_TAB_MODEL);
tabModel.setActiveTabBody(bodyWrapper.getChildMarkup());
bodyWrapper.remove();
}
}
You will still have a problem with two tabs on a form when each tab has fields. Loading a second tab will wipe the field values in the first tab.
If you enclose a tab group in a form a random element is created for some reason.
Submitting the form loses the current tab group as well. In fact, the current tab is lost almost all the time unless one @Persist the activeTab property. Note sure if anything can be done about that, though.
Also it's pretty common to do initialization in onActivate, but that won't work with tabs since the active tab is set after onActivate is called. At least document it, I guess.