sharepoint list - column formatting doesn't render correctly in NewForm.aspx or EditForm.aspx (looks fine in DispForm.aspx) - sharepoint-online

I have used JSON column formatting in a SharePoint list. The fields appear correctly formatted in DispForm.aspx, but not EditForm.aspx or NewForm.aspx.
The formatting on the 'span' elements seems to work on all forms, but formatting on the 'div' parent only seems to work on DispForm. Is this by design?
EditForm.aspx
DispForm.aspx
My column formatting JSON for 'Applicant_Approval_Status' is -
{
"$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json",
"elmType": "div",
"style": {
"color":"black",
"background-color": "=if(#currentField == 'Approve', '#D5E8D4', if(#currentField == 'Pending', '#F5F5F5', if(#currentField == 'Reject', '#F8CECC', '#FFE6CC')))",
"border": "='1px solid ' + if(#currentField == 'Approve', '#82B366', if(#currentField == 'Pending', '#666666', if(#currentField == 'Reject', '#B85450', '#D79B00')))"
},
"children":
[
{
"elmType": "span",
"style": {"display": "inline-block", "padding": "0 4px", "background-color": "#D5E8D4"},
"attributes": {"iconName": "=if(#currentField == 'Approve', 'CheckMark', if(#currentField == 'Pending', 'Forward', if(#currentField == 'Reject', 'ErrorBadge', 'Warning')))"}
},
{
"elmType": "span",
"txtContent": "#currentField",
"style":{"background-color": "#D5E8D4"}
}
]
}
I have tried different parent 'elmType' (p, span, button) (As per Formatting syntax reference), but this had no effect.

Related

SharePoint column formatting referring to Hyperlink Column

