Arcade Expression with HTML, TextFormating.NewLine doesn't work ?

406
7
Jump to solution
12-05-2023 02:23 AM
JasonBOCQUET
Occasional Contributor II

Hello, I have an attribute expression like this :

var transactions = FeatureSetByRelationshipName($feature,"SDE.TRANSACTIONS")
//return transactions
 
// Build the pop-up string by iterating through all related features
var info = ''
for (var f in transactions){
    info += "ID : " + DefaultValue(f.TRA_ADR_ID, 'no data') + TextFormatting.NewLine +
        "Nom immeuble : " +
        DefaultValue(f.TRA_NOM_IMMEUBLE, 'no data') + TextFormatting.NewLine +
        "Montant : " + 
        DefaultValue(f.TRA_MONTANT, 'no data') + TextFormatting.NewLine +
        "Acquéreur : " +
        DefaultValue(f.TRA_ACQUEREUR, 'no data') + TextFormatting.NewLine + TextFormatting.NewLine 
}
iif(isempty(info),'Pas de transactions','Transactions utilisateurs :'+TextFormatting.NewLine +TextFormatting.NewLine+info)

 

and it returns me that :

JasonBOCQUET_0-1701771456532.png

 

It's good for me but i want to improve my pop-up windows with some HTML.

 

