From 27335b85b2494e8a578ba191d1e03dbf6db80f49 Mon Sep 17 00:00:00 2001 From: Andy Gup Date: Wed, 11 May 2016 11:50:31 -0600 Subject: [PATCH 01/12] Fix minor bug. Replace comma with semicolon --- lib/edit/editsStore.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/edit/editsStore.js b/lib/edit/editsStore.js index 8a5440a..86ffb03 100644 --- a/lib/edit/editsStore.js +++ b/lib/edit/editsStore.js @@ -590,7 +590,7 @@ O.esri.Edit.EditStore = function () { else { callback(null, "no db"); } - }, + }; /** * Returns all the edits as a single Array via the callback From 1291c932b0a42d0ba2cbbebbe83e4b50d59f46b2 Mon Sep 17 00:00:00 2001 From: Andy Gup Date: Wed, 11 May 2016 11:50:55 -0600 Subject: [PATCH 02/12] Closes #461 --- lib/edit/OfflineEditAdvanced.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/edit/OfflineEditAdvanced.js b/lib/edit/OfflineEditAdvanced.js index 99529c2..06c17b9 100644 --- a/lib/edit/OfflineEditAdvanced.js +++ b/lib/edit/OfflineEditAdvanced.js @@ -2040,8 +2040,11 @@ define([ } } + // Respect the proxyPath if one has been set (Added at v3.2.0) + var url = this.proxyPath ? this.proxyPath + "?" + layer.url : layer.url; + var req = new XMLHttpRequest(); - req.open("POST", layer.url + "/applyEdits", true); + req.open("POST", url + "/applyEdits", true); req.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); req.onload = function() { From 13fad4fcbf1f7b1b1949ba5c44c2b5943edfeca4 Mon Sep 17 00:00:00 2001 From: Andy Gup Date: Wed, 11 May 2016 11:51:32 -0600 Subject: [PATCH 03/12] Adds proxyPath support to OfflineEditBasic --- lib/edit/OfflineEditBasic.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/edit/OfflineEditBasic.js b/lib/edit/OfflineEditBasic.js index b264dc2..a331cac 100644 --- a/lib/edit/OfflineEditBasic.js +++ b/lib/edit/OfflineEditBasic.js @@ -947,8 +947,11 @@ define([ } } + // Respect the proxyPath if one has been set (Added at v3.2.0) + var url = this.proxyPath ? this.proxyPath + "?" + layer.url : layer.url; + var req = new XMLHttpRequest(); - req.open("POST", layer.url + "/applyEdits", true); + req.open("POST", url + "/applyEdits", true); req.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); req.onload = function() { From 5b5736cd7883815e8e8d6bd3f8f330af2be05a65 Mon Sep 17 00:00:00 2001 From: Andy Gup Date: Wed, 11 May 2016 12:39:18 -0600 Subject: [PATCH 04/12] Fix minor typo in console.log --- lib/edit/OfflineEditAdvanced.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/edit/OfflineEditAdvanced.js b/lib/edit/OfflineEditAdvanced.js index 06c17b9..6ff7862 100644 --- a/lib/edit/OfflineEditAdvanced.js +++ b/lib/edit/OfflineEditAdvanced.js @@ -2055,7 +2055,7 @@ define([ callback(obj.addResults, obj.updateResults, obj.deleteResults); } catch(err) { - console.error("EDIT REQUEST REPONSE WAS NOT SUCCESSFUL:", req); + console.error("EDIT REQUEST RESPONSE WAS NOT SUCCESSFUL:", req); errback("Unable to parse xhr response", req); } } From fff1b61f2eb08345013fc4a507d4054adfd8f7c7 Mon Sep 17 00:00:00 2001 From: Andy Gup Date: Wed, 11 May 2016 12:49:39 -0600 Subject: [PATCH 05/12] Verify _nextTempId --- test/spec/offlineEditingBasicSpec.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/spec/offlineEditingBasicSpec.js b/test/spec/offlineEditingBasicSpec.js index 5d9181f..5f76bbb 100644 --- a/test/spec/offlineEditingBasicSpec.js +++ b/test/spec/offlineEditingBasicSpec.js @@ -79,6 +79,7 @@ describe("Normal online editing - Exercise the feature services", function() async.it("add test features", function(done) { expect(g_featureLayers[0].graphics.length).toBe(0); + expect(g_featureLayers[0]._nextTempId).toBe(-1); g1 = new g_modules.Graphic({"geometry":{"x":-105400,"y":5137000,"spatialReference":{"wkid":102100}},"attributes":{"lat":0.0,"lng":0.0,"description":"g1"}}); g2 = new g_modules.Graphic({"geometry":{"x":-105600,"y":5137000,"spatialReference":{"wkid":102100}},"attributes":{"lat":0.0,"lng":0.0,"description":"g2"}}); From 797e4f60bada72e863d4366fb18765b0bd977555 Mon Sep 17 00:00:00 2001 From: Andy Gup Date: Wed, 11 May 2016 12:58:42 -0600 Subject: [PATCH 06/12] Closes #462 --- lib/edit/OfflineEditBasic.js | 56 ++++++++++++++++++++---------------- lib/edit/editStorePOLS.js | 51 ++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 25 deletions(-) diff --git a/lib/edit/OfflineEditBasic.js b/lib/edit/OfflineEditBasic.js index a331cac..1c537a7 100644 --- a/lib/edit/OfflineEditBasic.js +++ b/lib/edit/OfflineEditBasic.js @@ -485,21 +485,6 @@ define([ }, this); return files; }; - - // we need to identify ADDs before sending them to the server - // we assign temporary ids (using negative numbers to distinguish them from real ids) - // query the database first to find any existing offline adds, and find the next lowest integer to start with. - this._editStore.getNextLowestTempId(layer, function(value, status){ - if(status === "success"){ - console.log("_nextTempId:", value); - layer._nextTempId = value; - } - else{ - console.log("_nextTempId, not success:", value); - layer._nextTempId = -1; - console.debug(layer._nextTempId); - } - }); layer._getNextTempId = function () { return this._nextTempId--; @@ -508,20 +493,41 @@ define([ // We are currently only passing in a single deferred. all(extendPromises).then(function (r) { - if(self._autoOfflineDetect){ - Offline.on('up', function(){ // jshint ignore:line + if(r[0].success){ - self.goOnline(function(success,error){ // jshint ignore:line - console.log("GOING ONLINE"); + // we need to identify ADDs before sending them to the server + // we assign temporary ids (using negative numbers to distinguish them from real ids) + // query the database first to find any existing offline adds, and find the next lowest integer to start with. + self._editStore.getNextLowestTempId(layer, function(value, status){ + if(status === "success"){ + console.log("_nextTempId:", value); + layer._nextTempId = value; + } + else{ + console.log("_nextTempId, not success:", value); + layer._nextTempId = -1; + console.debug(layer._nextTempId); + } + }); + + if(self._autoOfflineDetect){ + Offline.on('up', function(){ // jshint ignore:line + + self.goOnline(function(success,error){ // jshint ignore:line + console.log("GOING ONLINE"); + }); }); - }); - Offline.on('down', function(){ // jshint ignore:line - self.goOffline(); // jshint ignore:line - }); + Offline.on('down', function(){ // jshint ignore:line + self.goOffline(); // jshint ignore:line + }); + } + + callback(true, null); + } + else { + callback(false, r[0].error); } - - callback(true, null); }); }, // extend diff --git a/lib/edit/editStorePOLS.js b/lib/edit/editStorePOLS.js index f0b48c9..4f04445 100644 --- a/lib/edit/editStorePOLS.js +++ b/lib/edit/editStorePOLS.js @@ -147,6 +147,57 @@ O.esri.Edit.EditStorePOLS = function () { } }; + /* + * Query the database, looking for any existing Add temporary OIDs, and return the nextTempId to be used. + * @param feature - extended layer from offline edit advanced + * @param callback {int, messageString} or {null, messageString} + */ + this.getNextLowestTempId = function (feature, callback) { + var addOIDsArray = [], + self = this; + + if (this._db !== null) { + + var fLayerJSONId = this.FEATURE_LAYER_JSON_ID; + var fCollectionId = this.FEATURE_COLLECTION_ID; + + var transaction = this._db.transaction([this.objectStoreName]) + .objectStore(this.objectStoreName) + .openCursor(); + + transaction.onsuccess = function (event) { + var cursor = event.target.result; + if (cursor && cursor.value && cursor.value.id) { + // Make sure we are not return FeatureLayer JSON data or a Phantom Graphic + if (cursor.value.id !== fLayerJSONId && cursor.value.id !== fCollectionId) { + if(cursor.value.layer === feature.url && cursor.value.operation === "add"){ // check to make sure the edit is for the feature we are looking for, and that the operation is an add. + addOIDsArray.push(cursor.value.graphic.attributes[self.objectId]); // add the temporary OID to the array + } + } + cursor.continue(); + } + else { + if(addOIDsArray.length === 0){ // if we didn't find anything, + callback(-1, "success"); // we'll start with -1 + } + else{ + var filteredOIDsArray = addOIDsArray.filter(function(val){ // filter out any non numbers from the array... + return !isNaN(val); // .. should anything have snuck in or returned a NaN + }); + var lowestTempId = Math.min.apply(Math, filteredOIDsArray); // then find the lowest number from the array + callback(lowestTempId-1, "success"); // and we'll start with one less than tat. + } + } + }.bind(this); + transaction.onerror = function (err) { + callback(null, err); + }; + } + else { + callback(null, "no db"); + } + }; + /** * Update an edit already exists in the database * @param operation add, update or delete From 3fde83b2e7beac739bc53114cefdcdc5916f88c2 Mon Sep 17 00:00:00 2001 From: Andy Gup Date: Wed, 11 May 2016 13:07:11 -0600 Subject: [PATCH 07/12] Clarification updates to README --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d72809b..52ce225 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,8 @@ This project is also available on npm: **[https://www.npmjs.com/package/esri-off This repo contains the following libraries in the `/dist` directory. The use of `basic` in the name indicates intermittent offline-only, and `advanced` indicates the library can be used for both intermittent and full offline. +Reference URLs are provided for developement only. It's recommended to use a CDN or host your own. + Use_Case | Name, Description and gh-pages URL --- | --- Basic editing | **`offline-edit-basic-min.js`** Simple, lightweight *(14k minimized)* offline editing library that automatically caches adds, updates and deletes when the internet is temporarily interrupted.

[`http://esri.github.io/offline-editor-js/dist/offline-edit-basic-min.js`](http://esri.github.io/offline-editor-js/dist/offline-edit-basic-min.js) @@ -83,7 +85,7 @@ Go __[here](https://github.com/Esri/offline-editor-js/wiki/FAQ)__ for answers to ##Dependencies -* [ArcGIS API for JavaScript (v3.12+)](https://developers.arcgis.com/javascript/) +* [ArcGIS API for JavaScript (v3.14+)](https://developers.arcgis.com/javascript/) * [Offline.js](http://github.hubspot.com/offline/docs/welcome/) - it allows detection of the online/offline condition and provides events to hook callbacks on when this condition changes * Node.js required for building the source * [IndexedDBShim](https://github.com/axemclion/IndexedDBShim) - polyfill to simulate indexedDB functionality in browsers/platforms where it is not supported notably older versions desktop Safari and iOS Safari. From e56b74ee0f2a3ddd1e878cc109e675ab90417d33 Mon Sep 17 00:00:00 2001 From: Andy Gup Date: Thu, 12 May 2016 09:27:15 -0600 Subject: [PATCH 08/12] Closes #463 --- samples/simple-edit.html | 286 ++++++++++++++++++++++++--------------- 1 file changed, 178 insertions(+), 108 deletions(-) diff --git a/samples/simple-edit.html b/samples/simple-edit.html index b25ada4..6523f57 100644 --- a/samples/simple-edit.html +++ b/samples/simple-edit.html @@ -2,129 +2,199 @@ - - - Update Fire Perimeter + - - + + Simple Edit + + + - - - + + + - -
-