Robert Scheitlin, GISP got it all figured out, it was a matter of using symbology from config. The other glitch I presume was a misfigured expression. It works perfectly now, awesome!!
There is some miscommunication going on here. The drop down I am referencing is the one with the label "Get features in the layer that match [drop down here] of this and the preceding expression criteria".
As always you're putting out fantastic content, so first of all thank you very much for all the hard work that you do.
My question is about domains and how they populate for end users.
I'm currently using the "Value" option in an expression to create a drop down menu for the end user (which comes from the domain of the feature class). This part works perfect, but always uses the first value in the domain as the default value. Is there any way to make this default to a "blank" value, for attributes that are not required to run a search?
This way a user would not have to go through and set multiple optional attributes to "blank" every time they wanted to search by only one or two of them.
Thank you for the quick response. I just have one more question, relating to subtypes this time.
I have a feature class using Architectural Classification as a sub-type field. Each Architecture Class then has a sub-classification field, with a unique domain for each.
When I try to set up the search for the sub-classification field, its domain always comes back as that of the default subtype (both in formatting screen and on the user end). To remedy this, I attempted to create a Predefined list of all of the values of the sub-classifcation domains. This appears to work fine in the formatting of the widget, but upon trying the use the widget it seems that it is still being overrided by the default subtype domain.
I hope that made sense. If not I can use pictures to help show what I'm talking about.
I'll tell you why, Robert Scheitlin, GISP... it's because the field LOOKS like it is supposed to have something put in there. I've been doing this exact thing. Until today.
What I would recommend is in the part of the Widget where you wrote "Such as NAME like 'Roberts'" that you instead put 'Treat This Like A Definition Expression In An MXD' or something similar.
I figured it out today, and just stumbled across this post today.
Love the widget... still having issues creating that custom search like I want, but I'm digging...
I use the option ALL in these dropdowns because I want to use all the criterias that I select value for them in their ComboBox. Criterias that I don't select value in their ComboBox and they stay empty, I don't want to include in my query.
That gives a lot of flexibility because:
in query1 I want to ask about A and B and C so I select only values in ComboBox A, B ,C.
in query2 I want to ask about D and E so I select only values in ComboBox D, E.
If I would have select the option ANY, it would have select A or B or C but I don't want that. I want A and B and C (without D and E).
So here is how the widget works. When you add a second or more expression value the dropdown I am talking about should default to "All" which means the SQL statement will get "AND" concatenated in between the previous value expression and the one you are currently entering. If the field is not set to be required and no value is entered or selected for that expression value, then it will not get added to the SQL statement that is submitted to the server. If the field is required then the widget will force you to enter a value and/or will not provide a blank option in the dropdown.
So my question for you is: Is the widget NOT working for you in this manner and are you using the latest version?
I am not sure I have tested your exact scenario. Is your map service public?
It really makes no sense that you have tried to configure the widget using predefined field values and when you use the widget it returns to the default sub type dropdown. I have not seen this.
Thanks for the feedback. Sometimes I have to nudge people a little harder to read the widget help doc. So I have decided to change the placeholder for that input to "Optional (see widgets help for details)"
Your Enhanced Search Widget 1.2.0.5 offers tremendous flexibility on how you can construct complex SQL queries by chaining together values from multiple items using the AND/OR operators.
The most common example is to locate a specific Section from a specific Township and specific Range.
Thanks so much for your work in creating the enhanced widgets it's really helping us move our organisations apps to Javascript without major pain!
First time poster here hoping you or someone will be able to help me..
Seems like a minor issue but I'm using the eSearch widget on a layer that I have defined labels for but the labels don't carry through to appear in the map after my query. Previously for flex I would have used the MapServer layer but for this eSearch you need to define the layer you're querying. I've tried using a dynamic layer and then defining labels in a webmap and saving it as a feature layer on AGOL, and when I take this layer and add it to another webmap the labels appear no worries, but when I use it in the enhanced query no luck with the labels?
Any thoughts anyone? I'd really appreciate any help!
Previously for flex I would have used the MapServer layer but for this eSearch you need to define the layer you're querying.
As the developer of the Flex and WAB version I can say that you have always had to specify the layer of the map service, so I am a little confused by your statement.
Labels will not carry over to the eSearch results because I am using a FeatureLayer to display the results. You would have to have the dynamic map services added to your map (which allows for drawing labels) if you want the labels to show.
I agree that it makes no sense. I'm hoping I'm just doing something simple wrong someplace but I don't know what it would be. You can see below that I've created a very short predefined list, of just some of the values the list would need
However, once I have clicked through all of the ok buttons and look at it through the preview, what I see is is the domain for the first subtype, not the predefined list I created.
The map service is not public, but I'd be happy to give a temporary password via PM if you'd like to investigate for yourself.
Well actually looking at the code the fact that you have defined a user list and it is ignored makes a lot of sense. In the code when I find a domain I stop and take the domain path in the code and do not continue to check if there is a userlist or unique vals defined. The fix is a simple one liner in code if you are interested, if not then I will have this fixed in the next release.
Thank you for looking into this for me. I'm glad it's a relatively easy thing to fix, and that it will be in the next release. In the meantime though I'd be happy to try and implement a fix myself if you don't mind passing some instructions along.
Thanks a million for releasing so many updates to your Custom Widgets last Friday!
I decided to start with a clean slate and publish our PlanNet Web Application using the most recent versions of all your 9 Custom Widgets as of 10/23/2015.
Robert Scheitlin, GISP I'm trying to use this on a REST service that contains roughly 1 million records (police arrests) and I'm getting a massive lag with timeouts. Is there something I can do to minimize or remove these issues?
Unfortunately no. This is for basic (non-GIS trained) officers to use for analysis. Technically, I'm replacing an ancient, custom-coded, javascript web map from like 7-8 years ago. So if it worked before WAB then I'm dumbfounded on why WAB is hitting these timeouts.
I fully agree with Glenn's comment. Web browsers only have access to limited memory resources and can not be compared to ArcMap. You need to limit the data with a definition query.
I am not sure if this may be a bug in the widget but when I try and access the unique values for a data layer that has many unique values present (i.e. over 100), in the 'Add Expression' dialogue the window just seems to spin on the 'Retrieving unique values' (see attached print screen). Have you encountered any other problems with this or is the number of unique values present a problem? Thanks!
Name : Value When entering list values (for the predefined expression values) it would be wonderful to be able to craft them for the GUI as well as the backend. Instead of just entering the value to search by, I would like to enter a "label" (if you will) AND a value. Then, when the database has an entry that is an acronym (like LOL) then I could enter a "Name" (or label) of "Laugh Out Loud" and have the value be "LOL" to make options simpler for the end users.
Straight SQL : Field Value (Field Calculator) For those of us with a deeper understanding it would be AWESOME to be able to have a FIELD search. Where we pick a column from the REST Service, and the GUI pops up a FIELD with that name. Then be able to EDIT the section listed as "SQL STATEMENT" in most of the Expression Values. Then we could craft a SQL statement (like in Field Calculator) and present the user with our FIELD and some label text telling them what to enter and whatever they enter in that field is used in our customized SQL statement. While we're on this road... give us MULTIPLE fields... so we can construct some sweet queries and have the user pass on the values through their entries.
Not something i am considering because you as a the GIS person can create a coded value domain for that field with names and values and the widget will use that coded value domain. The user predefined list is suppose to be simple data entry for predefined values.
FYI, I am not interested in creating a widget that gives that level of complexity to the end user. I was against it in Flex and still am in WAB.
Is it possible to add a summary function for certain fields to the search results similar to your Flex Advanced Search widget? I looked through the help guide but didn't see anything. There is the Summary widget in WAB but this requires feature services and the user to open a separate widget.
My sum function in eSearch for Flex was tied to the Datagrid that I developed to go with the eSearch. I will have to look into the level of effort of adding this to the WAB eSearch results and how to tie it in with the widgets UI as I do not have much control over the Attribute Table widget that I am using to display the search results in a grid format.
1. Sadly, as the GIS person I don't always own the data. As things stand, this is police data. I have zero control over it. The only people WITH control are not GIS-empowered and could care less. But I get it. Makes sense. I'll try to show how my OTHER maps look great while theirs has these non-human-readable entries because of a lack of domains and GIS-friendly data structure.
2. I totally get that. Makes sense. HOWEVER... I do think that a Field Calculator widget would be very nice to have. For those developers with more GIS background than Web.
Thanks for the response man. Love your products as always...
I have a question? Maybe you have answer this already. Is there a way to configure and use my own symbology for individual search layers? I wish not to use the default symbology, very confusing for a user to quickly tell if the symbol return on the map a "hydrant" or "valve".
ha Thach yes you can do this. Just change it to "from Config" as below.
Then adjust the default Search symbology:
I had the very same question the first time I used this widget. I also prefer to use the default Search Symbology, and not from Server. Just like you, I want to have all my parcels highlight yellow for example, and all roads, red, etc...
I tried this approach. What I'm really after is be able to configure each search layer to use different search symbol. I was thinking of using my own symbol on the server instead of ArcGIS Server symbol. Is there an option to doing that?
ha Thach Oh I see what you mean, one symbol for each layer. Interesting though. Ah such it is with such a powerful widget, we always have more ideas for Robert.
I would just recommend you adjust it on the MXD. Do you have access to it and can you do that?
Kevin - Thanks for the recommendation, yes I have done that. I thought that the same functionality transition over to WAB latest version of the eSearch widget as well.
This is how I configure in flexviewer with Robert search widget.
';
}
}
}
catch(e){
}
}
}
if (newSub.getAttribute("slang").toLowerCase() != code_l.toLowerCase()) {
if (trLabelsHtml != "") {
var labelSname = "";
if(labelEle[i].querySelector("ul li:nth-child(1)").getAttribute("aria-hidden")){
labelSname = labelEle[i].querySelector("ul li:nth-child(1)").outerHTML;
}
labelEle[i].innerHTML = "";
labelEle[i].innerHTML = labelSname + trLabelsHtml;
}
}
}
}
}
catch(e){
}
}
}
/* V 2.0:3 = Store not translated reply id */
if(lingoRSXML.snapshotLength == 0){
if($scope.falseReplyID == "") {
$scope.falseReplyID = value;
}
}
/* Get translated Body of Replies/Comments */
var lingoRBXML = doc.evaluate(lingoRBExp, doc, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
for(var i=0;i 0) {
var attachDiv = rootElement.querySelector('div.lia-quilt-row-main').querySelector('div.custom-attachments');
if (attachDiv) {
attachDiv = attachDiv.outerHTML;
}
else if(rootElement.querySelector('div.lia-quilt-row-main').querySelectorAll('#attachments').length > 0){
if ("TkbArticlePage" == "BlogArticlePage") {
attachDiv = rootElement.querySelector('div.lia-quilt-row-main .lia-message-body-content').querySelector('#attachments');
if (attachDiv) {
attachDiv = attachDiv.outerHTML;
}
else{
attachDiv = "";
}
}else{
attachDiv = rootElement.querySelector('div.lia-quilt-row-main').querySelector('#attachments').outerHTML;
}
}
else {
attachDiv = "";
}
/* Feedback Div */
var feedbackDiv = "";
var feedbackDivs = rootElement.querySelector('div.lia-quilt-row-main').querySelectorAll('div.lia-panel-feedback-banner-safe');
if (feedbackDivs.length > 0) {
for (var k = 0; k < feedbackDivs.length; k++) {
feedbackDiv = feedbackDiv + feedbackDivs[k].outerHTML;
}
}
}
else {
var attachDiv = rootElement.querySelector('div.lia-message-body-content').querySelector('div.Attachments.preview-attachments');
if (attachDiv) {
attachDiv = attachDiv.outerHTML;
} else {
attachDiv = "";
}
/* Everyone tags links */
if (document.querySelectorAll("div.TagList").length > 0){
var everyoneTagslink = document.querySelector('div.lia-quilt-row-main').querySelector(".MessageTagsTaplet .TagList");
if ((everyoneTagslink != null)||(everyoneTagslink != undefined)){
everyoneTagslink = everyoneTagslink.outerHTML;
}
else{
everyoneTagslink = "";
}
}
/* Feedback Div */
var feedbackDiv = "";
var feedbackDivs = rootElement.querySelector('div.lia-message-body-content').querySelectorAll('div.lia-panel-feedback-banner-safe');
if (feedbackDivs.length > 0) {
for (var m = 0; m < feedbackDivs.length; m++) {
feedbackDiv = feedbackDiv + feedbackDivs[m].outerHTML;
}
}
}
}
} catch (e) {
}
if (body_L == "") {
/* V 2.0:7 Replacing translated video data with source video data */
var newBodyVideoData = newBody.querySelectorAll('div[class*="video-embed"]');
angular.forEach($scope.videoData[value], function (sourceVideoElement, index) {
if (index <= (newBodyVideoData.length - 1)) {
newBodyVideoData[index].outerHTML = sourceVideoElement.outerHTML
}
});
/* V 2.0:7 = Replacing translated image data with source data */
var newBodyImageData = newBody.querySelectorAll('[class*="lia-image"]');
angular.forEach($scope.imageData[value], function (sourceImgElement, index) {
if (index <= (newBodyImageData.length - 1)) {
newBodyImageData[index].outerHTML = sourceImgElement.outerHTML;
}
});
/* V 2.0:7 = Replacing translated pre tag data with source data */
var newBodyPreTagData = newBody.querySelectorAll('pre');
angular.forEach($scope.preTagData[value], function (sourcePreTagElement, index) {
if (index <= (newBodyPreTagData.length - 1)) {
newBodyPreTagData[index].outerHTML = sourcePreTagElement.outerHTML;
}
});
}
var copyBodySubject = false;
if (body_L == "") {
copyBodySubject = true;
body_L = newBody.innerHTML;
}
/* This code is written as part of video fix by iTalent */
/* try{
var iframeHTMLText = body_L;
var searchIframeText = "<IFRAME";
var foundiFrameTag;
if (iframeHTMLText.indexOf(searchIframeText) > -1) {
foundiFrameTag = decodeHTMLEntities(iframeHTMLText);
foundiFrameTag = foundiFrameTag.split('src="')[1];
body_L = foundiFrameTag;
}
}
catch(e){
} */
/* This code is placed to remove the extra meta tag adding in the UI*/
try{
body_L = body_L.replace('<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />','');
}
catch(e){
}
/** We should not replace the source content if user profile language and selected target language matches with source language **/
if(showTrContent) {
var compiled = false;
rootElement.querySelectorAll('div.lia-message-body-content')[0].innerHTML = null
if("TkbArticlePage"=="IdeaPage"){
// var customAttachDiv = '';
rootElement.querySelectorAll('div.lia-message-body-content')[0].innerHTML = body_L + feedbackDiv ;
$compile(rootElement.querySelectorAll('div.lia-message-body-content')[0])($scope);
compiled = true;
/* Attach atttach div */
// document.querySelector("div.translation-attachments-"+value).innerHTML = attachDiv;
rootElement.querySelectorAll('div.lia-message-body-content')[0].insertAdjacentHTML('afterend',attachDiv);
if(rootElement.querySelectorAll('div.lia-quilt-idea-message .lia-message-body .lia-attachments-message').length > 1){
rootElement.querySelectorAll('div.lia-quilt-idea-message .lia-message-body .lia-attachments-message')[1].remove();
}
} else {
if("TkbArticlePage"=="TkbArticlePage"){
rootElement.querySelectorAll('div.lia-message-body-content')[0].innerHTML = body_L + feedbackDiv ;
}else{
rootElement.querySelectorAll('div.lia-message-body-content')[0].innerHTML = body_L + feedbackDiv + attachDiv;
compiled = true;
}
}
/* Destroy and recreate OOyala player videos to restore the videos in target languages which is written by iTalent as part of iTrack LILICON-79 */ /* Destroy and recreate OOyala player videos */
try{
// $scope.videoData[value][0].querySelector("div").getAttribute("id");
for(var vidIndex=0; vidIndex<$scope.videoData[value].length; vidIndex++){
if( $scope.videoData[value][vidIndex].querySelector("div") != null){
var containerId = LITHIUM.OOYALA.players[$scope.videoData[value][vidIndex].querySelector("div").getAttribute("id")].containerId;
videoId = LITHIUM.OOYALA.players[$scope.videoData[value][vidIndex].querySelector("div").getAttribute("id")].videoId;
/** Get the Video object */
vid = OO.Player.create(containerId,videoId);
/** Destroy the video **/
vid.destroy();
/** recreate in the same position */
var vid = OO.Player.create(containerId,videoId);
}
}
}
catch(e){
}
try{
for(var vidIndex=0; vidIndex<($scope.videoData[value].length); vidIndex++){
if($scope.videoData[value][vidIndex].querySelector('video-js') != null){
var data_id = $scope.videoData[value][vidIndex].querySelector('video-js').getAttribute('data-video-id');
var data_account = $scope.videoData[value][vidIndex].querySelector('video-js').getAttribute('data-account');
var data_palyer = $scope.videoData[value][vidIndex].querySelector('video-js').getAttribute('data-player');
var div = document.createElement('div');
div.id = "brightcove";
div.class = "brightcove-player";
div.innerHTML =
'(view in my videos)'
var data = div.getElementsByClassName("video-js");
var script = document.createElement('script');
script.src = "https://players.brightcove.net/" + data_account + "/" + data_palyer + "_default/index.min.js";
for(var i=0;i< data.length;i++){
videodata.push(data[i]);
}
}
}
for(var i=0;i< videodata.length;i++){
document.getElementsByClassName('lia-vid-container')[i].innerHTML = videodata[i].outerHTML;
document.body.appendChild(script);
}
}
catch(e){
}
if(!compiled){
/* Re compile html */
$compile(rootElement.querySelectorAll('div.lia-message-body-content')[0])($scope);
}
}
if (code_l.toLowerCase() != newBody.getAttribute("slang").toLowerCase()) {
/* Adding Translation flag */
var tr_obj = $filter('filter')($scope.sourceLangList, function (obj_l) {
return obj_l.code.toLowerCase() === newBody.getAttribute("slang").toLowerCase()
});
if (tr_obj.length > 0) {
tr_text = "Esri may utilize third parties to translate your data and/or imagery to facilitate communication across different languages.".replace(/lilicon-trans-text/g, tr_obj[0].title);
try {
if ($scope.wootMessages[$rootScope.profLang] != undefined) {
tr_text = $scope.wootMessages[$rootScope.profLang].replace(/lilicon-trans-text/g, tr_obj[0].title);
}
} catch (e) {
}
} else {
//tr_text = "This message was translated for your convenience!";
tr_text = "Esri may utilize third parties to translate your data and/or imagery to facilitate communication across different languages.";
}
try {
if (!document.getElementById("tr-msz-" + value)) {
var tr_para = document.createElement("P");
tr_para.setAttribute("id", "tr-msz-" + value);
tr_para.setAttribute("class", "tr-msz");
tr_para.style.textAlign = 'justify';
var tr_fTag = document.createElement("IMG");
tr_fTag.setAttribute("class", "tFlag");
tr_fTag.setAttribute("src", "/html/assets/langTrFlag.PNG");
tr_fTag.style.marginRight = "5px";
tr_fTag.style.height = "14px";
tr_para.appendChild(tr_fTag);
var tr_textNode = document.createTextNode(tr_text);
tr_para.appendChild(tr_textNode);
/* Woot message only for multi source */
if(rootElement.querySelector(".lia-quilt-forum-message")){
rootElement.querySelector(".lia-quilt-forum-message").appendChild(tr_para);
} else if(rootElement.querySelector(".lia-message-view-blog-topic-message")) {
rootElement.querySelector(".lia-message-view-blog-topic-message").appendChild(tr_para);
} else if(rootElement.querySelector(".lia-quilt-blog-reply-message")){
rootElement.querySelector(".lia-quilt-blog-reply-message").appendChild(tr_para);
} else if(rootElement.querySelector(".lia-quilt-tkb-message")){
rootElement.querySelector(".lia-quilt-tkb-message").appendChild(tr_para);
} else if(rootElement.querySelector(".lia-quilt-tkb-reply-message")){
rootElement.querySelector(".lia-quilt-tkb-reply-message").insertBefore(tr_para,rootElement.querySelector(".lia-quilt-row.lia-quilt-row-footer"));
} else if(rootElement.querySelector(".lia-quilt-idea-message")){
rootElement.querySelector(".lia-quilt-idea-message").appendChild(tr_para);
} else if(rootElement.querySelector('.lia-quilt-occasion-message')){
rootElement.querySelector('.lia-quilt-occasion-message').appendChild(tr_para);
}
else {
if (rootElement.querySelectorAll('div.lia-quilt-row-footer').length > 0) {
rootElement.querySelectorAll('div.lia-quilt-row-footer')[0].appendChild(tr_para);
} else {
rootElement.querySelectorAll('div.lia-quilt-column-message-footer')[0].appendChild(tr_para);
}
}
}
} catch (e) {
}
}
} else {
/* Do not display button for same language */
// syncList.remove(value);
var index = $scope.syncList.indexOf(value);
if (index > -1) {
$scope.syncList.splice(index, 1);
}
}
}
}
});
});
/* V 1.1:2 = Reply Sync button for multi source translation */
} catch(e){
console.log(e);
}
};
if((rContent != undefined) && (rContent != "")) {
drawCanvas(decodeURIComponent(rContent));
/** Update variable with selected language code **/
$scope.previousSelCode = code_l;
}
};
/**
* @function manageTranslation
* @description Managess the translation of given language for the thread
* @param {string} langCode - Language Code
* @param {string} tid - Thread ID
*/
$scope.manageTranslation = function (langCode, tid) {
//debugger;
$scope.showTrText = false;
/* V 2.0:5 = actualStatus variable introduced to indicate detailed connector status on UI. This variable holds the actual translation percentage */
$scope.transPercent = "";
$scope.actualStatus = "";
if (tid != "") {
var bulkTranslation = lithiumPlugin.bulkTranslation(langCode, tid);
bulkTranslation.then(function (trContent) {
if(trContent.body != "") {
$scope.showPreview(trContent.body, $scope.mszList, langCode);
if(langCode != "en-US") {
$scope.showTrText = true;
}
}
if((trContent.status != "NA") && trContent.status != null) {
// $scope.transPercent = String(trContent.status);
$scope.actualStatus = String(trContent.status);
} else {
// $rootScope.errorMsg = "Translation is in progress. Please check again a few minutes."
$rootScope.errorMsg = "Translation is in progress. Please retry in a few minutes."
}
$scope.workbench = trContent.wb;
/* V 2.0:4 = Trigger uncalled or delayed callbacks (documnet uploaded/translation completed from lithium).*/
if(trContent.callback == 'true') {
var trCompletCallback = lithiumPlugin.trCompletCallback(langCode, trContent.docID);
trCompletCallback.then(function (callback){
// $rootScope.errorMsg = "Downloading Translated content in " + langCode + " now. Please check again in a few minutes."
$rootScope.errorMsg = "Uploading content to translate. Please check again in a few minutes."
});
} else if (trContent.callback == 'upload') {
var trCompletUpload = lithiumPlugin.trCompletUpload(langCode, trContent.docID);
trCompletUpload.then(function (callback) {
//$rootScope.errorMsg = "Uploading content to translate. Please check again in a few minutes."
$rootScope.errorMsg = "Uploading content to translate. Please check again in a few minutes."
});
} else if ("many" == "one") {
$scope.updateOOS();
} else if("SmartConx" == "SmartConx"){
if ("many" == "many"){
$scope.updateOOS();
}
}else if ((trContent.status != null) && trContent.status.includes("100")) {
/* If everything fine then only check Out of Sync status */
$scope.updateOOS();
} else {
/* If translation perccent is less than 100 then show the percentage on UI */
$scope.transPercent = $scope.actualStatus;
}
});
}
}
/**
* @function selectThisLang
* @description Called on select dropdown.
* @param {string} lang - Language code
*
*/
$scope.selectThisLang = function (lang, anonymousFlag) {
/* 1.4:3 Update Analytics on language selection */
try {
lingoThreadLangSelected(lang, '910880');
} catch (e) {
}
/** Display Translated content **/
var getTranslation = lithiumPlugin.getTranslation(lang, "910880");
getTranslation.then(function (trContent) {
if (trContent.body != "") {
$scope.showPreview(trContent.body, $scope.mszList, lang);
} else {
//$rootScope.errorMsg = "Translation is in progress. Please check again in a few minutes."
$rootScope.errorMsg = "Translation is in progress. Please retry in a few minutes."
}
});
};
var decodeEntities = (function() {
// this prevents any overhead from creating the object each time
var element = document.createElement('div');
function decodeHTMLEntities (str) {
if(str && typeof str === 'string') {
// strip script/html tags
str = str.replace(/