///////////////////////////////////////////////////////////////////////////
|
// 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/Deferred',
|
'esri/tasks/query',
|
'dojo/_base/array',
|
'dojo/_base/lang',
|
'dojo/_base/declare',
|
'jimu/Query',
|
'jimu/LayerStructure',
|
'dijit/_WidgetBase',
|
'dijit/_TemplatedMixin',
|
'dijit/_WidgetsInTemplateMixin',
|
'dojo/text!./pageControlForQuery.html',
|
'jimu/utils'
|
],
|
function(Deferred, EsriQuery, array,
|
lang, declare, JimuQuery, LayerStructure, _WidgetBase,
|
_TemplatedMixin, _WidgetsInTemplateMixin, template, jimuUtils){
|
|
return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
|
templateString: template,
|
|
layerUrl: null,
|
fieldInfo: null,
|
fieldPopupInfo: null,
|
spatialReference: null,
|
layerDefinition: null,
|
isNumberField: false,
|
showNullValues: false,
|
|
_isUniqueValueCacheFinish: false,
|
_uniqueValueCache: {},
|
_uniqueValueCacheForOtherTypes: {}, //cache for searchKey & types = 2 or 3
|
_codedvalueCache: [],
|
|
cascadeFilterExprs: '1=1',
|
|
numbericFieldLength: {
|
'esriFieldTypeOID': 32,
|
'esriFieldTypeSmallInteger': 16,
|
'esriFieldTypeInteger': 32,
|
'esriFieldTypeSingle': 128,
|
'esriFieldTypeDouble': 1024
|
},
|
pageIndex: 1, //current page
|
pageSize: 1000, //optional, feature count per page
|
postCreate: function(){
|
this.inherited(arguments);
|
this.spatialReference = LayerStructure.getInstance().map.spatialReference;
|
this.reset();
|
this.queryType = JimuQuery.getQueryType(this.layerDefinition);
|
if(this.isNumberField){
|
this.fieldLength = this.numbericFieldLength[this.fieldInfo.type];
|
}
|
},
|
|
reset:function(){
|
this.pageIndex = 1;
|
this._isUniqueValueCacheFinish = false;
|
this._uniqueValueCache = {};
|
this._uniqueValueCacheForOtherTypes = {};
|
this._codedvalueCache = [];
|
},
|
|
isKeyQueryLoader: false,
|
_searchKey: function(name){
|
var def = new Deferred();
|
var query = new EsriQuery();
|
//"%123%" works for string field and number field
|
var keyWhere = '';
|
if(this.isNumberField){ // CAST(objectid AS CHAR(32)) LIKE '%1%'
|
keyWhere = "CAST(" + this.fieldInfo.name + " AS CHAR(" + this.fieldLength + ")) LIKE '%" + name + "%'";
|
}else{
|
keyWhere = this.fieldInfo.name + " LIKE '%" + name + "%'";
|
}
|
query.where = '((' + this.cascadeFilterExprs + ') AND (' + keyWhere + '))';
|
|
query.geometry = null;
|
query.outSpatialReference = this.spatialReference;
|
query.outFields = [this.fieldInfo.name];
|
query.returnDistinctValues = true;
|
query.returnGeometry = false;
|
query.orderByFields = query.outFields;//for order
|
|
this.layerLoaderForKey = new JimuQuery({
|
url: this.layerUrl,
|
query: query,
|
pageSize: this.pageSize
|
});
|
|
this.isKeyQueryLoader = true;
|
this._uniqueValueCacheForOtherTypes = {};
|
this.queryByPage(true).then(lang.hitch(this, function(valueLabels){
|
def.resolve(valueLabels);
|
}), lang.hitch(this, function(err){
|
def.reject('reject:' + err);
|
}));
|
return def;
|
},
|
|
_searchKeyLocal: function(name){
|
name = name.toUpperCase();
|
this.isKeyQueryLoader = false;
|
var valueLabels = [];
|
var cacheData = this._codedvalueCache;
|
var item;
|
if(cacheData.length > 0){ //coded value
|
for (var key1 = 0; key1 < cacheData.length; key1++){
|
item = cacheData[key1];
|
if(item.label && item.label.toString().toUpperCase().indexOf(name) >= 0){
|
valueLabels.push(item);
|
}
|
}
|
}else{
|
cacheData = this._uniqueValueCache;
|
// var enName = this.isNumberField ? name.replace(',', '.') : name;
|
for (var key2 in cacheData){
|
var items = cacheData[key2];
|
for (var index = 0; index < items.length; index++){
|
item = items[index];
|
var mathStr = item.label;
|
if(mathStr && mathStr.toString().toUpperCase().indexOf(name) >= 0){
|
valueLabels.push(item);
|
}
|
//match value as well if it's a number.
|
// if(this.isNumberField){
|
// var mathStrNew = item.value.toString();
|
// if(mathStrNew && mathStrNew.toString().indexOf(enName) >= 0){
|
// valueLabels.push(item);
|
// }
|
// }
|
}
|
}
|
}
|
return valueLabels;
|
},
|
|
queryByPage: function(ifFristPage){
|
var def = new Deferred();
|
|
//jimuQuery will remember the totalcount after first query,
|
//so need new a query to get count for new exprs
|
if(this.layerLoader && (this.layerLoader.query.where !== this.cascadeFilterExprs)){
|
this.layerLoader = null;
|
this.isKeyQueryLoader = false;
|
this.reset();//need to test
|
}
|
|
if(!this.layerLoader){
|
var query = new EsriQuery();
|
query.where = this.cascadeFilterExprs;
|
query.geometry = null;
|
// query.outSpatialReference = this.map.spatialReference;
|
query.outSpatialReference = this.spatialReference;
|
//outFields&returnDistinctValues can work only when returnGeometry is false
|
query.outFields = [this.fieldInfo.name];
|
query.returnDistinctValues = true;
|
query.returnGeometry = false;
|
query.orderByFields = query.outFields;//for order
|
|
this.layerLoader = new JimuQuery({
|
url: this.layerUrl,
|
query: query,
|
pageSize: this.pageSize
|
});
|
}
|
|
if(ifFristPage){ //init pageindex
|
this.pageIndex = 1;
|
}
|
|
var cacheValueLabels = [], loader;
|
if(this.isKeyQueryLoader){
|
if(this._uniqueValueCacheForOtherTypes[this.pageIndex]){
|
cacheValueLabels = this._resolveValueLabelsFromCache(this._uniqueValueCacheForOtherTypes);
|
def.resolve(cacheValueLabels);
|
return def;
|
}else{
|
loader = this.layerLoaderForKey;
|
}
|
}else{
|
if(this._uniqueValueCache[this.pageIndex]){
|
cacheValueLabels = this._resolveValueLabelsFromCache(this._uniqueValueCache);
|
def.resolve(cacheValueLabels);
|
return def;
|
}else{
|
loader = this.layerLoader;
|
}
|
}
|
|
if(this.queryType === 1){
|
loader.queryByPage(this.pageIndex).then(lang.hitch(this, function(response){
|
if(response){
|
var features = response.features || [];
|
|
var featuresLength = features.length; //for calc cache
|
if(!this.showNullValues){ //remove null data
|
features = this._getNotNullValues(features);
|
}
|
|
var valueLabels = this._getValueLabelsFromFeatures(features);
|
|
if(!this.isKeyQueryLoader){ //only cache the data list which has no conditions
|
this._uniqueValueCache[this.pageIndex - 1] = valueLabels;
|
if(featuresLength < this.pageSize){
|
this._uniqueValueCache[this.pageIndex] = [];
|
this._isUniqueValueCacheFinish = true;
|
}
|
}else{
|
this._uniqueValueCacheForOtherTypes[this.pageIndex - 1] = valueLabels;
|
if(featuresLength < this.pageSize){
|
this._uniqueValueCacheForOtherTypes[this.pageIndex] = [];
|
}
|
}
|
if(valueLabels.length === 0){
|
this.pageIndex --;
|
}
|
def.resolve(valueLabels);
|
}else{
|
def.reject("Can't get features from current layer");
|
}
|
}), lang.hitch(this, function(err){
|
def.reject(err);
|
}));
|
} else{ //get all features
|
loader.getAllFeatures().then(lang.hitch(this, function(response){
|
if(response){
|
var features = response.features || [];
|
if(!this.showNullValues){
|
features = this._getNotNullValues(features);
|
}
|
var isReturnValueLabels = features.length > 0 ? true : false;
|
|
features = this._getDistinctValues(features);
|
var valueLabels = this._getValueLabelsFromFeatures(features);
|
if(this.isKeyQueryLoader){
|
valueLabels = this._getAndStoreValueLabelsForOtherTypes(valueLabels,
|
this._uniqueValueCacheForOtherTypes);
|
}else{ //only cache the data list which has no conditions
|
valueLabels = this._getAndStoreValueLabelsForOtherTypes(valueLabels,
|
this._uniqueValueCache);
|
}
|
this._isUniqueValueCacheFinish = true;
|
|
var reValueLabels = isReturnValueLabels ? valueLabels : [];
|
def.resolve(reValueLabels);
|
}else{
|
def.reject("Can't get features from current layer");
|
}
|
}), lang.hitch(this, function(err){
|
def.reject(err);
|
}));
|
}
|
this.pageIndex ++;
|
return def;
|
},
|
|
_resolveValueLabelsFromCache: function(cacheValueLabels){
|
var valueLabels = cacheValueLabels[this.pageIndex];
|
if(valueLabels.length !== 0){
|
this.pageIndex++;
|
}
|
return valueLabels;
|
},
|
|
_getAndStoreValueLabelsForOtherTypes: function(valueLabels, cacheValueLabels){
|
for (var key = 0; key < valueLabels.length; key = key + this.pageSize){
|
cacheValueLabels[parseInt(key / this.pageSize, 10) + 1] = valueLabels.slice(key, key + this.pageSize);
|
}
|
for (var k in cacheValueLabels){
|
var next = parseInt(k, 10) + 1;
|
if(!cacheValueLabels[next]){
|
cacheValueLabels[next] = [];
|
}
|
}
|
return cacheValueLabels[1];//return the data of first page
|
},
|
|
_getDistinctValues: function(features){
|
var hash = {};
|
var distinctFeatures = [];
|
for(var key in features){
|
var feature = features[key];
|
var featureVal = feature.attributes[this.fieldInfo.name];
|
if(!hash[featureVal]){
|
hash[featureVal] = true;//value = featureVal will cause bug, when value=0
|
distinctFeatures.push(feature);
|
}
|
}
|
return distinctFeatures;
|
},
|
|
//value could be undefined or null or '',now only delete null values
|
_getNotNullValues: function(features){
|
features = array.filter(features, lang.hitch(this, function(feature){
|
var featureVal = feature.attributes[this.fieldInfo.name];
|
return featureVal !== '<Null>' && featureVal !== null;
|
}));
|
return features;
|
},
|
|
//get dataList with valueLabel's format include codedvalue
|
//could partially solve decimal point.#13334
|
_getValueLabelsFromFeatures: function(featureList){
|
var fieldName = this.fieldInfo.name;
|
var values = array.map(featureList, function(feature){
|
return feature.attributes[fieldName];
|
});
|
var valueLabels = jimuUtils._getValues(this.layerDefinition, this.fieldPopupInfo, fieldName, values);
|
return valueLabels;
|
}
|
|
});
|
});
|