How to Insert a Line Break in a String in Perspective

Howdy y’all,

We were having issues determining the method to put a line break inside of a string with perspective. We tried the usual
<br> and <br/> and some other CSS code but with no avail.

Thanks

Looks like it depends on the component you are using. If you use the Markdown component, and uncheck the ‘Escape HTML’ checkbox the <br> works similar to Vision module.

I also want to insert line breaks/html formatting into perspective, on a label in this case. The following expression evaluates and displays line breaks correctly in the expression editor, but the resulting label is just a single line with the html tags displayed as text.

"<html>" + dateFormat({[System]Gateway/CurrentDateTime},"h:mm:ss:a") + "<br>" + 
dateFormat({[System]Gateway/CurrentDateTime},"EEEE") + "<br>" + 
dateFormat({[System]Gateway/CurrentDateTime},"MMMM") + 
dateFormat({[System]Gateway/CurrentDateTime},"d")

I’m looking for:

7:00:00:PM
Monday
January 14

I don’t think it works the same in a label (someone from IA would need to confirm why), but is there a reason you can’t use the markdown component? Seems to be essentially a label / text area ?
image

Text displayed in the web is almost always sanitized for safety and security reasons and perspective is no different there. The text you set as a prop (with very specific exceptions such as in the markdown component) is never submitted to the page as interpretable markup. Doing so would open up all kinds of security risks and injection opportunities.

While the markdown component does provide the ability to allow markup, I’d be careful allowing it due to the potential risks involved.

In your example, I’d suggest simply using 3 labels. If you want the convenience of a single expression and consistent layout, I’d suggest creating a ‘view component’ with 3 labels and appropriate formatting, with an input parameter if you want to pass values in.

2 Likes

In the case we are looking at is a multistate button. How do you address this?

Sounds like the ‘recomended’ way would be 2 labels on top of the multistate button.

Meaning you want words to wrap in the label applied to the multistate button?

Labels over the button could do it, or depending on the formatting of the text you're trying to apply, using style properties might also suffice. Can you post a screenshot or sketch of what you're trying to accomplish?

Using the markdown component is not a bad solution for formatting text and will work just fine without enabling markup support. You just have to format your text to use the appropriate markdown syntax for a new line (use two carriage returns instead of injecting a <br>). The markdown component will definitely have a little more overhead than a pure label, but shouldn't be noticeable as long as you aren't filling large tables with them.

Using the markdown component is not a bad solution for formatting text and will work just fine without enabling markup support. You just have to format your text to use the appropriate markdown syntax for a new line (use two carriage returns instead of injecting a <br>).

How do I do this?

I'm creating a multi-state indicator of sorts, and sometimes I want it to display one line of text, other times I want it to display two.

e.g. sometimes I just want "Drive Running" centred in the object, while sometimes I want

Drive Fault
Fault Code: 123

Still centred in the object. Using two labels isn't practical as I'd have to auto-position them based on whether I had one or two lines. I can format text wrapping in styles, but that doesn't help me to force a new line when there's still more room on the first line (I don't think there's a way to do that using styles, happy to be corrected).

So I think the markdown solution is my best shot (unless there's a multi-state indicator coming shortly?).

If I understand correctly, I should not enable markup support for security reasons. This (again, if I understand correctly) means I need to leave the "escape HTML" box checked, which in turn means I can't just use <br> to force a new line.

How do I insert two carriage returns into my expression?

I was able to use\n\r or \r\r or \n\n (two carriage returns) to create a new line in an expression. Probably will want to reduce the sectionSpacing from 24.

5 Likes

None of these options worked for me, they all just displayed in the markdown field exactly as typed. Are you able to paste a screenshot of your setup, in case I’m missing something simple?

Did you type it directly in the source field, or did you use the expression binding. Works for me in the expression binding.

2 Likes

Try toggling escapeHtml property under the markdown object.
This works in the source or expression binding.
image

Disregard. I’m clearly still half asleep and used forward slashes, not backslashes :man_facepalming:

Does toggling the escapeHtml property introduce the security risks mentioned by PerryAJ, though?

I think it’s a security risk if the input is user-generated. In your case for displaying only I wouldn’t think so but I’m not certain.

Thanks. I might break this out into another thread for clarification.

The markdown component does not seem to obey the overflow:hidden style parameter. Am I mistaken?

08%20PM

I’m just now getting started with Perspective, so I’m a little late to this topic. I was struggling with this same topic and stumbled onto this solution which I think addresses this issue but in a less than obvious way and without markup. (V8.0.4)

In the source property if you type enough characters to fill the ‘visible area’ of the source value (this area changes based on how wide you set the properties panel of your designer). Once you’ve typed enough characters to fill that space (and move focus away from the field), you will get the edit icon next to the source property value. You can then click on the edit icon and edit the value in a text area similar to how could in Vision. When editing in the text area, you can simply type the first line, hit enter twice (two carriage returns) and type the second line. There you have it, a line break in a string.
This may become more obvious if you keep the property panel very narrow as the icon only appears if there isn’t enough room in the panel to display all of the text in the property. It would be nice for this property if the icon were always displayed.

Hope this helps anyone else just getting started.

I’ve been using SVG objects with text to allow better font scaling, as well as multi line support.

You do have to modify the view box, as well as the text placement, but that can be automated (if the text is dynamic) or static for each object.

Here’s an example with 2 lines on a button. I’ve also pasted the style class below. (To add a shadow when hovering over the button.)

[
  {
    "type": "ia.shapes.svg",
    "version": 0,
    "props": {
      "viewBox": "0 0 112 20",
      "elements": [
        {
          "type": "text",
          "style": {
            "outlineStyle": "none",
            "textAlign": "center"
          },
          "name": "text",
          "text": "ENGINEERING",
          "y": 7.5,
          "x": 5
        },
        {
          "type": "text",
          "text": "MODE",
          "y": 22.5,
          "x": 33
        }
      ],
      "style": {
        "classes": "Button/TextButton",
        "backgroundColor": "#AAAAAA",
        "textAlign": "center"
      }
    },
    "meta": {
      "name": "EngModeOn_0"
    },
    "position": {
      "height": 0.1618,
      "width": 0.0871,
      "x": 0.8774,
      "y": 0.7321
    },
    "custom": {},
    "events": {
      "dom": {
        "onClick": {
          "type": "script",
          "scope": "G",
          "config": {
            "script": "\t# Write your script here"
          },
          "permissions": {
            "type": "AnyOf",
            "securityLevels": [
              {
                "name": "Authenticated",
                "children": [
                  {
                    "name": "Roles",
                    "children": [
                      {
                        "name": "Automation Engineer",
                        "children": []
                      },
                      {
                        "name": "IgnitionAdministrators",
                        "children": []
                      }
                    ]
                  }
                ]
              }
            ]
          }
        }
      }
    }
  }
]
.psc-TextButton {
  border-color: #000000;
  border-style: solid;
  border-width: 2px;
  border-radius: 8px;
  color: #000000;
  cursor: pointer;
  font-weight: bold;
  padding: 3px;
  text-justify: auto;
  white-space: pre-line;
  word-wrap: break-word;
}
.psc-TextButton:hover {
  box-shadow: 2px 2px #555555;
}
1 Like