///////////////////////////////////////////////////////////////////////////
// Copyright © 2014 - 2018 Esri. All Rights Reserved.
//
// Licensed under the Apache License Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
///////////////////////////////////////////////////////////////////////////
define([
'dojo/aspect',
'dojo/Deferred',
'dojo/_base/lang',
'dojo/_base/html',
'dojo/_base/array',
'dojo/on',
'dojo/_base/declare',
'./ValueProvider',
'dijit/_TemplatedMixin',
'dijit/_WidgetsInTemplateMixin',
'dojo/text!./ListValueProvider.html',
'dojo/store/Memory',
'jimu/utils',
'dijit/form/FilteringSelect'
],
function(aspect, Deferred, lang, html, array, on, declare, ValueProvider, _TemplatedMixin, _WidgetsInTemplateMixin,
template, Memory, jimuUtils) {
return declare([ValueProvider, _TemplatedMixin, _WidgetsInTemplateMixin], {
templateString: template,
codedValues: null,//[{value,label}] for coded values and sub types
staticValues: null,//[{value,label}]
showNullValues: false,//show null values
layerDataChanged: false, //layer data update status
ifDropDown: false,
postCreate: function(){
this.inherited(arguments);
html.addClass(this.domNode, 'jimu-filter-list-value-provider');
this._uniqueValueCache = {};
this.noDataTips = '
' +
'' +
'' + this.nls.noFilterValueTip + '
';
//[{id,value,label}]
var store = new Memory({idProperty:'id', data: []});
this.valuesSelect.set('store', store);
//is numberical field
this.isNumberField = jimuUtils.isNumberField(this.fieldInfo.type);
if(!this.staticValues && typeof this.valuesSelect._onDropDownMouseDown === 'function'){
if(!this.codedValues || (this.codedValues && this.filterCodedValue)){
this.own(
aspect.before(this.valuesSelect,
"_onDropDownMouseDown",
lang.hitch(this, this._onBeforeDropDownMouseDown))
);
this.own(on(document.body, 'click', lang.hitch(this, this._onBodyClick)));
if(this.layerInfo){ //it always exsits because it's required from valueProviderFactory constructor
//it will tragger after the add/remove/update events happen
this.layerInfo.getLayerObject().then(lang.hitch(this, function(layerObject){
layerObject.on("edits-complete", lang.hitch(this, function() {
this.layerDataChanged = true;
}));
}));
}
}
}
},
_onFilteringSelectInput: function(){
this.emit('change');
},
_getCodedValueLabelsBySubTypeId:function(){
// var newExpr = this.getDropdownFilterExpr();
// return jimuUtils.getCodedValueLabelsByExprs(this.layerDefinition, this.fieldName, newExpr, this.codedValues);
var newParj = this.getDropdownFilterPartsObj();
return this.getCodedValueListByPartsObj(this.layerDefinition, this.fieldName, newParj, this.codedValues);
},
_onBeforeDropDownMouseDown: function(){
this.ifDropDown = true;
this._tryUpdatingUniqueValues(undefined, true);
return arguments;
},
_onBodyClick: function(evt){
var target = evt.target || evt.srcElement;
if(target === this.domNode || html.isDescendant(target, this.domNode)){
return;
}
if(this.msgDiv){
html.setStyle(this.msgDiv, "display", "none");
}
},
getDijits: function(){
return [this.valuesSelect];
},
isValidValue: function(){
return this.getStatus() > 0;
},
//-1 means invalid value type
//0 means empty value, this ValueProvider should be ignored
//1 means valid value
getStatus: function(){
var item = this.valuesSelect.get('item');
if(item){
if(item.value !== undefined){ //if(item.label !== ''){
if(this.isNumberField && !jimuUtils.isValidNumber(item.value)){
var newVal = parseFloat(item.value);
if(jimuUtils.isValidNumber(newVal)){
item.value = newVal;
return this._getStatusForDijit(this.valuesSelect);
}
return -1;
}
return this._getStatusForDijit(this.valuesSelect);
}else{
return 0;
}
}else{
return 0;
}
},
//return -1 means input a wrong value
//return 0 means empty value
//return 1 means valid value
_getStatusForDijit: function(dijit){
if(dijit.validate()){
if(dijit.get("DisplayedValue")){
return 1;
}else{
return 0;
}
}else{
return -1;
}
},
//maybe return a deferred
setValueObject: function(valueObj){
if(this.staticValues){
return this._setValueForStaticValues(valueObj.value, this.staticValues);
} else if(this.codedValues){
if(this.filterCodedValue){
return this._tryUpdatingUniqueValues(valueObj.value, false);
}else{
return this._setValueForStaticValues(valueObj.value, this.codedValues);
}
} else{
return this._tryUpdatingUniqueValues(valueObj.value, false);
}
},
getValueObject: function(){
if(this.isValidValue()){
var item = this.valuesSelect.get('item');
var value = item.value;
return {
"isValid": true,
"type": this.partObj.valueObj.type,
"value": value
};
}
return null;
},
tryGetValueObject: function(){
if(this.isValidValue()){
return this.getValueObject();
}else if(this.isEmptyValue()){
return {
"isValid": true,
"type": this.partObj.valueObj.type,
"value": this.shortType === 'string' ? "" : null
};
}
return null;
},
setRequired: function(required){
this.valuesSelect.set("required", required);
},
/*disable: function(){
this.inherited(arguments);
this.valuesSelect.closeDropDown(true);
this.valuesSelect.set('disabled', true);
},
enable: function(){
this.inherited(arguments);
this.valuesSelect.set('disabled', false);
},*/
_setValueForStaticValues: function(selectedValue, valueLabels){
//selectedValue maybe undefined or null
var data = null;
var selectedId = -1;
var selectedItem = null;
if(valueLabels){
data = array.map(valueLabels, lang.hitch(this, function(item, index){
var dataItem = {
id: index,
value: item.value,
label: item.label
};
if(dataItem.value + '' === selectedValue + ''){
selectedId = index;
}
return dataItem;
}));
this.valuesSelect.store.setData(data);
if(selectedId >= 0){
selectedItem = this.valuesSelect.store.get(selectedId);
if(selectedItem){
this.valuesSelect.set('item', selectedItem);
}
}
this._checkIfNoData();
}
},
_uniqueValueLoadingDef: null,
_uniqueValueLoadingExpr: '',
_uniqueValueCache: null,//{expr1:values1,expr2:values2}
_tryUpdatingUniqueValues: function(selectedValue, showDropDownAfterValueUpdate){
var def = new Deferred();
if(!this.valuesSelect._opened){
var newExpr = this.getDropdownFilterExpr();
if(newExpr !== this._uniqueValueLoadingExpr || this.layerDataChanged){
//expr changed
this.valuesSelect.readOnly = true;
if(this._uniqueValueLoadingDef){
this._uniqueValueLoadingDef.reject();
this._uniqueValueLoadingDef = null;
}
this._uniqueValueLoadingExpr = newExpr;
this._uniqueValueLoadingDef = this._getUniqueValues(newExpr);
this._uniqueValueLoadingDef.then(lang.hitch(this, function(valueLabels){
if(!this.domNode){
return;
}
this._uniqueValueLoadingDef = null;
this.valuesSelect.readOnly = false;
this._setValueForUniqueValues(selectedValue, valueLabels);
this._hideLoadingIcon();
if(showDropDownAfterValueUpdate){
this.valuesSelect.toggleDropDown();
}
this._checkIfNoData();
def.resolve();
}), lang.hitch(this, function(err){
console.error(err);
if(!this.domNode){
return;
}
this._uniqueValueLoadingDef = null;
this.valuesSelect.readOnly = false;
this._hideLoadingIcon();
this._checkIfNoData();
def.reject(err);
}));
}else{
this._checkIfNoData();
def.resolve();
}
}else{
this._checkIfNoData();
def.resolve();
}
return def;
},
//return a deferred
_setValueForUniqueValues: function(selectedValue, valueLabels){
valueLabels.sort(function(item1, item2){
if(item1.value < item2.value){
return -1;
}else if(item1.value === item2.value){
return 0;
}else{
return 1;
}
});
//selectedValue maybe undefined or null
if(!this.showNullValues){
valueLabels = array.filter(valueLabels, lang.hitch(this, function(item){
return item.value !== '' && item.value !== null;
}));
}
if(selectedValue === undefined){
var currentValueObj = this.getValueObject();
if(currentValueObj){
selectedValue = currentValueObj.value;
}
}
var selectedId = -1;
var selectedItem = null;
var data = array.map(valueLabels, lang.hitch(this, function(item, index) {
var dataItem = {
id: index,
value: item.value,
label: item.label
};
if (item.value + '' === selectedValue + '') {
selectedId = index;
}
return dataItem;
}));
this.valuesSelect.store.setData(data);
if (selectedId >= 0) {
selectedItem = this.valuesSelect.store.get(selectedId);
}
//selectedItem maybe null
//we need to set item to null to clear the previous invlaid value
this.valuesSelect.set('item', selectedItem);
},
_checkIfNoData: function(){
if(this.runtime && this.ifDropDown){
this.ifDropDown = false;
var dataList = this.valuesSelect.store.data;
if (dataList.length === 0) {
if(!this.msgDiv){
this.msgDiv = document.createElement('div');
html.addClass(this.msgDiv, "jimu-filter-list-value-provider-tip-container");
this.msgDiv.innerHTML = this.noDataTips;
this.valuesSelect.domNode.parentNode.appendChild(this.msgDiv);
}else{
html.setStyle(this.msgDiv, "display", "block");
}
}
}
},
_showLoadingIcon: function(){
html.addClass(this.valuesSelect.domNode, 'loading');
},
_hideLoadingIcon: function(){
html.removeClass(this.valuesSelect.domNode, 'loading');
},
_getUniqueValues: function(where){
var def = new Deferred();
if(this._uniqueValueCache[where] && !this.layerDataChanged){
def.resolve(this._uniqueValueCache[where]);
}else{
this._showLoadingIcon();
jimuUtils.getUniqueValues(this.url, this.fieldName, where, this.layerDefinition, this.fieldPopupInfo)
.then(lang.hitch(this, function(valueLabels){
if(!this.domNode){
return;
}
this._uniqueValueCache[where] = valueLabels;
def.resolve(valueLabels);
this._hideLoadingIcon();
}), lang.hitch(this, function(err){
if(!this.domNode){
return;
}
def.reject(err);
this._hideLoadingIcon();
}));
}
this.layerDataChanged = false;//reset default value
return def;
}
});
});