Skip to content

In view, label of date and number fields isn't read #6707

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
avernet opened this issue Jan 6, 2025 · 13 comments
Closed

In view, label of date and number fields isn't read #6707

avernet opened this issue Jan 6, 2025 · 13 comments
Assignees

Comments

@avernet
Copy link
Collaborator

avernet commented Jan 6, 2025

See how how, for the first control, the <span>1/14/2025</span> is missing a number of the aria- attributes, while those are present to <span>52</span> for the second control.

Screenshot 2025-01-06 at 3 53 35 PM

Form in Form Builder on demo
+1 from customer

@ebruchez
Copy link
Collaborator

ebruchez commented Jan 7, 2025

In both cases, we use xf:input in static readonly mode: one within the fr:date, one as a standalone xf:input.

The handler for xf:input uses outputStaticReadonlyField(). This uses handleAriaByAtts() (which is probably badly named). Now, in the case of fr:date, nothing links the nested xf:input to the fr:date label. We use xxbl:label-for="input", which points to the regular, read-write xh:input, but the xh:input is not linked. Currently, we can only link one nested control, not two. We probably would like to write:

 xxbl:label-for="readwrite-input readonly-input"

I was thinking that alternatively, we could have the static-readonly detection be semi-statically-detected: when we build the subtree for the component, if we knew the readonly value, we could build only a single branch of the control. However, the tree is built entirely statically, without knowledge of the data, so we can't depend on the data. If we could otherwise know which controls are static-readonly, the we would be able to do that. This might be worth doing, but probably not as part of this bug.

So could we link two or more controls/elements with xxbl:label-for?

@avernet avernet changed the title In view, label of date field isn't not read In view, label of date and number fields isn't not read Jan 7, 2025
@avernet
Copy link
Collaborator Author

avernet commented Jan 7, 2025

I updated the title and example to show that this problem also occurs with the number field. Hopefully, the solution for both the date and number fields will be the same.

@ebruchez
Copy link
Collaborator

ebruchez commented Jan 8, 2025

We store a single LHHAAnalysis.lhhaPlacementType, which is then used in a few places. This is used:

  • Local.directTargetControl
  • External.forRepeatNestingOpt
  • isForRepeat
  • isLocal

However, if we restrict what xxbl:label-for can do, this might work:

  • single target: like now
  • multiple targets
    • cannot be Local
    • External must not point to a nested repeat (all must be non-repeated)
    • but they can mix and match LhhaControlRef.Control and LhhaControlRef.PrefixedId (as fr:date would)

Thinking about this, I am not sure it will work given the number of cases to handle! And annoyingly, we would be implementing this just to handle two exclusive branches: regular, and static-readonly. It does not, for now at lesat, satisfy other valid use cases, and that would come at the price of complexity.