In my list, I am referring to a hyperlink column on whether or not to show a field in a different column. My hyperlink field name is "Link to Site", so the internal name is "Link_x0020_to_x0020_Site".
I cannot get the logic to show/hide appropriately based on whether the Url in the hyperlink is empty or not - here is the beginning of my json:
{
"$schema": "https: //developer.microsoft.com/en-us/json-schemas/sp/column-formatting.schema.json",
"elmType": "span",
"style": {
"color": "#0078d7",
"display": "=if([$Link_x0020_to_x0020_Site]=='', '', 'none'"
},
If you want to show the span element if hyperlink column is empty, use in this format:
{
"$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json",
"elmType": "span",
"style": {
"color": "#0078d7",
"display": "=if([$Link_x0020_to_x0020_Site] == '', 'inherit', 'none')"
},
If you want to hide the span element if hyperlink column is empty, use in this format:
{
"$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json",
"elmType": "span",
"style": {
"color": "#0078d7",
"display": "=if([$Link_x0020_to_x0020_Site] == '', 'none', 'inherit')"
},
You can also try using block if inherit is not working for you.

Why do groups not respect the parent's padding, except at the top level?

What exactly is the behavior of padding for group marks in Vega? At the top-most level the children groups respect the top-level padding, but this doesn't seem the case for the children's children, they don't respect their parent's padding.
For example, here I would expect to get a rectangle centered in a rectangle centered in another rectangle:
Open the Chart in the Vega Editor
Instead each rectangle seems to be anchored at the origin of the top-level coordinate system.
Note that replacing "padding": {"signal": "level_2_padding"} with "padding": {"value": 0} doesn't seem to have any effect, so I'm not even sure if inner groups can have padding?
How can I best implement nested groups that respect the parent's padding?
There is no padding property on a Group mark. Instead, you can access group properties using Field Values. Something like the following should work.
Editor
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"autosize": "none",
"config": {"group": {"stroke": "black"}},
"signals": [
{"name": "target_height", "value": 400},
{"name": "target_width", "value": 300},
{"name": "level_0_padding", "value": 64},
{"name": "level_1_padding", "update": "1/2 * level_0_padding"},
{"name": "level_2_padding", "update": "1/4 * level_0_padding"},
{"name": "level_0_height", "update": "target_height - 2*level_0_padding"},
{"name": "level_0_width", "update": "target_width - 2*level_0_padding"},
{"name": "level_1_width", "update": "level_0_width - 2*level_1_padding"},
{"name": "level_1_height", "update": "level_0_height - 2*level_1_padding"}
],
"width": {"signal": "level_0_width"},
"height": {"signal": "level_0_height"},
"padding": {"signal": "level_0_padding"},
"marks": [
{
"type": "group",
"signals": [
{
"name": "level_2_width",
"update": "level_1_width - 2*level_2_padding"
},
{
"name": "level_2_height",
"update": "level_1_height - 2*level_2_padding"
}
],
"encode": {
"update": {
"width": {"signal": "level_1_width"},
"height": {"signal": "level_1_height"},
"x": {"signal": "level_0_width-level_1_width - level_1_padding"},
"y": {"signal": "level_0_height-level_1_height - level_1_padding"},
"stroke": {"value": "red"},
"strokeOpacity": {"value": 0.5}
}
},
"marks": [
{
"type": "group",
"encode": {
"update": {
"width": {"signal": "level_2_width"},
"height": {"signal": "level_2_height"},
"x": {
"field": {"group": "width"},
"mult": 0.5,
"offset": {"signal": "-level_2_width/2"}
},
"y": {
"field": {"group": "height"},
"mult": 0.5,
"offset": {"signal": "-level_2_height/2"}
},
"stroke": {"value": "blue"},
"strokeOpacity": {"value": 0.5}
}
}
}
]
}
]
}
I'll accept David's answer, but also post my own to complement David's.
Here's an alternative solution specification, like David's spec it uses the "x" and "y" group properties, but I think it's a bit simpler and closer to what I need: Open the Chart in the Vega Editor
An important point that I have to mention is that using layout prevents x and y from working, that is: groups directly contained in a layout/grid may not be offset using x or y.

How to display multiple Lookup column values on one line whilst retaining the links

By default, the values in a Lookup column display as links.
Clicking on these links takes you to the relevant item in the lookup list.
When setting the column to Allow multiple values, each value is displayed on a separate line.
To make the values appear on one line, I have applied this column formatting:
{
"$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json",
"elmType": "div",
"txtContent": "=join(#currentField.lookupValue, ', ')"
}
This results in the desired behavior of the values being on one line, separated by commas, eg:
Value1, Value2, Value3
However, the values are just plain text, ie the links have been removed.
How can I retain the links for each of the values, whilst still displaying them on one line.
Edit 1:
It seems that Lookup columns have two properties available via column formatting:
.lookupValue
.lookupId
When you click on a link in a Lookup column, it goes to a URL with this structure:
https://tenant-name.sharepoint.com/sites/site-name/Lists/Some%20List/DispForm.aspx?ID=n
Where the n at the end of the URL is the lookupId.
So one possible solution would be to:
use .lookupId to get the ID of the item in the lookup list
for each value in the lookup column, construct the URL and concatenate the .lookupId value to the end
Using this post an inspiration, the following code almost works, but the ID value in each of the links is output as the same (and is also incorrect):
{
"$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json",
"elmType": "div",
"children": [
{
"elmType": "a",
"style": {
"display": "block",
"width": "100%"
},
"txtContent": "=join(#currentField.lookupValue, ', ')",
"attributes": {
"target": "_blank",
"href": "='https://tenant-name.sharepoint.com/sites/site-name/Lists/Some%20List/DispForm.aspx?ID=' + [$ID]"
}
}
]
}
Edit 2:
Based on this answer, which references this blog post, the following achieves the desired behaviour using forEach, but it adds a trailing comma on the end of all last values in the column:
{
"$schema": "https://developer.microsoft.com/json-schemas/sp/column-formatting.schema.json",
"elmType": "div",
"children": [
{
"forEach": "lookupIterator in #currentField",
"elmType": "a",
"txtContent": "=[$lookupIterator.lookupValue] + ', '",
"attributes": {
"target": "_blank",
"href": "='https://tenant-name.sharepoint.com/sites/site-name/Lists/Some%20List/DispForm.aspx?ID=' + [$lookupIterator.lookupId]"
}
}
]
}
Below is another way to do it using operator and operands but it still shows the undesired trailing comma:
{
"$schema": "https://developer.microsoft.com/json-schemas/sp/column-formatting.schema.json",
"elmType": "div",
"children": [
{
"forEach": "lookupIterator in #currentField",
"elmType": "a",
"txtContent": {
"operator": "+",
"operands": [
"[$lookupIterator.lookupValue]", ", "
]
},
"attributes": {
"target": "_blank",
"href": "='https://tenant-name.sharepoint.com/sites/site-name/Lists/Some%20List/DispForm.aspx?ID=' + [$lookupIterator.lookupId]"
}
}
]
}
I don't know if it's possible to somehow define different concatenation on the last item in the loop, with something like:
"=if(loopIndex('lookupIterator') == length(#currentField - 1), 'DON'T ADD COMMA', 'DO ADD COMMA')"
This seems to work:
{
"$schema": "https://developer.microsoft.com/json-schemas/sp/column-formatting.schema.json",
"elmType": "div",
"children": [
{
"forEach": "lookupIterator in #currentField",
"elmType": "a",
"txtContent": "=if(loopIndex('lookupIterator') == length(#currentField) - 1, [$lookupIterator.lookupValue], [$lookupIterator.lookupValue] + ', ')",
"attributes": {
"target": "_blank",
"href": "='https://tenant-name.sharepoint.com/sites/site-name/Lists/Some%20List/DispForm.aspx?ID=' + [$lookupIterator.lookupId]"
}
}
]
}
It uses forEach, an if() statement, loopIndex and length() to concatenate values conditionally, i.e:
if it's the last item in the loop, don't add the separating comma
if it's not the last item in the loop, do add the separating comma
To be honest, i'm surprised the conditional structure worked in there, and the referenced column values as well.
Bonus
It seems you can also add a style property under txtContent which uses the same conditional logic, just to make the gap between values larger than the default 1 space character, i.e:
"style": {
"padding-right": "=if(loopIndex('lookupIterator') == length(#currentField) - 1, '0px', '5px'"
},

Working example to custom-format a column title/header?

I have a formatter that works for column data, using column parameter formatter. Using the same formatter with column parameter titleformatter, I get the error noted below. Also, I don't understand why HTML in title parameter text seems not to work for <b> ... </b> but does work for other things (e.g., <i> ... </i>. A working custom formatter example would help. (I don't see this in Tabulator documentation.) See this montage combining a column header and row header screenshot with common cell text---'bold' in the row looks bolder to me.
Cell text comparison screenshot montage
I've tried emulating some posted sample code, but I get the same error as reported by #dagroj in his comment to #Oli Folkerd's answer (to the question) about titleformatter --- viz. tabulator.min.js:2 Uncaught TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'. (Mentioning that here because I don't yet have the reputation to comment there.)
Here is a rendering of my CPT, without the titleformatter.
Corresponding table constructor:
"columnVertAlign": "bottom",
"height": "100%",
"layout": "fitColumns",
"columns": [
{
"title": "<i> absolute_T<--T (noisyAnd)</i>",
"columns": [
{
"title": "<b> NotCorrAnd_EffectiveHyp</b>",
"field": "label",
"align": "right",
"headerSort": false
}
]
},
{
"title": "NotB_EffectiveHyp",
"columns": [
{
"title": "<b>T</B>",
"field": "true",
"align": "center",
"headerSort": false
},
{
"title": "<i>F</i>",
"field": "false",
"align": "center",
"headerSort": false
}
]
},
{
"title": "<b> Belief </b>",
"columns": [
{
"title": "odds",
"field": "odds",
"align": "center",
"headerSort": false
},
{
"title": "log<sub>2</sub> odds",
"field": "log2odds",
"align": "center",
"headerSort": false
}
]
}
]
}
Formatter:
function truthFormatter(cell, formatterParams, onRendered) {
var cellValue = cell.getValue();
var cellElement = cell.getElement();
if (cellValue == "T") {
cellElement.style.backgroundColor = "#0000B3";
cellElement.style.color = "#FFFFFF";
cellElement.style.textAlign = "center";
cellElement.style.fontWeight = "bold";
}
else if (cellValue == "F") {
cellElement.style.backgroundColor = "#B30000";
cellElement.style.color = "#FFFFFF";
cellElement.style.textAlign = "center";
cellElement.style.fontWeight = "bold";
}
else cellElement.style.color = "#000000";
return cell.getValue();
}
Column headers are by default styled to be bold, so adding a bold or strong tag will not make them any bolder. On a side not you are using a mix of lowercase and uppercase "b" in your tags
If you are getting that error it means that your formatter is not returning a valid value, it must either be a string/number or a DOM element of type Node.

