Open randomblink opened 6 years ago
Updated GeoForm DEFAULT.JS File... Added some new attributes that are utilized in my customized MAIN.JS.
{
"name": "FULLADDR", // field id
"alias": "Full Address", // label
"fieldDescription": "The Full Address as in 175 E 2ND ST S for 175 E 2ND ST S", // Help text
"visible": true, // show this field?
"typeField": false, // subtype field?
"tooltip": "175 E 2ND ST S, SUITE 3", // placeholder text
"locked": true, // is this field editable on the main form?
"subscription": [
{
"publication": "${0.value} ${1.value} ${2.value} ${3.value} ${4.value}, ${5.value} ${6.value}",
"editorFields": [ "ADDRNUM", "PREADDRNUM", "STREETNAME", "STREETTYPE", "ADDRNUMSUF", "UNITTYPE", "UNITID" ],
"required": [ "UNITID", "UNITTYPE" ]
},
{
"publication": "${0.value} ${1.value} ${2.value} ${3.value} ${4.value}, ${5.value}",
"editorFields": [ "ADDRNUM", "PREADDRNUM", "STREETNAME", "STREETTYPE", "ADDRNUMSUF", "UNITID" ],
"required": [ "UNITID" ]
},
{
"publication": "${0.value} ${1.value} ${2.value} ${3.value} ${4.value}, ${5.value}",
"editorFields": [ "ADDRNUM", "PREADDRNUM", "STREETNAME", "STREETTYPE", "ADDRNUMSUF", "UNITTYPE" ],
"required": [ "UNITTYPE" ]
},
{
"publication": "${0.value} ${1.value} ${2.value} ${3.value} ${4.value}",
"editorFields": [ "ADDRNUM", "PREADDRNUM", "STREETNAME", "STREETTYPE", "ADDRNUMSUF" ],
"required": []
}
],
"displayType": "text" // text, checkbox, radio, textarea, url, email
},
As you can see there is a new attribute "SUBSCRIPTION" that holds a new object type. The new object type holds a PUBLICATION, EDITORFIELDS (list) and a REQUIRED fields (list). The order these publications are placed in the SUBSCRIPTION list is important. The strictest REQUIRED fields need to be at the top of the list. Also the EDITORFIELDS order of entry needs to match the publication format...
Here is the new MAIN.JS
` /global $,define,document,require,moment / /jslint sloppy:true,nomen:true / define([ "dojo/_base/declare", "dojo/_base/kernel", "dojo/_base/lang", "dojo/topic", "dojo/string", "esri/dijit/BasemapToggle", "esri/arcgis/utils", "esri/config", "dojo/dom", "dojo/dom-class", "dojo/dom-style", "dojo/on", "dojo/Deferred", "dojo/promise/all", "dojo/query", "dojo/io-query", "dojo/_base/array", "dojo/dom-construct", "dojo/dom-attr", "esri/dijit/LocateButton", "esri/dijit/Search", "dojo/text!views/modal.html", "dojo/text!views/user.html", "dojo/i18n!application/nls/resources", "esri/tasks/ProjectParameters", "esri/geometry/webMercatorUtils", "esri/geometry/Point", "esri/layers/GraphicsLayer", "application/ShareModal", "application/localStorageHelper", "esri/graphic", "esri/symbols/PictureMarkerSymbol", "esri/toolbars/edit", "esri/InfoTemplate", "esri/dijit/Popup", "application/themes", "application/pushpins", "application/SearchSources", "vendor/usng", "dijit/a11yclick", "dojo/NodeList-traverse", "application/wrapper/main-jquery-deps", "dojo/domReady!" ], function ( declare, kernel, lang, topic, string, basemapToggle, arcgisUtils, esriConfig, dom, domClass, domStyle, on, Deferred, all, query, ioQuery, array, domConstruct, domAttr, LocateButton, Search, modalTemplate, userTemplate, nls, ProjectParameters, webMercatorUtils, Point, GraphicsLayer, ShareModal, localStorageHelper, Graphic, PictureMarkerSymbol, editToolbar, InfoTemplate, Popup, theme, pushpins, SearchSources, usng, a11yclick) {
var NORTHING_OFFSET = 10000000.0; // (meters)
return declare([], { arrPendingAttachments: [], objFailedAttachments: {}, arrRetryAttachments: [], flagAttachingPrevFile: true, nls: nls, config: {}, map: null, addressGeometry: null, editToolbar: null, themes: theme, pins: pushpins, localStorageSupport: null, defaultValueAttributes: null, sortedFields: [], isHumanEntry: null, currentLocation: null, dateFormat: "LLL", subscriptions: [],
startup: function (config, appResponse, isPreview, node) {
document.documentElement.lang = kernel.locale;
this._appResponse = appResponse;
var localStorageSupport = new localStorageHelper();
if (localStorageSupport.supportsStorage() && localStorage.getItem("geoform_config")) {
config = JSON.parse(localStorage.getItem("geoform_config"));
localStorage.clear();
}
// config will contain application and user defined info for the template such as i18n strings, the web map id
// and application id
// any url parameters and any application specific configuration information.
if (config) {
this.config = config;
// create localstorage helper
this.localStorageSupport = new localStorageHelper();
// modal i18n
var modalTemplateSub = string.substitute(modalTemplate, {
id: "myModal",
title: "",
labelId: "myModalLabel",
close: nls.user.close
});
// place modal code
domConstruct.place(modalTemplateSub, document.body, 'last');
//supply either the webmap id or, if available, the item info
if (isPreview) {
this._initPreview(node);
} else {
this._init();
}
} else {
var error = new Error("Main:: Config is not defined");
this.reportError(error);
}
},
_loadCSS: function () {
var cssStyle;
cssStyle = dom.byId("rtlCSS");
cssStyle.href = "js/vendor/bootstrap-rtl.min.css";
},
_init: function () {
var userHTML, itemInfo;
// no theme set
if (!this.config.theme) {
// lets use bootstrap theme!
this.config.theme = "basic";
}
// set theme
this._switchStyle(this.config.theme);
if (this.config && this.config.i18n && this.config.i18n.direction == "rtl") {
this._loadCSS();
}
userHTML = string.substitute(userTemplate, nls);
dom.byId("parentContainter").innerHTML = userHTML;
// get item info from template
itemInfo = this.config.itemInfo || this.config.webmap;
// create map
this._createWebMap(itemInfo);
// if small header is set
if (this.config.useSmallHeader) {
// remove class
domClass.remove(dom.byId('jumbotronNode'), "jumbotron");
}
},
_initPreview: function (node) {
var cssStyle;
// if local storage supported
if (this.localStorageSupport.supportsStorage()) {
localStorage.setItem("geoform_config", JSON.stringify(this.config));
}
// set theme to selected
array.forEach(this.themes, lang.hitch(this, function (currentTheme) {
if (this.config.theme == currentTheme.id && currentTheme.url) {
cssStyle = domConstruct.create('link', {
rel: 'stylesheet',
type: 'text/css',
href: currentTheme.url
});
}
}));
//Handle case where edit is first url parameter we'll use the same logic we used in ShareModal.js
var url = 'https://' + window.location.host + window.location.pathname;
if (window.location.href.indexOf("?") > -1) {
var queryUrl = window.location.href;
var urlParams = ioQuery.queryToObject(window.location.search.substring(1)),
newParams = lang.clone(urlParams);
delete newParams.edit; //Remove edit parameter
delete newParams.folderid; //Remove folderid parameter
url = queryUrl.substring(0, queryUrl.indexOf("?") + 1) + ioQuery.objectToQuery(newParams);
}
node.src = url;
// on iframe load
node.onload = function () {
var frame = document.getElementById("iframeContainer").contentWindow.document;
var h = frame.getElementsByTagName('head')[0];
if (h && cssStyle) {
domConstruct.place(cssStyle, h, "last");
}
};
},
_submitForm: function () {
var btn = $('#submitButton');
btn.button('loading');
var erroneousFields = [];
array.forEach(query(".geoFormQuestionare"), lang.hitch(this, function (currentField) {
if (domClass.contains(currentField, "hasAttachment")) {
if (domClass.contains(currentField, "mandatory") && query(".alert-dismissable", dom.byId("divColumn2")).length === 0) {
this._validateUserInput(nls.user.requiredFields, currentField, query(".hideFileInputUI")[0].value, true);
erroneousFields.push(currentField);
}
return true;
}
//to check for errors in form before submitting.
//condition check to filter out radio fields
if (query(".form-control", currentField)[0]) {
//if condition to check for conditions where the entered values are erroneous.
if (domClass.contains(currentField, "has-error") && query("select", currentField).length === 0) {
erroneousFields.push(currentField);
}
//if condition to check for conditions where mandatory fields are kept empty.
if ((query(".form-control", currentField)[0] && (query(".form-control", currentField)[0].value === "") && domClass.contains(currentField, "mandatory")) || (query(".filterSelect", currentField)[0] && (query(".filterSelect", currentField)[0].value === "") && domClass.contains(currentField, "mandatory"))) {
var selectValue = query(".form-control", currentField)[0] ? query(".form-control", currentField)[0].value : query(".filterSelect", currentField)[1].value;
this._validateUserInput(nls.user.requiredFields, currentField, query(".form-control", selectValue, true));
erroneousFields.push(currentField);
} else {
if (domClass.contains(currentField, "mandatory")) {
var mandatoryValue = query(".form-control", currentField)[0] ? query(".form-control", currentField)[0].value : query(".filterSelect", currentField)[1].value;
this._validateUserInput(false, currentField, mandatoryValue, true);
}
}
}
//handle errors in radio and checkbox fields here.
else {
if (!query(".filterSelect", currentField)[0]) {
if (domClass.contains(currentField, "mandatory") && query(".radioInput:checked", currentField).length === 0 && query(".checkboxContainer", currentField).length === 0) {
this._validateUserInput(nls.user.requiredFields, currentField, query(".radioInput:checked", currentField), true);
erroneousFields.push(currentField);
} else {
if (domClass.contains(currentField, "mandatory")) {
this._validateUserInput(false, currentField, query(".radioInput:checked", currentField), true);
}
}
}
}
}));
array.forEach(query(".filterSelect"), lang.hitch(this, function (currentField) {
if (currentField.value === "" && domClass.contains(currentField.parentElement, "mandatory")) {
this._validateUserInput(nls.user.requiredFields, currentField, currentField.value, true);
erroneousFields.push(currentField);
}
}));
//this statement will remove the error message div at first and then will be applied if a valid location is not selected
this._removeErrorNode(dom.byId("select_location").nextSibling);
//conditional blocks to check and validate the form and show appropriate error messages.
var errorMessage;
if (erroneousFields.length !== 0) {
if (!this.addressGeometry) {
// reset submit button
this._resetButton();
// error message
errorMessage = '';
errorMessage += nls.user.selectLocation;
this._showErrorMessageDiv(errorMessage, dom.byId("select_location"));
}
var elementId;
if (!erroneousFields[0].children[0].id) {
elementId = erroneousFields[0].parentElement.children[0].id;
domClass.remove(elementId, "has-success");
} else {
elementId = erroneousFields[0].children[0].id;
}
$('html, body').animate({
scrollTop: $("#" + elementId).offset().top
}, 500);
btn.button('reset');
} else {
if (this.addressGeometry) {
this._addFeatureToLayer();
} else {
// reset submit button
this._resetButton();
// error message
errorMessage = '';
errorMessage += nls.user.selectLocation;
this._showErrorMessageDiv(errorMessage, dom.byId("select_location"));
$('html, body').animate({
scrollTop: $("#select_location").offset().top
}, 500);
}
}
},
reportError: function (error) {
// remove loading class from body
domClass.remove(document.body, "app-loading");
domClass.add(document.body, "app-error");
// an error occurred - notify the user. In this example we pull the string from the
// resource.js file located in the nls folder because we've set the application up
// for localization. If you don't need to support multiple languages you can hardcode the
// strings here and comment out the call in index.html to get the localization strings.
// set message
var node = dom.byId("loading_message");
if (node) {
if (this.config && this.config.i18n) {
node.innerHTML = this.config.i18n.map.error + ": " + error.message;
} else {
node.innerHTML = "Unable to create map: " + error.message;
}
}
},
_centerPopup: function () {
if (this.map.infoWindow && this.map.infoWindow.isShowing) {
var location = this.map.infoWindow.location;
if (location) {
this.map.centerAt(location);
}
}
},
_resizeInfoWin: function () {
if (this.map.infoWindow) {
var iw, ih;
var h = this.map.height;
var w = this.map.width;
// width
if (w < 300) {
iw = 125;
} else if (w < 600) {
iw = 200;
} else {
iw = 300;
}
// height
if (h < 300) {
ih = 75;
} else if (h < 600) {
ih = 100;
} else {
ih = 200;
}
this.map.infoWindow.resize(iw, ih);
}
},
// set symbol for submitting location
_setSymbol: function (point, isMapClicked) {
if (this.map.infoWindow) {
var symbolUrl, pictureMarkerSymbol, graphic, it;
// use appropriate symbol pin image
array.some(this.pins, lang.hitch(this, function (currentPin) {
if (this.config.pushpinColor == currentPin.id) {
symbolUrl = currentPin.url;
// create symbol and offset 10 to the left and 17 to the bottom so it points correctly
pictureMarkerSymbol = new PictureMarkerSymbol(symbolUrl, currentPin.width, currentPin.height).setOffset(currentPin.offset.x, currentPin.offset.y);
// text info template
it = new InfoTemplate(nls.user.locationPopupTitle, "${text}");
// graphic for point
graphic = new Graphic(point, pictureMarkerSymbol, {
text: nls.user.addressSearchText
}, it);
// private geoform graphic identifier
graphic._geoformGraphic = true;
// add to graphics layer
this._gl.add(graphic);
// get current features
var features = isMapClicked ? this.map.infoWindow.features : [];
// remove existing geoform graphic(s)
var filtered = array.filter(features, function (item) {
return !item._geoformGraphic;
});
// add feature
filtered.splice(0, 0, graphic);
// set popup features
this.map.infoWindow.setFeatures(filtered);
// show popup
this.map.infoWindow.show(graphic.geometry);
// edit movable
this.editToolbar.activate(editToolbar.MOVE, graphic, null);
return true;
}
}));
}
},
_setCoordInputs: function (pt) {
// get lat/lng
var lat = pt.getLatitude();
var lng = pt.getLongitude();
// if valid lat/lng
if (typeof lat !== "undefined" && typeof lng !== "undefined") {
dom.byId('lat_coord').value = lat.toFixed(5);
dom.byId('lng_coord').value = lng.toFixed(5);
// try to convert LL to other coordinates
try {
// set USNG
var usngResult = usng.LLtoUSNG(lat, lng, 5);
if (usngResult) {
dom.byId('usng_coord').value = usngResult;
}
// set MGRS
var mgrsResult = usng.LLtoMGRS(lat, lng, 5);
if (mgrsResult) {
dom.byId('mgrs_coord').value = mgrsResult;
}
// set UTM
var utmResults = [];
usng.LLtoUTM(lat, lng, utmResults);
if (utmResults && utmResults.length === 3) {
var northing = parseFloat(utmResults[1]);
var easting = parseFloat(utmResults[0]);
var zone = parseInt(utmResults[2], 10);
if(northing < 0){
zone += "S";
northing = northing + NORTHING_OFFSET;
}
else{
zone += "N";
}
dom.byId('utm_easting').value = parseInt(easting, 10);
dom.byId('utm_northing').value = parseInt(northing, 10);
dom.byId('utm_zone_number').value = zone;
}
} catch (e) {
console.log(e);
}
}
this._checkUTM();
this._checkMGRS();
this._checkLatLng();
this._checkUSNG();
},
// create lat lon point
_calculateLatLong: function (pt) {
// return string
var str = '';
// if spatial ref is web mercator
if (pt) {
// get lat/lng
var lat = pt.getLatitude();
var lng = pt.getLongitude();
if (lat && lng) {
// create string
str = nls.user.latitude + ': ' + lat.toFixed(5) + ', ' + ' ' + nls.user.longitude + ': ' + lng.toFixed(5);
}
}
return str;
},
//function to set the logo-path, application title and details
_setAppConfigurations: function (appConfigurations) {
var appLogoNode, appTitleNode, appDescNode;
// get all nodes
appLogoNode = dom.byId('appLogo');
appTitleNode = dom.byId('appTitle');
appDescNode = dom.byId('appDescription');
// set logo
if (appConfigurations.Logo && !this.config.disableLogo) {
appLogoNode.src = appConfigurations.Logo;
} else {
domClass.add(appLogoNode, "hide");
}
// set title
if (appConfigurations.Title) {
appTitleNode.innerHTML = appConfigurations.Title;
} else {
domClass.add(appTitleNode, "hide");
}
// set description
if (appConfigurations.Description) {
appDescNode.innerHTML = appConfigurations.Description;
} else {
domClass.add(appDescNode, "hide");
}
// remove jumbotron style option
if (domClass.contains(appLogoNode, "hide") && domClass.contains(appTitleNode, "hide") && domClass.contains(appDescNode, "hide")) {
domClass.add(dom.byId('jumbotronNode'), "hide");
}
},
//function to set the theme for application
_switchStyle: function (themeName) {
array.forEach(this.themes, lang.hitch(this, function (currentTheme) {
if (themeName == currentTheme.id && currentTheme.url) {
var themeNode = domConstruct.create("link", {
rel: "stylesheet",
type: "text/css",
href: currentTheme.url
});
domConstruct.place(themeNode, query("head")[0]);
// add identifying theme class to the body
domClass.add(document.body, "geoform-" + currentTheme.id);
}
}));
},
//function to validate and create the form
_createForm: function (fields) {
// editable layer
if (this._formLayer) {
// if indexedDB is supported
if (window.indexedDB && this.config.enableOfflineSupport) {
// get offline support
require(["application/OfflineSupport"], lang.hitch(this, function (OfflineSupport) {
// support basic offline editing
this._offlineSupport = new OfflineSupport({
map: this.map,
proxy: this.config.proxyurl,
layer: this._formLayer
});
}));
}
}
domConstruct.empty(dom.byId('userForm'));
this.sortedFields = [];
var formContent, labelContent, matchingField, newAddedFields = [],
userFormNode;
if (!this._formLayer) {
this._showErrorMessageDiv(nls.user.noLayerConfiguredMessage, dom.byId("errorMessageDiv"));
array.some(query(".row"), lang.hitch(this, function (currentNode) {
if (currentNode.children) {
if (domClass.contains(currentNode.children[0], "errorMessageDiv")) {
array.forEach(query(currentNode).nextAll(), lang.hitch(this, function (currentNode) {
domStyle.set(currentNode, "display", "none");
}));
return true;
}
}
}));
return;
}
array.forEach(this._formLayer.fields, lang.hitch(this, function (field) {
var layerField = lang.clone(field);
matchingField = false;
array.forEach(fields, lang.hitch(this, function (currentField) {
if (layerField.name == currentField.name && currentField.visible) {
if (layerField.name === this._formLayer.typeIdField) {
layerField.subTypes = this._formLayer.types;
layerField.typeField = true;
} else {
layerField.typeField = false;
}
newAddedFields.push(lang.mixin(layerField, currentField));
matchingField = true;
} else if (layerField.name == currentField.name && currentField.hasOwnProperty("visible") && !currentField.visible) {
matchingField = true;
}
}));
if (!matchingField) {
if ((layerField.editable && !(layerField.type === "esriFieldTypeOID" || layerField.type === "esriFieldTypeGeometry" || layerField.type === "esriFieldTypeBlob" || layerField.type === "esriFieldTypeRaster" || layerField.type === "esriFieldTypeGUID" || layerField.type === "esriFieldTypeGlobalID" || layerField.type === "esriFieldTypeXML"))) {
if (layerField.name === this._formLayer.typeIdField) {
layerField.subTypes = this._formLayer.types;
layerField.typeField = true;
} else {
layerField.typeField = false;
}
layerField.isNewField = true;
newAddedFields.push(layerField);
}
}
}));
array.forEach(fields, lang.hitch(this, function (sortedElement) {
array.some(newAddedFields, lang.hitch(this, function (newElement) {
var fName = newElement.name;
if (this.config.appid) {
if (sortedElement.name == fName) {
this.sortedFields.push(newElement);
return true;
}
} else {
if (sortedElement.name == fName) {
this.sortedFields.push(newElement);
return true;
}
}
}));
}));
array.forEach(this.sortedFields, lang.hitch(this, function (currentField, index) {
//code to set true/false value to property 'isTypeDependent' of the field.
currentField.isTypeDependent = false;
array.forEach(this._formLayer.types, function (type) {
var currentType = lang.clone(type);
var hasDomainValue = null,
hasDefaultValue = null;
hasDomainValue = currentType.domains[currentField.name];
hasDefaultValue = currentType.templates[0].prototype.attributes[currentField.name];
//if hasDefaultValue is 0 then we need to set isTypeDependent property to true
if (hasDefaultValue === 0) {
hasDefaultValue = true;
}
if ((hasDomainValue && hasDomainValue.type !== "inherited") || (hasDefaultValue && !currentField.typeField)) {
currentField.isTypeDependent = true;
}
});
if (currentField.isTypeDependent) {
return true;
}
//function to create form elements(referenceNode is passed null)
this._createFormElements(currentField, index, null);
}));
// if form has attachments
if (this._formLayer.hasAttachments && this.config.attachmentInfo[this._formLayer.id] && this.config.attachmentInfo[this._formLayer.id].enableAttachments) {
var requireField = null,
helpBlock, labelHTML = "",
divRow, divColumn1, fileBtnSpan, fileInput, fileChange, divColumn2, fileForm;
userFormNode = dom.byId('userForm');
formContent = domConstruct.create("div", {
className: "form-group hasAttachment geoFormQuestionare"
}, userFormNode);
//code to make the attachment input mandatory
if (this.config.attachmentInfo[this._formLayer.id].attachmentIsRequired) {
domClass.add(formContent, "mandatory");
requireField = domConstruct.create("small", {
className: 'requireFieldStyle',
innerHTML: nls.user.requiredField
}, formContent);
}
// attachment label html
labelHTML += "<span class=\"glyphicon glyphicon-paperclip\"></span> ";
labelHTML += (this.config.attachmentInfo[this._formLayer.id].attachmentLabel || nls.user.attachment);
// attachment label
labelContent = domConstruct.create("label", {
innerHTML: labelHTML,
id: "geoFormAttachmentLabel",
"for": "geoFormAttachment"
}, formContent);
if (requireField && labelContent) {
domConstruct.place(requireField, labelContent, "last");
}
divRow = domConstruct.create("div", {
"class": "row"
}, formContent);
divColumn1 = domConstruct.create("div", {
"class": "col-sm-2 form-group"
}, divRow);
fileBtnSpan = domConstruct.create("span", {
"class": "btn btn-default btn-file",
"innerHTML": nls.user.btnSelectFileText
}, divColumn1);
fileForm = domConstruct.create("form", {
"class": "selectFileForm"
}, fileBtnSpan);
fileInput = domConstruct.create("input", {
"type": "file",
"class": "hideFileInputUI",
"title": nls.user.selectFileTitle,
"name": "attachment"
}, fileForm);
fileChange = on(fileInput, "change", lang.hitch(this, function (evt) {
this._validateSelectedFile(evt, fileInput, fileBtnSpan, formContent, fileChange);
}));
if (this.config.attachmentInfo[this._formLayer.id].attachmentIsRequired) {
fileInput.setAttribute("aria-required", true);
fileInput.setAttribute("required", "");
}
if (this.config.attachmentInfo[this._formLayer.id].attachmentHelpText) {
helpBlock = domConstruct.create("p", {
className: "help-block",
innerHTML: this.config.attachmentInfo[this._formLayer.id].attachmentHelpText
}, formContent);
}
//prepare domnode to show the selected file list
divColumn2 = domConstruct.create("div", {
"class": "col-sm-10",
"id": "divColumn2"
}, divRow);
}
// randomblink : add in piece that creates the events and listeners
// make sure this is performed at end of all Form Element creation
this._createSubscribersList();
this._verifyHumanEntry();
},
// BLINKS CODE: Create the list of Subscribers.
_createSubscribersList: function(){
this.subscriptions = array.map( this.subscriptions, lang.hitch( this, function( currSubscriber ){
var currPublishers = array.map( currSubscriber.subscription, lang.hitch( this, function( currPublisher ){
array.forEach( currPublisher.editorFields, lang.hitch( this, function( editorField ){
this._createTopicPublisher( editorField );
}) );
return {
"publication": currPublisher.publication,
"editorFields": currPublisher.editorFields,
"requiredFields": currPublisher.required
};
}));
this. _createTopicSubscriber( currSubscriber.name );
return { "subscriber": currSubscriber.name, "subscription": currPublishers };
}));
},
// BLINKS CODE: Let's consume the publication as it's published.
_consumePublication: function( nameOfSubscriber ){
var targetSubscriber;
array.forEach( this.subscriptions, lang.hitch( this, function( currSubscriber ){
if( currSubscriber.subscriber === nameOfSubscriber ){
targetSubscriber = currSubscriber;
}
}) );
var targetSubscription;
if( array.some( targetSubscriber.subscription, lang.hitch( this, function( currSubscription )
{
var AllReqsMet = this._isRequirementsMet( currSubscription.requiredFields );
targetSubscription = currSubscription;
return AllReqsMet;
}))){
// If AllReqsMet returns TRUE then do this
var listOfFields = targetSubscription.editorFields;
var targetPublication = targetSubscription.publication;
listOfFields = array.map( listOfFields, lang.hitch( this, function( currField ){
var currTargetField = dom.byId( currField );
var currTargetFieldValue;
switch( currTargetField.nodeName )
{
case "INPUT": currTargetFieldValue = currTargetField.value; break;
case "SELECT":
if( currTargetField.selectedOptions[0].value !== "" ){
currTargetFieldValue = currTargetField.selectedOptions[0].text;
}else{
currTargetFieldValue = currTargetField.selectedOptions[0].value;
}
break;
}
return { "value": currTargetFieldValue };
}) );
var testPublish = string.substitute( targetPublication, listOfFields );
dom.byId( nameOfSubscriber ).value = testPublish;
}
},
// BLINKS CODE: Let's check if the Requirements are met.
_isRequirementsMet: function( requirementsArray ){
if( requirementsArray.length === 0 ){
return true;
}
if( array.every( requirementsArray, lang.hitch( this, function( requiredFieldName ){
var targetField = dom.byId( requiredFieldName ), valueToTest = "";
switch( targetField.nodeName ){
case "INPUT": valueToTest = targetField.value; break;
case "SELECT":
if( targetField.selectedOptions[0].value !== "" ){
valueToTest = targetField.selectedOptions[0].text;
}else{
valueToTest = targetField.selectedOptions[0].value;
}
break;
default: break;
}
return valueToTest !== "";
}))){
return true;
}else{
return false;
}
},
// BLINKS CODE: This takes the name of the field that is subscribing to the publication and sets up the Subscribe command
_createTopicSubscriber: function( subscriberName ){
topic.subscribe( "publishTopic", lang.hitch( this, function( ){
this._consumePublication( subscriberName, arguments[0].publisherName, arguments[0].publishedValue );
} ) );
},
// BLINKS CODE: This takes the name of the field that will be publishing it's data and sets up the Publish command
_createTopicPublisher: function( publisherName ){
var newPublisherField = dom.byId( publisherName ), publisherFieldType = newPublisherField.nodeName, fieldEvent = "N/A", publisherValue;
switch( publisherFieldType )
{
case "INPUT": fieldEvent = "keyup"; publisherValue = newPublisherField.value; break;
case "SELECT": fieldEvent = "change"; publisherValue = newPublisherField.selectedOptions[0].text; break;
}
on( newPublisherField, fieldEvent, function(){
switch( publisherFieldType )
{
case "INPUT": publisherValue = newPublisherField.value; break;
case "SELECT":
if( newPublisherField.selectedOptions[0].value !== "" ){
publisherValue = newPublisherField.selectedOptions[0].text;
}else{
publisherValue = newPublisherField.selectedOptions[0].value;
}
break;
}
topic.publish( "publishTopic", { "publisherName": publisherName, "publishedValue": publisherValue } );
});
},
_addToFileList: function (fileInput, fileBtnSpan, formContent, fileDetails) {
var unit, fileSize = "",
alertHtml, fileChange, fileForm, formsToSubmit, formId;
formsToSubmit = query(".formToSubmit", dom.byId('userForm'));
//Toggle class and give unique id to the form selected for attachment
domClass.replace(fileInput.parentNode, "formToSubmit", "selectFileForm");
if (formsToSubmit.length === 0) {
formId = 0;
} else {
formId = parseInt(formsToSubmit[formsToSubmit.length - 1].id.split("formToSubmit")[1]) + 1;
}
fileInput.parentNode.id = "formToSubmit" + formId;
//Toggle class and give unique id to the form selected for attachment
domClass.replace(fileInput, "fileToSubmit", "hideFileInputUI");
fileInput.id = "geoformAttachment" + formId;
//disabling and hiding the selected file so that it is neither clickable nor visible
//need to re-enable the file before submitting
domAttr.set(fileInput, "disabled", "disabled");
domStyle.set(fileInput, "opacity", "0");
domStyle.set(fileInput, "position", "absolute");
//check for availability of HTML-5 file handling properties and then display the file size on domNode
if (fileDetails.files && fileDetails.files[0]) {
fileSize = parseFloat(fileDetails.files[0].size / 1024);
unit = "kb";
if (fileSize > 999) {
unit = "mb";
fileSize = parseFloat(fileSize / 1024);
}
fileSize = fileSize.toFixed(2) + unit;
}
//Preparing the domNode for selected file
alertHtml = "<div class=\"alert alert-dismissable alert-success\">";
alertHtml += "<button type=\"button\" class=\"close\" data-dismiss=\"alert\">" + "×" + "</button>";
alertHtml += "<strong class=\"fileInputUI\">" + fileDetails.value.split('\\').pop() + "<br/>" + fileSize + "</strong>";
alertHtml += "</div>";
alertHtml = domConstruct.place(alertHtml, dom.byId("divColumn2"), "last");
domConstruct.place(fileInput.parentNode, alertHtml, "last");
//binding event to perform activities on removal of a selected file from the file list
on(query(".close", alertHtml)[0], a11yclick, function () {
if (query(".alert-dismissable").length === 1) {
domClass.remove(formContent, ".has-success");
}
});
fileInput = "";
fileForm = domConstruct.create("form", {
"class": "selectFileForm"
}, fileBtnSpan);
fileInput = domConstruct.create("input", {
"type": "file",
"class": "hideFileInputUI",
"title": nls.user.selectFileTitle,
"name": "attachment"
}, fileForm);
domConstruct.place(fileForm, fileBtnSpan, "first");
fileChange = on(fileInput, "change", lang.hitch(this, function (evt) {
this._validateSelectedFile(evt, fileInput, fileBtnSpan, formContent, fileChange);
}));
},
_validateSelectedFile: function (evt, fileInput, fileBtnSpan, formContent, fileChange) {
fileChange.remove();
if (evt.currentTarget.files && evt.currentTarget.files[0] && evt.currentTarget.files[0].size > 26214400) {
$(fileBtnSpan).popover({
content: nls.user.fileTooLargeError,
container: 'body',
trigger: 'manual',
placement: 'bottom'
});
$(fileBtnSpan).popover('show');
setTimeout(function () {
$(fileBtnSpan).popover('hide');
}, 3000);
//this line to change the value of fileinput so that on-change event fires
$(evt.currentTarget).replaceWith($(evt.currentTarget).val('').clone(true));
fileChange = on(query(".hideFileInputUI")[0], "change", lang.hitch(this, function (evt) {
this._validateSelectedFile(evt, fileInput, fileBtnSpan, formContent, fileChange);
}));
return true;
}
if (query(".alert-dismissable", dom.byId("divColumn2")).length > 19) {
$(fileBtnSpan).popover({
content: nls.user.exceededFileCountError,
container: 'body',
trigger: 'manual',
placement: 'bottom'
});
$(fileBtnSpan).popover('show');
setTimeout(function () {
$(fileBtnSpan).popover('hide');
}, 3000);
//this line to change the value of fileinput so that on-change event fires
$(evt.currentTarget).replaceWith($(evt.currentTarget).val('').clone(true));
fileChange = on(query(".hideFileInputUI")[0], "change", lang.hitch(this, function (evt) {
this._validateSelectedFile(evt, fileInput, fileBtnSpan, formContent, fileChange);
}));
return true;
}
//block to remove error message after selection of file and to replace error class with success class.
if (query(".errorMessage", formContent)[0]) {
this._removeErrorNode(query(".errorMessage", formContent)[0]);
domClass.replace(formContent, "has-success", "has-error");
}
this._addToFileList(query(".hideFileInputUI")[0], fileBtnSpan, formContent, evt.currentTarget);
},
//function to create elements of form.
_createFormElements: function (field, index, referenceNode) {
var currentField = lang.clone(field);
var radioContainer, fieldname, radioContent, inputContent, labelContent, fieldLabelText, selectOptions, inputLabel, radioInput, formContent, requireField, userFormNode,
checkboxContainer, checkboxContent, checkBoxCounter = 0,
helpBlock, rangeHelpText, inputGroupContainer;
userFormNode = dom.byId('userForm');
formContent = domConstruct.create("div", {}, userFormNode);
if (!!currentField.locked) {
domClass.add(formContent, "disabled");
}
// randomblink : Beginning of code for concantenated field
if (!!currentField.subscription)
{
domClass.add(formContent, "subscriber");
this.subscriptions.push(currentField);
}
// randomblink : End of code for concantenated field
//code block to fade in the sub-types dependent fields
if (referenceNode) {
domConstruct.place(formContent, referenceNode, "after");
domClass.add(formContent, "fade");
setTimeout(function () {
domClass.add(formContent, "in");
}, 100);
}
if ((!currentField.nullable || currentField.typeField) && currentField.displayType !== "checkbox") {
domClass.add(formContent, "form-group geoFormQuestionare mandatory");
requireField = domConstruct.create("small", {
className: 'requireFieldStyle',
innerHTML: nls.user.requiredField
}, formContent);
} else {
domClass.add(formContent, "form-group geoFormQuestionare");
}
if (currentField.alias) {
fieldLabelText = currentField.alias;
} else {
fieldLabelText = currentField.name;
}
fieldname = currentField.name;
if (currentField.displayType !== "checkbox" || currentField.domain) {
labelContent = domConstruct.create("label", {
"for": fieldname,
className: "control-label",
innerHTML: fieldLabelText,
id: fieldname + "_label_" + index
}, formContent);
}
if (requireField && labelContent) {
domConstruct.place(requireField, labelContent, "last");
}
if (this._formLayer.templates[0] && !currentField.defaultValue) {
for (var fieldAttribute in this._formLayer.templates[0].prototype.attributes) {
if (fieldAttribute.toLowerCase() == fieldname.toLowerCase()) {
currentField.defaultValue = this._formLayer.templates[0].prototype.attributes[fieldAttribute];
}
}
}
//code to make select boxes in case of a coded value
if (currentField.domain || currentField.typeField) {
if ((currentField.domain && (typeof currentField.domain.type === 'undefined' || currentField.domain.type === 'codedValue')) || currentField.typeField) {
radioInput = false;
if (currentField.displayType && currentField.displayType === "radio") {
radioInput = true;
}
//check for fieldType: if not present create dropdown
//If present check for fieldType value and accordingly populate the control
if (!radioInput) {
inputContent = domConstruct.create("select", {
className: "selectDomain",
disabled: !!currentField.locked,
"id": fieldname
}, formContent);
if (currentField.domain && !currentField.typeField) {
if (currentField.displayType == "Filter Select") {
this._createFilterSelectInput(inputContent, fieldname);
} else {
selectOptions = domConstruct.create("option", {
innerHTML: nls.user.domainDefaultText,
value: ""
}, inputContent);
domClass.add(inputContent, "form-control");
}
array.forEach(currentField.domain.codedValues, lang.hitch(this, function (currentOption) {
selectOptions = domConstruct.create("option", {
innerHTML: currentOption.name,
value: currentOption.code
}, inputContent);
//if field contain default value, make that option selected
if (currentField.defaultValue === currentOption.code) {
domAttr.set(selectOptions, "selected", true);
domClass.add(inputContent.parentNode, "has-success");
if (domClass.contains(inputContent, "filterSelect")) {
$(inputContent).val(currentOption.code).trigger("change");
}
}
}));
} else {
if (currentField.displayType == "Filter Select") {
this._createFilterSelectInput(inputContent, fieldname);
} else {
selectOptions = domConstruct.create("option", {
innerHTML: nls.user.domainDefaultText,
value: ""
}, inputContent);
domClass.add(inputContent, "form-control");
}
if(currentField.domain){
array.forEach(currentField.domain.codedValues, lang.hitch(this, function (currentOption) {
selectOptions = domConstruct.create("option", {}, inputContent);
selectOptions.text = currentOption.name;
selectOptions.value = currentOption.code;
//default values for subtypes(if any) has to be handled here
}));
}
else if(currentField.subTypes){
array.forEach(currentField.subTypes, lang.hitch(this, function (currentOption) {
selectOptions = domConstruct.create("option", {}, inputContent);
selectOptions.text = currentOption.name;
selectOptions.value = currentOption.id;
//default values for subtypes(if any) has to be handled here
}));
}
}
on($("#" + fieldname), "change", lang.hitch(this, function (evt) {
//function call to take appropriate actions on selection of a subtypes
if (currentField.typeField) {
this._validateTypeFields(evt.currentTarget, currentField);
}
//To apply has-success class on selection of a valid option
if (evt.target.value !== "") {
if (query(".errorMessage", evt.currentTarget.parentNode).length !== 0) {
domConstruct.destroy(query(".errorMessage", evt.currentTarget.parentNode)[0]);
domClass.remove($(evt.target.parentNode)[0], "has-error");
}
domClass.add($(evt.target.parentNode)[0], "has-success");
} else {
domClass.remove($(evt.target.parentNode)[0], "has-success");
}
}));
} else {
radioContainer = domConstruct.create("div", {
className: "radioContainer",
id: fieldname
}, formContent);
if (currentField.domain && !currentField.typeField) {
array.forEach(currentField.domain.codedValues, lang.hitch(this, function (currentOption) {
radioContent = domConstruct.create("div", {
className: "radio"
}, radioContainer);
inputLabel = domConstruct.create("label", {
"for": fieldname + currentOption.code
}, radioContent);
inputContent = domConstruct.create("input", {
"id": fieldname + currentOption.code,
disabled: !!currentField.locked,
className: "radioInput",
type: "radio",
name: fieldname,
value: currentOption.code
}, inputLabel);
//if field has default value,set radio button checked by default
if (currentOption.code === currentField.defaultValue) {
domAttr.set(inputContent, "checked", "checked");
domClass.add(radioContainer.parentNode, "has-success");
}
// add text after input
inputLabel.innerHTML += currentOption.name;
//code to assign has-success class on click of a radio button
on(inputContent, a11yclick, function (evt) {
if (evt.target.checked) {
if (query(".errorMessage", formContent).length !== 0) {
domConstruct.destroy(query(".errorMessage", formContent)[0]);
domClass.remove(formContent, "has-error");
}
domClass.add(formContent, "has-success");
} else {
domClass.remove(formContent, "has-success");
}
});
}));
} else {
array.forEach(currentField.subTypes, lang.hitch(this, function (currentOption) {
//Code to validate for applying has-success class
radioContent = domConstruct.create("div", {
className: "radio"
}, radioContainer);
inputLabel = domConstruct.create("label", {
"for": fieldname + currentOption.id
}, radioContent);
inputContent = domConstruct.create("input", {
"id": fieldname + currentOption.id,
disabled: !!currentField.locked,
className: "radioInput",
type: "radio",
name: fieldname,
value: currentOption.id
}, inputLabel);
//if field has default value,set radio button checked by default
if (currentOption.id === currentField.defaultValue) {
domAttr.set(inputContent, "checked", "checked");
domClass.add(radioContainer.parentNode, "has-success");
}
// add text after input
inputLabel.innerHTML += currentOption.name;
on(dom.byId(fieldname + currentOption.id), a11yclick, lang.hitch(this, function (evt) {
//function call to take appropriate actions on selection of a subtypes
if (currentField.typeField) {
this._validateTypeFields(evt.currentTarget, currentField);
}
if (evt.target.checked) {
if (query(".errorMessage", formContent).length !== 0) {
domClass.remove(formContent, "has-error");
domConstruct.destroy(query(".errorMessage", formContent)[0]);
}
domClass.add(formContent, "has-success");
} else {
domClass.remove(formContent, "has-success");
}
}));
}));
}
}
} else {
//if field type is date
if (currentField.type == "esriFieldTypeDate") {
var inputRangeDateGroupContainer = this._addNotationIcon(formContent, "glyphicon-calendar");
inputContent = this._createDateField(inputRangeDateGroupContainer, true, fieldname, currentField, currentField.defaultValue);
if(currentField.domain.minValue !== currentField.domain.maxValue && currentField.domain.minValue > -2147483648 && currentField.domain.maxValue > -2147483648){
rangeHelpText = string.substitute(nls.user.dateRangeHintMessage, {
minValue: moment(currentField.domain.minValue).format(this.dateFormat),
maxValue: moment(currentField.domain.maxValue).format(this.dateFormat),
openStrong: "<strong>",
closeStrong: "</strong>"
});
}
} else {
//if field type is integer
rangeHelpText = this._setRangeForm(currentField, formContent, fieldname);
}
}
} else {
//Condition to check if a checkbox is required for integer fields in user form
if (currentField.displayType && currentField.displayType === "checkbox") {
currentField.type = "binaryInteger";
}
switch (currentField.type) {
case "esriFieldTypeString":
if (currentField.displayType && currentField.displayType === "textarea") {
inputContent = domConstruct.create("textarea", {
disabled: !!currentField.locked,
className: "form-control",
"data-input-type": "String",
"rows": 4,
"maxLength": currentField.length,
"id": fieldname
}, formContent);
} else {
if (currentField.displayType && currentField.displayType === "email") {
inputGroupContainer = this._addNotationIcon(formContent, "glyphicon-envelope");
} else if (currentField.displayType && currentField.displayType === "url") {
inputGroupContainer = this._addNotationIcon(formContent, "glyphicon-link");
}
inputContent = domConstruct.create("input", {
type: "text",
disabled: !!currentField.locked,
className: "form-control",
"data-input-type": "String",
"maxLength": currentField.length,
"id": fieldname
}, inputGroupContainer ? inputGroupContainer : formContent);
}
break;
case "binaryInteger":
checkboxContainer = domConstruct.create("div", {
className: "checkboxContainer"
}, formContent);
checkboxContent = domConstruct.create("div", {
className: "checkbox"
}, checkboxContainer);
inputLabel = domConstruct.create("label", {
"for": fieldname
}, checkboxContent);
inputContent = domConstruct.create("input", {
className: "checkboxInput",
disabled: !!currentField.locked,
type: "checkbox",
"data-input-type": "binaryInteger",
"id": fieldname
}, inputLabel);
domAttr.set(inputContent, "data-checkbox-index", checkBoxCounter);
inputLabel.innerHTML += fieldLabelText;
checkBoxCounter++;
break;
case "esriFieldTypeSmallInteger":
inputContent = domConstruct.create("input", {
disabled: !!currentField.locked,
type: "text",
className: "form-control",
"data-input-type": "SmallInteger",
"id": fieldname,
"pattern": "[0-9]*"
}, formContent);
break;
case "esriFieldTypeInteger":
inputContent = domConstruct.create("input", {
disabled: !!currentField.locked,
type: "text",
className: "form-control",
"data-input-type": "Integer",
"id": fieldname,
"pattern": "[0-9]*"
}, formContent);
break;
case "esriFieldTypeSingle":
inputContent = domConstruct.create("input", {
disabled: !!currentField.locked,
type: "text",
className: "form-control",
"data-input-type": "Single",
"id": fieldname
}, formContent);
break;
case "esriFieldTypeDouble":
inputContent = domConstruct.create("input", {
disabled: !!currentField.locked,
type: "text",
className: "form-control",
"data-input-type": "Double",
"id": fieldname,
step: ".1"
}, formContent);
break;
case "esriFieldTypeDate":
var inputDateGroupContainer = this._addNotationIcon(formContent, "glyphicon-calendar");
if (currentField.hiddenDate) {
domClass.add(formContent, "hidden");
}
inputContent = this._createDateField(inputDateGroupContainer, false, fieldname, currentField, currentField.defaultValue);
break;
}
//Add Placeholder if present
if (currentField.tooltip) {
domAttr.set(inputContent, "placeholder", currentField.tooltip);
}
//If present fetch default values
if (currentField.defaultValue) {
if (currentField.type == "esriFieldTypeString" && lang.trim(currentField.defaultValue) !== "") {
domAttr.set(inputContent, "value", currentField.defaultValue);
domClass.add(formContent, "has-success");
}
}
//Add specific display type if present
if (currentField.displayType && currentField.displayType !== "") {
domAttr.set(inputContent, "data-display-type", currentField.displayType);
}
var helpHTML = "";
if (currentField.type !== "esriFieldTypeDate") {
on(inputContent, "focusout", lang.hitch(this, function (evt) {
this._validateField(evt, true);
}));
on(inputContent, "keyup", lang.hitch(this, function () {
if (currentField.displayType === "textarea") {
var availableLength;
if (inputContent.value.length > currentField.length) {
//Work around to make textarea work in IE8
//Truncate the text if necessary
$(inputContent).val(inputContent.value.substr(0, currentField.length));
} else {
availableLength = string.substitute(nls.user.remainingCharactersHintMessage, {
value: (currentField.length - inputContent.value.length).toString()
});
helpBlock.innerHTML = lang.trim(helpHTML + " " + availableLength);
}
}
}));
}
}
// if field is required and field exists
if (!currentField.nullable && inputContent) {
inputContent.setAttribute("aria-required", true);
inputContent.setAttribute("required", "");
}
if(currentField.defaultValue){
// store default value
domAttr.set(inputContent, "data-default-value", currentField.defaultValue);
}
if (currentField.isNewField) {
// make sure popup info and fields are defined
if (this._formLayer && this._formLayer.infoTemplate && this._formLayer.infoTemplate.info && this._formLayer.infoTemplate.info.fieldInfos) {
array.forEach(this._formLayer.infoTemplate.info.fieldInfos, function (currentFieldPopupInfo) {
if (currentFieldPopupInfo.fieldName == currentField.name) {
if (currentFieldPopupInfo.tooltip) {
helpHTML = currentFieldPopupInfo.tooltip;
}
}
});
}
} else {
helpHTML = currentField.fieldDescription;
}
if (helpHTML || currentField.displayType === "textarea") {
var availableLength = "";
if (currentField.displayType === "textarea") {
availableLength = string.substitute(nls.user.remainingCharactersHintMessage, {
value: currentField.length.toString()
});
}
helpBlock = domConstruct.create("p", {
className: "help-block",
innerHTML: lang.trim(helpHTML + " " + availableLength)
}, formContent);
}
if (rangeHelpText) {
var options = {
trigger: 'focus',
placement: 'top',
container: 'body',
content: rangeHelpText,
html: true
};
$('#' + fieldname).popover(options);
}
},
// date range field
_setRangeForm: function (currentField, formContent, fieldname) {
var inputContent, setStep, setDefault = "",
stepDivisibility = 'none',
decimalPoints = 0,
inputcontentSpinner, rangeHelpText;
inputContent = domConstruct.create("input", {
disabled: !!currentField.locked,
id: fieldname,
type: "text",
className: "form-control",
min: currentField.domain.minValue.toString(),
max: currentField.domain.maxValue.toString()
}, formContent);
domAttr.set(inputContent, "data-input-type", currentField.type.replace("esriFieldType", ""));
if (currentField.defaultValue) {
setDefault = currentField.defaultValue;
domClass.add(inputContent.parentNode, "has-success");
}
if (domAttr.get(inputContent, "data-input-type") === "Double" || domAttr.get(inputContent, "data-input-type") === "Single") {
decimalPoints = 2;
if (currentField.domain.minValue - Math.floor(currentField.domain.minValue) === 0.5) {
setStep = 0.5;
} else {
setStep = 0.1;
}
} else {
setStep = 1;
stepDivisibility = 'round';
}
inputcontentSpinner = $(inputContent).TouchSpin({
initval: setDefault,
min: currentField.domain.minValue.toString(),
max: currentField.domain.maxValue.toString(),
forcestepdivisibility: stepDivisibility,
step: setStep,
boostat: 5,
decimals: decimalPoints,
maxboostedstep: 10
});
//Event to address validations for manual entry in the touch-spinner input.
on(inputContent, "keyup", function () {
if (inputContent.value === "") {
domClass.remove(inputContent.parentNode.parentNode, "has-success");
} else {
domClass.add(inputContent.parentNode.parentNode, "has-success");
}
});
on(inputcontentSpinner, "touchspin.on.startspin", lang.hitch(this, function (evt) {
inputcontentSpinner.trigger("touchspin.updatesettings", {});
domClass.add(evt.currentTarget.parentNode.parentNode, "has-success");
}));
if (!currentField.nullable) {
inputContent.setAttribute("aria-required", true);
inputContent.setAttribute("required", "");
}
rangeHelpText = string.substitute(nls.user.textRangeHintMessage, {
minValue: currentField.domain.minValue.toString(),
maxValue: currentField.domain.maxValue.toString(),
openStrong: "<strong>",
closeStrong: "</strong>"
});
return rangeHelpText;
},
_createFilterSelectInput: function (inputContent, fieldname) {
domClass.add(inputContent, "filterSelect");
domStyle.set(inputContent, "width", "100%");
var options = domConstruct.create("option", {}, inputContent);
options.text = "";
options.value = "";
$("#" + fieldname).select2({
placeholder: nls.user.filterSelectEmptyText,
allowClear: true
});
},
//function to validate the fields defined within subtypes
_validateTypeFields: function (currentTarget, currentField) {
var selectedType, defaultValue, switchDomainType, referenceNode;
if (currentTarget.value === "") {
//no type is selected, so the code to remove the type dependent fields will come here
array.forEach(this.sortedFields, lang.hitch(this, function (currentInput) {
if (!currentInput.isTypeDependent) {
return true;
}
if (dom.byId(currentInput.name)) {
var domToDestroy = this._getFormElement(dom.byId(currentInput.name));
domConstruct.destroy(domToDestroy);
}
this._resizeMap();
}));
return true;
} else {
//code to get all the domains and default values of the selected subtype
array.some(currentField.subTypes, function (currentSelection) {
if (currentTarget.value === currentSelection.id.toString()) {
selectedType = currentSelection;
return true;
}
});
}
//initial point of reference to put elements
referenceNode = dom.byId(this._formLayer.typeIdField).parentNode;
//code to populate type dependent fields
array.forEach(this.sortedFields, lang.hitch(this, function (currentInput, index) {
var field = null,
domain, minValue, maxValue;
//condition to filter out fields independent of subtypes
if (!currentInput.isTypeDependent) {
return true;
}
array.some(this._formLayer.fields, function (layerField) {
var lyrField = lang.clone(layerField);
if (lyrField.name === currentInput.name) {
field = lang.clone(lang.mixin(lyrField, currentInput));
return true;
}
});
//code to fetch the default value of a field for selected subtype.
if (selectedType.templates[0]) {
for (var fieldAttribute in selectedType.templates[0].prototype.attributes) {
if (fieldAttribute.toLowerCase() === field.name.toLowerCase()) {
defaultValue = selectedType.templates[0].prototype.attributes[fieldAttribute];
field.defaultValue = defaultValue;
domAttr.set(currentTarget, "data-default-value", defaultValue);
break;
}
}
}
for (var i in selectedType.domains) {
//condition to find the domain properties for current field
if (i === field.name) {
switchDomainType = selectedType.domains[i].type || "codedValue";
switch (switchDomainType) {
case "inherited":
//for inherited domains we need to populate the domains from the layer.
if (field.domain.type === "range") {
minValue = field.domain.minValue;
maxValue = field.domain.maxValue;
} else {
domain = field.domain.codedValues;
}
break;
case "codedValue":
if (!field.domain) {
field.domain = {};
}
field.domain.codedValues = selectedType.domains[i].codedValues;
domain = selectedType.domains[i].codedValues;
break;
case "range":
//Condition to change the range domain values of field already having domain.
if (!field.domain) {
field.domain = {};
}
field.domain.minValue = selectedType.domains[i].minValue;
field.domain.maxValue = selectedType.domains[i].maxValue;
minValue = selectedType.domains[i].minValue;
maxValue = selectedType.domains[i].maxValue;
break;
}
}
}
//code to be executed when the input is already present
if (dom.byId(field.name)) {
var domToDestroy;
domToDestroy = this._getFormElement(dom.byId(field.name));
domConstruct.destroy(domToDestroy);
}
this._createFormElements(field, index, referenceNode);
referenceNode = this._getFormElement(dom.byId(field.name));
}));
this._resizeMap();
},
// validate form field
_validateField: function (currentNode, iskeyPress) {
var inputType, inputValue, displayType = null,
node, typeCastedInputValue, decimal = /^[-+]?[0-9]+$/,
float = /^[-+]?[0-9]+\.[0-9]+$/,
email = /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/,
url = /^(http[s]?:\/\/){0,1}(www\.){0,1}[a-zA-Z0-9\.\-]+\.[a-zA-Z]{2,5}[\.]{0,1}/,
error;
//To remove extra spaces
currentNode.currentTarget.value = lang.trim(currentNode.currentTarget.value);
if (iskeyPress) {
inputValue = currentNode.currentTarget.value;
inputType = domAttr.get(currentNode.currentTarget, "data-input-type");
if (domAttr.get(currentNode.currentTarget, "data-display-type") !== null) {
displayType = domAttr.get(currentNode.currentTarget, "data-display-type");
}
//Since we are adding a new div inside formContent in case of email and url
//We need to traverse one step more
if (displayType === "email" || displayType === "url") {
node = $(currentNode.target.parentNode.parentNode)[0];
} else {
if ($(currentNode.target)) {
node = $(currentNode.target.parentNode)[0];
} else {
node = $(currentNode.srcElement.parentNode)[0];
}
}
} else {
inputValue = query(".form-control", currentNode)[0].value;
inputType = domAttr.get(query(".form-control", currentNode)[0], "data-input-type");
if (domAttr.get(query(".form-control", currentNode)[0], "data-display-type") !== null) {
displayType = domAttr.get(query(".form-control", currentNode)[0], "data-display-type");
}
node = query(".form-control", currentNode)[0].parentElement;
}
switch (inputType) {
case "String":
if (inputValue.length !== 0 && ((displayType === "email" && inputValue.match(email)) || (displayType === "url" && inputValue.match(url)) || displayType === null) || displayType === "text" || displayType === "textarea") {
this._validateUserInput(false, node, inputValue, iskeyPress);
} else {
error = string.substitute(nls.user.invalidString, {
openStrong: "<strong>",
closeStrong: "</strong>"
});
this._validateUserInput(error, node, inputValue, iskeyPress);
}
break;
case "SmallInteger":
typeCastedInputValue = parseInt(inputValue);
if ((inputValue.match(decimal) && typeCastedInputValue >= -32768 && typeCastedInputValue <= 32767) && inputValue.length !== 0) {
this._validateUserInput(false, node, inputValue);
} else {
error = string.substitute(nls.user.invalidSmallNumber, {
openStrong: "<strong>",
closeStrong: "</strong>"
});
this._validateUserInput(error, node, inputValue, iskeyPress);
}
break;
case "Integer":
typeCastedInputValue = parseInt(inputValue);
if ((inputValue.match(decimal) && typeCastedInputValue >= -2147483648 && typeCastedInputValue <= 2147483647) && inputValue.length !== 0) {
this._validateUserInput(false, node, inputValue, iskeyPress);
} else {
error = string.substitute(nls.user.invalidNumber, {
openStrong: "<strong>",
closeStrong: "</strong>"
});
this._validateUserInput(error, node, inputValue, iskeyPress);
}
break;
case "Single":
//zero or more occurrence of (+-) at the start of expression
//at least one occurrence of digits between o-9
//occurrence of .
//at least one occurrence of digits between o-9 in the end
typeCastedInputValue = parseFloat(inputValue);
if (((inputValue.match(decimal) || inputValue.match(float)) && typeCastedInputValue >= -3.4 * Math.pow(10, 38) && typeCastedInputValue <= 1.2 * Math.pow(10, 38)) && inputValue.length !== 0) {
this._validateUserInput(false, node, inputValue, iskeyPress);
} else {
error = string.substitute(nls.user.invalidFloat, {
openStrong: "<strong>",
closeStrong: "</strong>"
});
this._validateUserInput(error, node, inputValue, iskeyPress);
}
break;
case "Double":
typeCastedInputValue = parseFloat(inputValue);
if (((inputValue.match(decimal) || inputValue.match(float)) && typeCastedInputValue >= -2.2 * Math.pow(10, 308) && typeCastedInputValue <= 1.8 * Math.pow(10, 38)) && inputValue.length !== 0) {
this._validateUserInput(false, node, inputValue, iskeyPress);
} else {
error = string.substitute(nls.user.invalidDouble, {
openStrong: "<strong>",
closeStrong: "</strong>"
});
this._validateUserInput(error, node, inputValue, iskeyPress);
}
break;
}
},
// reset form fields
_clearFormFields: function () {
this._createForm(this._savedFields);
},
// validate form input
_validateUserInput: function (error, node, inputValue, iskeyPress) {
if (domClass.contains(node, "filterSelect") && inputValue === "" && domClass.contains(node.parentElement, "mandatory")) {
this._showErrorMessageDiv(error, node.parentElement.children[0]);
domClass.add(node.parentElement, "has-error");
domClass.remove(node, "has-success");
return;
}
if (query(".errorMessage", node)[0]) {
domConstruct.destroy(query(".errorMessage", node)[0]);
}
if (!error || (inputValue.length === 0 && !domClass.contains(node, "mandatory"))) {
domClass.add(node, "has-success");
domClass.remove(node, "has-error");
} else {
this._showErrorMessageDiv(error, node.children[0]);
domClass.add(node, "has-error");
domClass.remove(node, "has-success");
}
if (iskeyPress && inputValue.length === 0 && !domClass.contains(node, "mandatory")) {
domClass.remove(node, "has-error");
domClass.remove(node, "has-success");
}
},
// create a map based on the input web map id
_createWebMap: function (itemInfo) {
var mouseWheel; //To capture the mouse-wheel scroll event and then later deactivate it
var popup = new Popup({
highlight: false
}, domConstruct.create("div"));
domClass.add(popup.domNode, 'light');
var mapDiv = dom.byId('mapDiv');
// fullscreen button HTML
if (this.config.enableBasemapToggle) {
var fsHTML = '';
fsHTML = '<div class="basemapToggle-button"><div class="basemapToggle-button" id="BasemapToggle"></div></div>';
fsHTML += '</div>';
mapDiv.innerHTML = fsHTML;
}
arcgisUtils.createMap(itemInfo, mapDiv, {
mapOptions: {
infoWindow: popup
// Optionally define additional map config here for example you can
// turn the slider off, display info windows, disable wraparound 180, slider position and more.
},
editable: true,
usePopupManager: false,
layerMixins: this.config.layerMixins || [],
bingMapsKey: this.config.bingKey
}).then(lang.hitch(this, function (response) {
// Once the map is created we get access to the response which provides important info
// such as the map, operational layers, popup info and more. This object will also contain
// any custom options you defined for the template. In this example that is the 'theme' property.
// Here' we'll use it to update the application to match the specified color theme.
// console.log(this.config);
this._createGeoformSections();
this.map = response.map;
// Disable scroll zoom handler
if (this.config.enableBasemapToggle) {
var toggle = new basemapToggle({
map: this.map,
basemap: this.config.defaultBasemap,
defaultBasemap: this.config.nextBasemap
}, "BasemapToggle");
toggle.startup();
var layers = this.map.getLayersVisibleAtScale(this.map.getScale());
on.once(this.map, 'basemap-change', lang.hitch(this, function () {
for (var i = 0; i < layers.length; i++) {
if (layers[i]._basemapGalleryLayerType) {
var layer = this.map.getLayer(layers[i].id);
this.map.removeLayer(layer);
}
}
}));
}
this.map.disableScrollWheelZoom();
this.defaultExtent = this.map.extent;
// webmap defaults
this._setWebmapDefaults();
// default layer
this._setLayerDefaults();
// set configuration
this._setAppConfigurations(this.config.details);
domAttr.set(dom.byId('submitButton'), "innerHTML", this.config.submitButtonText ? this.config.submitButtonText : nls.user.submitButtonText);
domAttr.set(dom.byId('viewSubmissionsButton'), "innerHTML", this.config.viewSubmissionsText ? this.config.viewSubmissionsText : nls.user.btnViewSubmissions);
// window title
if (this.config.details && this.config.details.Title) {
window.document.title = this.config.details.Title;
}
if (this.config.form_layer.id == "all") {
var webmapLayers, deferredListArray = [];
this.layerCollection = {};
webmapLayers = domConstruct.create("select", {
"class": "form-control selectDomain allLayerList"
}, dom.byId("multipleLayers"));
for (var key in this.config.fields) {
if (this.config.fields.hasOwnProperty(key) && key !== "length") {
deferredListArray.push(this._loadNewLayer(webmapLayers, key));
}
}
//run this block after all the layers are loaded and are correspondingly pushed in the layer-select-box
all(deferredListArray).then(lang.hitch(this, function () {
//if at-least one editable point layer is found then create the form or else show error message
if (webmapLayers.options[0]) {
webmapLayers.options[0].selected = true;
this._formLayer = this.layerCollection[webmapLayers.options[0].value];
this._savedFields = this.config.fields[webmapLayers.options[0].value];
this._createForm(this._savedFields);
on(webmapLayers, "change", lang.hitch(this, function (evt) {
this._savedFields = this.config.fields[evt.currentTarget.value];
this._formLayer = this.layerCollection[evt.currentTarget.value];
this._createForm(this._savedFields);
this._resizeMap();
}));
} else {
var error = new Error(nls.user.invalidLayerMessage);
this.reportError(error);
}
}));
} else {
if (this._formLayer) {
this._savedFields = this.config.fields[this._formLayer.id];
// create form fields
this._createForm(this._savedFields);
}
}
// create locate button
this._createLocateButton();
// create geocoder button
this._createGeocoderButton();
// make graphics layer
this._gl = new GraphicsLayer();
this.map.addLayer(this._gl);
// add border radius to map
domClass.add(this.map.root, 'panel');
// remove loading class from body
domClass.remove(document.body, "app-loading");
// drag point edit toolbar
this.editToolbar = new editToolbar(this.map);
// start moving
on(this.editToolbar, "graphic-move-start", lang.hitch(this, function () {
if (this.map.infoWindow) {
this.map.infoWindow.hide();
}
}));
// stop moving
on(this.editToolbar, "graphic-move-stop", lang.hitch(this, function (evt) {
var locationCoords = this._calculateLatLong(evt.graphic.geometry);
domAttr.set(dom.byId("coordinatesValue"), "innerHTML", locationCoords);
this.addressGeometry = evt.graphic.geometry;
this._setCoordInputs(evt.graphic.geometry);
}));
// show info window on graphic click
on(this.editToolbar, "graphic-click", lang.hitch(this, function (evt) {
var graphic = evt.graphic;
if (graphic && this.map.infoWindow) {
this.map.infoWindow.setFeatures([graphic]);
this.map.infoWindow.show(graphic.geometry);
}
}));
// map click
on(this.map, 'click', lang.hitch(this, function (evt) {
//remove the location-error message as soon as the point on the map is selected.
this._removeErrorNode(dom.byId("select_location").nextSibling);
this._clearSubmissionGraphic();
this.addressGeometry = evt.mapPoint;
this._setSymbol(this.addressGeometry, true);
// get coords string
var coords = this._calculateLatLong(evt.mapPoint);
domAttr.set(dom.byId("coordinatesValue"), "innerHTML", coords);
this._setCoordInputs(evt.mapPoint);
}));
//on mouse move show lat lon
on(this.map, 'mouse-move', lang.hitch(this, function (evt) {
// get coords string
var coords = this._calculateLatLong(evt.mapPoint);
domAttr.set(dom.byId("coordinatesValue"), "innerHTML", coords);
}));
mouseWheel = on(this.map, 'mouse-wheel', lang.hitch(this, function () {
//Enables scrollwheel zoom 3 seconds after a user hovers over the map
setTimeout(lang.hitch(this, function () {
this.map.enableScrollWheelZoom();
}), 3000);
mouseWheel.remove();
}));
// Add desirable touch behaviors here
if (this.map.hasOwnProperty("isScrollWheelZoom")) {
if (this.map.isScrollWheelZoom) {
this.map.enableScrollWheelZoom();
} else {
this.map.disableScrollWheelZoom();
}
} else {
// Default
this.map.disableScrollWheelZoom();
}
// FeatureLayers
if (this.map.infoWindow) {
// resize popup
on(this.map.infoWindow, "selection-change, set-features, show", lang.hitch(this, function () {
this._resizeInfoWin();
}));
}
// When window resizes
on(window, 'resize', lang.hitch(this, function () {
this._resizeMap(true);
this._resizeInfoWin();
this._centerPopup();
}));
// Lat/Lng coordinate events
var latNode = dom.byId('lat_coord');
var lngNode = dom.byId('lng_coord');
on(latNode, "keyup", lang.hitch(this, function () {
this._validateLocationInputs('lat');
}));
on(latNode, "keypress", lang.hitch(this, function (evt) {
this._findLocation(evt);
this._checkLatLng();
}));
on(lngNode, "keypress", lang.hitch(this, function (evt) {
this._findLocation(evt);
this._checkLatLng();
}));
on(lngNode, "keyup", lang.hitch(this, function () {
this._validateLocationInputs('lng');
}));
// lat/lng changed
on(latNode, "change", lang.hitch(this, function () {
this._checkLatLng();
}));
on(lngNode, "change", lang.hitch(this, function () {
this._checkLatLng();
}));
on(dom.byId('cordsSubmit'), a11yclick, lang.hitch(this, function (evt) {
this._evaluateCoordinates(evt);
}));
// USNG
on(dom.byId('usng_submit'), a11yclick, lang.hitch(this, function () {
this._convertUSNG();
}));
var usngInput = dom.byId('usng_coord');
on(usngInput, "change", lang.hitch(this, function () {
this._checkUSNG();
}));
on(usngInput, "keypress", lang.hitch(this, function (evt) {
var keyCode = evt.charCode || evt.keyCode;
if (keyCode === 13) {
this._convertUSNG();
}
this._checkUSNG();
}));
// MGRS
on(dom.byId('mgrs_submit'), a11yclick, lang.hitch(this, function () {
this._convertMGRS();
}));
var mgrsInput = dom.byId('mgrs_coord');
on(mgrsInput, "change", lang.hitch(this, function () {
this._checkMGRS();
}));
on(mgrsInput, "keypress", lang.hitch(this, function (evt) {
var keyCode = evt.charCode || evt.keyCode;
if (keyCode === 13) {
this._convertMGRS();
}
this._checkMGRS();
}));
// UTM
var northNode = dom.byId('utm_northing');
var eastNode = dom.byId('utm_easting');
var zoneNode = dom.byId('utm_zone_number');
on(dom.byId('utm_submit'), a11yclick, lang.hitch(this, function () {
this._convertUTM();
}));
on(northNode, "keypress", lang.hitch(this, function (evt) {
var keyCode = evt.charCode || evt.keyCode;
if (keyCode === 13) {
this._convertUTM();
}
this._checkUTM();
}));
on(northNode, "change", lang.hitch(this, function () {
this._checkUTM();
}));
on(eastNode, "keypress", lang.hitch(this, function (evt) {
var keyCode = evt.charCode || evt.keyCode;
if (keyCode === 13) {
this._convertUTM();
}
this._checkUTM();
}));
on(eastNode, "change", lang.hitch(this, function () {
this._checkUTM();
}));
on(zoneNode, "keypress", lang.hitch(this, function (evt) {
var keyCode = evt.charCode || evt.keyCode;
if (keyCode === 13) {
this._convertUTM();
}
this._checkUTM();
}));
on(zoneNode, "change", lang.hitch(this, function () {
this._checkUTM();
}));
// fullscreen
var fsButton = domConstruct.create("div", {
tabindex: "0",
"class": "fullScreenButtonContainer"
}, mapDiv);
domConstruct.create("span", {
id: "fullscreen_icon",
title: "Full Screen",
"class": "glyphicon glyphicon-fullscreen fullScreenImage"
}, fsButton);
if (fsButton) {
on(fsButton, a11yclick, lang.hitch(this, function () {
this._toggleFullscreen();
}));
}
// fullscreen esc key
on(document.body, 'keyup', lang.hitch(this, function (evt) {
var keyCode = evt.charCode || evt.keyCode;
if (keyCode === 27) {
this._toggleFullscreen(false);
}
}));
// finished button
var submitButtonNode = dom.byId('submitButton');
if (submitButtonNode) {
on(submitButtonNode, a11yclick, lang.hitch(this, function () {
this._submitForm();
}));
}
//disable viewSubmissionsButton
if (this.config.disableViewer) {
domClass.add(dom.byId("viewSubmissionsButton"), 'hidden');
}
domAttr.set(dom.byId("viewSubmissionsButton"), "href", this._viewSubmissions());
// set location options
this._populateLocationsOptions();
// resize map
this._resizeMap();
// load map
if (this.map.loaded) {
this._mapLoaded();
} else {
// map loaded
on(this.map, 'load', lang.hitch(this, function () {
this._mapLoaded();
}));
}
//Check location parameters in url
if (this.config.locate) {
this._setLocation("locate", this.config.locate);
} else if (this.config.search) {
this._setLocation("search", this.config.search);
} else if (this.config.latlon) {
this._setLocation("latlon", this.config.latlon);
}
}), this.reportError);
},
//this function opens viewer page
_viewSubmissions: function () {
var urlString = "viewer.html";
if (this.config.appid) {
urlString += "?appid=" + this.config.appid;
} else if (this.config.webmap) {
urlString += "?webmap=" + this.config.webmap;
}
return urlString;
},
//this function ensures that the layer is either loaded or throws an error in console naming the layer that did not load successfully
_loadNewLayer: function (webmapLayers, key) {
var layerLoadedEvent, errorLoadEvent, def, layer;
//Fetch all the layers at once
def = new Deferred();
layer = this.map.getLayer(key);
//this block will be called if the layer is already loaded
if (layer && layer.url) {
if (layer.loaded) {
if (layer.isEditable() && layer.geometryType === 'esriGeometryPoint') {
this._pushToLayerDrpDwn(webmapLayers, key, layer);
}
def.resolve();
} else {
//this block will be called if there is some error in layer load
if (layer.loadError) {
console.log(nls.user.error + ": " + layer.name);
def.resolve();
}
//this block attaches 'load' and 'loadError' events respectively
else {
layerLoadedEvent = on.once(layer, "load", lang.hitch(this, function () {
errorLoadEvent.remove();
if (layer.isEditable() && layer.geometryType === 'esriGeometryPoint') {
this._pushToLayerDrpDwn(webmapLayers, key, layer);
}
def.resolve();
}));
errorLoadEvent = on.once(layer, "error", lang.hitch(this, function () {
layerLoadedEvent.remove();
console.log(nls.user.error + ": " + layer.name);
def.resolve();
}));
}
}
} else {
//This error will be logged in case the layer is undefined
//this will happen in case where the key from this.config.fields supplies a layer id not present in the map
console.log(nls.user.invalidLayerMessage + ": " + key);
def.resolve();
}
return def.promise;
},
//function to push the layer name to layer drop down
_pushToLayerDrpDwn: function (webmapLayers, key, layer) {
this.layerCollection[key] = layer;
var option = domConstruct.create("option", {}, webmapLayers);
option.text = this.layerCollection[key].name;
option.value = key;
},
_createGeoformSections: function () {
array.forEach(query(".geoformSection"), lang.hitch(this, function (currentSection, index) {
if (this.config.form_layer.id === "all") {
currentSection.innerHTML = string.substitute(currentSection.innerHTML, {
formSection: ++index + "."
});
} else {
if (index !== 0) {
currentSection.innerHTML = string.substitute(currentSection.innerHTML, {
formSection: index + "."
});
} else {
domStyle.set(dom.byId("selectLayer"), "display", "none");
}
}
}));
},
_mapLoaded: function () {
// center coords
setTimeout(lang.hitch(this, function () {
var mapCenter = this.map.extent.getCenter();
if (mapCenter) {
this._setCoordInputs(mapCenter);
var locationCoords = this._calculateLatLong(mapCenter);
domAttr.set(dom.byId("coordinatesValue"), "innerHTML", locationCoords);
}
this._resizeMap();
}), 500);
// resize map
setTimeout(lang.hitch(this, function () {
this._resizeMap();
}), 1000);
},
_setLocation: function (urlParameter, value) {
switch (urlParameter) {
case "locate":
this.currentLocation.locate();
break;
case "search":
this.geocodeAddress.set("value", value);
this.geocodeAddress.search();
break;
case "latlon":
var latlonValue = value.split(",");
this._locatePointOnMap(latlonValue[0], latlonValue[1], 'latlon');
domAttr.set(dom.byId('lat_coord'), "value", latlonValue[0]);
domAttr.set(dom.byId('lng_coord'), "value", latlonValue[1]);
break;
default:
//Code for default value
break;
}
},
_fullscreenState: function () {
// get all nodes
var mapNode, fsContainerNode, btnNode, mapContainerNode;
mapNode = dom.byId('mapDiv');
fsContainerNode = dom.byId('fullscreen_container');
mapContainerNode = dom.byId('map_container');
btnNode = dom.byId('fullscreen_icon');
if (domClass.contains(document.body, 'fullscreen')) {
domClass.remove(this.map.root, 'panel');
domConstruct.place(mapNode, fsContainerNode);
domClass.replace(btnNode, "glyphicon glyphicon-remove", "glyphicon glyphicon-fullscreen");
// move map node and clear hash
window.location.hash = "";
btnNode.title = nls.user.mapRestore;
} else {
domClass.add(this.map.root, 'panel');
domConstruct.place(mapNode, mapContainerNode);
domClass.replace(btnNode, "glyphicon glyphicon-fullscreen", "glyphicon glyphicon-remove");
window.location.hash = "#mapDiv";
btnNode.title = nls.user.mapFullScreen;
}
this._resizeMap();
// if current selected location
if (this.addressGeometry) {
setTimeout(lang.hitch(this, function () {
this.map.centerAt(this.addressGeometry);
}), 500);
}
},
_toggleFullscreen: function (condition) {
// swap classes
domClass.toggle(document.body, 'fullscreen', condition);
// update state
this._fullscreenState();
},
_validateLocationInputs: function (mode) {
switch (mode) {
case 'lat':
var lat = lang.trim(dom.byId('lat_coord').value);
if (lat === '') {
domClass.remove(dom.byId('lat_coord').parentNode, 'has-error');
domClass.remove(dom.byId('lat_coord').parentNode, 'has-success');
return;
}
if (lat >= -90 && lat <= 90) {
domClass.replace(dom.byId('lat_coord').parentNode, 'has-success', 'has-error');
} else {
domClass.replace(dom.byId('lat_coord').parentNode, 'has-error', 'has-success');
}
break;
case 'lng':
var lng = lang.trim(dom.byId('lng_coord').value);
if (lng === '') {
domClass.remove(dom.byId('lng_coord').parentNode, 'has-error');
domClass.remove(dom.byId('lng_coord').parentNode, 'has-success');
return;
}
if (lng >= -180 && lng <= 180) {
domClass.replace(dom.byId('lng_coord').parentNode, 'has-success', 'has-error');
} else {
domClass.replace(dom.byId('lng_coord').parentNode, 'has-error', 'has-success');
}
break;
}
},
// utm to lat lon
_convertUTM: function () {
this._clearSubmissionGraphic();
var northing = parseFloat(dom.byId('utm_northing').value);
var easting = parseFloat(dom.byId('utm_easting').value);
var zoneNode = dom.byId('utm_zone_number');
var zoneString = zoneNode.value;
var zoneLastChar = zoneString.substr(zoneString.length-1);
var zone = parseInt(zoneString, 10);
if(isNaN(zoneLastChar)){
if(zoneLastChar.toLowerCase() === "s"){
northing = Math.abs(northing) - NORTHING_OFFSET;
}
}
else{
northing = Math.abs(northing);
}
var converted = {};
try {
usng.UTMtoLL(northing, easting, zone, converted);
} catch (e) {
this._coordinatesError('utm');
}
if (converted) {
this._locatePointOnMap(converted.lat, converted.lon, 'utm');
}
},
// usng to lat lon
_convertUSNG: function () {
this._clearSubmissionGraphic();
var value = dom.byId('usng_coord').value;
var converted = [];
try {
usng.USNGtoLL(value, converted);
} catch (e) {
this._coordinatesError('usng');
}
if (converted.length === 2) {
this._locatePointOnMap(converted[0], converted[1], 'usng');
}
},
// convert mgrs to lat lon
_convertMGRS: function () {
this._clearSubmissionGraphic();
var value = dom.byId('mgrs_coord').value;
var converted = [];
try {
usng.USNGtoLL(value, converted);
} catch (e) {
this._coordinatesError('mgrs');
}
if (converted.length === 2) {
this._locatePointOnMap(converted[0], converted[1], 'mgrs');
}
},
// make sure valid coordinates
_evaluateCoordinates: function () {
var latNode = dom.byId('lat_coord');
var lngNode = dom.byId('lng_coord');
this._clearSubmissionGraphic();
if (latNode.value === "") {
this._showErrorMessageDiv(nls.user.emptylatitudeAlertMessage, dom.byId("select_location"));
return;
} else if (lngNode.value === "") {
this._showErrorMessageDiv(nls.user.emptylongitudeAlertMessage, dom.byId("select_location"));
return;
}
// place on map
this._locatePointOnMap(latNode.value, lngNode.value, 'latlon');
},
_checkLatLng: function () {
// make sure lat and lon are both filled out to show button
var lat = lang.trim(dom.byId('lat_coord').value);
var lng = lang.trim(dom.byId('lng_coord').value);
var coord = dom.byId('cordsSubmit');
if (lat && lng) {
domAttr.remove(coord, 'disabled');
} else {
domAttr.set(coord, 'disabled', 'disabled');
}
},
_checkUTM: function () {
// make sure lat and lon are both filled out to show button
var e = dom.byId('utm_northing').value;
var n = dom.byId('utm_easting').value;
var z = dom.byId('utm_zone_number').value;
var s = dom.byId('utm_submit');
if (e && n && z) {
domAttr.remove(s, 'disabled');
} else {
domAttr.set(s, 'disabled', 'disabled');
}
},
_checkUSNG: function () {
// make value(s) are set
var inputVal = dom.byId('usng_coord').value;
var btn = dom.byId('usng_submit');
if (inputVal) {
domAttr.remove(btn, 'disabled');
} else {
domAttr.set(btn, 'disabled', 'disabled');
}
},
_checkMGRS: function () {
// make value(s) are set
var inputVal = dom.byId('mgrs_coord').value;
var btn = dom.byId('mgrs_submit');
if (inputVal) {
domAttr.remove(btn, 'disabled');
} else {
domAttr.set(btn, 'disabled', 'disabled');
}
},
// find location for coordinates
_findLocation: function (evt) {
var keyCode = evt.charCode || evt.keyCode;
if (keyCode === 13) {
// check coordinates
this._evaluateCoordinates();
}
},
// my location button
_createLocateButton: function () {
// create widget
this.currentLocation = new LocateButton({
map: this.map,
highlightLocation: false,
theme: "btn btn-default"
}, domConstruct.create('div'));
this.currentLocation.startup();
if(this.currentLocation.visible){
// on current location submit
on(this.currentLocation, "locate", lang.hitch(this, function (evt) {
// remove error
var errorMessageNode = dom.byId('errorMessageDiv');
domConstruct.empty(errorMessageNode);
// if error
if (evt.error) {
alert(nls.user.locationNotFound);
} else {
this.addressGeometry = evt.graphic.geometry;
this._setSymbol(evt.graphic.geometry);
this._resizeMap();
//If the location is found we will remove the location-error message if it exists
this._removeErrorNode(dom.byId("select_location").nextSibling);
}
// reset button
$('#geolocate_button').button('reset');
}));
// event for clicking node
on(dom.byId('geolocate_button'), a11yclick, lang.hitch(this, function (evt) {
// remove graphic
this._clearSubmissionGraphic();
// set loading button
$('#geolocate_button').button('loading');
// widget locate
this.currentLocation.locate();
evt.stopPropagation();
evt.preventDefault();
}));
}
else{
$('#geolocate_button').addClass('hidden');
}
},
// geocoder with bootstrap
_createGeocoderButton: function () {
var searchOptions = {
map: this.map,
geocoders: this.config.helperServices.geocode || [],
itemData: this.config.itemInfo.itemData
};
if (this.config.searchConfig) {
searchOptions.enableSearchingAll = this.config.searchConfig.enableSearchingAll;
searchOptions.activeSourceIndex = this.config.searchConfig.activeSourceIndex;
searchOptions.applicationConfiguredSources = this.config.searchConfig.sources || [];
} else {
var configuredSearchLayers = (this.config.searchLayers instanceof Array) ? this.config.searchLayers : JSON.parse(this.config.searchLayers);
searchOptions.configuredSearchLayers = configuredSearchLayers;
searchOptions.geocoders = this.config.locationSearch ? this.config.helperServices.geocode : [];
}
var searchSources = new SearchSources(searchOptions);
// get options
var createdOptions = searchSources.createOptions();
createdOptions.enableHighlight = false;
createdOptions.enableInfoWindow = false;
// create geocoder
this.geocodeAddress = new Search(createdOptions, "search-widget");
this.geocodeAddress.startup();
// on find
on(this.geocodeAddress, "select-result", lang.hitch(this, function (evt) {
var coords = this._calculateLatLong(evt.result.feature.geometry);
domAttr.set(dom.byId("coordinatesValue"), "innerHTML", coords);
//this will remove the error message if it exists
this._removeErrorNode(dom.byId("select_location").nextSibling);
this.addressGeometry = evt.result.feature.geometry;
this._setSymbol(evt.result.feature.geometry);
this.map.centerAt(evt.result.feature.geometry).then(lang.hitch(this, function () {
this._resizeMap();
}));
}));
},
// submit form with applyedits
_addFeatureToLayer: function () {
var userFormNode, featureData, key, value, defaultValue;
userFormNode = dom.byId('userForm');
//To populate data for apply edits
featureData = new Graphic();
featureData.attributes = {};
// start with layer defaults
if (this._formLayer.templates[0] && this._formLayer.templates[0].prototype.attributes) {
featureData.attributes = lang.clone(this._formLayer.templates[0].prototype.attributes);
}
//condition to filter out radio inputs
array.forEach(query(".geoFormQuestionare .form-control"), function (currentField) {
key = domAttr.get(currentField, "id");
if (currentField.value !== "") {
if (domClass.contains(currentField, "hasDatetimepicker")) {
var picker = $(currentField.parentNode).data('DateTimePicker');
var d = picker.date();
// need to get time of date in ms for service
value = d.valueOf();
} else {
value = lang.trim(currentField.value);
}
featureData.attributes[key] = value;
}
else if(domAttr.has(currentField, "data-default-value")){
defaultValue = domAttr.get(currentField, "data-default-value");
value = defaultValue;
featureData.attributes[key] = value;
}
});
array.forEach(query(".filterSelect"), function (currentField) {
key = domAttr.get(currentField, "id");
if (currentField.value) {
value = lang.trim(currentField.value);
featureData.attributes[key] = value;
}
else if(domAttr.has(currentField, "data-default-value")){
defaultValue = domAttr.get(currentField, "data-default-value");
value = defaultValue;
featureData.attributes[key] = value;
}
});
// each radio button
array.forEach(query(".geoFormQuestionare .radioContainer"), function (currentField) {
var radioFields = query(".radioInput:checked", currentField);
if (radioFields.length) {
var selectedField = radioFields[0];
key = selectedField.name;
value = lang.trim(selectedField.value);
featureData.attributes[key] = value;
}
});
// each checkbox
array.forEach(query(".geoFormQuestionare .checkboxContainer"), function (currentField) {
key = query(".checkboxInput", currentField)[0].id;
value = query(".checkboxInput:checked", currentField).length;
featureData.attributes[key] = value;
});
featureData.geometry = {};
featureData.geometry = new Point(Number(this.addressGeometry.x), Number(this.addressGeometry.y), this.map.spatialReference);
//code for apply-edits
this._formLayer.applyEdits([featureData], null, null, lang.hitch(this, function (addResults) {
// Add attachment on success
if (addResults[0].success && this.isHumanEntry) {
if (query(".fileToSubmit", userFormNode).length === 0) {
this._resetAndShare();
} else {
this._openFileUploadStatusModal(query(".fileToSubmit", userFormNode));
var fileObjArray = [];
for (var i = 0; i < query(".formToSubmit", userFormNode).length; i++) {
fileObjArray.push(query(".formToSubmit", userFormNode)[i].id);
}
this.arrPendingAttachments = fileObjArray.reverse();
this._addAttachment(addResults[0].objectId, dom.byId(this.arrPendingAttachments.pop()));
}
return true;
}
domConstruct.destroy(query(".errorMessage")[0]);
// open error modal if unsuccessful
if (!addResults[0].success || (!this.isHumanEntry && addResults[0].success)) {
var error;
if(!addResults[0].success){
error = addResults[0].error || new Error("");
}
else {
error = new Error(nls.user.applyEditsFailedRobot);
}
this._openErrorModal(error);
this._verifyHumanEntry();
return;
}
}), lang.hitch(this, function (error) {
// no longer editable
this._formLayer.setEditable(false);
// remove error
domConstruct.destroy(query(".errorMessage")[0]);
// open error
this._openErrorModal(error);
// log for development
console.log(nls.user.addFeatureFailedMessage);
}));
},
_resetAndShare: function () {
// remove graphic
this._clearSubmissionGraphic();
// reset form
this._clearFormFields();
// reset to default extent
if (this.config.defaultMapExtent) {
this.map.setExtent(this.defaultExtent);
}
this._verifyHumanEntry();
this._openShareModal();
// reset submit button
this._resetButton();
window.location.href = '#top';
// After moving geoform to top, map was not getting resized properly.
// And pushpin was not getting placed correctly.
this._resizeMap();
},
_addAttachment: function (recordId, currentElement) {
var currentBadge;
this.flagAttachingPrevFile = true;
currentBadge = query(".file-upload-status-badge[data-badge=" + currentElement[0].id + "]")[0];
//re-enabling the file i/p field before sending to attach
domAttr.set(currentElement[0], "disabled", false);
this._formLayer.addAttachment(recordId, currentElement, lang.hitch(this, function () {
if (dom.byId("fileUploadStatusMsgContainer")) {
this.flagAttachingPrevFile = false;
//adding/removing attributes to keep the user updated on current state of file attachment
domClass.replace(currentBadge.parentNode, "alert-success", "alert-info");
domClass.replace(currentBadge, "glyphicon-ok", "glyphicon-upload");
domStyle.set(currentBadge, "cursor", "auto");
currentBadge.innerHTML = nls.user.successBadge;
if (this.arrRetryAttachments.length !== 0) {
this._addAttachment(recordId, dom.byId(this.arrRetryAttachments.pop()));
return true;
}
if (this.arrPendingAttachments.length !== 0) {
this._addAttachment(recordId, dom.byId(this.arrPendingAttachments.pop()));
return true;
}
}
}), lang.hitch(this, function () {
//condition to check whether file upload status modal is open or not
if (dom.byId("fileUploadStatusMsgContainer")) {
this.flagAttachingPrevFile = false;
//Keep a copy of ids that failed to upload to pick them back while retrying to upload the failed file
this.objFailedAttachments[currentElement[0].id] = currentElement.id;
//adding/removing attributes to keep the user updated on current state of file attachment
domClass.replace(currentBadge.parentNode, "alert-warning", "alert-info");
domClass.remove(query(".attachment-error-message", currentBadge.parentNode)[0], "hide");
domClass.replace(currentBadge, "btn btn-danger btn-xs", "glyphicon-upload");
currentBadge.innerHTML = nls.user.retryBadge;
domStyle.set(currentBadge, "cursor", "pointer");
//This click event will work on retry button in case of failure in attachment
//and process to re-upload the file will start
on.once(currentBadge, a11yclick, lang.hitch(this, function (evt) {
//adding/removing attributes to keep the user updated on current state of file attachment
domClass.replace(currentBadge.parentNode, "alert-info", "alert-warning");
domClass.add(query(".attachment-error-message", currentBadge.parentNode)[0], "hide");
domClass.replace(currentBadge, "glyphicon-upload", "btn btn-danger btn-xs glyphicon-repeat");
evt.currentTarget.innerHTML = nls.user.uploadingBadge;
domStyle.set(evt.currentTarget, "cursor", "auto");
this.arrRetryAttachments.push(this.objFailedAttachments[domAttr.get(evt.currentTarget, "data-badge")]);
delete this.objFailedAttachments[domAttr.get(evt.currentTarget, "data-badge")];
if (this.flagAttachingPrevFile === false) {
this._addAttachment(recordId, dom.byId(this.arrRetryAttachments.pop()));
}
return true;
}));
console.log(nls.user.addAttachmentFailedMessage);
if (this.arrRetryAttachments.length !== 0) {
this._addAttachment(recordId, dom.byId(this.arrRetryAttachments.pop()));
return true;
}
if (this.arrPendingAttachments.length !== 0) {
this._addAttachment(recordId, dom.byId(this.arrPendingAttachments.pop()));
return true;
}
}
}));
},
// remove point graphic
_clearSubmissionGraphic: function () {
this.addressGeometry = null;
this._gl.clear();
if (this.map.infoWindow && this.map.infoWindow.isShowing) {
this.map.infoWindow.hide();
}
},
// display coordinates error
_coordinatesError: function (type) {
switch (type) {
case "utm":
this._showErrorMessageDiv(nls.user.invalidUTM, dom.byId("select_location"));
break;
case "usng":
this._showErrorMessageDiv(nls.user.invalidUSNG, dom.byId("select_location"));
break;
case "mgrs":
this._showErrorMessageDiv(nls.user.invalidMGRS, dom.byId("select_location"));
break;
default:
this._showErrorMessageDiv(nls.user.invalidLatLong, dom.byId("select_location"));
}
},
_projectPoint: function (geometry) {
// this function takes a lat/lon (4326) point and converts it to map's spatial reference.
var def = new Deferred();
// maps spatial ref
var sr = this.map.spatialReference;
// map and point are both lat/lon
if (sr.wkid === 4326) {
def.resolve(geometry);
}
// map is mercator
else if (sr.isWebMercator()) {
// convert lat lon to mercator. No network request.
var pt = webMercatorUtils.geographicToWebMercator(geometry);
def.resolve(pt);
}
// map is something else & has geometry service
else if (esriConfig.defaults.geometryService) {
// project params
var params = new ProjectParameters();
params.geometries = [geometry];
params.outSR = this.map.spatialReference;
// use geometry service to convert lat lon to map format (network request)
esriConfig.defaults.geometryService.project(params).then(function (projectedPoints) {
if (projectedPoints && projectedPoints.length) {
def.resolve(projectedPoints[0]);
} else {
def.reject(new Error("GeoForm::Point was not projected."));
}
}, function (error) {
def.reject(error);
});
}
// cant do anything, leave lat/lon
else {
def.resolve(geometry);
}
return def;
},
// put x,y point on map in mercator
_locatePointOnMap: function (x, y, type) {
if (x >= -90 && x <= 90 && y >= -180 && y <= 180) {
var mapLocation = new Point(y, x);
// convert point
this._projectPoint(mapLocation).then(lang.hitch(this, function (pt) {
if (pt) {
this._removeErrorNode(dom.byId("select_location").nextSibling);
this.addressGeometry = pt;
// set point symbol
this._setSymbol(pt);
// center map at point and resize
this.map.centerAt(pt).then(lang.hitch(this, function () {
this._resizeMap();
}));
var errorMessageNode = dom.byId('errorMessageDiv');
domConstruct.empty(errorMessageNode);
}
}), lang.hitch(this, function (error) {
console.log(error);
this._coordinatesError(type);
}));
} else {
// display coordinates error
this._coordinatesError(type);
}
},
// open modal
_openShareModal: function () {
// destroy modal if it exists
if (this._ShareModal) {
this._ShareModal.destroy();
}
// create modal content
this._createShareDlgContent();
// create modal
this._ShareModal = new ShareModal({
image: this.config.sharinghost + '/sharing/rest/content/items/' + this.config.itemInfo.item.id + '/info/' + this.config.itemInfo.item.thumbnail,
title: this.config.details.Title || nls.user.geoformTitleText || '',
summary: this.config.itemInfo.item.snippet || '',
hashtags: 'esriGeoForm',
shareOption: this.config.enableSharing
});
this._ShareModal.startup();
// show modal
$("#myModal").modal('show');
domAttr.set(dom.byId("viewSubmissionsOption"), "href", this._viewSubmissions());
},
// error modal content
_openErrorModal: function (error) {
var errorMsgContainer;
domConstruct.empty(query(".modal-body")[0]);
domAttr.set(dom.byId('myModalLabel'), "innerHTML", nls.user.error);
errorMsgContainer = domConstruct.create("div", {}, query(".modal-body")[0]);
var errorMessage = (error && error.message) || nls.user.applyEditsFailedMessage;
if(error && error.code === "IdentityManagerBase.1"){
errorMessage = nls.user.applyEditsAuthError;
}
domConstruct.create("div", {
className: "alert alert-danger errorMessage",
innerHTML: errorMessage
}, errorMsgContainer);
$("#myModal").modal('show');
this._resetButton();
},
_openFileUploadStatusModal: function (fileList) {
var fileUploadStatusMsgContainer, fileUploadStatusMsgUl, fileUploadStatusMsgLi, fileUploadStatusMsgBadge;
domConstruct.empty(query(".modal-body")[0]);
if (dom.byId("viewSubmissionsOption")) {
domConstruct.destroy(query(".modal-footer")[0].children[1]);
}
domAttr.set(dom.byId('myModalLabel'), "innerHTML", nls.user.fileUploadStatus);
fileUploadStatusMsgContainer = domConstruct.create("div", {
"id": "fileUploadStatusMsgContainer"
}, query(".modal-body")[0]);
fileUploadStatusMsgUl = domConstruct.create("ul", {
"class": "list-group"
}, fileUploadStatusMsgContainer);
for (var i = 0; i < fileList.length; i++) {
fileUploadStatusMsgLi = domConstruct.create("li", {
"class": "message alert alert-info fileInputUI"
}, fileUploadStatusMsgUl);
fileUploadStatusMsgBadge = domConstruct.create("span", {
"class": "pull-right file-upload-status-badge glyphicon glyphicon-upload",
"innerHTML": nls.user.uploadingBadge,
"id": "badge" + i
}, fileUploadStatusMsgLi);
fileUploadStatusMsgBadge = domConstruct.create("span", {
"class": "pull-right hide attachment-error-message",
"innerHTML": nls.user.errorBadge
}, fileUploadStatusMsgLi);
fileUploadStatusMsgLi.innerHTML += fileList[i].value.split('\\').pop();
domAttr.set(dom.byId("badge" + i), "data-badge", fileList[i].id);
}
$('#myModal').on('hidden.bs.modal', lang.hitch(this, function () {
if (dom.byId("fileUploadStatusMsgContainer")) {
this._resetAndShare();
}
}));
$("#myModal").modal('show');
},
// share modal content
_createShareDlgContent: function () {
var iconContainer, group;
// empty modal node
domConstruct.empty(query(".modal-body")[0]);
if (dom.byId("viewSubmissionsOption")) {
domConstruct.destroy(query(".modal-footer")[0].children[1]);
}
// set modal title
domAttr.set(dom.byId('myModalLabel'), "innerHTML", nls.user.shareUserTitleMessage);
// create nodes for modal
iconContainer = domConstruct.create("div", {
className: "iconContainer"
}, query(".modal-body")[0]);
domConstruct.create("div", {
className: "alert alert-success",
role: "alert",
innerHTML: nls.user.entrySubmitted
}, iconContainer);
if (this.config.enableSharing) {
domConstruct.create("h3", {
innerHTML: nls.user.shareThisForm
}, iconContainer);
domConstruct.create("p", {
innerHTML: nls.user.shareUserTextMessage
}, iconContainer);
domConstruct.create("a", {
"tabindex": "0",
className: "fa fa-facebook-square iconClass text-primary",
id: "facebookIcon"
}, iconContainer);
domConstruct.create("a", {
"tabindex": "0",
className: "fa fa-twitter-square iconClass text-primary",
id: "twitterIcon"
}, iconContainer);
domConstruct.create("a", {
"tabindex": "0",
className: "fa fa-google-plus-square iconClass text-primary",
id: "google-plusIcon"
}, iconContainer);
}
domConstruct.create("a", {
"tabindex": "0",
className: "fa fa-envelope iconClass text-primary",
id: "mailIcon"
}, iconContainer);
domConstruct.create("div", {
className: "clearfix"
}, iconContainer);
domConstruct.create("h3", {
innerHTML: nls.user.shareModalFormText
}, iconContainer);
group = domConstruct.create("div", {
className: "input-group"
}, iconContainer);
domConstruct.create("span", {
className: "input-group-addon",
innerHTML: "<span class=\"glyphicon glyphicon-link\"></span>"
}, group);
domConstruct.create("input", {
type: "text",
className: "form-control",
id: "shareMapUrlText"
}, group);
domConstruct.create("a", {
className: "btn btn-default pull-left",
href: "#",
id: "viewSubmissionsOption",
innerHTML: this.config.viewSubmissionsText ? this.config.viewSubmissionsText : nls.user.btnViewSubmissions
}, query(".modal-footer")[0]);
if (this.config.disableViewer) {
domClass.add(dom.byId("viewSubmissionsOption"), "hidden");
}
},
// display error message
_showErrorMessageDiv: function (errorMessage, errorMessageNode) {
// clear node
var errorNode, place = "after";
if (errorMessageNode.id === "errorMessageDiv") {
place = "only";
}
if (errorMessageNode) {
this._removeErrorNode(errorMessageNode.nextSibling);
}
// create node
errorNode = domConstruct.create("div", {
className: "alert alert-danger errorMessage",
id: "errorMessage" + errorMessageNode.id,
innerHTML: errorMessage
}, null);
domConstruct.place(errorNode, errorMessageNode, place);
// resize map
this._resizeMap();
},
// reset submit button
_resetButton: function () {
var btn = $(dom.byId('submitButton'));
btn.button('reset');
},
// set defaults for layer
_setLayerDefaults: function () {
var error, flagPointFeatureLayer;
// if no layer id is set, try to use first feature layer
if (!this.config.form_layer || !this.config.form_layer.id) {
flagPointFeatureLayer = false;
array.some(this.config.itemInfo.itemData.operationalLayers, lang.hitch(this, function (currentLayer) {
if (currentLayer.layerType && currentLayer.layerType === "ArcGISFeatureLayer") {
if (currentLayer.resourceInfo.geometryType === 'esriGeometryPoint') {
flagPointFeatureLayer = true;
// if no object present
if (!this.config.form_layer) {
this.config.form_layer = {};
}
// set id
this.config.form_layer.id = currentLayer.id;
//Add the default fields in the fields object
//This case will work when application is running without app id
if(!this.config.fields.hasOwnProperty(this.config.form_layer.id)){
this.config.fields[this.config.form_layer.id] = this.map.getLayer(this.config.form_layer.id).fields;
}
return true;
} else {
flagPointFeatureLayer = false;
}
}
}));
if (!flagPointFeatureLayer) {
error = new Error(nls.user.invalidLayerMessage);
this.reportError(error);
}
}
// get editable layer
this._formLayer = this.map.getLayer(this.config.form_layer.id);
// if we have a layer
if (this._formLayer) {
// if fields not set or empty
var isFieldsEmpty = this._isFieldsEmpty(this.config.fields);
if (!this.config.fields || (this.config.fields && isFieldsEmpty)) {
array.some(this.config.itemInfo.itemData.operationalLayers, lang.hitch(this, function (operationalLayer, index) {
//condition to catch the right layer from webmap
if (operationalLayer.id === this._formLayer.id) {
//This loop runs through all the fields configured in the popup
array.forEach(this.config.itemInfo.itemData.operationalLayers[index].popupInfo.fieldInfos, lang.hitch(this, function (popupField) {
//This loop will run through all the fields in the formLayer and will break when the field matches with currently selected field of pop
array.some(this._formLayer.fields, lang.hitch(this, function (formLayerField) {
//condition to match the popup field with the formLayer field to mixin the properties of object.
if (formLayerField.name === popupField.fieldName) {
//condition to show a type field irrespective of it's configured edit property.
if (formLayerField.name === this._formLayer.typeIdField) {
popupField.isEditable = true;
}
formLayerField.alias = popupField.label;
formLayerField.editable = popupField.isEditable;
formLayerField.visible = popupField.isEditable;
formLayerField.tooltip = popupField.tooltip;
formLayerField.locked = popupField.locked;
this.config.fields[this._formLayer.id].push(formLayerField);
return true;
}
}));
}));
return true;
}
}));
}
if (this.config.showLayer) {
this._formLayer.setVisibility(true);
} else {
this._formLayer.setVisibility(false);
}
//This logic will convert the old array structure to equivalent object
if (this.config.fields.length) {
var fieldsArray = lang.clone(this.config.fields);
this.config.fields = {};
this.config.fields[this._formLayer.id] = fieldsArray;
}
} else {
if (this.config.form_layer.id !== "all") {
error = new Error(nls.user.invalidLayerMessage);
this.reportError(error);
return;
}
}
},
_isFieldsEmpty: function (object) {
for (var key in object) {
if (object[key]) {
return false;
}
return true;
}
},
// set defaults for app settings
_setWebmapDefaults: function () {
// if details not defined
if (!this.config.details) {
this.config.details = {};
}
// if no app title
if (!this.config.details.Title) {
if (this._appResponse && this._appResponse.item) {
// use app title
this.config.details.Title = this._appResponse.item.title;
}
// if item
if (this.config.itemInfo && this.config.itemInfo.item) {
// use webmap title
this.config.details.Title = this.config.itemInfo.item.title;
}
}
// if no app description
if (!this.config.details.Description) {
// if item
if (this.config.itemInfo && this.config.itemInfo.item) {
// use webmap snippet
this.config.details.Description = this.config.itemInfo.item.snippet;
}
}
// if no app logo
if (!this.config.details.Logo) {
// if item and thumb
if (this.config.itemInfo && this.config.itemInfo.item && this.config.itemInfo.item.thumbnail) {
// use webmap logo
this.config.details.Logo = this.config.sharinghost + "/sharing/rest/content/items/" + this.config.webmap + '/info/' + this.config.itemInfo.item.thumbnail;
}
}
},
// resize map
_resizeMap: function (force) {
if (this.map) {
this.map.reposition();
this.map.resize(force);
}
},
// set visible location options
_populateLocationsOptions: function () {
var count = 0,
total = 0,
locationTabs, tabContents;
locationTabs = query("#location_pills li");
tabContents = query("#location_tabs .tab-pane");
if (!this.config.locationSearchOptions) {
this.config.locationSearchOptions = {
"enableMyLocation": true,
"enableSearch": true,
"enableLatLng": true,
"enableUSNG": false,
"enableMGRS": false,
"enableUTM": false
};
}
for (var key in this.config.locationSearchOptions) {
if (this.config.locationSearchOptions.hasOwnProperty(key) && key !== "enableMyLocation") {
for(var i = 0; i < locationTabs.length; i++){
var tab = locationTabs[i];
var tabId = domAttr.get(tab, "data-tab-id");
if(tabId === key){
domStyle.set(tab, 'display', this.config.locationSearchOptions[key] ? "block" : "none");
}
on(tab, a11yclick, lang.hitch(this, this._resizeMap));
total++;
}
}
}
if (!this.config.locationSearchOptions.enableMyLocation) {
domStyle.set(dom.byId("geolocate_button"), 'display', 'none');
}
if (!this.config.locationSearchOptions.enableSearch) {
domStyle.set(dom.byId("search-widget"), 'display', 'none');
}
//add 'active' class to first tab and its content
array.some(locationTabs, lang.hitch(this, function (tab, idx) {
if (domStyle.get(tab, 'display') == 'block') {
domClass.add(tab, 'active');
domClass.add(tabContents[idx], 'active');
return true;
}
}));
if (total > 1) {
dom.byId("locationOptionDescriptor").innerHTML = nls.user.locationDescriptionForMoreThanOneOption;
} else {
// hide tab nav if zero or one tabs
var node = dom.byId('location_nav');
if (node) {
domStyle.set(node, 'display', 'none');
}
var panelNode = dom.byId('location_panel');
if (panelNode) {
domClass.remove(panelNode, 'panel panel-default');
}
var panelBodyNode = dom.byId('location_panel_body');
if (panelBodyNode) {
domClass.remove(panelBodyNode, 'panel-body');
}
if (total === 1) {
dom.byId("locationOptionDescriptor").innerHTML = nls.user.locationDescriptionForOneOption;
} else {
dom.byId("locationOptionDescriptor").innerHTML = nls.user.locationDescriptionForNoOption;
}
}
// resize map
this._resizeMap();
},
_addNotationIcon: function (formContent, imageIconClass) {
var inputIconGroupContainer, inputIconGroupAddOn;
inputIconGroupContainer = domConstruct.create("div", {
className: "input-group"
}, formContent);
inputIconGroupAddOn = domConstruct.create("span", {
className: "input-group-addon"
}, inputIconGroupContainer);
domConstruct.create("span", {
className: "glyphicon " + imageIconClass
}, inputIconGroupAddOn);
return inputIconGroupContainer;
},
_getFormElement: function (currentDom) {
var formElement = currentDom;
while (!domClass.contains(formElement, "geoFormQuestionare")) {
formElement = formElement.parentNode;
}
return formElement;
},
_createDateField: function (parentNode, isRangeField, fieldname, currentField, defaultValue) {
domClass.add(parentNode, "date");
var minDate, maxDate, defaultDate;
if (currentField && currentField.preventPast) {
minDate = new Date();
}
if (currentField && currentField.preventFuture) {
maxDate = new Date();
}
if (currentField && currentField.setCurrentDate) {
defaultDate = new Date();
}
else if (defaultValue) {
defaultDate = moment(defaultValue).format(this.dateFormat);
}
var dateInputField = domConstruct.create("input", {
disabled: !!currentField.locked,
type: "text",
value: "",
className: "form-control hasDatetimepicker",
"data-input-type": "Date",
"id": fieldname
}, parentNode);
on(dateInputField, "focus", function (e) {
$(this.parentElement).data("DateTimePicker").show(e);
});
on(dateInputField, "blur", function () {
$(this.parentElement).data("DateTimePicker").hide();
});
var dpOptions = {
useStrict: false,
locale: kernel.locale,
minDate: minDate,
maxDate: maxDate,
format: this.dateFormat,
defaultDate: defaultDate,
useCurrent: true
};
if (kernel.locale === "en" || kernel.locale === "en-us") {
dpOptions.extraFormats = ["M/D/YYYY", "M-D-YYYY", "M.D.YYYY", "M D YYYY"];
}
if (isRangeField && currentField.domain.minValue !== currentField.domain.maxValue && currentField.domain.minValue > -2147483648 && currentField.domain.maxValue > -2147483648) {
dpOptions.minDate = moment(currentField.domain.minValue);
dpOptions.maxDate = moment(currentField.domain.maxValue);
}
$(parentNode).datetimepicker(dpOptions).on('dp.show', function (evt) {
var picker = $(this).data('DateTimePicker');
var selectedDate = picker.date();
if (selectedDate === null) {
query("input", this)[0].value = "";
}
domClass.remove(query(evt.target).parents(".geoFormQuestionare")[0], "has-error");
domClass.add(query(evt.target).parents(".geoFormQuestionare")[0], "has-success");
if (query("input", this)[0].value === "") {
domClass.remove(query(evt.target).parents(".geoFormQuestionare")[0], "has-success");
}
}).on('dp.error', function (evt) {
evt.target.value = '';
domClass.remove(query(evt.target).parents(".geoFormQuestionare")[0], "has-success");
domClass.add(query(evt.target).parents(".geoFormQuestionare")[0], "has-error");
$(this).data("DateTimePicker").hide();
}).on("dp.hide", function (evt) {
if (query("input", this)[0].value === "") {
domClass.remove(query(evt.target).parents(".geoFormQuestionare")[0], "has-success");
domClass.remove(query(evt.target).parents(".geoFormQuestionare")[0], "has-error");
}
}).on('dp.change', function (evt) {
domClass.add(query(evt.target).parents(".geoFormQuestionare")[0], "has-success");
domClass.remove(query(evt.target).parents(".geoFormQuestionare")[0], "has-error");
});
return dateInputField;
},
_verifyHumanEntry: function () {
this.isHumanEntry = false;
setTimeout(lang.hitch(this, function () {
this.isHumanEntry = true;
}), 2000);
},
//This function will remove the error message div.
_removeErrorNode: function (node) {
if (domClass.contains(node, "errorMessage")) {
domConstruct.destroy(node);
}
}
}); }); `
Hello,
Is this to store address into attribute from search location map? Please kindly confirm. Thank you for your assistance.
Alex
So I'm using the GeoForm to allow our permitting department to INSTANTLY create new Addresses in order to assign Permits when an address isn't in our Site Address Points "Address GeoDatabase."
What this means is that I would LOVE to avoid user-input-errors by avoid duplicate entries.
We currently need users to input the following fields.
ADDRNUM (such as 175 in 175 E 2ND ST S) PREADDRNUM (such as E in 175 E 2ND ST S) STREETNAME (such as 2ND in 175 E 2ND ST S) STREETTYPE (such as ST in 175 E 2ND ST S) ADDRNUMSUF (such as S in 175 E 2ND ST S) FULLNAME (such as E 2ND ST S in 175 E 2ND ST S) FULLADDR (such as 175 E 2ND ST S in 175 E 2ND ST S)
So I'm hoping / wondering... Is there anyway to concantenate the FULLNAME and FULLADDR field based on the entries in the other fields?