So I try this code (it's only a short part of the code) :

 

var transactions = FeatureSetByRelationshipName($feature,"SDE.TRANSACTIONS")
var info = ''
for (var f in transactions){
    info += "ID : " + DefaultValue(f.TRA_ADR_ID, 'no data') + TextFormatting.NewLine +
       "Nom immeuble : " +
        DefaultValue(f.TRA_NOM_IMMEUBLE, 'no data') + TextFormatting.NewLine +
        "Montant : " + 
        DefaultValue(f.TRA_MONTANT, 'no data') + TextFormatting.NewLine +
        "Acquéreur : " +
        DefaultValue(f.TRA_ACQUEREUR, 'no data') + TextFormatting.NewLine + TextFormatting.NewLine
}


HTML += "<p style='text-align: left;'><span style='font-size: 16px; font-family: Calibri, sans-serif;'>"+"<strong>"+iif(isempty(info),'Pas de transactions',TextFormatting.NewLine +TextFormatting.NewLine+info)+"</strong></span></p>"

 

But it returns me this :

JasonBOCQUET_1-1701771620030.png

 

It seems that the TextFormatting.NewLine constants do not work in the arcade window but only in the attribute expressions window? Or did I make a mistake in my code?

 

0 Kudos
1 Solution

Accepted Solutions
ZachBodenner
MVP Regular Contributor

One of the utilities of the backticks is so that you don't actually need to rely on textformatting etc.

https://developers.arcgis.com/arcade/guide/template-literals/#:~:text=Template%20literals%20can%20co....

https://www.esri.com/arcgis-blog/products/arcgis-online/mapping/manage-your-strings-quite-literally-...

Here are some ESRI provided resources that can provide a little more info.

 

And here's one more example of using the backticks to make writing HTML returns a bit easier

//set variables. First variable is the unique ID that is shared by the primary and related data. Second variable is calling the related forms as a FeatureSet
 
var treeGlobal = $feature.GlobalID;
var relatedForms = FeatureSetByName($map, "Tree Inventory Form")

//create a filter statement where the maintenance form GUID = the Tree Inventory GlobalID

var filterStatement = "TreeInv_Rel = @treeGlobal"

//a maintenance form equals the table run through the filter
 
var inspForm = Filter(relatedForms, filterStatement)

console (inspForm)

if (isEmpty(inspForm)) {
  var title = ``
}

else if (!isEmpty(inspForm)) {
  var title = `<div style="text-align:center"><b>Inspection Records</b></div><br>` 
}
// Sort related features by oldest to newest
var relatedDataSorted = OrderBy(inspForm, 'Date ASC')
 
// Build the pop-up string by iterating through all related features. Add or subtract new lines in the popupString as needed from the related form.
var popupString = ''
for (var f in relatedDataSorted){
    
    popupString += 
        `<div style="text-align:center"><b>${Text(f.Date, 'MMMM DD, Y')}</b></div><br>    
        <b>Maintenance Performed: </b>${DefaultValue(f.Maintenance_Performed, 'No maintenance performed')}<br>

        <b>Maintenance Performed by: </b>${DefaultValue(f.Performed_By, 'No maintenance performed')}<br>

        <b>Condition:  </b>${DefaultValue(f.Condition, 'Condition not assessed')} <br>

        <b>Chemical Used (if any): </b>${DefaultValue(f.Chemical_Treatment, 'No chemical treatment')} <br>

        <b>Amount Used (if any): </b>${DefaultValue(f.Chemical_Qty_ML, 'No chemical treatment')} <br>
              
        <b>Notes: </b>${DefaultValue(f.Notes, 'No notes')}<br><br>
        `
 
}

return { 
	type : 'text', 
	text : `${title} 
  ${popupString}`
}

 

You'll notice the backticks enclose my final popupstring variable and I just include an extra <br> tag at the end of the loop. That way, multiple related record come in with some breathing room between each.

 

ZachBodenner_0-1701873552904.png

 

View solution in original post

7 Replies
ZachBodenner
MVP Regular Contributor

If you're going to be returning HTML in the Arcade popup element, you need to use template literals (so enclose your variable HTML in  backticks (`) instead of quotes ("), and then use the HTML tag <br> instead of textformatting.newline. Then, remove all the plus signs and enclose your variables in brackets preceeded by a $. 

 

var transactions = FeatureSetByRelationshipName($feature,"SDE.TRANSACTIONS")
var info = ''
for (var f in transactions){
    info += "ID : " + DefaultValue(f.TRA_ADR_ID, 'no data') + TextFormatting.NewLine +
       "Nom immeuble : " +
        DefaultValue(f.TRA_NOM_IMMEUBLE, 'no data') + TextFormatting.NewLine +
        "Montant : " + 
        DefaultValue(f.TRA_MONTANT, 'no data') + TextFormatting.NewLine +
        "Acquéreur : " +
        DefaultValue(f.TRA_ACQUEREUR, 'no data') + TextFormatting.NewLine + TextFormatting.NewLine
}

HTML += `<p style="text-align: left;"><span style="font-size: 16px; font-family: Calibri, sans-serif;"><strong>${iif(isempty(info),'Pas de transactions'},<br> <br>${info})</strong></span></p>`

 

 

Give that a try and see if it works, though there might still be issues with the HTML return portion ${iif(isempty(info),'Pas de transactions'},<br> <br>${info}). You may want to assign that to it's own variable, and then just use that new one in the final HTML return so it would look like:

 

 

var newVariable = iif(isempty(info),'Pas de transactions',info);

HTML += `<p style="text-align: left;"><span style="font-size: 16px; font-family: Calibri, sans-serif;"><strong>${newVariable}</strong></span></p>`

 

jcarlson
MVP Esteemed Contributor

Just a note: HTML generated by Arcade will only work using the Arcade popup element.

https://www.esri.com/arcgis-blog/products/arcgis-online/mapping/part-1-introducing-arcade-pop-up-con...

You might check out using the Arcade element to return a field list, too. Takes care of some of the styling and formatting for youl

- Josh Carlson
Kendall County GIS
0 Kudos
JasonBOCQUET
Occasional Contributor II

Thanks for your replies both of you.

 

I don't understand one thing, i can use the HTML with Arcade like i write here :

var immeuble = $feature.lp_nom_immeuble
var id_lp = $feature.id_lp
var adresse = $feature.lp_num_voie + ', ' + $feature.lp_nom_voie + ' ' + $feature.lp_code_postal + ' ' + $feature.lp_ville
var surface = $feature.lp_surface_totale
var construction = $feature.periode_de_construction
var etat = $feature.etat_general
var nature = $feature.destination_principale
var loyer = $feature.loyer_moyen
var vacance = $feature.taux_de_vacance
var offre = $feature.offre_en_cours

var HTML = "<p style='text-align: center; line-height: 0.1;'><strong><span style='font-size: 30px; font-family: Calibri, sans-serif; color: rgb(1, 42, 132);'>"+iif(IsEmpty(immeuble),'',immeuble)+"</span></strong></p>"
HTML += "<p style='text-align: center; line-height: 0.1;'><span style='font-family: Calibri, sans-serif;'><em><span style='font-size: 12px; color: rgb(1, 42, 132);'>"+iif(isempty(id_lp),"Pas d'ID Logipro","ID Logipro : "+id_lp)+"</span></em></span></p>"
HTML += "<p style='text-align: left;'><span style='font-family: Calibri, sans-serif;'><strong><span style='font-size: 16px; color: rgb(1, 42, 132);'>"+adresse+"</span></strong></span></p>"
HTML += "<p style='text-align: left;'><span style='font-size: 16px; font-family: Calibri, sans-serif; color: rgb(1, 42, 132);'>"+iif(surface < 1,"Pas de surface renseignée","Surface de "+"<strong>"+surface+" m²")+"</strong></span></p>"
HTML += "<p style='text-align: left;'><span style='font-size: 16px; font-family: Calibri, sans-serif; color: rgb(1, 42, 132);'>"+iif(construction < 1,"Pas d'année de construction renseignée","Année de construction : "+"<strong>"+construction)+"</strong></span></p>"
HTML += "<p style='text-align: left;'><span style='font-size: 16px; font-family: Calibri, sans-serif; color: rgb(1, 42, 132);'>"+iif(isempty(etat),"Pas d'état renseigné","État de l'immeuble : "+"<strong>"+etat)+"</strong></span></p>"
HTML += "<p style='text-align: left;'><span style='font-size: 16px; font-family: Calibri, sans-serif; color: rgb(1, 42, 132);'>"+iif(isempty(nature),"Pas de nature d'immeuble renseigné","Nature de l'immeuble : "+"<strong>"+nature)+"</strong></span></p>"
HTML += "<p style='text-align: left;'><span style='font-size: 16px; font-family: Calibri, sans-serif; color: rgb(1, 42, 132);'>"+iif(loyer < 1,"Pas de loyer moyen renseigné","Loyer moyen de "+"<strong>"+loyer+" €/m²/an")+"</strong></span></p>"
HTML += "<p style='text-align: left;'><span style='font-size: 16px; font-family: Calibri, sans-serif; color: rgb(1, 42, 132);'>"+iif(isempty(vacance),"Pas de taux de vacance renseigné","Taux de vacance de "+"<strong>"+(Round(vacance, 4)*100)+"%")+"</strong></span></p>"
HTML += "<p style='text-align: left;'><span style='font-size: 16px; font-family: Calibri, sans-serif; color: rgb(1, 42, 132);'>"+"Offre en cours : "+"<strong>"+offre+"</strong></span></p>"
HTML += "<p style='text-align: center;'><span style='font-family: Calibri, sans-serif; font-size: 20px; color: rgb(1, 42, 132);'><strong>Transactions utilisateurs</strong></span></p>"

 

to build a pop-up like this :

JasonBOCQUET_0-1701791481651.png

And it works, all of the code that I write works.

 

So why I have to use backticks and <br> for that if everything else works ?

Can I only use this replacement to make a line break or it's mandatory to change all of my code ?

 

@ZachBodenner I try your code but it doesn't change anything, I don't understand what I have to make in <br> tags ?

 

0 Kudos
ZachBodenner
MVP Regular Contributor

First, I tried this (plugging your Arcade into my own data)

var PID = $feature.PID
var HTML = ``
//var newVariable = IIF(isempty(PID),"Pas d'ID Logipro","ID Logipro : "+PID)
//HTML += "<p style='text-align: center; line-height: 0.1;'><span style='font-family: Calibri, sans-serif;'><em><span style='font-size: 12px; color: rgb(1, 42, 132);'>"+iif(isempty(PID),"Pas d'ID Logipro","ID Logipro : "+PID+TextFormatting.NewLine+$feature.Address)+"</span></em></span></p>"
//HTML += `<p style='text-align: center; line-height: 0.1;'><span style='font-family: Calibri, sans-serif;'><em><span style='font-size: 12px; color: rgb(1, 42, 132);'>"${newVariable}<br>${$feature.ADDRESS}"</span></em></span></p>`
HTML += "<p style='text-align: center; line-height: 0.1;'><span style='font-family: Calibri, sans-serif;'><em><span style='font-size: 12px; color: rgb(1, 42, 132);'>"+IIF(isempty(PID),"Pas d'ID Logipro","ID Logipro : "+PID)+"</span></em></span></p>"

return HTML

 

The expression validates but doesn't actually return anything in my Arcade popup element. So then I tried to plug the variable HTML into the arcade return that exists when you add a new Arcade popup element:

var PID = $feature.PID
var HTML = ``
//var newVariable = IIF(isempty(PID),"Pas d'ID Logipro","ID Logipro : "+PID)
//HTML += "<p style='text-align: center; line-height: 0.1;'><span style='font-family: Calibri, sans-serif;'><em><span style='font-size: 12px; color: rgb(1, 42, 132);'>"+iif(isempty(PID),"Pas d'ID Logipro","ID Logipro : "+PID+TextFormatting.NewLine+$feature.Address)+"</span></em></span></p>"
//HTML += `<p style='text-align: center; line-height: 0.1;'><span style='font-family: Calibri, sans-serif;'><em><span style='font-size: 12px; color: rgb(1, 42, 132);'>"${newVariable}<br>${$feature.ADDRESS}"</span></em></span></p>`
HTML += "<p style='text-align: center; line-height: 0.1;'><span style='font-family: Calibri, sans-serif;'><em><span style='font-size: 12px; color: rgb(1, 42, 132);'>"+IIF(isempty(PID),"Pas d'ID Logipro","ID Logipro : "+PID)+"</span></em></span></p>"

//return HTML

return { 
	type : 'text', 
	text : HTML 
}

 

That got me somewhere:

ZachBodenner_0-1701799728651.png

Then I tried adding the new newline formatting that you included in your original post:

var PID = $feature.PID
var HTML = ``
//var newVariable = IIF(isempty(PID),"Pas d'ID Logipro","ID Logipro : "+PID)
HTML += "<p style='text-align: center; line-height: 0.1;'><span style='font-family: Calibri, sans-serif;'><em><span style='font-size: 12px; color: rgb(1, 42, 132);'>"+iif(isempty(PID),"Pas d'ID Logipro","ID Logipro : "+PID+TextFormatting.NewLine+$feature.Address)+"</span></em></span></p>"
//HTML += `<p style='text-align: center; line-height: 0.1;'><span style='font-family: Calibri, sans-serif;'><em><span style='font-size: 12px; color: rgb(1, 42, 132);'>"${newVariable}<br>${$feature.ADDRESS}"</span></em></span></p>`
//HTML += "<p style='text-align: center; line-height: 0.1;'><span style='font-family: Calibri, sans-serif;'><em><span style='font-size: 12px; color: rgb(1, 42, 132);'>"+IIF(isempty(PID),"Pas d'ID Logipro","ID Logipro : "+PID)+"</span></em></span></p>"

//return HTML

return { 
	type : 'text', 
	text : HTML 
}

 

But I did wind up with the same issue as you:

ZachBodenner_1-1701799806381.png

 

Then I tried using the template literal formatting, with backticks, and using the <br> tag to create the carriage return (you don't need to close the break tag, just put it somewhere where you want a new line, along with placing the IIF in a separate variable:

var PID = $feature.PID
var HTML = ``
var newVariable = IIF(isempty(PID),"Pas d'ID Logipro","ID Logipro : "+PID)
//HTML += "<p style='text-align: center; line-height: 0.1;'><span style='font-family: Calibri, sans-serif;'><em><span style='font-size: 12px; color: rgb(1, 42, 132);'>"+iif(isempty(PID),"Pas d'ID Logipro","ID Logipro : "+PID+TextFormatting.NewLine+$feature.Address)+"</span></em></span></p>"
HTML += `<p style='text-align: center; line-height: 0.1;'><span style='font-family: Calibri, sans-serif;'><em><span style='font-size: 12px; color: rgb(1, 42, 132);'>"${newVariable}<br>${$feature.ADDRESS}"</span></em></span></p>`
//HTML += "<p style='text-align: center; line-height: 0.1;'><span style='font-family: Calibri, sans-serif;'><em><span style='font-size: 12px; color: rgb(1, 42, 132);'>"+IIF(isempty(PID),"Pas d'ID Logipro","ID Logipro : "+PID)+"</span></em></span></p>"

//return HTML

return { 
	type : 'text', 
	text : HTML 
}

 

And that got me where I think you want it to be?

ZachBodenner_2-1701799951975.png

 

I think if you're using the Arcade element, it makes the most sense to utilize that

return{

    type: 'text',

    text: 

}

statement, which allows you to utilize the backticks notation and shorten the code a bit. As to why...I'm sure someone else could answer that question better than me.

 

Hope that helps!

0 Kudos
JasonBOCQUET
Occasional Contributor II

I use actually the return things.

 

The point is this : I have a function to get all of my transaction associated at one building (relationship class between building shape and transaction table).

 

there is the code : 

var transactions = FeatureSetByRelationshipName($feature,"SDE.TRANSACTIONS")
var info = ''
for (var f in transactions){
    info += "ID : " + DefaultValue(f.TRA_ADR_ID, 'no data') + TextFormatting.NewLine +
       "Nom immeuble : " +
        DefaultValue(f.TRA_NOM_IMMEUBLE, 'no data') + TextFormatting.NewLine +
        "Montant : " + 
        DefaultValue(f.TRA_MONTANT, 'no data') + TextFormatting.NewLine +
        "Acquéreur : " +
        DefaultValue(f.TRA_ACQUEREUR, 'no data') + TextFormatting.NewLine + TextFormatting.NewLine
}

On one building i can have N transactions associated, so when I click on my pop-up of the building shape, i can see all of the transaction associated, and all of the variables on the transaction are separated by a "TextFormatting.NewLine" to make a line break between variable so the information it show like that :

JasonBOCQUET_0-1701849837045.png

and between each transaction, i would make a line break to have a more airy text.

 

But i think the HTML have to be integrate directly in the function who recover my transaction information (so the part of the code that i share to you in this post) no ? But it is possible to do that ?

 

On your previous exemple, you can't parameter the HTML on the contents of the expression that you write, it's only on the expression himself when it called.

Because I try your thing, and all of my transaction are packed like this :

JasonBOCQUET_1-1701850114755.png

here is the code :

var transactions = FeatureSetByRelationshipName($feature,"SDE.TRANSACTIONS")
var info = ''
for (var f in transactions){
    info += "ID : " + DefaultValue(f.TRA_ADR_ID, 'no data') + TextFormatting.NewLine +
       "Nom immeuble : " +
        DefaultValue(f.TRA_NOM_IMMEUBLE, 'no data') + TextFormatting.NewLine +
        "Montant : " + 
        DefaultValue(f.TRA_MONTANT, 'no data') + TextFormatting.NewLine +
        "Acquéreur : " +
        DefaultValue(f.TRA_ACQUEREUR, 'no data') + TextFormatting.NewLine + TextFormatting.NewLine
}

var newVariable = iif(isempty(info),'Pas de transactions',info);

HTML += `<p style="text-align: left;"><span style="font-size: 16px; font-family: Calibri, sans-serif;"><em><strong>${newVariable}<br></strong></span></p>`

return { 
	type : 'text', 
	text : HTML
}

 

Maybe i miss something in your explanation but i didn't get the point of the utility of the backticks notation to resolve my problem ? 

 

0 Kudos
ZachBodenner
MVP Regular Contributor

One of the utilities of the backticks is so that you don't actually need to rely on textformatting etc.

https://developers.arcgis.com/arcade/guide/template-literals/#:~:text=Template%20literals%20can%20co....

https://www.esri.com/arcgis-blog/products/arcgis-online/mapping/manage-your-strings-quite-literally-...

Here are some ESRI provided resources that can provide a little more info.

 

And here's one more example of using the backticks to make writing HTML returns a bit easier

//set variables. First variable is the unique ID that is shared by the primary and related data. Second variable is calling the related forms as a FeatureSet
 
var treeGlobal = $feature.GlobalID;
var relatedForms = FeatureSetByName($map, "Tree Inventory Form")

//create a filter statement where the maintenance form GUID = the Tree Inventory GlobalID

var filterStatement = "TreeInv_Rel = @treeGlobal"

//a maintenance form equals the table run through the filter
 
var inspForm = Filter(relatedForms, filterStatement)

console (inspForm)

if (isEmpty(inspForm)) {
  var title = ``
}

else if (!isEmpty(inspForm)) {
  var title = `<div style="text-align:center"><b>Inspection Records</b></div><br>` 
}
// Sort related features by oldest to newest
var relatedDataSorted = OrderBy(inspForm, 'Date ASC')
 
// Build the pop-up string by iterating through all related features. Add or subtract new lines in the popupString as needed from the related form.
var popupString = ''
for (var f in relatedDataSorted){
    
    popupString += 
        `<div style="text-align:center"><b>${Text(f.Date, 'MMMM DD, Y')}</b></div><br>    
        <b>Maintenance Performed: </b>${DefaultValue(f.Maintenance_Performed, 'No maintenance performed')}<br>

        <b>Maintenance Performed by: </b>${DefaultValue(f.Performed_By, 'No maintenance performed')}<br>

        <b>Condition:  </b>${DefaultValue(f.Condition, 'Condition not assessed')} <br>

        <b>Chemical Used (if any): </b>${DefaultValue(f.Chemical_Treatment, 'No chemical treatment')} <br>

        <b>Amount Used (if any): </b>${DefaultValue(f.Chemical_Qty_ML, 'No chemical treatment')} <br>
              
        <b>Notes: </b>${DefaultValue(f.Notes, 'No notes')}<br><br>
        `
 
}

return { 
	type : 'text', 
	text : `${title} 
  ${popupString}`
}

 

You'll notice the backticks enclose my final popupstring variable and I just include an extra <br> tag at the end of the loop. That way, multiple related record come in with some breathing room between each.

 

ZachBodenner_0-1701873552904.png

 

JasonBOCQUET
Occasional Contributor II

Ok i understand !

In practice i suceed to combine my typping method with " and your technic with backtricks and it works for what i want to produce. Thanks you ! 

0 Kudos