Skip to content

fix(#805): allow labels with computed media urls#806

Open
garethbowen wants to merge 2 commits intomainfrom
805-outputs-in-media
Open

fix(#805): allow labels with computed media urls#806
garethbowen wants to merge 2 commits intomainfrom
805-outputs-in-media

Conversation

@garethbowen
Copy link
Copy Markdown
Collaborator

Closes #805

I have verified this PR works in these browsers (latest versions):

  • Chrome
  • Firefox
  • Safari (macOS)
  • Safari (iOS)
  • Chrome for Android
  • Not applicable

What else has been done to verify that this works as intended?

Why is this the best possible solution? Were any other approaches considered?

How does this change affect users? Describe intentional changes to behavior and behavior that could have accidentally been affected by code changes. In other words, what are the regression risks?

Do we need any specific form for testing your changes? If so, please attach one.

7-images-choice-computed.xml in this PR

What's changed

Media chunks are combined into a single string which is treated as the URL so if there are multiple elements in the chunk it still works.

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 7, 2026

🦋 Changeset detected

Latest commit: 992cee8

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@getodk/xforms-engine Patch
@getodk/web-forms Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

const setMedia = (value: string) => {
mediaUrl.value = value;
loading.value = false;
errorMessage.value = '';
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without this the first time through media was successfully loaded but because it's async it never showed because the message took precedence.

if (isElementNode(grandchild)) {
const expression = TextChunkExpression.fromOutput(grandchild);
if (expression) {
parts.push(createComputedExpression(context, expression)());
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the crux of the change - by evaluating the output element the reactive code updates when the value changes.

chunkExpression.stringValue as JRResourceURLString
);
const url = chunkExpression.stringValue?.trim();
if (JRResourceURL.isJRResourceReference(url)) {
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This validation step is important... if you call JRResourceURL.from with an invalid URL it throws an Error which can be fatal. If this is based on user input, or at load time the input is blank, then we should just handle it gracefully.

@garethbowen garethbowen requested a review from latin-panda May 7, 2026 06:13
@garethbowen
Copy link
Copy Markdown
Collaborator Author

@latin-panda This isn't urgent IMO but was an interesting problem to solve while I was waiting for the monorepo code to land. But I'm happy enough with the solution to send it for review.

Copy link
Copy Markdown
Collaborator

@latin-panda latin-panda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice ✨ I didn't spot any regression. Could you please add a scenario test for this case?

@garethbowen
Copy link
Copy Markdown
Collaborator Author

Could you please add a scenario test for this case?

Added testing for image, audio, and video, both hardcoded and calculated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Outputs in text range media chunks do not work

2 participants