JavaScript not invoked on zone refresh

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

JavaScript not invoked on zone refresh

Christopher
Hi all,

I suspect there's a simple solution to this small, but annoying problem.

My Tapestry page uses a simple javascript to rotate an image 90 degrees
the moment the image is rendered on screen.  It does this by adding a CSS
class to the button element that contains the image.


**The JavaScript**

    $(document).ready(function(){
    $('.accordion').addClass('active');
    });


**The CSS Classes**

    .open-section{
        transform: rotate(0deg);
        transition:1s;
    }
    .close-section{
        transform: rotate(0deg);
        transition:1s;
    }
    .accordion.active .open-section {
        transform: rotate(-90deg);
        transition:1s;
    }
    .accordion.active .close-section {
        transform: rotate(90deg);
        transition:1s;
    }


The above works perfectly well when the page first loads, and if I
manually refresh the page.  But when the button/image appears within a
zone that is refreshed, the javascript evidently doesn't get invoked, as
the button image doesn't rotate.

How would one normally resolve this little problem?

Regards,

Chris.


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

"A designer knows he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away." - Antoine de Saint-Exupéry.
Reply | Threaded
Open this post in threaded view
|

Re: JavaScript not invoked on zone refresh

duymap
Your javascript register when document is ready , it means just affect when
page load or refresh page. If you want handle it via button, please
register onclick event for this button and implement new small function
with call the same snippet. Assume you're using jquery, so here is my
thoughts:

$("button-id").click(function() {
$('.accordion').addClass('active');
})

On Tue, Sep 25, 2018 at 12:22 PM Christopher Dodunski <
[hidden email]> wrote:

> Hi all,
>
> I suspect there's a simple solution to this small, but annoying problem.
>
> My Tapestry page uses a simple javascript to rotate an image 90 degrees
> the moment the image is rendered on screen.  It does this by adding a CSS
> class to the button element that contains the image.
>
>
> **The JavaScript**
>
>     $(document).ready(function(){
>     $('.accordion').addClass('active');
>     });
>
>
> **The CSS Classes**
>
>     .open-section{
>         transform: rotate(0deg);
>         transition:1s;
>     }
>     .close-section{
>         transform: rotate(0deg);
>         transition:1s;
>     }
>     .accordion.active .open-section {
>         transform: rotate(-90deg);
>         transition:1s;
>     }
>     .accordion.active .close-section {
>         transform: rotate(90deg);
>         transition:1s;
>     }
>
>
> The above works perfectly well when the page first loads, and if I
> manually refresh the page.  But when the button/image appears within a
> zone that is refreshed, the javascript evidently doesn't get invoked, as
> the button image doesn't rotate.
>
> How would one normally resolve this little problem?
>
> Regards,
>
> Chris.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>

--
Chung Khánh Duy
Director of Technology
Formos
Reply | Threaded
Open this post in threaded view
|

Re: JavaScript not invoked on zone refresh

Chris Poulsen
In reply to this post by Christopher
Hi

Zone updates are updates of parts of the page, so the ready function is not
triggered for those. Consider also performing your initialization on zone
updates. See:
http://tapestry.apache.org/current/coffeescript/events.html#section-20 for
the zone related events.

--
Chris

On Tue, Sep 25, 2018 at 7:22 AM Christopher Dodunski <
[hidden email]> wrote:

> Hi all,
>
> I suspect there's a simple solution to this small, but annoying problem.
>
> My Tapestry page uses a simple javascript to rotate an image 90 degrees
> the moment the image is rendered on screen.  It does this by adding a CSS
> class to the button element that contains the image.
>
>
> **The JavaScript**
>
>     $(document).ready(function(){
>     $('.accordion').addClass('active');
>     });
>
>
> **The CSS Classes**
>
>     .open-section{
>         transform: rotate(0deg);
>         transition:1s;
>     }
>     .close-section{
>         transform: rotate(0deg);
>         transition:1s;
>     }
>     .accordion.active .open-section {
>         transform: rotate(-90deg);
>         transition:1s;
>     }
>     .accordion.active .close-section {
>         transform: rotate(90deg);
>         transition:1s;
>     }
>
>
> The above works perfectly well when the page first loads, and if I
> manually refresh the page.  But when the button/image appears within a
> zone that is refreshed, the javascript evidently doesn't get invoked, as
> the button image doesn't rotate.
>
> How would one normally resolve this little problem?
>
> Regards,
>
> Chris.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>
Reply | Threaded
Open this post in threaded view
|

Re: JavaScript not invoked on zone refresh

Christopher
In reply to this post by Christopher
Thanks Chung and Chris.

