Igor,
Thanks for your feedback. I'm certainly not a Wicket expert, so I'm
still trying to figure out the *right* approach to things - and the page
approach was based on feedback.
My previous approach was to try and use my existing panel control as the
content of the AJAX response (via a ComponentRequestTarget). This didn't
work because the component had never been run before.
Your suggestion then, is that I take the panel control (the
BlogCommentPanel), attach it to the page, but make it !visible (or leave
it as empty). Then, when the AJAX callback is performed, either make it
visible, or fill it with the contents, and ask it to re-render (would
you recommend the use of a ComponentRequestTarget for this?). The
problem I ran into going that route previously was from not having the
component attached to the owning page. Obviously, if I were to attach it
as invisible or as empty, that wouldn't be a problem.
Thanks for your time and feedback - it's very valuable. I'm currently
completely re-writing my website from the ground up on Wicket, and I'm
trying to do it right. I'm making multiple passes on things like
understanding models (the first pass I just passed my Dao loaded objects
around directly, without any detached logic), working on AJAX, and
reorganizing my use of components and markup containers.
Thanks again,
R.J.
Igor Vaynberg wrote:
imho,
i think this is the wrong approach because it will cause problems with
links and forms. if you do max_pages_in_pagemap ajax requests and then
click a link or submit a form that was not updated by ajax you will
get a page expired error. it also creates a sync issue because the
page you are looking at is not the last rendered page.
i think a better approach would be to create the listview for comments
and set it its visibility to false. then in the ajax handler set its
visibility to true, render it, and set it back to false. this way you
are not putting a new page into the pagemap so there are no expiration
issues, and this feels more intuitive because you are doing it without
any tricks, you are rendering a part of a page that was invisible
before and updating it on the client side.
if the listview causes you to issue unncessary queries use a dataview,
i believe it does not call any methods on the data provider if it is
not visible.
just my two cents.
-Igor
On 12/28/05, *R.J. Lorimer* <[EMAIL PROTECTED]
<mailto:[EMAIL PROTECTED]>> wrote:
Just to update on my progress, switching to a new page object really
made everything work great. I now have the individual comment fields
being lazily built (using a LoadableModel) on the page that is
passed in
to the handler. The handler sets the page as the request target
when the
callback is made, and the page renders into an XML result, which
is then
passed back to the AJAX callee. The AJAX callee then populates that
particular 'div' tag using JS DOM stuff, and can unload it for
reload later.
Next question I would have - the original page that has these AJAX
links
on it (Page A) has a form on it (to allow you to do a search on the
site). That form is bound to Page A.
When the user clicks on an AJAX link, Wicket handles that as a new
request, effectively rendering a new page (Page B).
Because I'm not there yet, my form isn't implemented - but my question
is, will I have problems where the form in Page A isn't available
in the
Wicket system when the user performs a search (since the last page
loaded was Page B, the AJAX result)?
For those interested, Attached is my latest handler source:
public class BlogCommentAjaxHandler extends AjaxHandler {
private Component component;
private Page elementToRender;
private Component trigger;
private String componentId;
private String htmlId;
public BlogCommentAjaxHandler(Page elemToRender, Component
trigger) {
this.trigger = trigger;
this.elementToRender = elemToRender;
}
@Override protected String getImplementationId() {
return "DojoImpl";
}
@Override protected void respond() {
RequestCycle requestCycle = RequestCycle.get();
requestCycle.setRequestTarget(new
PageRequestTarget(elementToRender));
}
/**
* The duration of the animation.
*/
protected int getDuration() {
return 500;
}
protected Component getTrigger() {
return trigger;
}
protected void onBind() {
Component c = getComponent();
this.component = (Component) c;
this.componentId = c.getId();
// create a unique HTML for the wipe component
htmlId = this.component.getId() + "_" + component.getPath();
// Add ID to component, and bind effect to trigger
this.component.add(new AttributeModifier("id", true, new
Model(htmlId)));
Component commentContainer =
((MarkupContainer)this.component).get("commentContainer");
commentContainer.add(new AttributeModifier("style", true, new
Model("display:none;")));
commentContainer.add(new AttributeModifier("id", true, new
Model(htmlId+"_container")));
this.getTrigger().add(
new AttributeModifier("onclick", true, new
Model("comp_"
+ componentId
+ "_expandComments('" + htmlId + "', '" +
getCallbackUrl() + "', " + getDuration()
+ "); return false;")));
}
@Override protected void
renderHeadInitContribution(HtmlHeaderContainer container) {
String s = "<script language=\"JavaScript\"
type=\"text/javascript\">\n"
+ "var currentWipedComments = null;\n"
+ "function wipeoutCurrentCommentBox(duration) {\n"
+ " if(currentWipedComments) {\n"
+ " aNode =
document.getElementById(currentWipedComments);\n"
+ " dojo.fx.html.wipeOut(aNode, duration,
function() {\n"
+ " aNode.innerHTML = null;\n"
+ " });\n"
+ " currentWipedComments = null;\n"
+ " }\n"
+ "}\n"
+ "function setCurrentCommentBox(nodeId) {\n"
+ " currentWipedComments = nodeId;\n"
+ "}\n"
+ "function isCurrentCommentBox(nodeId) {\n"
+ " return currentWipedComments == nodeId;\n"
+ "}\n"
+ "</script>";
container.getResponse().write(s);
}
public final void renderHeadContribution(HtmlHeaderContainer
container) {
String isWiping = "comp_" + componentId + "_wiping";
String s = "\t"
+ "<script language=\"JavaScript\"
type=\"text/javascript\">\n"
+ isWiping + "= 0; \n"
+ "function comp_"+ componentId + "_expandComments(id,
componentUrl, duration) { \n"
+ " if(isCurrentCommentBox(id +\"_container\")) {\n"
+ " wipeoutCurrentCommentBox(duration);\n"
+ " return;\n"
+ " }\n"
+ " if("+ isWiping + "==0){\n"
+ " node = document.getElementById(id
+\"_container\");\n"
+ " " + isWiping + "= 1;\n"
+ " dojo.io.bind({\n"
+ " url: componentUrl,\n"
+ " mimetype: \"text/plain\",\n"
+ " load: \n"
+ " function(type, data, evt) {\n"
+ " node.innerHTML = data;\n"
+ " wipeoutCurrentCommentBox(duration);\n"
+ " dojo.fx.html.wipeIn(node, duration,
function(){"
+ " setCurrentCommentBox(id +
\"_container\");\n"
+ " " + isWiping + "=0;\n"
+ " });\n"
+ " }\n"
+ " });\n"
+ " }\n"
+ "}\n"
+ "</script>\n";
container.getResponse().write(s);
}
}
R.J. Lorimer wrote:
> shh, of course. The response shouldn't just be the panel - it should
> be an entire Page! That makes sense.
>
> Thanks for your help, I'll keep my progress posted here.
>
> Emergence Dinterstage wrote:
>> On 12/28/05, R.J. Lorimer <[EMAIL PROTECTED]
<mailto:[EMAIL PROTECTED]>> wrote:
>>
>>>> ComponentRequestTarget re-renders components which have
already been
>>>> rendered during the full page render. We only recently fixed
a bug to
>>>> allow Panel children to be re-rendered as well. Because you are
>>>> re-rendering a Panel that bug should not affect you, but
because of
>>>> the change I'd still suggest to use cvs head.
>>>>
>>>>
>>> This may be part of my problem - the component being passed in
to the
>>> handler has never been rendered before - part of the advantage
of using
>>> an additional click/AJAX is that I don't have to do the extra
query
>>> until the user asks for it. I was trying to achieve that by
creating a
>>> component that would be rendered for the first time when the AJAX
>>> request was complete.
>>>
>>
>> where is the components markup you try to render?
>>
>>
>>> The core problem is that I have never rendered the component
before, I
>>> think. Is there a way to achieve this?
>>>
>>
>> In order to render a Component it (the root component; not its
>> children) must know its associated markup. And the only way to
achieve
>> it is to render the whole page first. To clarify it a little
bit more.
>> You'll find a labels markup somewhere with a panel, border or page
>> markup file. To render this label the associated markup stream
>> position is required, which gets assigned during a page render
phase.
>>
>>
>>> Effectively, I want to send the
>>> HTML result of my component render to the user on an AJAX bind
call.
>>>
>>
>> Ok, the response is XML and it has never been rendered before.
>> Actually it is like a page request which returns XML instead of
HTML.
>> It is not a component re-render, it is whole new request.
>> Create a new Page, override MarkupContainer.getMarkupType() (see
>> src/test ... XmlPage) create whatever XML response is required.
>>
>>
>>> Perhaps I am missing some of the puzzle for using deferred
AJAX calls
>>> using the AjaxHandler. I dug through the contrib-dojo stuff -
and the
>>> only one that handles a callback completely is the Validation
stuff,
>>> and
>>> it simply returns a valid/invalid plain text mime-type result.
>>>
>>
>>
>> -------------------------------------------------------
>> This SF.net email is sponsored by: Splunk Inc. Do you grep through
>> log files
>> for problems? Stop! Download the new AJAX search engine that
makes
>> searching your log files as easy as surfing the web. DOWNLOAD
SPLUNK!
>> http://ads.osdn.com/?ad_idv37&alloc_id865&op=click
<http://ads.osdn.com/?ad_idv37&alloc_id%16865&op=click>
>> _______________________________________________
>> Wicket-user mailing list
>> Wicket-user@lists.sourceforge.net
<mailto:Wicket-user@lists.sourceforge.net>
>> https://lists.sourceforge.net/lists/listinfo/wicket-user
>>
>>
>>
>>
>
>
> -------------------------------------------------------
> This SF.net email is sponsored by: Splunk Inc. Do you grep
through log
> files
> for problems? Stop! Download the new AJAX search engine that makes
> searching your log files as easy as surfing the web. DOWNLOAD
SPLUNK!
> http://ads.osdn.com/?ad_id=7637&alloc_id=16865&op=click
<http://ads.osdn.com/?ad_id=7637&alloc_id=16865&op=click>
> _______________________________________________
> Wicket-user mailing list
> Wicket-user@lists.sourceforge.net
<mailto:Wicket-user@lists.sourceforge.net>
> https://lists.sourceforge.net/lists/listinfo/wicket-user
>
>
>
-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through
log files
for problems? Stop! Download the new AJAX search engine that makes
searching your log files as easy as surfing the web. DOWNLOAD
SPLUNK!
http://ads.osdn.com/?ad_id=7637&alloc_id=16865&op=click
<http://ads.osdn.com/?ad_id=7637&alloc_id=16865&op=click>
_______________________________________________
Wicket-user mailing list
Wicket-user@lists.sourceforge.net
<mailto:Wicket-user@lists.sourceforge.net>
https://lists.sourceforge.net/lists/listinfo/wicket-user
-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems? Stop! Download the new AJAX search engine that makes
searching your log files as easy as surfing the web. DOWNLOAD SPLUNK!
http://ads.osdn.com/?ad_id=7637&alloc_id=16865&op=click
_______________________________________________
Wicket-user mailing list
Wicket-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/wicket-user