From b270a94d438bf6e14204100153c7d162226a5213 Mon Sep 17 00:00:00 2001 From: James Bate Date: Wed, 16 Sep 2015 16:17:53 +0100 Subject: [PATCH] Support for multiple instances * New demo page with two address forms, * Removed cache, * Removed mergeSettings. --- demo-dual-forms.html | 68 +++++++ demo.html | 19 +- src/js/contact-data-services.js | 306 +++++++++++++++----------------- 3 files changed, 225 insertions(+), 168 deletions(-) create mode 100644 demo-dual-forms.html diff --git a/demo-dual-forms.html b/demo-dual-forms.html new file mode 100644 index 0000000..0d75a2b --- /dev/null +++ b/demo-dual-forms.html @@ -0,0 +1,68 @@ + + + + Contact Data Services - sample code + + +
+ + + + + + +
+
+
+ +
+ + + + + + +
+
+
+ + + + + \ No newline at end of file diff --git a/demo.html b/demo.html index 8784e55..1b59c44 100644 --- a/demo.html +++ b/demo.html @@ -17,24 +17,23 @@ + +
+
-
-
\ No newline at end of file diff --git a/src/js/contact-data-services.js b/src/js/contact-data-services.js index 8cdd22c..70f91c3 100644 --- a/src/js/contact-data-services.js +++ b/src/js/contact-data-services.js @@ -1,154 +1,144 @@ -var contactDataServices = { - urls: { +(function (window, document, undefined) { + var ContactDataServices = window.ContactDataServices = window.ContactDataServices || {}; + window.ContactDataServices = ContactDataServices; + + // Generate the URLs for the various requests + ContactDataServices.urls = { endpoint: "http://int-test-01/capture/v2/search", construct: { address: { // Construct the Search URL by appending query, country & token - search: function(searchTerm, countryCode){ - var url = contactDataServices.urls.endpoint; - url += "?query=" + contactDataServices.address.currentSearchTerm; - url += "&country=" + contactDataServices.address.currentCountryCode; + search: function(instance){ + var url = ContactDataServices.urls.endpoint; + url += "?query=" + instance.currentSearchTerm; + url += "&country=" + instance.currentCountryCode; - url = contactDataServices.urls.addToken(url); + url = ContactDataServices.urls.addToken(url, instance.token); return url; }, // Construct the Format URL by appending the token - format: function(url){ - url = contactDataServices.urls.addToken(url); + format: function(url, instance){ + url = ContactDataServices.urls.addToken(url, instance.token); return url; } } }, // Append the token (this must be specified when initialising) - addToken: function(url){ - return url + "&auth-token=" + contactDataServices.token; + addToken: function(url, token){ + return url + "&auth-token=" + token; } - }, - // Merge in any settings the user wants to override - mergeSettings: function(destination, source) { - for (var property in source) { - if (source[property] && source[property].constructor && - source[property].constructor === Object) { - destination[property] = destination[property] || {}; - arguments.callee(destination[property], source[property]); - } else { - destination[property] = source[property]; - } - } - return destination; - }, - init: function(options){ - // Merge in any overrides (such as token, elements IDs etc.) - contactDataServices = contactDataServices.mergeSettings(contactDataServices, options); + }; - if(!contactDataServices.token){ - console.log("Please provide a token for ContactDataServices."); - } + // Integrate with address searching + ContactDataServices.address = function(options){ + // Build our new instance from user defaults + var instance = options || {}; + + instance.lastSearchTerm = ""; + instance.currentSearchTerm = ""; + instance.lastCountryCode = ""; + instance.currentCountryCode = ""; + instance.currentSearchUrl = ""; + instance.currentFormatUrl = ""; + instance.enabled = true; - contactDataServices.address.setCountryList(); - contactDataServices.address.input = contactDataServices.address.elements.input; - contactDataServices.address.input.addEventListener("keyup", contactDataServices.address.search); - }, - address: { - input: null, - lastSearchTerm: "", - currentSearchTerm: "", - lastCountryCode: "", - currentCountryCode: "", - currentSearchUrl: "", - currentFormatUrl: "", + // Initialise this instance + instance.init = function(){ + if(!instance.token){ + console.log("Please provide a token for ContactDataServices."); + // Disable searching on this instance + instance.enabled = false; + } + instance.setCountryList(); + instance.input = instance.elements.input; + instance.input.addEventListener("keyup", instance.search); + }; + // Main function to search for an address from an input string - search: function(){ - console.log(contactDataServices.address.input.value); - contactDataServices.address.currentSearchTerm = contactDataServices.address.input.value, - contactDataServices.address.currentCountryCode = contactDataServices.address.countryList.value; - + instance.search = function(){ + instance.currentSearchTerm = instance.input.value; + instance.currentCountryCode = instance.countryList.value; // Check is searching is permitted - if(contactDataServices.address.canSearch()){ + if(instance.canSearch()){ // Abort any outstanding requests - if(contactDataServices.request.currentRequest){ - contactDataServices.request.currentRequest.abort(); + if(instance.request.currentRequest){ + instance.request.currentRequest.abort(); } // Construct the new Search URL - var url = contactDataServices.urls.construct.address.search(); - contactDataServices.address.lastSearchTerm = contactDataServices.address.currentSearchTerm; + var url = ContactDataServices.urls.construct.address.search(instance); + + // Store the last search term + instance.lastSearchTerm = instance.currentSearchTerm; + // Hide any previous results - contactDataServices.address.result.hide(); + instance.result.hide(); - // Check in the cache for a previous match - var cachedData = contactDataServices.address.cache.checkCache(contactDataServices.address.currentSearchTerm); - if(cachedData){ - // Show cached copy - contactDataServices.address.picklist.show(cachedData); - } else { - // Initiate new Search request - contactDataServices.request.get(url, contactDataServices.address.picklist.show); - } - } else if (contactDataServices.address.currentSearchTerm === "") { + // Initiate new Search request + instance.request.get(url, instance.picklist.show); + } else { // Clear the picklist if the search term is cleared/empty - contactDataServices.address.picklist.hide(); + instance.picklist.hide(); } - }, - canSearch: function(){ - // If search term is not empty and - return (contactDataServices.address.currentSearchTerm !== "" && - // If search term is not the same as previous search term and - contactDataServices.address.lastSearchTerm !== contactDataServices.address.currentSearchTerm && - // If the country is not empty - contactDataServices.address.countryList.value !== ""); - }, - // Bind a list of countries. Using either a user-defined list or creating a new one. - setCountryList: function(){ - contactDataServices.address.countryList = contactDataServices.address.elements.countryList; + }; + + instance.setCountryList = function(){ + instance.countryList = instance.elements.countryList; - // If the user hasn't passed us a country list, then create new list - if(!contactDataServices.address.countryList){ - contactDataServices.address.createCountryDropdown(); + // If the user hasn't passed us a country list, then create new list? + if(!instance.countryList){ + instance.createCountryDropdown(); } - }, - createCountryDropdown: function(){ + }; + + // Determine whether searching is currently permitted + instance.canSearch = function(){ + // If searching on this instance is enabled, and + return (instance.enabled && + // If search term is not empty, and + instance.currentSearchTerm !== "" && + // If search term is not the same as previous search term, and + instance.lastSearchTerm !== instance.currentSearchTerm && + // If the country is not empty + instance.countryList.value !== ""); + }; + + instance.createCountryDropdown = function(){ // What countries? // Where to position it? - }, + }; + // Get a final (Formatted) address - format: function(url){ - contactDataServices.address.currentFormatUrl = contactDataServices.urls.construct.address.format(url); + instance.format = function(url){ + instance.currentFormatUrl = ContactDataServices.urls.construct.address.format(url, instance); - // Check in the cache for a previous match - var cachedData = contactDataServices.address.cache.checkCache(contactDataServices.address.currentFormatUrl); - if(cachedData){ - // Show cached copy - contactDataServices.address.result.show(cachedData); - } else { - // Initiate a new Format request - contactDataServices.request.get(contactDataServices.address.currentFormatUrl, contactDataServices.address.result.show); - } - }, - picklist: { + // Initiate a new Format request + instance.request.get(instance.currentFormatUrl, instance.result.show); + }; + + instance.picklist = { // Render a picklist of search results show: function(items){ - contactDataServices.address.picklist.hide(); - // Update the cache for this result - contactDataServices.address.cache.updateCache(contactDataServices.address.currentSearchTerm, items); + instance.picklist.hide(); // Get picklist container element - var picklist = contactDataServices.address.elements.picklist; + var picklist = instance.elements.picklist; + // Prepend an option for "use address entered" - contactDataServices.address.picklist.createUseAddressEntered(); + instance.picklist.createUseAddressEntered(); if(items.results.length > 0){ // Iterate over and show results items.results.forEach(function(item, i){ // Create a new item/row in the picklist - var listItem = contactDataServices.address.picklist.createListItem(item); + var listItem = instance.picklist.createListItem(item); picklist.appendChild(listItem); // Listen for selection on this item - contactDataServices.address.picklist.listen(listItem); + instance.picklist.listen(listItem); }); } }, hide: function(){ - contactDataServices.address.elements.picklist.innerHTML = ""; + instance.elements.picklist.innerHTML = ""; }, // Create a "use address entered" option createUseAddressEntered: function(){ @@ -156,25 +146,25 @@ var contactDataServices = { suggestion: "Use address entered", format: "" }; - var listItem = contactDataServices.address.picklist.createListItem(item); - contactDataServices.address.elements.picklist.appendChild(listItem); - listItem.addEventListener("click", contactDataServices.address.picklist.useAddressEntered); + var listItem = instance.picklist.createListItem(item); + instance.elements.picklist.appendChild(listItem); + listItem.addEventListener("click", instance.picklist.useAddressEntered); }, // Use the address entered as the Formatted address useAddressEntered: function(){ var inputData = { address: [ { - content: contactDataServices.address.currentSearchTerm + content: instance.currentSearchTerm } ] }; - contactDataServices.address.result.show(inputData); + instance.result.show(inputData); }, // Create a new picklist item/row createListItem: function(item){ var row = document.createElement("div"); - row.innerHTML = contactDataServices.address.picklist.addMatchingEmphasis(item); + row.innerHTML = instance.picklist.addMatchingEmphasis(item); // Store the Format URL row.setAttribute("format", item.format); return row; @@ -191,24 +181,24 @@ var contactDataServices = { return label; }, + // Listen to a picklist selection listen: function(row){ - row.addEventListener("click", contactDataServices.address.picklist.pick); + row.addEventListener("click", instance.picklist.pick); }, + // How to handle a picklist selection pick: function(){ - // How to handle a picklist selection - contactDataServices.address.format(this.getAttribute("format")); + instance.format(this.getAttribute("format")); } - }, - result: { + }; + + instance.result = { // Render a Formatted address show: function(data){ - contactDataServices.address.picklist.hide(); - // Update the cache - contactDataServices.address.cache.updateCache(contactDataServices.address.currentFormatUrl, data); - + instance.picklist.hide(); + if(data.address.length > 0){ // Get formatted address container element - var formattedAddress = contactDataServices.address.elements.formattedAddress; + var formattedAddress = instance.elements.formattedAddress; data.address.forEach(function(line, i){ var row = document.createElement("div"); row.innerHTML = line.content; @@ -217,47 +207,47 @@ var contactDataServices = { } }, hide: function(){ - contactDataServices.address.elements.formattedAddress.innerHTML = ""; - } - }, - cache: { - data: {}, - checkCache: function(key){ - return contactDataServices.address.cache.data[key]; - }, - updateCache: function(key, data){ - contactDataServices.address.cache.data[key] = data; + instance.elements.formattedAddress.innerHTML = ""; } - } - }, - request: { - currentRequest: null, - get: function(url, callback){ - contactDataServices.request.currentRequest = new XMLHttpRequest(); - contactDataServices.request.currentRequest.open('GET', url, true); - contactDataServices.request.currentRequest.timeout = 5000; // 5 seconds + }; + + // Use this to initiate and track XMLHttpRequests + instance.request = { + currentRequest: null, + get: function(url, callback){ + instance.request.currentRequest = new XMLHttpRequest(); + instance.request.currentRequest.open('GET', url, true); + instance.request.currentRequest.timeout = 5000; // 5 seconds - contactDataServices.request.currentRequest.onload = function() { - if (contactDataServices.request.currentRequest.status >= 200 && contactDataServices.request.currentRequest.status < 400) { - // Success! - var data = JSON.parse(contactDataServices.request.currentRequest.responseText); - console.log(data); - callback(data); - } else { - // We reached our target server, but it returned an error + instance.request.currentRequest.onload = function() { + if (instance.request.currentRequest.status >= 200 && instance.request.currentRequest.status < 400) { + // Success! + var data = JSON.parse(instance.request.currentRequest.responseText); + console.log(data); + callback(data); + } else { + // We reached our target server, but it returned an error + + } + }; + + instance.request.currentRequest.onerror = function() { + // There was a connection error of some sort + }; + + instance.request.currentRequest.ontimeout = function() { + // There was a connection timeout + }; - } - }; + instance.request.currentRequest.send(); + } + }; - contactDataServices.request.currentRequest.onerror = function() { - // There was a connection error of some sort - }; + // Initialise this instance of ContactDataServices + instance.init(); - contactDataServices.request.currentRequest.ontimeout = function() { - // There was a connection timeout - }; + // Return the instance object to the invoker + return instance; + }; - contactDataServices.request.currentRequest.send(); - } - } -}; \ No newline at end of file +})(window, window.document); \ No newline at end of file