Generation of an object property form input via display + edit versus displayHidden

Hi all,

Imagine you have an XClass which, among other properties, has a date property (of type Date with a custom date format) and you need a custom form for displaying an XObject of that class in edit mode, with the date field hidden. I noticed that, as far as the date value formatting is concerned, the two calls below behave differently:

  • $doc.display('date', 'edit', $object) : produces an input element whose value attribute is formatted along the property date format
  • $doc.displayHidden($object.getxWikiClass().date, '', $object): produces an element whose value is not formatted along the property date format

From what I understand, the date displayer (displayer_date.vm) is not used when calling displayHidden. However it contains code for the case where type=="hidden" so I’m confused about the actual expected output and the usage of displayHidden. Any help appreciated :slight_smile:

Cheers

Seems to be the case of all the displayView/Edit/Hidden methods, actually. They seem to be here as helpers to call PropertyClass#display* methods, but it indeed means that they totally miss customizations like templates following a specific naming (like displayer_date.vm) and even worst the custom displayer that would be set in a class from what I see in the code.

We should probably ideally have all the XWikiDocument#displayView/Edit/Hidden methods call XWikiDocument#display with the right type name, but I’m afraid this might break things (code expecting to bypass custom displayers like the custom displayers themself as a fallback).

1 Like

Hello,

There is a need for display functions that bypass the custom displayers, and that need is the implementation of the fallback in these very custom displayers (i.e. a custom displayer that only provides a custom view and falls back on the “standard” edit would use displayEdit() to call the standard edit without ending up in an infinite loop).

@slauriere maybe you want to share with us the need that made you endup using the displayXXX() functions and not the standard display() function that goes through the custom displayer? It would be useful to know that it’s a valid usecase and evaluate how probable it is…

Now, displayHidden() may not be the only function that results in a hidden display (I am thinking about a display() function with parameters, for example, that may allow to make a hidden display that goes through the custom displayer), but this is to be checked, I’m just guessing here.

However, this doesn’t mean that the standard displayHidden() can display a value that is not compatible with a subsequent save and that the fix for that can be only in the functions that go through the custom displayer. This is the whole purpose of displayHidden(), to transport the value through an HTML form, so if indeed the value displayed by displayHidden() cannot be saved, it’s a bug. No going through custom displayers would fix it, it’s a bug.

It will break things, it will cause infinite loops for some custom displayers, as I explained above.

Thank you Thomas and Anca for your insights.

The needs arises imho when one wants to generate a form for an XClass without any prefix for the form input names or ids: the standard display appends a prefix containing the XClass name and the object index (eg XWiki.MyClass_1_myProperty) while in some cases, we want an empty prefix or one that does not contain the object index, so as to control the form input keys. A typical usage consists in creating a “fake” object just for form generation purpose and in calling displayEdit or displayHidden to obtain the form inputs with a value that would be formatted along what the underlying displayer implements.

Just to clarify this: the save that I am talking about here is the /save/ action, the “main” save endpoint that is supposed to be paired with forms created through the display functions.

If another save method (e.g. the REST endpoint) has trouble parsing the values from the forms created with the display() functions, it may not be a bug or it may be a bug of that specific save endpoint.

Indeed, another way to generate a hidden input consists in calling display('myProperty', 'hidden', $object), which then uses the custom displayer. Only the generated prefix can be cumbersome in that case.

Yes, I was just checking that as well.
In addition, apparently there are display() functions that also advertise a prefix as a parameter, but it doesn’t seem to do the same thing as the “prefix” parameter of the displayXXX() functions, which is kinda of a problem.
The prefix of the display() functions is used to prefix the actual full name of the field, already generated using the standard rule (className_objnumber_fieldname) - who even needs that, I wonder? - while the prefix of the displayXXX() functions is used to prefix only the fieldname.
Maybe this right here is the issue we have, that there is no display() function with a prefix that works in the same way as the prefix for displayXXX() function. I am wondering if we ended up here intentionally or by mistake…

Well, in my head it would be nice to be able to generate a form without worrying about the actual UI/UX details of the actual displayers and only having to worry about defining how the information fetched trough that form is delivered to the backend (this means being able to control all the names of the inputs while completely delegating the display details).

Today, it appears like that only existing way to do that is to use the displayXXX() functions (including displayCustom() ) and thus having to be aware which of the fields in your form has a custom displayer and which doesn’t, which is not fully respecting the principle that I mentioned above.

Another way is to completely handle the form elements (thus ignoring whatever UI/UX could be provided by the platform, but this is totally against the goal that I mentioned above…

Another technique that I think I’ve seen is using the standard display() functions and then regexing the transformation of the form input names to whatever it needs to be. But then, as programming folklore nicely explains, we may end up just adding one more problem to the list…

I’m wondering as well what’s the need to prefix the standard prefix with an additional one. If the given prefix could be just be used as is instead of getting concatenated with the standard prefix, that would solve the issue I’m facing :slight_smile: (I had actually overlooked the existence of Document#display methods accepting a prefix parameter, thanks for pointing them out).

It seems this prefix concatenation was introduced in this commit, I cannot understand the exact rationale so far, ccing @ludovic in case you remember the intent.