I doubt using .click() will work, as the button being clicked on is
immediately replaced, and it is this new button that must rotate.  The
buttons are for expanding and collpasing sections of a webpage.  Once a
user clicks on an expand button, it is immediately replaced with a
collapse button.  And vice versa.  Below is the TML:

<div class="expand-item">
    <t:if test="expanded" negate="true">
        <a t:type="actionlink" async="true">
            <button class="accordion">
                <img src="${context:/assets/expand-helm.png}"
class="open-section" id="expand" alt="expand" width="100"
/>
            </button>
        </a>
    </t:if>
    <t:if test="expanded">
        <a t:type="actionlink" async="true">
            <button class="accordion">
                <img src="${context:/assets/collapse-helm.png}"
class="close-section" id="collapse" alt="collapse"
width="100" />
            </button>
        </a>
    </t:if>
</div>

Chris, invoking my javascript within the page's Java code sounds
interesting.  I've not done this before, but will look into it.  Do you
have any sample code for this approach?

Thanks,

Chris.


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

"A designer knows he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away." - Antoine de Saint-Exupéry.
Reply | Threaded
Open this post in threaded view
|

Re: JavaScript not invoked on zone refresh

Christopher
In reply to this post by Christopher
After exploring a little further, I discovered the below thread on
invoking javascript from within Tapestry.

https://stackoverflow.com/questions/27988473/pass-parameter-from-java-to-js-in-tapestry

Joost writes:

You will need to use the JavaScriptSupport service.

Your java file:

@Import(library = "RoomManagement.js")
public final class RoomManagement{

  @Inject
  private JavaScriptSupport javascriptSupport;

  @Property
  private long contactId;

  @AfterRender
  private void setup() {
    JSONObject jsonObject = new JSONObject();
    jsonObject.put("contactId", contactId);
    javascriptSupport.addInitializerCall("RoomManagement",jsonObject);
  }
}

Your RoomManagement.js

Tapestry.Initializer.RoomManagement = function (parameters) {
    //do whatever you need here
    alert('Your contactId: ' + parameters.contactId);
};

This looks promising, but I later read that Tapestry's handling of
javascript has been completely rewritten in Tapestry 5.4, with the above
being deprecated.  And I've not found any example code of doing tnings the
new way.  Any pointers would be much appreciated.

My page contains 10 expand/collapse buttons, and I only wish to animate
the one connected to the zone being updated.  So am thinking of giving
each button a unique ID, and passing that ID to the javascript so just the
one button animates.

My needs are pretty straight forward, and reportedly Tapestry's javascript
handling was completely rewritten in 5.4 to simplify things.  Look forward
to seeing how things now get done.  :-)

Appreciate any help.

Regards,

Chris.


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

"A designer knows he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away." - Antoine de Saint-Exupéry.
Reply | Threaded
Open this post in threaded view
|

Re: JavaScript not invoked on zone refresh

Chris Poulsen
Reacting to the zone events sounds like the best option IMO. Controlling
this from the server side seems needlessly complex and fragile in this case.

Not really related to your issue, but you can call exported module methods
in 5.4 like this:

JSONObject specification = new JSONObject( "diagramClientId",
diagram.getClientId(), "modelJson", modelJson );

jsSupport.require( "pages/contentspace/content-space-index" ).invoke(
"init" ).with( specification );

HTH.

--
Chris

On Wed, Sep 26, 2018 at 1:10 AM Christopher Dodunski <
[hidden email]> wrote:

> After exploring a little further, I discovered the below thread on
> invoking javascript from within Tapestry.
>
>
> https://stackoverflow.com/questions/27988473/pass-parameter-from-java-to-js-in-tapestry
>
> Joost writes:
>
> You will need to use the JavaScriptSupport service.
>
> Your java file:
>
> @Import(library = "RoomManagement.js")
> public final class RoomManagement{
>
>   @Inject
>   private JavaScriptSupport javascriptSupport;
>
>   @Property
>   private long contactId;
>
>   @AfterRender
>   private void setup() {
>     JSONObject jsonObject = new JSONObject();
>     jsonObject.put("contactId", contactId);
>     javascriptSupport.addInitializerCall("RoomManagement",jsonObject);
>   }
> }
>
> Your RoomManagement.js
>
> Tapestry.Initializer.RoomManagement = function (parameters) {
>     //do whatever you need here
>     alert('Your contactId: ' + parameters.contactId);
> };
>
> This looks promising, but I later read that Tapestry's handling of
> javascript has been completely rewritten in Tapestry 5.4, with the above
> being deprecated.  And I've not found any example code of doing tnings the
> new way.  Any pointers would be much appreciated.
>
> My page contains 10 expand/collapse buttons, and I only wish to animate
> the one connected to the zone being updated.  So am thinking of giving
> each button a unique ID, and passing that ID to the javascript so just the
> one button animates.
>
> My needs are pretty straight forward, and reportedly Tapestry's javascript
> handling was completely rewritten in 5.4 to simplify things.  Look forward
> to seeing how things now get done.  :-)
>
> Appreciate any help.
>
> Regards,
>
> Chris.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>
Reply | Threaded
Open this post in threaded view
|

