let searchController = (() => {
let view = undefined,
searchWidget = undefined,
faultsMapSearchSource = undefined;
let initSearch = () => {
window.faultsMap.searchSources = [];
window.faultsMap.searchSources.push(createFaultsMapSearchSource());
searchWidget = new Search({
view: mapController.getView(),
container: "search-box",
locationEnabled: false,
includeDefaultSources: false,
maxSuggestions: 5,
suggestionsEnabled: false,
maxResults: 5,
popupEnabled: false,
popupTemplate: popupController.getTemplate(),
minSuggestCharacters: 5,
goToOverride: (view, options) => {
view.graphics.removeAll();
let _extent = undefined;
if (options.target.target.expand) {
_extent = options.target.target.expand(0.7);
} else {
_extent = createPointExtent(options.target.target.geometry);
}
let distance = window.geometryEngine.distance(_extent.center, view.center, "meters");
if (distance < 5000) {
options.options.duration = 1500;
} else {
options.options.duration = 2250;
}
options.options.easing = 'ease-in-out';
return view.goTo({ target:_extent, zoom:16 }, options.options);
},
sources: window.faultsMap.searchSources
});
searchWidget.on("search-start", (event) => {
clearSearchError();
$('#list-content').empty();
mapController.getView().popup.close();
let _selectedSuggestion = $('.esri-menu__list-item:hover');
if (_selectedSuggestion && _selectedSuggestion.length > 0) {
_selectedSuggestion = _selectedSuggestion[0];
searchWidget.searchTerm = _selectedSuggestion['data-suggestion'].text;
}
/***START : Code added to search SR using paste functionality****/
let _srInputEntry = /^[0-9]{1,8}$/g;
let _inputText = $('#search-box-input').val().replace(/[, ]+/g, "").trim();
if (_srInputEntry.test(_inputText)) {
window.faultsMap.searchMode = 'sr';
searchWidget.suggestionsEnabled = false;
searchWidget.popupEnabled = true;
}
/***END : Code added to search SR using paste functionality****/
// removes the focus from the search input so keypad will close
$('#search-box-input').blur();
});
searchWidget.on("search-clear", (event) => {
formController.clearExistingFaultsSection();
formController.clearAllLevels();
formController.hideFaultFormSection();
formController.hidePhoneCallSection();
updateReportFaultAction(false);
if (window.faultsMap.searchMode == 'sr') {
window.faultsMap.searchMode = 'address';
searchWidget.popupEnabled = false;
faultsMapSearchSource.resultSymbol = { type: "simple-marker", style: "square", angle: 0, size: 1 };
}
let _searchWarningParent = $('.esri-search__container');
if (window.faultsMap.isIE && _searchWarningParent.length > 0 && _searchWarningParent[0].classList.contains('esri-search--warning')) {
_searchWarningParent.removeClass('esri-search--warning');
}
faultsMap.currentAddress.source = '';
faultsMap.currentAddress.term = '';
});
searchWidget.on("suggest-start", (event) => {
let _srInputEntry = /^[0-9]{1,8}$/g;
let _inputText = event.searchTerm.replace(/[, ]+/g, "").trim();
if (_srInputEntry.test(_inputText)) {
window.faultsMap.searchMode = 'sr';
searchWidget.suggestionsEnabled = false;
searchWidget.popupEnabled = true;
} else {
let _searchWarningParent = $('.esri-search__container');
_searchWarningParent.removeClass('nofault-sr');
_searchWarningParent.removeClass('nofault-sr');
searchWidget.popupEnabled = false;
window.faultsMap.searchMode = 'address';
faultsMapSearchSource.resultSymbol = {
type: "simple-marker",
style: "square",
angle: 0,
size: 1
};
if (_inputText.length >= 5) {
searchWidget.suggestionsEnabled = true;
} else {
searchWidget.suggestionsEnabled = false;
}
}
});
searchWidget.on("search-blur", (event) => {
let _searchSuggestionsContainer = $('.esri-search--show-suggestions.esri-search__container');
if (_searchSuggestionsContainer && _searchSuggestionsContainer.length > 0) {
document.onkeydown = (e) => {
//disable document scroll when suggestion list is visible
if (e.keyCode == 38 || e.keyCode == 40) {
return false;
}
return true;
};
} else {
document.onkeydown = null;
}
});
searchWidget.on("search-focus", (event) => {
document.onkeydown = null;
let _searchWarningParent = $('.esri-search__container');
if (window.faultsMap.isIE && _searchWarningParent.length > 0 && _searchWarningParent[0].classList.contains('esri-search--warning')) {
setTimeout(() => {
_searchWarningParent.removeClass('esri-search--warning');
}, 100);
}
});
};
let queryFeatures = (screenPoint) => {
let point = screenPoint;
let layerNonPropertyFaults = mapController.getNonPropertyLayer();
layerNonPropertyFaults.queryFeatures({
//where:"1=1",
geometry: point,
// distance and units will be null if basic query selected
distance: 5000,
units: "meters",
spatialRelationship: "intersects",
returnGeometry: true,
outFields: ["*"]
})
.then((featureSet) => {
// set graphic location to mouse pointer and add to mapview
//Getting distance from the center of the map to the events
let distanceCandidate = [];
for (let feature in featureSet.features) {
let distance = window.geometryEngine.distance(point, featureSet.features[feature].geometry, "meters")
distanceCandidate.push({
feature: featureSet.features[feature],
distance: distance
});
}
//Sorting events based on distance in ascending order
distanceCandidate.sort((candidate1, candidate2) => {
return (candidate1.distance > candidate2.distance) ? 1 : -1;
});
let _features = [];
for (let i in distanceCandidate) {
_features.push(distanceCandidate[i].feature)
}
if (_features.length > 0) {
$('#discogAccordianTitle').css('display', 'block');
appController.albumAccordion(_features, "address", "#list-content");
} else {
$('#discogAccordianTitle').css('display', 'none');
$('#list-content').append(
'
'
)
}
});
};
let adjustSuggestterm = (suggestTerm) => {
suggestTerm = suggestTerm.toLowerCase();
suggestTerm = suggestTerm.replace('south australia', '');
return suggestTerm;
};
let createPointExtent = (point) => {
let _xMargin = 0,
_yMargin = 0;
if (window.faultsMap.screenMode == 'mobile') {
_xMargin = 100;
_yMargin = 50;
} else {
_xMargin = 320;
_yMargin = 175;
}
return new Extent({
spatialReference: { wkid: 102100 },
xmin: point.x - _xMargin,
xmax: point.x + _xMargin,
ymin: point.y - _yMargin,
ymax: point.y + _yMargin
}).expand(1.1);
};
let suggestSRs = (params) => {
return [];
};
let suggestAddress = (params) => {
let suggestTerm = adjustSuggestterm(params.suggestTerm);
let addressRequest = esriRequest("https://lsa1.geohub.sa.gov.au/server/rest/services/Locators/SAGAF_PLUS/GeocodeServer/findAddressCandidates", {
query: {
"Single Line Input": suggestTerm,
maxLocations: 15,
searchExtent: '{"spatialReference":{"wkid":102100},"xmin":14362631.373704566,"ymin":-4577649.456300738,"xmax":15693247.162092555,"ymax":-2999989.1924951235}',
outFields: ["Addr_type"],
f: "json"
},
responseType: "json"
}).catch((e) => e);
let suburbRequest = esriRequest("https://lsa1.geohub.sa.gov.au/server/rest/services/Locators/SuburbPostcode/GeocodeServer/findAddressCandidates", {
query: {
suburb: suggestTerm,
maxLocations: 15,
searchExtent: '{"spatialReference":{"wkid":102100},"xmin":14362631.373704566,"ymin":-4577649.456300738,"xmax":15693247.162092555,"ymax":-2999989.1924951235}',
outFields: ["Addr_type"],
f: "json"
},
responseType: "json"
}).catch((e) => e);
return all([addressRequest, suburbRequest]).then((response) => {
let candidates = [...(response[0]?.data.candidates ?? []), ...(response[1]?.data.candidates ?? [])];
candidates = candidates
.filter((candidate) => {
return !(candidate.address.indexOf('Longitude') > -1) && !(candidate.address.indexOf(', SUB') > -1) && !(candidate.address.indexOf(', HMSD') > -1) && !(candidate.address.indexOf(', GTWN') > -1) && !(candidate.address.indexOf(', LOCB') > -1) && !(candidate.address.indexOf(', BORE') > -1) && !(candidate.address.indexOf(', WELL') > -1)
})
.filter(function (candidate, index, array) {
return index === array.findIndex((originalCandidate) => (
originalCandidate.address === candidate.address
));
})
.sort((candidate1, candidate2) => {
return (candidate1.score > candidate2.score) ? -1 : 1;
})
.splice(0, 5)
.map((candidate) => {
return {
key: "name",
text: candidate.address,
sourceIndex: params.sourceIndex
};
});
return candidates;
});
};
let clearSearchError = (message) => {
$('.esri-search__warning-menu').addClass('hide');
$('.esri-search__warning-body .search-result').remove();
}
let showSearchError = (message) => {
$('.esri-search__warning-body').append(`
No results found.
${message}
`);
$('.esri-search__warning-menu').removeClass('hide');
}
let searchSRs = (params) => {
let _promise = new Deferred();
let _srValidEntry = /^[0-9]{8}$/g;
if (_srValidEntry.test(params.suggestResult.text)) {
let query = {};
query.where = `srnumber='${params.suggestResult.text}' OR wonum='${params.suggestResult.text}'`;
query.outSpatialReference = { wkid: 102100 };
query.returnGeometry = true;
query.outFields = ["*"];
faultsMap.currentAddress.source = '';
faultsMap.currentAddress.term = '';
let _promises = window.faultsMap.faultsLayers
.filter((layer) => { return layer.id !== window.portalItemIDAreaFaults })
.map((layer) => {
return layer.queryFeatures(query);
});
try {
all(_promises).then((results) => {
let features = [];
results.map((_source) => {
features = features.concat(_source.features);
});
if (features.length == 0) {
_promise.reject();
showSearchError('Please ensure you have entered an 8 digit number or a valid address.');
return;
}
let graphic = new Graphic({
geometry: features[0].geometry,
attributes: features[0].attributes
});
let _result = {
extent: createPointExtent(graphic.geometry),
feature: graphic,
name: graphic.attributes['srnumber']
};
let _symbolURL = './?a=442595';
switch (graphic.attributes['outagestatus']) {
case 'Water Outage':
_symbolURL = './?a=442598';
break;
case 'Reported Fault':
_symbolURL = './?a=442595';
break;
case 'Planned Outage':
_symbolURL = './?a=442596';
break;
case 'Recently Resolved Outage':
_symbolURL = './?a=442597';
break;
}
faultsMapSearchSource.resultSymbol = {
type: "picture-marker",
url: _symbolURL,
width: "40px",
height: "44px"
};
appController.albumAccordion(features, "sr", "#list-content");
_promise.resolve([_result]);
if (window.faultsMap.screenMode == 'mobile') {
$('#map-view').show('slow', () => {
$('html, body').stop().animate({ scrollTop: $("#map-view").offset().top - 100 }, 1000);
});
}
});
} catch (e) {
console.log(e);
}
} else {
setTimeout(() => {
_promise.reject();
showSearchError('Please ensure you have entered an 8 digit number or a valid address.');
}, 100);
}
return _promise;
};
let searchAddress = (params) => {
faultsMap.currentAddress.source = '';
faultsMap.currentAddress.term = '';
let suggestTerm = adjustSuggestterm(params.suggestResult.text);
let addressRequest = esriRequest("https://lsa1.geohub.sa.gov.au/server/rest/services/Locators/SAGAF_PLUS/GeocodeServer/findAddressCandidates", {
query: {
"Single Line Input": suggestTerm,
maxLocations: 15,
searchExtent: '{"spatialReference":{"wkid":102100},"xmin":14362631.373704566,"ymin":-4577649.456300738,"xmax":15693247.162092555,"ymax":-2999989.1924951235}',
outFields: ["*"],
outSR: 102100,
f: "json"
},
responseType: "json"
}).catch((e) => e);
let suburbRequest = esriRequest("https://lsa1.geohub.sa.gov.au/server/rest/services/Locators/SuburbPostcode_Suggest/GeocodeServer/findAddressCandidates", {
query: {
suburb: suggestTerm?.slice(0, 30),
maxLocations: 15,
searchExtent: '{"spatialReference":{"wkid":102100},"xmin":14362631.373704566,"ymin":-4577649.456300738,"xmax":15693247.162092555,"ymax":-2999989.1924951235}',
outFields: ["*"],
outSR: 102100,
f: "json"
},
responseType: "json"
}).catch((e) => e);
return all([addressRequest, suburbRequest]).then((response) => {
let candidates = [...(response[0]?.data.candidates ?? []), ...(response[1]?.data.candidates ?? [])];
candidates = candidates
.filter((candidate) => {
return !(candidate.address.indexOf('Longitude') > -1) && !(candidate.address.indexOf(', SUB') > -1) && !(candidate.address.indexOf(', HMSD') > -1) && !(candidate.address.indexOf(', GTWN') > -1) && !(candidate.address.indexOf(', LOCB') > -1) && !(candidate.address.indexOf(', BORE') > -1) && !(candidate.address.indexOf(', WELL') > -1)
})
.filter((candidate, index, array) => {
return index === array.findIndex((originalCandidate) => (
originalCandidate.address === candidate.address
));
});
let exactMatch = candidates.find((candidate) => {
return candidate.address === params.suggestResult.text;
});
if (exactMatch) {
candidates = [exactMatch];
} else {
candidates = candidates
.sort((candidate1, candidate2) => {
return (candidate1.score > candidate2.score) ? -1 : 1;
})
.splice(0, 1);
}
if (candidates.length == 1 && candidates[0].score >= 70) {
let location = candidates[0].location;
let graphic = new Graphic({
geometry: new Point({ x: location.x, y: location.y, spatialReference: { wkid: 102100 } }),
attributes: {
name: candidates[0].address
}
});
let result = {
extent: createPointExtent(graphic.geometry),
feature: graphic,
name: candidates[0].address
};
faultsMap.currentAddress.source = faultsMap._ADDRESS_SEARCH_;
faultsMap.currentAddress.term = searchController.getUserAddress();
queryFeatures(result.feature.geometry);
window.faultsMap.allowReverseGeocoding = false;
updateReportFaultAction(true);
faultsMap.addressValidationPromise?.resolve(graphic.geometry);
if (window.faultsMap.screenMode == 'mobile') {
$('#map-view').show('slow', () => {
$('html, body').stop().animate({ scrollTop: $("#map-view").offset().top - 100 }, 1000);
});
}
return [result];
}
faultsMap.addressValidationPromise?.reject();
updateReportFaultAction(false);
showSearchError('Please ensure you have entered an 8 digit number or a valid address.');
return [];
});
};
let createFaultsMapSearchSource = () => {
faultsMapSearchSource = new SearchSource({
placeholder: "Search",
resultSymbol: { type: "simple-marker", style: "square", angle: 0, size: 1 },
getSuggestions: (params) => {
if (window.faultsMap.searchMode == 'sr') {
return suggestSRs(params);
} else {
return suggestAddress(params);
}
},
getResults: (params) => {
formController.clearExistingFaultsSection();
formController.clearAllLevels();
formController.hidePhoneCallSection();
if (window.faultsMap.searchMode == 'sr') {
updateReportFaultAction(false);
return searchSRs(params);
} else {
return searchAddress(params);
}
}
});
return faultsMapSearchSource;
};
let getUserLocationAddress = (location) => {
return esriRequest("https://lsa1.geohub.sa.gov.au/server/rest/services/Locators/SAGAF_PLUS/GeocodeServer/reverseGeocode", {
query: {
location: JSON.stringify(location),
returnIntersection: false,
f: "json",
outSR: 102100
},
responseType: "json"
}).then(
(response) => {
// https://jira.squiz.net/browse/SUPPORT-272210
$.post('/works-and-faults/support-272210', JSON.stringify({
method:'getUserLocationAddress',
location:location,
response:response
}))
let address = (response && response.data && response.data.address) ? response.data.address : undefined;
if (address && address.State && address.State.toLowerCase() == "south australia") {
let _addressDescription = response.data.address.Street + ', ' + response.data.address.Locality + ', ' + response.data.address.State + ', ' + response.data.address.Postcode;
searchWidget.searchTerm = _addressDescription;
faultsMap.currentAddress.source = faultsMap._ADDRESS_MARKER_;
faultsMap.currentAddress.term = _addressDescription;
updateReportFaultAction(true);
} else {
faultsMap.isManualSearchTermClear = true;
searchWidget.searchTerm = "";
updateReportFaultAction(false);
}
},
(error) => {
console.log(error);
getUserLocationAddressWorldGeocoder(location);
});
};
let getUserLocationAddressWorldGeocoder = (location) => {
return esriRequest("https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/reverseGeocode", {
query: {
location: JSON.stringify(location),
returnIntersection: false,
f: "json",
outSR: 102100
},
responseType: "json"
}).then(
(response) => {
// https://jira.squiz.net/browse/SUPPORT-272210
$.post('/works-and-faults/support-272210', JSON.stringify({
method:'getUserLocationAddressWorldGeocoder',
location:location,
response:response
}))
let address = (response && response.data && response.data.address) ? response.data.address : undefined;
if (address && address.Region == "South Australia") {
let _addressDescription = (response.data.address.Match_addr.trim() == "") ? response.data.address.LongLabel : response.data.address.Match_addr;
searchWidget.searchTerm = _addressDescription;
faultsMap.currentAddress.source = faultsMap._ADDRESS_MARKER_;
faultsMap.currentAddress.term = _addressDescription;
updateReportFaultAction(true);
} else {
faultsMap.isManualSearchTermClear = true;
searchWidget.searchTerm = "";
updateReportFaultAction(false);
}
},
(error) => {
console.log(error);
faultsMap.isManualSearchTermClear = true;
searchWidget.searchTerm = "";
updateReportFaultAction(false);
setTimeout(() => {
faultsMap.isManualSearchTermClear = false;
}, 500);
});
};
let setUserAddress = (address) => {
searchWidget.searchTerm = address;
};
let updateReportFaultAction = (enabled) => {
if (enabled) {
$('#report-fault-button').removeClass('disabled');
$('#report-fault-button').text("Report a fault at this location");
$('#report-fault-button').attr('disabled', false)
} else {
$('#report-fault-button').addClass('disabled');
$('#report-fault-button').text("'Report a fault' only available in SA");
$('#report-fault-button').attr('disabled', true);
}
};
let getUserAddress = () => {
return searchWidget.searchTerm;
};
let refreshFaultsList = (mapPoint) => {
$('#list-content').empty();
queryFeatures(mapPoint);
};
let startSearch = () => {
searchWidget.search(searchWidget.searchTerm);
};
return {
initSearch: initSearch,
getUserLocationAddress: getUserLocationAddress,
setUserAddress: setUserAddress,
queryFaults: queryFeatures,
updateReportFaultAction: updateReportFaultAction,
getUserAddress: getUserAddress,
refreshFaultsList: refreshFaultsList,
startSearch: startSearch
}
})();