Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

routing not working with Phonegap 2.6 #174

Closed
xliyong opened this issue Apr 18, 2013 · 9 comments
Closed

routing not working with Phonegap 2.6 #174

xliyong opened this issue Apr 18, 2013 · 9 comments
Labels

Comments

@xliyong
Copy link

xliyong commented Apr 18, 2013

I am trying the following simple setup using the adapter. The routing works on web browser, but fails on phonegap.

index.html

    <div data-role="content">
        <button ng-click="goto('/page1')">page1</button>
        <a href="/page2">page2</a>
    </div>

goto() function is defined in angularjs controller as $scope.goto = function(path){$location.url(path);}

app.js

    $routeProvider
        .when('/page1', {
        templateUrl: '/views/page1.html'
    })
        .when('/page2', {
        templateUrl: '/views/page2.html'
    })

I have logged the pagebeforeload event. From the log, the relative path has been resolved to be in file:/// path !?

Any ideas ?

04-18 18:06:38.069: D/CordovaLog(32660): pagebeforeload:
04-18 18:06:38.069: I/Web Console(32660): pagebeforeload: at file:///android_asset/www/scripts/application.js:51
04-18 18:06:38.069: D/CordovaLog(32660): url:/views/page1.html
04-18 18:06:38.069: I/Web Console(32660): url:/views/page1.html at file:///android_asset/www/scripts/application.js:52
04-18 18:06:38.069: D/CordovaLog(32660): absUrl:file:///views/page1.html
04-18 18:06:38.069: I/Web Console(32660): absUrl:file:///views/page1.html at file:///android_asset/www/scripts/application.js:53
04-18 18:06:38.069: D/CordovaLog(32660): dataUrl:/views/page1.html
04-18 18:06:38.069: I/Web Console(32660): dataUrl:/views/page1.html at file:///android_asset/www/scripts/application.js:54

@xliyong
Copy link
Author

xliyong commented Apr 18, 2013

forgot to mention that I tested it on Android 4 device an iOS 6 simulator. Both are having the same issue.

And it seems that multi page template works well with angular routing.

It works If the route is defined as
$routeProvider .when('/page1', { templateUrl: '#page1' })
But this would require me to write a huge combined template.

@asgeo1
Copy link

asgeo1 commented Apr 19, 2013

I think that is expected behaviour.

Think about it - you are asking for a url "/views/page1.html". What does that mean? The leading slash means "start from the root of the domain".

When you are operating from your desktop browser, this means http://localhost:9000/views/page1.html or http://mydomain/views/page1.html

But when you are operating in Cordova, there is no domain because you are working on the file:/// protocol. So the url "/views/page1.html" maps to file:///views/page1.html

Obviously there is no such file /views/page1.html on your android operating system. So it fails.

I had some luck in integrating jquery-mobile-angular-adapter with Cordova. But I had to call the templates with relative urls, not absolute:

$routeProvider
  .when('/page1', {
    templateUrl: 'views/page1.html'
  })

There are still other issues getting anchors (<a href="") working such that they will from both http:// and file:/// - some of that can be solved by setting the base url in the jquery mobile page:

<div data-role="page" data-url="{{location.baseUrl}}">
</div>