Re: JavaScript not invoked on zone refresh

JumpStart
Examples can be found in JumpStart, starting here:

        http://jumpstart.doublenegative.com.au/jumpstart/examples/javascript/javascript

> On 26 Sep 2018, at 3:19 pm, Chris Poulsen <[hidden email]> wrote:
>
> Reacting to the zone events sounds like the best option IMO. Controlling
> this from the server side seems needlessly complex and fragile in this case.
>
> Not really related to your issue, but you can call exported module methods
> in 5.4 like this:
>
> JSONObject specification = new JSONObject( "diagramClientId",
> diagram.getClientId(), "modelJson", modelJson );
>
> jsSupport.require( "pages/contentspace/content-space-index" ).invoke(
> "init" ).with( specification );
>
> HTH.
>
> --
> Chris
>
> On Wed, Sep 26, 2018 at 1:10 AM Christopher Dodunski <
> [hidden email]> wrote:
>
>> After exploring a little further, I discovered the below thread on
>> invoking javascript from within Tapestry.
>>
>>
>> https://stackoverflow.com/questions/27988473/pass-parameter-from-java-to-js-in-tapestry
>>
>> Joost writes:
>>
>> You will need to use the JavaScriptSupport service.
>>
>> Your java file:
>>
>> @Import(library = "RoomManagement.js")
>> public final class RoomManagement{
>>
>>  @Inject
>>  private JavaScriptSupport javascriptSupport;
>>
>>  @Property
>>  private long contactId;
>>
>>  @AfterRender
>>  private void setup() {
>>    JSONObject jsonObject = new JSONObject();
>>    jsonObject.put("contactId", contactId);
>>    javascriptSupport.addInitializerCall("RoomManagement",jsonObject);
>>  }
>> }
>>
>> Your RoomManagement.js
>>
>> Tapestry.Initializer.RoomManagement = function (parameters) {
>>    //do whatever you need here
>>    alert('Your contactId: ' + parameters.contactId);
>> };
>>
>> This looks promising, but I later read that Tapestry's handling of
>> javascript has been completely rewritten in Tapestry 5.4, with the above
>> being deprecated.  And I've not found any example code of doing tnings the
>> new way.  Any pointers would be much appreciated.
>>
>> My page contains 10 expand/collapse buttons, and I only wish to animate
>> the one connected to the zone being updated.  So am thinking of giving
>> each button a unique ID, and passing that ID to the javascript so just the
>> one button animates.
>>
>> My needs are pretty straight forward, and reportedly Tapestry's javascript
>> handling was completely rewritten in 5.4 to simplify things.  Look forward
>> to seeing how things now get done.  :-)
>>
>> Appreciate any help.
>>
>> Regards,
>>
>> Chris.
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: [hidden email]
>> For additional commands, e-mail: [hidden email]
>>
>>


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: JavaScript not invoked on zone refresh

Christopher
In reply to this post by Christopher
Thanks Chris & JumpStart, with your help I was able to get this CSS
animation working, using JavaScriptSupport in combination with RequireJS.

Below is the code, for anyone else wishing to do the same.

**The CSS**

.open-section{
    transition:0s;
    transform: rotate(90deg);
}
.close-section{
    transition:0s;
    transform: rotate(-90deg);
}
.accordion.active .open-section {
    transition:1.0s;
    transform: rotate(0deg);
}
.accordion.active .close-section {
    transition:1.0s;
    transform: rotate(0deg);
}

The animation occurs simply by adding one of the latter two classes to its
former counterpart.  The first two display the button 90 degrees offset
(hence the animation).

**The Component's Java Code**

    public void afterRender(){

        //Invoke client-side javascript to rotate the 'accordion' helm for
this component/zone
        javaScriptSupport.require("activate-helm").with("userAccordion");
    }

**The RequireJS Script**

define(["jquery"], function($){

    return function(accordionId){
        var element = document.getElementById(accordionId);
        element.classList.add("active");
    }

})

The page contains multiple zones, and the above animates the button within
a zone that gets refreshed.

The only glitch is that occasionally, especially with Firefox browser, the
button jumps rather than rotates to it's final position.  I suspect the
browser may be prematurely acting on the 'active' version of the CSS
class, before displaying the button in its initial 90 degree offset
position.  I'm not quite sure yet how to remedy this.  I think having the
RequireJS script wait a while would be a bit of a hack.

Regards,

Chris.


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

"A designer knows he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away." - Antoine de Saint-Exupéry.