|
26 | 26 | --> |
27 | 27 | <!-- |
28 | 28 | Sample HTML page showing use of Force.com JavaScript REST Toolkit from |
29 | | - a PhoneGap app using jQuery Mobile |
| 29 | + a Cordova 4.3.0 app using jQuery Mobile. |
| 30 | +
|
| 31 | + Save this as www/index.html in your PhoneGap project. You'll need to copy all |
| 32 | + the .js files referenced below to the js directory, as well as the jQuery Mobile |
| 33 | + CSS file. |
| 34 | +
|
| 35 | + The sample uses the InAppBrowser and iOS Keychain plugins. Install these with |
| 36 | +
|
| 37 | + cordova plugin add org.apache.cordova.inappbrowser |
| 38 | + cordova plugin add com.shazron.cordova.plugin.keychainutil |
30 | 39 |
|
31 | | - Save this as www/index.html in your PhoneGap project. You'll also need all |
32 | | - the .js files referenced below. |
33 | 40 | --> |
34 | 41 | <html> |
35 | 42 | <head> |
|
41 | 48 | from the CDN, but then the device needs to be online for the app to |
42 | 49 | be functional. |
43 | 50 | --> |
44 | | - <link rel="stylesheet" href="static/jquery.mobile-1.0a4.1.min.css" /> |
45 | | - <script type="text/javascript" src="static/jquery-1.5.2.min.js"></script> |
46 | | - <script type="text/javascript" src="static/jquery.mobile-1.0a4.1.min.js"></script> |
47 | | - <script type="text/javascript" src="forcetk.js"></script> |
48 | | - <script type="text/javascript" src="mobileapp.js"></script> |
49 | | - <script type="text/javascript" src="phonegap.0.9.5.min.js"></script> |
50 | | - <script type="text/javascript" src="ChildBrowser.js"></script> |
51 | | - <script type="text/javascript" src="SAiOSKeychainPlugin.js"></script> |
| 51 | + <link rel="stylesheet" href="css/jquery.mobile-1.0a4.1.min.css" /> |
| 52 | + <script type="text/javascript" src="js/jquery-1.5.2.min.js"></script> |
| 53 | + <script type="text/javascript" src="js/jquery.mobile-1.0a4.1.min.js"></script> |
| 54 | + <script type="text/javascript" src="js/forcetk.js"></script> |
| 55 | + <script type="text/javascript" src="js/mobileapp.js"></script> |
| 56 | + <script type="text/javascript" src="cordova.js"></script> |
52 | 57 | <script type="text/javascript"> |
53 | | - // OAuth Configuration |
54 | | - var loginUrl = 'https://login.salesforce.com/'; |
55 | | - var clientId = '3MVG9Km_cBLhsuPzTtcGHsZpj9HSp.uUwbHupEXhWi6k3JJphEv8swpsUYIFCZSLp8pi7YYMbRjeQUxptYdIt'; |
56 | | - var redirectUri = 'https://login.salesforce.com/services/oauth2/success'; |
57 | | - |
58 | | - var client = new forcetk.Client(clientId, loginUrl); |
59 | | - |
60 | | - // Make our own startsWith utility fn |
61 | | - String.prototype.startsWith = function(str) { |
62 | | - return (this.substr(0, str.length) === str); |
63 | | - } |
64 | | - |
65 | | - function getAuthorizeUrl(loginUrl, clientId, redirectUri) { |
66 | | - return loginUrl + 'services/oauth2/authorize?display=touch' |
67 | | - + '&response_type=token&client_id=' + escape(clientId) |
68 | | - + '&redirect_uri=' + escape(redirectUri); |
69 | | - } |
70 | | - |
71 | | - function sessionCallback(oauthResponse) { |
72 | | - client.setSessionToken(oauthResponse.access_token, null, |
73 | | - oauthResponse.instance_url); |
74 | | - |
75 | | - addClickListeners(); |
76 | | - |
77 | | - $('#logoutbtn').click(function(e) { |
78 | | - // Delete the saved refresh token |
79 | | - window.plugins.keychain.removeForKey('refresh_token', |
80 | | - 'forcetk', |
81 | | - function() { |
82 | | - var cb = ChildBrowser.install(); |
83 | | - |
84 | | - client.setRefreshToken(null); |
85 | | - $.mobile.changePage('#loginpage', "slide", false, true); |
86 | | - $.mobile.pageLoading(); |
87 | | - cb.onLocationChange = function(loc) { |
88 | | - if (loc.startsWith(redirectUri)) { |
89 | | - cb.close(); |
90 | | - oauthCallback(unescape(loc)); |
91 | | - } |
92 | | - }; |
93 | | - cb.showWebPage(getAuthorizeUrl(loginUrl, clientId, redirectUri)); |
94 | | - } |
95 | | - ); |
96 | | - }); |
97 | | - |
98 | | - $.mobile.changePage('#mainpage', "slide", false, true); |
99 | | - $.mobile.pageLoading(); |
100 | | - getAccounts(function() { |
101 | | - $.mobile.pageLoading(true); |
102 | | - }); |
103 | | - } |
104 | | - |
105 | | - function oauthCallback(loc) { |
106 | | - var oauthResponse = {}; |
107 | | - |
108 | | - var fragment = loc.split("#")[1]; |
109 | | - |
110 | | - if (fragment) { |
111 | | - var nvps = fragment.split('&'); |
112 | | - for (var nvp in nvps) { |
113 | | - var parts = nvps[nvp].split('='); |
114 | | - oauthResponse[parts[0]] = unescape(parts[1]); |
115 | | - } |
116 | | - } |
117 | | - |
118 | | - if (typeof oauthResponse === 'undefined' |
119 | | - || typeof oauthResponse['access_token'] === 'undefined') { |
120 | | - errorCallback({ |
121 | | - status: 0, |
122 | | - statusText: 'Unauthorized', |
123 | | - responseText: 'No OAuth response' |
124 | | - }); |
125 | | - } else { |
126 | | - window.plugins.keychain.setForKey('refresh_token', |
127 | | - oauthResponse.refresh_token, |
128 | | - 'forcetk', |
129 | | - null, |
130 | | - function(key, error) { |
131 | | - alert("Error storing OAuth refresh token!"); |
132 | | - } |
133 | | - ); |
134 | | - |
135 | | - sessionCallback(oauthResponse); |
136 | | - } |
137 | | - } |
138 | | - |
139 | | - // We use $ rather than $ for jQuery |
140 | | - if (window.$ === undefined) { |
141 | | - $ = $; |
142 | | - } |
143 | | - |
144 | | - $(document).ready(function() { |
145 | | - var cb = ChildBrowser.install(); |
146 | | - SAiOSKeychainPlugin.install(); |
147 | | - window.plugins.keychain.getForKey('refresh_token', |
148 | | - 'forcetk', |
149 | | - function(key, value) { |
150 | | - $.mobile.pageLoading(); |
151 | | - client.setRefreshToken(value); |
152 | | - client.refreshAccessToken(sessionCallback, |
153 | | - function(jqXHR, textStatus, errorThrown) { |
154 | | - alert('Error getting refresh token: ' + errorThrown); |
155 | | - }); |
156 | | - }, |
157 | | - function(key, error) { |
158 | | - // No refresh token - do OAuth |
159 | | - cb.onLocationChange = function(loc) { |
160 | | - if (loc.startsWith(redirectUri)) { |
161 | | - cb.close(); |
162 | | - oauthCallback(unescape(loc)); |
163 | | - } |
164 | | - }; |
165 | | - cb.showWebPage(getAuthorizeUrl(loginUrl, clientId, redirectUri)); |
166 | | - }); |
167 | | - }); |
| 58 | + // OAuth Configuration |
| 59 | + var loginUrl = 'https://login.salesforce.com/'; |
| 60 | + var clientId = '3MVG9Km_cBLhsuPzTtcGHsZpj9HSp.uUwbHupEXhWi6k3JJphEv8swpsUYIFCZSLp8pi7YYMbRjeQUxptYdIt'; |
| 61 | + var redirectUri = 'https://login.salesforce.com/services/oauth2/success'; |
| 62 | + |
| 63 | + var client = new forcetk.Client(clientId, loginUrl); |
| 64 | + |
| 65 | + var keychain; |
| 66 | + |
| 67 | + // Make our own startsWith utility fn |
| 68 | + if (!String.prototype.startsWith) { |
| 69 | + String.prototype.startsWith = function(searchString, position) { |
| 70 | + position = position || 0; |
| 71 | + return this.lastIndexOf(searchString, position) === position; |
| 72 | + }; |
| 73 | + } |
| 74 | + |
| 75 | + function getAuthorizeUrl(loginUrl, clientId, redirectUri) { |
| 76 | + return loginUrl + 'services/oauth2/authorize?display=touch' |
| 77 | + + '&response_type=token&client_id=' + escape(clientId) |
| 78 | + + '&redirect_uri=' + escape(redirectUri); |
| 79 | + } |
| 80 | + |
| 81 | + function sessionCallback(oauthResponse) { |
| 82 | + client.setSessionToken(oauthResponse.access_token, null, |
| 83 | + oauthResponse.instance_url); |
| 84 | + |
| 85 | + addClickListeners(); |
| 86 | + |
| 87 | + $('#logoutbtn').click(function(e) { |
| 88 | + // Delete the saved refresh token |
| 89 | + keychain.removeForKey( |
| 90 | + function() { |
| 91 | + client.setRefreshToken(null); |
| 92 | + $.mobile.changePage('#loginpage', "slide", false, true); |
| 93 | + $.mobile.pageLoading(); |
| 94 | + var ref = window.open(getAuthorizeUrl(loginUrl, clientId, redirectUri), '_blank', 'location=no,toolbar=no'); |
| 95 | + ref.addEventListener('loadstop', function(evt) { |
| 96 | + if (evt.url.startsWith(redirectUri)) { |
| 97 | + ref.close(); |
| 98 | + oauthCallback(unescape(evt.url)); |
| 99 | + } |
| 100 | + }); |
| 101 | + }, function(error) { |
| 102 | + console.log(error); |
| 103 | + }, 'refresh_token', 'forcetk' |
| 104 | + ); |
| 105 | + }); |
| 106 | + |
| 107 | + $.mobile.changePage('#mainpage', "slide", false, true); |
| 108 | + $.mobile.pageLoading(); |
| 109 | + getAccounts(function() { |
| 110 | + $.mobile.pageLoading(true); |
| 111 | + }); |
| 112 | + } |
| 113 | + |
| 114 | + function oauthCallback(loc) { |
| 115 | + var oauthResponse = {}; |
| 116 | + |
| 117 | + var fragment = loc.split("#")[1]; |
| 118 | + |
| 119 | + if (fragment) { |
| 120 | + var nvps = fragment.split('&'); |
| 121 | + for (var nvp in nvps) { |
| 122 | + var parts = nvps[nvp].split('='); |
| 123 | + oauthResponse[parts[0]] = unescape(parts[1]); |
| 124 | + } |
| 125 | + } |
| 126 | + |
| 127 | + if (typeof oauthResponse === 'undefined' |
| 128 | + || typeof oauthResponse['access_token'] === 'undefined') { |
| 129 | + errorCallback({ |
| 130 | + status: 0, |
| 131 | + statusText: 'Unauthorized', |
| 132 | + responseText: 'No OAuth response' |
| 133 | + }); |
| 134 | + } else { |
| 135 | + keychain.setForKey( |
| 136 | + function(){ |
| 137 | + console.log('Refresh token stored'); |
| 138 | + }, |
| 139 | + function(error) { |
| 140 | + alert("Error storing OAuth refresh token!"); |
| 141 | + }, |
| 142 | + 'refresh_token', |
| 143 | + 'forcetk', |
| 144 | + oauthResponse.refresh_token |
| 145 | + ); |
| 146 | + |
| 147 | + sessionCallback(oauthResponse); |
| 148 | + } |
| 149 | + } |
| 150 | + |
| 151 | + document.addEventListener("deviceready", function(){ |
| 152 | + keychain = new Keychain(); |
| 153 | + keychain.getForKey( |
| 154 | + function(value) { |
| 155 | + $.mobile.pageLoading(); |
| 156 | + client.setRefreshToken(value); |
| 157 | + client.refreshAccessToken(sessionCallback, |
| 158 | + function(jqXHR, textStatus, errorThrown) { |
| 159 | + alert('Error getting refresh token: ' + errorThrown); |
| 160 | + }); |
| 161 | + }, |
| 162 | + function(error) { |
| 163 | + // No refresh token - do OAuth |
| 164 | + var ref = window.open(getAuthorizeUrl(loginUrl, clientId, redirectUri), '_blank', 'location=no,toolbar=no'); |
| 165 | + ref.addEventListener('loadstop', function(evt) { |
| 166 | + if (evt.url.startsWith(redirectUri)) { |
| 167 | + ref.close(); |
| 168 | + oauthCallback(unescape(evt.url)); |
| 169 | + } |
| 170 | + }); |
| 171 | + }, 'refresh_token', 'forcetk'); |
| 172 | + }); |
168 | 173 | </script> |
169 | 174 | </head> |
170 | 175 | <body> |
|
0 commit comments