Hi Eugen,

my javascript file is located in META-INF/modules/. It is loaded without problems when I call js.require("myModule.js");. Just the invoke call gives the problem.

Anyway, I've missed that some form input values should be up to date when doing the zone update request. So I did a little bit research and found the perfect working zone parameter of the tapestry form :).

*.tml
<form t:type="form" t:zone="myZone" t:id="submitForm">
  // some input values that should update the zone
</form>

<t:zone id="myZone" t:id="myZone">
  <ul>
    <li t:type="loop" source="hits" value="hit">
      // update the zone with solr data
    </li>
</ul>
</t:zone>

*.js
    require([ "jquery", "myController" ], function($, myController) {
        var submitForm = $("#submitForm");
        $(myController.route).on("onChange", function(e) {
            submitForm.submit();
        });
        myController.create();
    });

*.java
    @OnEvent(component = "submitForm", value = EventConstants.SUCCESS)
    Object formSubmitted() {
        if (request.isXHR()) {
            return myZone.getBody();
        } else {
            return this;
        }
    }

    public Collection<Hit> getHits() {
// form input is updated, so we can do a solr search with new values
        return solr.get(...)
    }

It works really great. Thanks all for your support.


On 17.12.2013 12:30, Eugen wrote:
Hi Matthias,
how do You define the myModule?
It should be a javascript file in META-INF/modules/myModule.js to be
automatically loaded as module.
alternatively You can contribute the ModuleManager in Yout AppModule
to laod desired JS file as module:
     @Contribute(ModuleManager.class)
     public static void loadExtraModules(MappedConfiguration<String,
Object> configuration,
             @Path("META-INF/assets/js/myModule.js") Resource myModule)
throws IOException {
         configuration.add("myModule", new
JavaScriptModuleConfiguration(myModule));
     }

2013/12/15 Matthias <thegreatme...@gmail.com>:
Hi Eugen,

thanks a lot, I got the zone updates now :). There is only one problem with
the initialisation at startup.
When I use the invoke method require js prints an error: RequireJS error:
require: moduleLib is undefined

     @AfterRender
     public void afterRender() {
         javaScriptSupport.require("myModule").invoke("moduleFunc");
     }

When I debug the javascript code it looks like my module is not loaded
correctly by require js, but I have no idea why:

t5/core/pageinit (line 63)

return require([moduleName], function(moduleLib) {
   // moduleLib is undefined here
});

The moduleName is "myModule", but when the function is executed the
moduleLib is "undefined" and cannot call
the moduleFunc function.



On 12.12.2013 21:34, Eugen wrote:
Hi Matthias,
as second parameter of deferredZoneUpdate() function You need to
provide a event link to a function that returns a block or a
Zone.Body, something like:

      @OnEvent("update-zone-event")
      Object myEvent() {
         return request.isXHR()?zone.getBody():null;
      }

the event Link, that should be passed to js Module can be created as
follow:

public String getZoneUpdateLink() {
       componentResources.createEventLink("update-zone-event",
context).toAbsoluteURI();
}

JavaScript, something like
require([ "jquery", "t5/core/zone" ], function($, zoneManager) {
      var moduleFunc, exports;
      moduleFunc = function(myController, myZoneId, url){
          $('#'+myControllerId).on("myEvent", function(e) {
              zoneManager.deferredZoneUpdate(myZoneId, url);
          }
      };
      return exports = {
          moduleFunc: moduleFunc
      };
});
}).call(this);

and initialization call in page/component:


javaScriptSupport.require("myModule").invoke("moduleFunc").with(myControllerId,
zone.getClientId(), getZoneUpdateLink());


2013/12/12 Matthias <thegreatme...@gmail.com>:
Thanks to both of you, I tried Howard's approach but I think I missing
something fundamental.
Heres my new code:

JavaScript
require([ "jquery", "t5/core/zone" ], function($, zoneManager) {

      // #1 with zone.update
      var myZone = $("#myZone");
      // why do I have to set the data-update-zone attribute?
      myZone.attr("data-update-zone", "myZone");
      var zone = zoneManager.findZone(myZone);
      // this works, but just with a string. should I get the dom elements
via
ajax?
      zone.update("some string");

      // #2 refresh - there is no refresh method on the zone?
      // zone.refresh();

      // #3 defferedZoneUpdate
      // the java method is called - maybe this can work
      zoneManager.deferredZoneUpdate("myZone",
"http://localhost:8080/search.myZone";);
});

Java
public class Search {

      // the method is called successfully, but my zone is not updated in
any
way.
      JSONArray onActionFromDriverZone() {
          JSONArray arr = new JSONArray();
          JSONObject d = new JSONObject();
          d.put("id", "2");
          arr.put(d);
          return arr;

      }
}


On 12.12.2013 12:56, Howard Lewis Ship wrote:
The short form is:  trigger an events.zone.update event on the zone's
client-side element to update it immediately, using available content (a
string, or DOM elements).