angular.module('myApp')
  .controller 'AppCtrl', ['$rootScope', ($rootScope) ->
    $rootScope.location = {
      baseUrl: $('base').attr 'href'
    }

Still not sure if that's a good way of dealing with it or not, but it's working for me for now.

@xliyong
Copy link
Author

xliyong commented Apr 19, 2013

Thanks . That solved my problem.

Thought I have got another problem with form handling.

ng-submit should prevent jquery mobiles form submit handling, and action attribute is not needed in the form.

So the following code snippet should work.

<form ng-submit="addTodo()" data-ajax="false">
<input type="text" id="inputText" ng-model="data.inputText" placeholder="enter your todo here" ng-model-instant>
</form>

But in my setup, it only works if the form is in index page.

If the form in views/page1.html does not have action attribute, jquery mobile won't load it.

#92 seems to be related. But the fix for #92 is to activate $.support.dynamicBaseTag, which is false by default.

Have you encountered it before ?

@asgeo1
Copy link

asgeo1 commented Apr 19, 2013

Yeah, I've had issues with preventing forms from submitting.

I had to ensure that I specified a "src" attribute. I've forgotten why - obviously forms don't have src attributes. However, when I was debugging, I found that jQuery Mobile was expecting a src attribute.

  <form name="lookupItem" ng-submit="lookupItem(itemNumber)" data-ajax="false" src="">
  </form>

@xliyong
Copy link
Author

xliyong commented Apr 19, 2013

It is related to $.support.dynamicBaseTag support.

Looking at jQuery Mobile source, it is expecting to find action attributes and rewrite them. Adding src="" attribute to form tag would make the code go through without handling form submission; otherwise, thisUrl would be undefined if action attribute is not defined.

//rewrite src and href attrs to use a base url
if ( !$.support.dynamicBaseTag ) {
    var newPath = path.get( fileUrl );
    page.find( "[src], link[href], a[rel='external'], :jqmData(ajax='false'), a[target]" ).each(function() {
        var thisAttr = $( this ).is( '[href]' ) ? 'href' :
                $( this ).is( '[src]' ) ? 'src' : 'action',
            thisUrl = $( this ).attr( thisAttr );

        // XXX_jblas: We need to fix this so that it removes the document
        //            base URL, and then prepends with the new page URL.
        //if full path exists and is same, chop it - helps IE out
        thisUrl = thisUrl.replace( location.protocol + '//' + location.host + location.pathname, '' );

        if ( !/^(\w+:|#|\/)/.test( thisUrl ) ) {
            $( this ).attr( thisAttr, newPath + thisUrl );
        }
    });
}

@xliyong
Copy link
Author

xliyong commented Apr 19, 2013

Looks like routing the index page is not working with Phonegap (2.6).

When running on desktop / mobile browsers, the original index.html page might show up and then browser would switch to the view defined in routeProvider immediately.

With phonegap, $routeChangeStart event isn't fired at all, and index.html shows up.

Any ideas ? Thanks in advance.

$routeProvider
  .when('/', {
    templateUrl: 'views/page.html'
  })

@tbosch
Copy link
Contributor

tbosch commented Apr 24, 2013

Hi,
ok, there are multiple issues involved here, trying to sort them out:

  1. The initial problem was due to the fact that templateUrl was an absolute not a relative path, as stated correctly by @asgeo1.
  2. An issue by @asgeo1 "There are still other issues getting anchors (<a href="") working such that they will from both http:// and file:///...": Could you create an own issue for this? This should work and we have an example app that is working in both, phonegap and webserver...
  3. A problem with form submitting by @leyonh. Will comment on that later.
  4. A problem for specifying an external template as initial page.
    If you open your app via http server using the url http://someServer/somePath/ and your index.html is in /somePath/index.html, you need the routing .when('/'...). If you open the app with a link to the index.html, i.e. http://someServer/somePath/index.html you need a route for .when('/index.html'...). Phonegap always opens your app using the later case. So for phonegap your initial route should be .when('/index.html'...).

Tobias

@tbosch
Copy link
Contributor

tbosch commented Apr 24, 2013

The Problem with form submitting is a known jqm bug: jquery-archive/jquery-mobile#4896
And the workaround is, as @asgeo1 suggested, to add a src="" attribute to the form.

With this, all problems seems to be solved, except for 2. by @asgeo1. As I mentioned, please open another issue for this if needed...

And thanks, @asgeo1 for providing the answers for 1. and 3.!

Tobias

@roy650
Copy link

roy650 commented Sep 22, 2014

Hi @tbosch,
I seem to be running into the issue described by @asgeo1 as number 2. on your list above - However, I can't seem to understand the implementation suggested by @ASGEO.
Has there been any follow up issue for this or a resolution for this problem?
Thanks,
Roy

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants