I have a Fiscal Year Start field in a Feature Class which is shared as a Feature Service in a Web Map > Web Mapping Application (built with Web AppBuilder) workflow. The field must only contain 4-digit years, therefore, I cannot set the field to data type 'Date'. Instead, the field uses a Short Int data type with precision 5 (I set the precision to 4 but ArcGIS automatically changes it back to 5). Here are the field properties:
Now, I can go into the config attribute settings in my Web Map and turn off the 1000 separator option. This works for displaying the years correctly in the Web Map. However, this does not carry over to the Web Mapping Application. When I use the Filter widget in the Web Mapping Application, the 1000 separator returns.
I initially tried to get around this problem by using a Text field for year input, but that option does not work for this workflow due to the presence of a GeoForm - the GeoForm is where data is entered for the project. The reason a text field does not work is because the GeoForm Fiscal Year Start field must throw an error if a non-4-digit-integer is entered, i.e., FY17, or 17.
Essentially then, my question is this - is there a better solution for representing a year in a geodatabase? This ideal solution would do the following:
Thanks in advance.
(By the way, is there a way to change the Error Message of 'Please enter a valid integer between -32768 and 32767.'? I'd much rather it said what the help text says, e.g., 'Enter a fiscal year as the four-digit year...'.)
Solved! Go to Solution.
Jason,
The fact that the filter widget does not respect the format in the web map is a bug in my opinion but will likely be viewed by esri as an enhancement request. I would call this into esri tech support. But in the mean time you can make this modification to WAB Dev edition to force the no 1000 separator in the filter and query widgets:
In the jimu.js\dijit\_SingleFilterParameter.js make this change to the _buildNumber function (Lines 81-85):
_buildNumber: function(fieldInfo, part){
/*jshint unused: false*/
var def = new Deferred();
html.setStyle(this.stringTextBoxContainer, 'display', 'none');
html.setStyle(this.numberTextBoxContainer, 'display', 'block');
html.setStyle(this.dateTextBoxContainer, 'display', 'none');
this._hideDijit(this.numberTextBox);
this._hideDijit(this.numberCodedValuesFS);
html.setStyle(this.numberRangeTable, 'display', 'none');
this._hideDijit(this.numberUniqueValuesSelect);
var fieldObj = part.fieldObj;//name,shortType
var valueObj = part.valueObj;//value,value1,value2
var radioType = valueObj.type;//'value' or 'unique',not 'field'
var operator = part.operator;
var isNumBetween = operator === this.OPERATORS.numberOperatorIsBetween;
var isNumNotBetween = operator === this.OPERATORS.numberOperatorIsNotBetween;
var isRange = isNumBetween || isNumNotBetween;
if(isRange){
this._type = 3;
html.setStyle(this.numberRangeTable, 'display', 'table');
if(jimuUtils.isValidNumber(valueObj.value1)){
this.numberTextBox1.set('value', valueObj.value1);
}
if(jimuUtils.isValidNumber(valueObj.value2)){
this.numberTextBox2.set('value', valueObj.value2);
}
def.resolve();
}
else{
html.setStyle(this.numberRangeTable, 'display', 'none');
var codedValues = this._getCodedValues(fieldInfo);
if(codedValues){
this._type = 2;
this._showDijit(this.numberCodedValuesFS);
var numberCodedData = array.map(codedValues, lang.hitch(this, function(item, index){
//item:{name,code},name is the code description and code is code value.
var dataItem = lang.clone(item);
dataItem.id = index;
return dataItem;
}));
var numberCodedStore = new Memory({data:numberCodedData});
this.numberCodedValuesFS.set('store', numberCodedStore);
if(valueObj && jimuUtils.isValidNumber(valueObj.value)){
var number = parseFloat(valueObj.value);
var numberSelectedItems = array.filter(numberCodedData,
lang.hitch(this, function(item){
return parseFloat(item.code) === number;
}));
if(numberSelectedItems.length > 0){
this.numberCodedValuesFS.set('value', numberSelectedItems[0].id);
}
else{
this.numberCodedValuesFS.set('value', numberCodedData[0].id);
}
}
else{
this.numberCodedValuesFS.set('value', numberCodedData[0].id);
}
def.resolve();
}
else{
if(radioType === 'unique'){
this._type = 4;
this._showDijit(this.numberUniqueValuesSelect);
jimuUtils.getUniqueValues(this.url, fieldObj.name).then(
lang.hitch(this, function(values){
var selectedId = -1;
//don't select the first value by default, issue #2477
/*if(values.length > 0){
selectedId = 0;
}*/
var data = array.map(values, lang.hitch(this, function(value, index){
var label = value;
if(fieldObj.shortType === 'number'){
value = parseFloat(value);
if(fieldObj.name === "FY_Start" || fieldObj.name === "FY_End"){
label = value;
}else{
label = this._tryLocaleNumber(value);
}
}
Jason,
The fact that the filter widget does not respect the format in the web map is a bug in my opinion but will likely be viewed by esri as an enhancement request. I would call this into esri tech support. But in the mean time you can make this modification to WAB Dev edition to force the no 1000 separator in the filter and query widgets:
In the jimu.js\dijit\_SingleFilterParameter.js make this change to the _buildNumber function (Lines 81-85):
_buildNumber: function(fieldInfo, part){
/*jshint unused: false*/
var def = new Deferred();
html.setStyle(this.stringTextBoxContainer, 'display', 'none');
html.setStyle(this.numberTextBoxContainer, 'display', 'block');
html.setStyle(this.dateTextBoxContainer, 'display', 'none');
this._hideDijit(this.numberTextBox);
this._hideDijit(this.numberCodedValuesFS);
html.setStyle(this.numberRangeTable, 'display', 'none');
this._hideDijit(this.numberUniqueValuesSelect);
var fieldObj = part.fieldObj;//name,shortType
var valueObj = part.valueObj;//value,value1,value2
var radioType = valueObj.type;//'value' or 'unique',not 'field'
var operator = part.operator;
var isNumBetween = operator === this.OPERATORS.numberOperatorIsBetween;
var isNumNotBetween = operator === this.OPERATORS.numberOperatorIsNotBetween;
var isRange = isNumBetween || isNumNotBetween;
if(isRange){
this._type = 3;
html.setStyle(this.numberRangeTable, 'display', 'table');
if(jimuUtils.isValidNumber(valueObj.value1)){
this.numberTextBox1.set('value', valueObj.value1);
}
if(jimuUtils.isValidNumber(valueObj.value2)){
this.numberTextBox2.set('value', valueObj.value2);
}
def.resolve();
}
else{
html.setStyle(this.numberRangeTable, 'display', 'none');
var codedValues = this._getCodedValues(fieldInfo);
if(codedValues){
this._type = 2;
this._showDijit(this.numberCodedValuesFS);
var numberCodedData = array.map(codedValues, lang.hitch(this, function(item, index){
//item:{name,code},name is the code description and code is code value.
var dataItem = lang.clone(item);
dataItem.id = index;
return dataItem;
}));
var numberCodedStore = new Memory({data:numberCodedData});
this.numberCodedValuesFS.set('store', numberCodedStore);
if(valueObj && jimuUtils.isValidNumber(valueObj.value)){
var number = parseFloat(valueObj.value);
var numberSelectedItems = array.filter(numberCodedData,
lang.hitch(this, function(item){
return parseFloat(item.code) === number;
}));
if(numberSelectedItems.length > 0){
this.numberCodedValuesFS.set('value', numberSelectedItems[0].id);
}
else{
this.numberCodedValuesFS.set('value', numberCodedData[0].id);
}
}
else{
this.numberCodedValuesFS.set('value', numberCodedData[0].id);
}
def.resolve();
}
else{
if(radioType === 'unique'){
this._type = 4;
this._showDijit(this.numberUniqueValuesSelect);
jimuUtils.getUniqueValues(this.url, fieldObj.name).then(
lang.hitch(this, function(values){
var selectedId = -1;
//don't select the first value by default, issue #2477
/*if(values.length > 0){
selectedId = 0;
}*/
var data = array.map(values, lang.hitch(this, function(value, index){
var label = value;
if(fieldObj.shortType === 'number'){
value = parseFloat(value);
if(fieldObj.name === "FY_Start" || fieldObj.name === "FY_End"){
label = value;
}else{
label = this._tryLocaleNumber(value);
}
}
Don't forget to mark this question as answered by clicking on the "Correct Answer" link on the reply that answered your question.