Zingchart how to add custom legend item

I have a bar chart with 3 kinds of bar: FOO, BAR and BAZ.
Horizontal axis are quarters.
BAR and BAZ use the same series. BAR (blue) becoming BAZ (orange) after Q1-17.
"rules": [{
"rule": "%kv > 1",
"background-color":"orange"
}]
How can I add BAZ (orange) to the legend?
zingchart.THEME = "classic";
var myConfig = {
"graphset": [{
"type": "bar",
"background-color": "white",
"plotarea": {
"margin": "80 60 100 60",
"y": "125px"
},
"legend": {
"layout": "x3",
"y": "13%",
"x": "34.5%",
"overflow": "page",
"toggle-action": "remove",
},
"scale-x": {
"labels": [
"Q4-16",
"Q1-17",
"Q2-17",
"Q3-17"
],
"markers": [{
"value-range": true,
"range": [1.5],
"line-color": "red",
"line-width": 1,
"line-style": "solid",
"type": "line"
}]
},
"series": [{
"values": [
37.47,
57.59,
45.65,
37.43
],
"background-color": "#8993c7",
"text": "FOO"
},
{
"values": [
13.4,
14.11,
14.89,
16.86
],
"background-color": "blue",
"text": "BAR",
"rules": [{
"rule": "%kv > 1",
"background-color": "orange"
}]
}
]
}]
};
zingchart.render({
id: 'myChart',
data: myConfig,
height: 500,
width: 725
});
.zc-ref {
display: none;
}
<html>
<head>
<script src="https://cdn.zingchart.com/zingchart.min.js"></script>
<script>
zingchart.MODULESDIR = "https://cdn.zingchart.com/modules/";
ZC.LICENSE = ["569d52cefae586f634c54f86dc99e6a9", "ee6b7db5b51705a13dc2339db3edaf6d"];
</script>
</head>
<body>
<div id='myChart'><a class="zc-ref" href="https://www.zingchart.com/">Charts by ZingChart</a></div>
</body>
</html>
So one way to do it is split up your data. The easiest way to explain this is to make another series for "BAZ" and in the first two quarters have null values.
demo here
The main reason for doing it this way is maintaining the built in legend toggling functionality. This way when you click it wont turn off the whole series (blue and orange bars.) Which I assume is the intended functionality.
If you don't mind turning off blue and orange bars at the same time you can do the following to add another legend item. Add the text and color inside the series object. Essentially, create a blank series object.
...{
"text":"BAZ",
"background-color":"orange"
}...
non interactive legend demo here
If you are looking for something in between these two demos it will take some custom Javascript using the ZingChart API.

Resources