Ughhh...That is a lot of code to read ;) It sounds like because your
component "disappears" on the page the it is correctly being specified
in your service as something that needs updating, but for one reason
or another it never actually gets rendered, or doesn't get access to a
writer that will send it's content back to the page...
Hmmm hmmm...I had problems like this very early on but don't run
across them anymore. My AjaxWebRequest has a hivemind logging
interceptor that, when turned on, will display a log statement for
every single component that does or doesn't get rendered.
"isValidRequest" is if it's a valid ajax request, and
"containsComponentId" shows the method call for each component and the
id value it's checking. This has helped me in scnerios like this one.
Ho humm ho humm..If you had only asked earlier I would have been able
to save you so much trouble. I'm being told that "Lost" is going to be
played on tivo now whether I like it or not by my wife so I have to go
(until early tomorrow)....It will be a one hour change for me to do
tomorrow morning, so that when you wake it will be to a new day filled
with care free ajax form submissions and frivalous lattes served by
buxom blonde aphrodite women...Or at least one filled with single form
field form submissions that can easily be specified with onchange()
attributes without the need to write special javascript or define
components that don't get used.
Make it so! Hah! Has enyone seen Extras lately? Piccard was there
blathering on about his screenplay of him seeing women nude...It was
very funny.
j
On 11/9/05, Leonardo Quijano Vincenzi <[EMAIL PROTECTED]> wrote:
> Ok, my head's gonna explode (yeah! I should've listened to Patrick
> Casey!!)... but I have a solution *almost* there... At least for the
> simpler case.
> I think the perfomance considerations can be solved later, if they're
> really needed. A simple "behind the scenes" form submit with some
> components being refreshed would be enough for this case (better keep it
> simple!)
>
> Right now, I have a kind of derivation of AjaxDirectLink, AjaxForm,
> Refresh, etc... components. I called "AjaxListenerInvoker" and it
> generates a JavaScript function I can later hook into my components to
> invoke a listener on "onchange()" events, or such.
>
> For example: This generates a unique Javascript function on the body of
> my document.
>
> <span jwcid="[EMAIL PROTECTED]"
> listener="listener:changeCountry"
> updateComponents="ognl:{components.stateField.id}"
> />
>
> Then, my 'master' select:
>
> <div>
> <label jwcid="@FieldLabel" field="component:country" />
> <select jwcid="[EMAIL PROTECTED]" displayName="Country"
> validators="validators:required"
> onchange="ognl:components.countryChangeInvoker.href"
> model="ognl:referenceData.getCountriesModel(true)"
> value="ognl:value.country" />
> </div>
>
> And my 'detail' select:
>
> <div jwcid="[EMAIL PROTECTED]"
> id="ognl:components.stateField.id">
> <label jwcid="@FieldLabel" field="component:state" />
> <select jwcid="[EMAIL PROTECTED]" displayName="State"
> validators="validators:required"
> model="ognl:referenceData.getStatesModel(true, countryId)"
> value="ognl:value.state" />
> </div>
>
> Now... right now a change in the master select would submit the form
> (using AjaxListenerInvoker) and invoke a listener on the page. The
> listener does nothing... just because right now the values are generated
> on form rendering, not on listener invocation. That could change (and
> does change on some components).
>
> The only problem I have right now is that updateComponents is failing to
> work. It seems that it invokes the listener fine, gets the appropiate
> response to the selected country, but the states field disappears from
> the page!! I'm hitting my head on the wall on this, maybe you can help out.
>
> I implemented the script component similar to what Tacos' does. Like this:
>
> AjaxListenerInvoker.script:
> *****************************************************************************************************
> <?xml version="1.0"?>
> <!DOCTYPE script PUBLIC
> "-//Apache Software Foundation//Tapestry Script Specification 3.0//EN"
> "http://jakarta.apache.org/tapestry/dtd/Script_3_0.dtd">
> <script>
> <include-script resource-path="/net/sf/tacos/ajax/components/tacos.js" />
> <include-script
> resource-path="/net/sf/tacos/ajax/components/prototype.js" />
>
> <input-symbol key="hiddenId" class="java.lang.String" required="yes"/>
> <input-symbol key="formId" required="yes" />
> <input-symbol key="url" required="yes" />
> <input-symbol key="evalScripts" required="yes" />
> <input-symbol key="updateObject" required="yes" />
> <input-symbol key="effects" />
> <input-symbol key="statusElement" />
>
> <let key="functionName" unique="yes">
> ajaxListenerInvoker_${hiddenId}
> </let>
>
> <let key="href">
> javascript:${functionName}();
> </let>
>
> <body>
> <unique> <![CDATA[
> dojo.require("dojo.fx.html");
> ]]></unique>
>
> <![CDATA[
> function ${functionName}() {
> Tapestry.find('${hiddenId}').value = "T";
> tacos.formSubmit(
> {
> url: "${url}",
> processScripts: "${evalScripts}",
> effects: ${effects},
> updateObject: ${updateObject},
> formId: "${formId}",
> changeUrl: false,
> statusElement: "${statusElement}"
> });
> }
> ]]>
> </body>
>
> </script>
> *****************************************************************************************************
>
> AjaxListenerInvoker.jwc:
> *****************************************************************************************************
> <component-specification allow-body="no" allow-informal-parameters="no">
> <parameter name="updateComponents" />
> <parameter name="updateBlocks" />
> <parameter name="processScripts" default-value="ognl:false" />
> <parameter name="updateObject" />
> <parameter name="listener" required="yes" />
> <parameter name="parameters" />
> <parameter name="direct" />
> <parameter name="effects" />
> <parameter name="statusElement" />
> <parameter name="stateful" />
> <parameter name="disabled" />
> <parameter name="id" property="idParameter" default-value="id"/>
> <parameter name="anchor"/>
> <parameter name="renderer"/>
>
> <inject property="listenerInvoker"
> object="infrastructure:listenerInvoker"/>
> <inject property="ajaxEngineService" object="service:tacos.ajaxdirect"/>
> <inject property="script" type="script"
> object="AjaxListenerInvoker.script"/>
>
> <reserved-parameter name="href"/>
> <reserved-parameter name="onclick"/>
>
> </component-specification>
> *****************************************************************************************************
>
> AjaxListenerInvoker.java (I stripped all comments... after all they are
> all in Spanish :P):
> *****************************************************************************************************
> import *;
>
> /** @author Leonardo Quijano Vincenzi **/
> public abstract class AjaxListenerInvoker extends AbstractFormComponent {
>
> @Override
> protected boolean getCanTakeFocus() {
> return false;
> }
>
> protected boolean isClicked(IRequestCycle cycle, String name) {
> String value = cycle.getParameter(name);
> return HiveMind.isNonBlank(value);
> }
>
> public static Object[] constructServiceParameters(Object
> parameterValue) {
> Object result[] = null;
>
> if(parameterValue != null) {
> if(parameterValue instanceof Object[]) { result = (Object
> []) parameterValue; }
> else if(parameterValue instanceof List) {
> List list = (List) parameterValue;
> result = list.toArray();
> }
> else { return new Object[] { parameterValue }; }
> }
>
> return result;
> }
>
> /** @see AbstractFormComponent#renderFormComponent(IMarkupWriter,
> IRequestCycle) */
> @SuppressWarnings("unchecked")
> @Override
> protected void renderFormComponent(IMarkupWriter writer,
> IRequestCycle cycle) {
> boolean disabled = isDisabled();
>
> IForm form = getForm();
> String name = getName();
>
> String hiddenId =
> cycle.getUniqueId(TapestryUtils.convertTapestryIdToNMToken(getIdParameter()));
>
> setClientId(hiddenId);
> form.addHiddenValue(name, hiddenId, "");
>
> if(!disabled) {
> Object[] parameters =
> constructServiceParameters(getParameters());
>
> String[] updateComponents = new String[0];
> if (getUpdateComponents() != null) {
> updateComponents = (String[]) getUpdateComponents()
> .toArray(new String[getUpdateComponents().size()]);
> }
>
> //TODO: Add more html block logic hooks
> String[] updateBlocks = new String[0];
> if (getUpdateBlocks() != null) {
> updateBlocks = (String[])getUpdateBlocks()
> .toArray(new String[getUpdateBlocks().size()]);
> }
>
> AjaxDirectServiceParameter dsp = new AjaxDirectServiceParameter(
> (IDirect) form, parameters, updateComponents,
> updateBlocks, isDirect());
> String reqUrl = getAjaxEngineService().getLink(
> cycle, false, dsp).getAbsoluteURL();
>
> Map<String, Object> symbols = new HashMap<String, Object>();
> symbols.put("hiddenId", hiddenId);
> symbols.put("formId", form.getName());
> symbols.put("url", reqUrl);
> symbols.put("evalScripts", String.valueOf(isProcessScripts()));
> if(getUpdateObject() != null) {
> symbols.put("updateObject", getUpdateObject());
> }
> else {
> symbols.put("updateObject", "null");
> }
> if (getEffects() != null) {
> symbols.put("effects", StringUtils.escapeJavaScriptHash(
> getEffects()));
> }
> else{
> symbols.put("effects", "{}");
> }
> if(getStatusElement() != null) {
> symbols.put("statusElement", getStatusElement());
> }
>
> PageRenderSupport pageRenderSupport =
> TapestryUtils.getPageRenderSupport(cycle, this);
> getScript().execute(
> cycle, pageRenderSupport, symbols);
>
> setHref((String) symbols.get("href"));
> setFunctionName((String) symbols.get("functionName"));
> }
> }
>
> /** @see AbstractFormComponent#rewindFormComponent(IMarkupWriter,
> IRequestCycle) */
> @Override
> protected void rewindFormComponent(IMarkupWriter writer,
> IRequestCycle cycle) {
> if(isClicked(cycle, getName())) {
> handleClick(cycle, getForm());
> }
> }
>
> private void handleClick(final IRequestCycle cycle, IForm form) {
> final IActionListener listener = getListener();
> final IActionListener action = getAction();
>
> if(listener == null && action == null) {
> return;
> }
>
> final ListenerInvoker listenerInvoker = getListenerInvoker();
>
> Object parameters = getParameters();
> if (parameters != null) {
> if (parameters instanceof Collection) {
> cycle.setListenerParameters(((Collection)
> parameters).toArray());
> }
> else {
> cycle.setListenerParameters(new Object[] { parameters });
> }
> }
>
> if(listener != null) {
> listenerInvoker.invokeListener(listener,
> AjaxListenerInvoker.this, cycle);
> }
>
> if(action != null) {
> Runnable notify = new Runnable() {
> public void run() {
> listenerInvoker.invokeListener(
> action, AjaxListenerInvoker.this, cycle);
> }
> };
>
> form.addDeferredRunnable(notify);
> }
> }
>
> public abstract IActionListener getListener();
> public abstract IActionListener getAction();
> public abstract Object getParameters();
> public abstract String getHref();
> public abstract void setHref(String href);
> public abstract ListenerInvoker getListenerInvoker();
> public abstract IScript getScript();
> public abstract AjaxDirectService getAjaxEngineService();
> public abstract Collection getUpdateComponents();
> public abstract Collection getUpdateBlocks();
> public abstract boolean isProcessScripts();
> public abstract String getUpdateObject();
> public abstract boolean isDirect();
> public abstract String getEffects();
> public abstract String getStatusElement();
> public abstract boolean isDisabled();
> }
> *****************************************************************************************************
>
> --
> Ing. Leonardo Quijano Vincenzi
> Director T�cnico
> DTQ Software
>
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>
>