0

I need to do something seemingly quite simple.

In the same way that I can, from my scala.html file, create a link to another url, /entry, I need to do that from a javascript file.

i.e., from the scala.html:

    <div class="footer">
        <a href='@routes.Application.index()'>Home</a>
    </div>

from my javascript event:

function() myEvent {
    window.location="@routes.Application.entry()"; // DOESN'T WORK!
}

For routing from javascript, I've already had to setup my javascript routes for some ajax work I've already had to do.

My ajax work was calling a method 'findPersons()' so in my Application.java file, I had already:

public Result jsRoutes()
{
    response().setContentType("text/javascript");
    return ok(Routes.javascriptRouter(  "appRoutes",
                                        routes.javascript.Application.findPersons()));
}

Because I want to be able to redirect to my GET entry() method, I modified it to look like this:

public Result jsRoutes()
{
    response().setContentType("text/javascript");
    return ok(Routes.javascriptRouter(  "appRoutes",
                                        routes.javascript.Application.findPersons(),
                                        routes.javascript.Application.entry()));
}

Additionally I have these in my routes file:

GET     /entry              controllers.Application.entry()

POST    /findPersons        controllers.Application.findPersons()

When I am invoking my findPersons method, it is really nice and simple. It looks like this:

appRoutes.controllers.Application.findPersons().ajax({
    data: {
        personIdentifier : personIdentifier,
        surname : surname, 
        givenNames : givenNames
    },
    success : processDBQuery
});

For my simple redirect, I would like to be able to maintain the same loose coupling between my html/javascript code and the urls, as I can the ajax call above.

My redirect needs to occur on an event. Therefore, the easiest and quickest solution would have been simple to write:

function() myEvent {
    window.location="/entry";
}

However, then I would be hard-coding the URL (which I have managed to avoid for my ajax call above), no longer maintaining that loose coupling I would so much like to have.

However, I see no examples in the documentation, and from what I have in the generated javascript (for my routes) there is no chance.

Is there any way to achieve what I am after?

thanks for reading!

p.s., I should add; I guess I have also thought of the possibility of using the ajax call that is generated, I guess I can probably fetch the page I want... and there is probably a means of replacing the current document with the entire content of the fetched page. but that just sounds bad.... wrong...

or not?

I was rather hoping for a substitution, as is done in my html

i.e, my link as shown above is generated to look like this:

    <div class="footer">
        <a href='/'>Home</a>
    </div>

In the same way, I hoped there was some means of substitution in the javascript, so that the event function above ends up in being massaged into looking like this:

function() myEvent {
    window.location="/entry";
}
svaens
  • 649
  • 7
  • 23
  • How are you firing the event? – Jacques ジャック Jan 01 '16 at 14:14
  • @Jacques The event is definitely firing. I have setup an onclick listener on all table rows (currently in my initial testing) and when I click, the event is fired and the offending code fails. But the problem can anyway be seen before I go clicking. When looking , in Chrome dev tools, I can see that there is no replacement of my reference. Or if I use the method generated, OK, there is an ajax call, and I guess the page is fetched, but obviously not replacing the current page. Should I do it like that? How can one replace the current page with the result of an ajax GET? It sounds not ideal. – svaens Jan 01 '16 at 14:21
  • So, if it's in an onclick on the row, you can add the url as a parameter in your html: `Click Me!` If you do this, you can just use the argument as your location for the redirect. – Jacques ジャック Jan 01 '16 at 14:22
  • @Jacques No, the row is generated by the javascript code itself. the javascript code is in its own separate file. The event is watched by adding an event listener via the DOM method 'addEventListener'. But yes, that kind of substitution is what I was hoping for. Just within my javascript file (as I don't have the row hard-coded within the html) – svaens Jan 01 '16 at 14:28
  • Ah, I assumed the rows were being generated on the server via the framework. (I'm not a java guy.) – Jacques ジャック Jan 01 '16 at 14:37
  • @Jacques OK. Your idea in the end did it for me. In fact, I was able to refer to a new function within my template, from the function acting as the event handler. So, that javascript (which is in the template file) does transformed as I need (though I'd have thought asset located javascript would also benefit from this!?) and I can do it that way. It's a bit dodgy, but it works.. at least until I figure out a better way. Thanks! – svaens Jan 01 '16 at 14:53
  • Glad I helped! Good luck! – Jacques ジャック Jan 01 '16 at 14:54

1 Answers1

0

Jacques, from the above comments, helped me to realize a work-around.

From within my "assets located" javascript file, I can still refer to page/template located javascript.

Own-file/assets located javascript doesn't seem to be transformed how I expected. However, Page/template located javascript is transformed exactly how I require.

I can refer to a template located javascript function from my assets located javascript.

This means, I have a little work-around of one extra little function inside the template which does the redirection for me.

i.e.,

myJavascript.js:

    function personResultsListClickHandler(personId) {
        var fpersonId = personId;
        return function() {
            window.alert("hello! " + fpersonId);
            affectRedirect();
        };
    }

myTemplate.scala.html

@main("person lookup") {

    <script type="text/javascript">
        function affectRedirect(){  
            window.location="@routes.Application.entry()";
        } // Need this here so it will be transformed.
          // asset located javascript doesn't seem to get transformed like javascript here in template! :(...
    </script>

Another possibility is the fact that the Javascript object retrieved by calling:

appRoutes.controllers.Application.entry()

contains a url member. This url member is exactly what I can use to assign to window.location. However, it looks a bit unofficial.. in terms of 1. the member not being documented 2. not sure if the url member will exist in the future 3. the generated javascript is constructing an object dealing with ajax... and i'm just grabbing the URL member from it... it just feels... like a hack.

But i've tested this, and it works. See code below:

    function patientResultsListClickHandler(personId) {
        var fpersonId = personId;
        return function() {
            window.location=appRoutes.controllers.Application.entry(personId).url;
        //  window.location="/entry/" + fpersonId; // the sort of hard-coding of URL that
        };                                          // I wanted to avoid, but don't seem able to.
    }

Does anyone else have a better solution?

svaens
  • 649
  • 7
  • 23
  • hmmm..... I just realized this has a major problem. I am unable to pass a javascript argument to my Scala code method "entry", which I also do need to do. – svaens Jan 01 '16 at 15:32
  • The above comment "major problem" was only related to the idea of calling the template-located javascript method. Using the url member of the javascript object gotten from the call to appRoutes.controllers.Application.entry(personId) does work! – svaens Jan 02 '16 at 09:39