Or, trigger events.zone.refresh event when you know a URL and additional
parameters; Tapestry will run the Ajax request and update the zone when
the
content is available.

I think Geoff's example is actually a bit complicated.  Take a peek at
the
t5/core/zone module to see how simple it can be:
http://people.apache.org/~hlship/t5api/coffeescript/zone.html


On Thu, Dec 12, 2013 at 1:47 AM, Geoff Callender <
geoff.callender.jumpst...@gmail.com> wrote:

This should give you the clues you need: it's the ZoneUpdater mixin
from
the upcoming preview of JumpStart 7. It uses a dependency on
"t5/core/zone".

Example usage:

<t:textfield t:id="firstName" t:mixins="zoneUpdater"
clientEvent="keyup"
event="firstNameChanged" zone="nameZone"/>


ZoneUpdater.java:

/**
    * A simple mixin for attaching javascript that updates a zone on any
client-side event.
    * Based on
http://tinybits.blogspot.com/2010/03/new-and-better-zoneupdater.html
    */
package jumpstart.web.mixins;

import org.apache.tapestry5.BindingConstants;
import org.apache.tapestry5.ClientElement;
import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.annotations.Environmental;
import org.apache.tapestry5.annotations.InjectContainer;
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.services.javascript.JavaScriptSupport;

public class ZoneUpdater {

           // Parameters

           /**
            * The event to listen for on the client. If not specified,
zone
update can only be triggered manually through
            * calling updateZone on the JS object.
            */
           @Parameter(name = "clientEvent", defaultPrefix =
BindingConstants.LITERAL)
           private String clientEvent;

           /**
            * The event to listen for in your component class
            */
           @Parameter(name = "event", defaultPrefix =
BindingConstants.LITERAL, required = true)
           private String event;

           @Parameter(name = "prefix", defaultPrefix =
BindingConstants.LITERAL, value = "default")
           private String prefix;

           @Parameter(name = "context")
           private Object[] context;

           /**
            * The zone to be updated by us.
            */
           @Parameter(name = "zone", defaultPrefix =
BindingConstants.LITERAL, required = true)
           private String zone;

           /**
            * Set secure to true if https is being used, else set to
false.
            */
           @Parameter(name = "secure", defaultPrefix =
BindingConstants.LITERAL, value = "false")
           private boolean secure;

           // Useful bits and pieces

           @Inject
           private ComponentResources componentResources;

           @Environmental
           private JavaScriptSupport javaScriptSupport;

           /**
            * The element we attach ourselves to
            */
           @InjectContainer
           private ClientElement clientElement;

           // The code

           void afterRender() {
                   String listenerURI =
componentResources.createEventLink(event,
context).toAbsoluteURI(secure);




javaScriptSupport.require("mixins/zone-updater").with(clientElement.getClientId(),
clientEvent, listenerURI,
                                   zone);
           }
}


zone-updater.js:

define(["jquery", "t5/core/zone"], function($, zoneManager) {

           return function(elementId, clientEvent, listenerURI,
zoneElementId) {
                   var element = $("#" + elementId);

                   if (clientEvent) {
                           element.on(clientEvent, updateZone);
                   }

                   function updateZone() {
                           var listenerURIWithValue = listenerURI;

                           if (element.val()) {
                                   listenerURIWithValue =
appendQueryStringParameter(listenerURIWithValue, 'param',
element.val());
                           }

                           zoneManager.deferredZoneUpdate(zoneElementId,
listenerURIWithValue);
                   }
           }

           function appendQueryStringParameter(url, name, value) {
                   if (url.indexOf('?') < 0) {
                           url += '?'
                   }
                   else {
                           url += '&';
                   }
                   value = escape(value);
                   url += name + '=' + value;
                   return url;
           }

});

Cheers,

Geoff


On 12/12/2013, at 6:50 AM, Matthias wrote:

Hi,

I'd like to update a zone with a simple ajax call and I'm not sure how
its done:
Javascript
require([ "jquery", "myController"], function($, myController) {

      $(myController).on("myEvent", function(e) {
         // here i'd like to fire an ajax call that should update my
zone
      });
});

tml
<t:zone id="myZone" t:id="myZone">
    <table class="table">
      <tbody>
         <tr t:type="loop" source="hits" value="hit">
           <td>${hit.id}</td>
         </tr>
      </tbody>
    </table>
</t:zone>

Java
public class Search {

      @Property
      // some other annotations needed?
      List<Hit> hits;

      @Property
      // some other annotations needed?
      Hit hit; // i need this right?

      @InjectComponent
      private Zone myZone;

      private void setupRender() {
          hits = new ArrayList<>();
      }

      Object onAjaxEvent() {
         hits = // do some solr stuff to get hits
         return myZone;
      }
}

In 5.3 there was a Tapestry javascript object with a
findZoneManagerForZone() method. How is this done in 5.4?
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org

Reply via email to