Can we explore the alternative of updating components with a static-readonly annotation? What it would take:

  • in components.xsl/controls.xsl: add an attribute to controls within grids
    • for example fr:static-readonly="true"
    • this is ok, because new/edit and view/pdf are separate compiled forms
  • create new XBL bindings that bind to:
    • `fr|date[fr:static-readonly = true], xf|input[fr:static-readonly = true]:xxf-type('xs:date')
    • same for fr:number, maybe others
    • Q: Do we support the binding logic?
      • Form Builder to support cumulative appearances #4370 seems to say that we support the representation in BindingDescriptor
      • but we don't support this in Form Builder (which is ok for this current issue)
      • but do we support the binding logic at all? we imply that not; if not, would that be easy?

@ebruchez
Copy link
Collaborator

ebruchez commented Jan 8, 2025

BindingIndex.findMostSpecificBinding(). BindingDescriptor, right now, only holds a single optional attribute selector. This would work for a plain fr:date and fr:number, since they don't match on anything else, but it wouldn't work for fr:dropdown-date, in particular, which has xf|input:xxf-type('xs:date')[appearance ~= dropdowns].

In this Gist I show which bindings based on attributes we have right now for the Controls form. We bind on:

  • appearance
  • mediatype (xf:textarea)
  • repeat, bind, nodeset, ref (fr:grid)

@ebruchez
Copy link
Collaborator

ebruchez commented Jan 8, 2025

So we do have the ability to match on different attributes, just a single attribute at a time. The code does check all attributes of the element for a match.

@ebruchez
Copy link
Collaborator

ebruchez commented Jan 8, 2025

Issue: right now we determine xxf:readonly-appearance="static" using an XForms AVT, which is lazily evaluated. So we don't know it yet at form transformation time. Yet we should be able to know it, right?

xxf:readonly-appearance="{{
    for $mode in fr:mode()
    return
        if (
            $mode = 'view' or (
                $mode = ('pdf', 'test-pdf', 'email') and not(fr:use-pdf-template())
            )
        ) then
            'static'
        else
            'dynamic'
}}"

The mode as known by XSLT and the mode as known by XForms can differ:

<xf:bind
    ref="instance('fr-parameters-instance')/mode"
    xxf:default="
        if (. = ('tiff', 'test-pdf')) then
            'pdf'
        else if (. = ('export', 'excel-export') and xxf:is-blank(../document)) then
            'new'
        else if (. = ('export', 'excel-export') and xxf:non-blank(../document)) then
            'edit'
        else
            ."/>

(Based on this, testing on 'test-pdf' in the first case above should not be needed.)

fr:use-pdf-template() depends on:

  • content of fr-form-attachments (so form definition, which is ok)
  • req.getMethod
  • req.getFirstParamAsString for fr-use-pdf-template

The latter two are annoying, because that means we depend on parameters and method. Does that mean we'd possibly generate two different compiled forms depending on whether we are doing a POST or not? This is unclear.

@ebruchez
Copy link
Collaborator

ebruchez commented Jan 14, 2025

After further discussion. I dislike the first approach of supporting multiple references for label-for, because that's not a feature we want in itself. In practice, we always only want a single target for label-for.

The annotation approach might be better, but it is work. In the longer term, we don't want the PDF template to work the way it does (#1573). But in the meanwhile, it is probably ok to modify components.xsl to depend on fr-use-pdf-template and on the HTTP method. This would cause a different compiled version for the form. The only issue is it is not an insignificant change.

  • move static-readonly detection to components.xsl
  • add annotations on controls within grids
  • create separate XBL components for static-readonly appearances:
    • fr:date
    • fr:time
    • fr:datetime
    • fr:number
    • fr:currency
  • fr:component-param-value('foo') takes configuration from, for example, xbl.fr.date-output.foo
    • this doesn't work for finding things such as oxf.xforms.xbl.fr.currency.prefix, which should remain in sync with the read-write implementation
  • fix natural width for Fields Date, Dropdown Date, Date and Time in static readonly
  • can we update selector parsing to support [fr|static-readonly = true]?
  • Form Builder shows extra XBL components in toolbox
  • tests
    • unit test for annotations: run form definition through unroll-form.xpl?
    • manual (or automated?) test of PDF output scenarios

@ebruchez
Copy link
Collaborator

ebruchez commented Feb 20, 2025

One issue with fr:date and fr:time: if fr:component-param-value('native-picker') = 'always', in static readonly, we still output the HTML xh:input "to have consistent output format". Can figure this out outside of fr:date/fr:time? Not ideal, but maybe the only way?

  • make determination outside of XBL for fr:date and fr:time

@avernet avernet changed the title In view, label of date and number fields isn't not read In view, label of date and number fields isn't read Feb 20, 2025
@ebruchez
Copy link
Collaborator

  • check why we have an aria-labelledby pointing to a <span>, instead of <label> pointing to <input>

@ebruchez
Copy link
Collaborator

In handleLabel(), we have the following to output a <span> in static readonly mode instead of a <label>:

protected def handleLabel(lhhaAnalysis: LHHAAnalysis): Unit =
  handleLabelHintHelpAlert(
    lhhaAnalysis            = lhhaAnalysis,
    controlEffectiveIdOpt   = XFormsBaseHandler.isStaticReadonly(currentControl) option getEffectiveId,
    forEffectiveIdWithNsOpt = getForEffectiveIdWithNs(lhhaAnalysis),
    requestedElementNameOpt = XFormsBaseHandler.isStaticReadonly(currentControl) option "span",
    control                 = currentControl
  )

On the other side, we use handleAriaByAtts() to place ariea-labelledby and others, but it's unclear what the logic is here.

@ebruchez
Copy link
Collaborator

Discussion with @avernet: with the current solution, the decision about whether to show a static readonly date or time, due to the native picker logic, is taken externally from fr:date and fr:time, which is not ideal. We could possibly improve this in the future by providing more attributes on the controls: instead or in addition to static-readonly, we could maybe add:

  • mode
  • use-pdf-template
  • native-picker (resolved using form/properties as well)

and have the binding selector use the combination of these extra attributes to make the decision.

ebruchez added a commit that referenced this issue Feb 22, 2025
ebruchez added a commit that referenced this issue Feb 22, 2025
- they would NPE if there was no query string
ebruchez added a commit that referenced this issue Feb 22, 2025
ebruchez added a commit that referenced this issue Feb 25, 2025
@ebruchez
Copy link
Collaborator

Included in 2024.1.1. However, a backport to 2023.1.x might be too difficult.

@avernet
Copy link
Collaborator Author

avernet commented Feb 28, 2025

Included in 2024.1.1. However, a backport to 2023.1.x might be too difficult.

I removed this from the 2023.1.8 project.

ebruchez added a commit that referenced this issue Mar 3, 2025
ebruchez added a commit that referenced this issue Mar 5, 2025
ebruchez added a commit that referenced this issue Mar 10, 2025
- remove extra `xf:group`
- remove some CSS duplication
- remove unneeded `date` CSS class
ebruchez added a commit that referenced this issue Mar 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Development

No branches or pull requests

2 participants