Hello community! I have a Field of unique coded values. these unique codes reference a full URL in a Table. however for each Feature there could be multiple codes(that are separated by piping '|'). example: WoodOthers1948 | Barnes1953 | HailOthers1971
in the past, I have hard coded the URLs to the codes and used HTML 'href' in the Arcade window to get my results, however, there are hundreds of these combinations.
I would like to have the attribute codes show in the popup and each individual code would be hyperlinked/href to their unique URL.
*this is visually how it should look in the popup, but each coded value would be a unique hyperlink-
Data Source: WoodOthers1948 | Barnes1953 | HailOthers1971 | StevenOthers1974 | Condon1992 | CarrollOthers1999 | KirkhamNavarre2003 | CarrollOthers2014
I have thought of using 'Decode' to reassign the codes to URLs, but not sure how to read the clicked $feature list in to assign those individual URLs each time.
Any help? im assuming creating a unique Array will help, but accessing and href'ing each code correctly back to the coded text list is still an issue.
thx!
Solved! Go to Solution.
Here's one way of doing it. I'm using a table I set up that has the codes and their associated URLs. In the Arcade element, I get the codes from the feature (here I use a dummy variable in lieu of an actual feature), split them into an array, and loop through that array. For each code, I get the URL from the table and create an href, which is pushed into an array. That array is concatentated with the Data Source text.
var feat = 'WoodOthers1948 | Barnes1953 | HailOthers1971';
var source = FeatureSetByPortalItem(myPortal, myTableId, 0, ['Code', 'URL'], false)
var arr = Split(feat, " | ")
var output = []
for (var index in arr) {
var code = arr[index]
var pub = Filter(source, "Code = @code")
var item = `<a href="${First(pub).URL}">${code}</a>`
Push(output, item)
}
return {
type : 'text',
text : `<b>Data Source:</b> ${Concatenate(output, " | ")}`
}
This returns this popup, with each link functional
Here's one way of doing it. I'm using a table I set up that has the codes and their associated URLs. In the Arcade element, I get the codes from the feature (here I use a dummy variable in lieu of an actual feature), split them into an array, and loop through that array. For each code, I get the URL from the table and create an href, which is pushed into an array. That array is concatentated with the Data Source text.
var feat = 'WoodOthers1948 | Barnes1953 | HailOthers1971';
var source = FeatureSetByPortalItem(myPortal, myTableId, 0, ['Code', 'URL'], false)
var arr = Split(feat, " | ")
var output = []
for (var index in arr) {
var code = arr[index]
var pub = Filter(source, "Code = @code")
var item = `<a href="${First(pub).URL}">${code}</a>`
Push(output, item)
}
return {
type : 'text',
text : `<b>Data Source:</b> ${Concatenate(output, " | ")}`
}
This returns this popup, with each link functional
@KenBuja! Thank you! I just wasn't sure how to extract that array correctly, this worked great. I just replaced your dummy variable list with my polygon $feature layer, and used an existing Table that included the Codes and URLs, and the array was built off that.
Thanks for looking at this so quickly. it definitely takes an extra second to think when it needs to sort thru a longer array list, but it outputs what I need!
here is an example of the new popup output, with active href links>
Hi Ken,
Thank you so much for sharing your example.
I have run into something that is making me crazy! The code below modeled after your example is being used in a popup Arcade element. Its basically looping through a table of images and I’m reformatting the string into a usable URL. It seems to work when I run it in the code window, but it fails to render the links in the popup. I think it has something to do with the loop but the text that is output in the run looks correct.
Any advice? (see images below)
var portal = Portal('https://gis.clark.wa.gov/portalpw/')
var Stmdocs = FeatureSetByPortalItem(portal,
"4b35b095430d47d699dea875e62dd0b6", 3, [ 'MmsId','FilePath']) //42 is the table ID in the service
// Filter related features by using a common attribute
// Here both table have identical MMSID fields
var MMSID = $feature.MmsId
var filterStatement = 'MMSID = @MMSID'
// Related features as a variable
var relatedData = Filter(Stmdocs, filterStatement)
// Sort related features by oldest to newest
var relatedDataSorted = OrderBy(relatedData, 'MmsId')
// Build the pop-up string by iterating through all related features ideally as hyperlinks
var thenewpath = ''
var theurl = ''
var output = []
for (var f in relatedDataSorted){
thenewpath = Replace(f.filepath, 'olympus', '')
thenewpath = Replace(thenewpath, 'gisdata', '')
thenewpath = Replace(thenewpath, 'Images', 'ccimages')
thenewpath = Replace(thenewpath, '\\', '/')
thenewpath = Replace(thenewpath, '////', 'https://gis.clark.wa.gov/')
theurl = "<a href=" + TextFormatting.DoubleQuote + thenewpath + TextFormatting.DoubleQuote + ">Image</a>"
Push(output, theurl)
}
return {
type : 'text',
text : `<b>Image Links:</b> ${Concatenate(output, TextFormatting.NewLine)}`
}
That code should work. Did you check whether you're getting any valid related records? It would be something like this (untested)
var portal = Portal("https://gis.clark.wa.gov/portalpw/");
var Stmdocs = FeatureSetByPortalItem(portal, "4b35b095430d47d699dea875e62dd0b6", 3, ["MmsId", "FilePath"]); //42 is the table ID in the service
// Filter related features by using a common attribute
// Here both table have identical MMSID fields
var MMSID = $feature.MmsId;
var filterStatement = "MMSID = @MMSID";
// Related features as a variable
var relatedData = Filter(Stmdocs, filterStatement);
var output = 'No images found'
if (Count(relatedData) > 0) {
// Sort related features by oldest to newest
var relatedDataSorted = OrderBy(relatedData, "MmsId");
// Build the pop-up string by iterating through all related features ideally as hyperlinks
var thenewpath = "";
var theurl = "";
var list = [];
for (var f in relatedDataSorted) {
thenewpath = Replace(f.filepath, "olympus", "");
thenewpath = Replace(thenewpath, "gisdata", "");
thenewpath = Replace(thenewpath, "Images", "ccimages");
thenewpath = Replace(thenewpath, "\\", "/");
thenewpath = Replace(thenewpath, "////", "https://gis.clark.wa.gov/");
theurl = `<a href="${thenewpath}">Image</a>`;
Push(list, theurl);
}
output = `<b>Image Links:</b> ${Concatenate(list, TextFormatting.NewLine)}`;
}
return {
type: "text",
text: output
};
This isn't the most efficient code, so I can imagine it's slower with longer array lists. Since it has to make a query for each item in the list, multiple requests are sent back to the server. You might look at @jcarlson's blog about "memorizing" the table and see if that makes a measurable difference.
You could also just read the table into a dictionary and use the code field as a key to get the URL value instead of using the Filter on the Table.
Yep, understood and agreed. Code efficiency will need to be looked at. However, your code definitely helped us get over that first hump, and truly does not slow the popups down too much(2-3 seconds depending on the array list pulled, which can go up to about 10 Codes). For now, our task has been automated, thanks again. But yes, we will look at the efficiency and update where needed..and your link to "Memorizing" is a terrific post, full of great ideas.
Thanks again!
p