Can these techniques also be used when doing “group by” these choice columns? The short answer is no. But fear not, a design decision in SharePoint that normally breaks localization can be used to enable localization.
Let’s have a look at what happens when we see a list that is “grouped by” a choice column. Here it is in English, grouped by “progress”:
We have applied the technique from the Language-dependent JSON column formatting blog post so that the choice column values are localized into French and German. However as we can see below, this does not extend to the “group by” headers, those remain in English. The column value, in blue, is localized, but the same value in the header is not.
The display of values in the columns can be customized by column formatting JSON, but display of values in the group-by headers must be customized by view formatting JSON. Let’s have a look at how we can change that formatting. In the View menu, we can find “Format current view” in the bottom. In this case we are going to format the AllItems (default) list view.
By default it offers the graphical “design mode”.
Let’s select “Advanced mode” to see the JSON. It is initially empty other than the schema declaration, so it uses some default formatting.
There are relatively few examples or information on what to do next, but we will add a minimalist formatting skeleton. The syntax is described here https://learn.microsoft.com/en-us/sharepoint/dev/declarative-customization/view-group-formatting
The “group by” headers are within “headerFormatter” within “groupProps”.
The syntax for “headerFormatter” is identical to that of column format, with the important caveat that a lot of it, despite correct syntax, does not work. Yes, there is a “txtContent”, but things like “@currentField” and “[$FieldName]” are not defined and most special strings, most notably "@UIlcid", are not available.
That makes determining the language and formatting the value depending on the language difficult, because all of the techniques discussed in previous posts are not available.
What is available is "@group", which has three properties, "fieldData", "columnDisplayName", and "count". Normally the use of column display names rather than internal names is a mistake. If you rely on it then things will break badly (like they do for list form JSON formatting) when you change the language, but in this case, that unfortunate design decision can be used to our advantage.
In this case we have already localized the column names by entering the translations in the MUI (Multilingual User Interface) That means that the “Progress” column has a column display name of “Progress” in English, “Progrès” in French, and “Fortschritt” in German. The value of “@group.columnDisplayName” therefore tells us what is the current UI language, as long as the column header has been localized and its name is different in different languages.
If we display the value of “@group.columnDisplayName” and of “@group.fieldData” in English we get this:
We see “Progress=New application” But in French we get “Progrès=New application”
The “columnDisplayName” is localized by the MUI, but the column value is not localized by our column formatting. We can put this all together to take advantage of the display names. In the nested ifs below, we check the value of “@group.columnDisplayName” to determine the current language, then the current value, and then display the appropriate translation of that value.
Here is the result, in French
And in German
What if the user decides to group by Position, a different Choice column, rather than by Progress? There is only one view formatting JSON no matter what you group by, and only one “groupProps” and one “headerFormatter”. Luckily the value of “group.columnDisplayName” detects not only the language but also which column is being grouped by, so you can just extend the nested ifs and localize all the choice columns from the view in a single “txtContent” expression.
The technique of using of “group.columnDisplayName” works for “@group” within the “group by” header as shown above, but it will also work for “@columnAggregate” in the footer and for the “@aggregates” array elements where applicable, and it also works for Gallery view.
Was this useful? Leave us your questions in the comments section below!