POST
|
Apparently the Internal Server did NOT have the MIME type JSON. Now it does. Problem solved.
... View more
07-24-2018
10:49 AM
|
0
|
0
|
98
|
POST
|
Another interesting note... I have placed a PNG file in the DIST folder. If I enter a direct URL to that server and that file then it loads. But... if I enter a direct URL to that server and the application or boilerplate JSON files, I still get a 404.
... View more
07-24-2018
06:52 AM
|
0
|
0
|
98
|
POST
|
I've begun deployment of the Minimal Map Gallery application. I took a test map I was using that I had shared with NO ONE and added it to a TEST group I created for this Gallery specifically. I uploaded the code for the Gallery. I try to access it through the (extremely awkward and what were they thinking) URL requirement... http://myserver/application-name/dist But I get 404 errors... Nothing loads. So I adjust the JSON... "agolLinkLocation": " https://mygroup.maps.arcgis.com/home/group.html?=$ {GROUP_ID}", ... "group": "my group id", ... "portalUrl": " https://mygroup.maps.arcgis.com ", ... "proxyUrl": " http://our.url.to/proxy ", ... Still nothing... I am wondering if there is any special steps that maybe are missing from the Github page or whatever? But I've done everything I would normally do to prop up a web app from ESRI and nothing will display?
... View more
07-24-2018
06:23 AM
|
1
|
2
|
234
|
POST
|
I have spent a good couple of hours trying to figure out why I can't get these labels to rotate on a web map. I thought I had done this before. I've set the labels on the MXD to rotate based on an ANGLE field in the point feature class. But nothing I do on the AGOL side shows those rotated labels. I can create an AGOL layer from the MapServer version, the FeatureServer version, I can adjust everything I know how to adjust and nothing makes those labels display rotated. Are point feature labels unable to be rotated on an AGOL Web Map?
... View more
06-26-2018
11:49 AM
|
1
|
2
|
245
|
POST
|
How difficult would it be to edit the LayerList widget to allow re-organization of layers (including remove from groups, create new groups, etc)? I was gearing up to start research for development of a means to manage Groupings and Organization of layers on maps. We have several departments that constantly require our GIS group to edit MXD's to change layer groupings and organization. Which ends up in re-configuring hundreds of layers in other widgets. Very frustrating. So as I started my initial foray into researching what would be required I was looking at the Layer List configuration screen and wondered whether it would be worth it to just edit it to allow moving layers around, creating (and removing) groupings, from within the Layer List Configuration screen itself? Any thoughts from those with more experience?
... View more
06-06-2018
08:46 AM
|
0
|
1
|
203
|
POST
|
So I've finally been given some time to begin learning my way around Dojo and the ArcGIS API as I was forced to customize the GeoForm to allow contcatenation and required fields involved in said concatenation. Now that my appetite is whetted I'm ready to start digging in and I have been. One of the ways was jumping onboard the Dojo group on Facebook and walking through multiple tutorials online. During this process I was both introduced to the RC-2 for Dojo2 and now apparently Dojo2 is officially live. https://dojo.io/ And it appears to be amazing. So now the question is... do I continue learning Dojo 1... or go ahead and jump in to Dojo 2?
... View more
05-03-2018
08:01 AM
|
0
|
1
|
280
|
POST
|
I customized the MAIN.JS and DEFAULT.JS files to allow for concatenated fields. I think I am going to try to use this experience to start work on an ATTRIBUTE ASSISTANT widget. We shall see...
... View more
04-24-2018
02:06 PM
|
0
|
1
|
222
|
POST
|
Here is the customized MAIN.js file. Make sure you use the new JSON from my default.js as well. /*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 ?:\/\/){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 ) ; |