openmrs / openmrs-esm-form-engine-lib

React Form Engine library for O3
Other
10 stars 59 forks source link

(feat) O3-3359: Add ability to clear radio button values #344

Closed CynthiaKamau closed 3 months ago

CynthiaKamau commented 3 months ago

Requirements

Summary

When an answer is selected on a radio button field the is no way the user can clear is selection. This pr attempts to address that.

Screenshots

https://github.com/openmrs/openmrs-form-engine-lib/assets/19533785/96d0646f-2d35-4d3f-ae84-f103a4f20f51

Related Issue

Other

github-actions[bot] commented 3 months ago

Size Change: +2.52 kB (+0.25%)

Total Size: 1.01 MB

ℹ️ View Unchanged | Filename | Size | Change | | :--- | :---: | :---: | | `dist/184.js` | 11.2 kB | 0 B | | `dist/195.js` | 76.6 kB | 0 B | | `dist/225.js` | 2.57 kB | 0 B | | `dist/29.js` | 166 kB | +2.56 kB (+1.57%) | | `dist/300.js` | 709 B | 0 B | | `dist/327.js` | 1.84 kB | 0 B | | `dist/335.js` | 967 B | 0 B | | `dist/353.js` | 3.02 kB | 0 B | | `dist/41.js` | 3.36 kB | 0 B | | `dist/422.js` | 6.79 kB | 0 B | | `dist/474.js` | 116 kB | 0 B | | `dist/491.js` | 9.18 kB | 0 B | | `dist/540.js` | 2.63 kB | 0 B | | `dist/55.js` | 756 B | 0 B | | `dist/635.js` | 14.3 kB | 0 B | | `dist/70.js` | 482 B | 0 B | | `dist/708.js` | 245 kB | -17 B (-0.01%) | | `dist/776.js` | 3.2 kB | 0 B | | `dist/99.js` | 690 B | 0 B | | `dist/993.js` | 3.09 kB | 0 B | | `dist/main.js` | 343 kB | -25 B (-0.01%) | | `dist/openmrs-form-engine-lib.js` | 3.72 kB | 0 B |

compressed-size-action

samuelmale commented 3 months ago

@CynthiaKamau I pushed a commit to simplify the logic, can you kindly test out the latest changes?

CynthiaKamau commented 3 months ago

@CynthiaKamau I pushed a commit to simplify the logic, can you kindly test out the latest changes?

A heads up on the ticket would have been nice to avoid duplicated efforts

samuelmale commented 3 months ago

The PR title reads like it also addresses a similar problem for the "select" inputs but I don't see any related logic, is this a draft? Did we reach a consensus on how to approach this?

If not, here is a rough one:

The idea is adding an extra option (at index 0) which represents empty or "no-op". The tricky part is the wording for the label. I've seen many forms with real options labeled as "None", "N/A" etc. To solve this problem, we can drive this through a config:

{
  "id": "example-question",
  "label": "Example Question",
  "questionOptions": {
    "rendering": "select",
    "answers": [
      { "label": "Option 1", "value": "1" },
      { "label": "Option 2", "value": "2" }
    ],
    "emptyOptionLabel": "None",
  }
}

We then add this option conditionally based on whether emptyOptionLabel exists:

(src/transformers/default-schema-transformer.ts)

function setFirstDropdownOptionToNoop(question: FormField) {
  const label = question.questionOptions['emptyOptionLabel'];
  if (Array.isArray(question.questionOptions.answers) && label) {
    const firstOption = question.questionOptions.answers[0];
    if (firstOption?.value !== '') {
      question.questionOptions.answers.unshift({ label, value: 'NOOP' });
    }
  }
}

// ... existing code ...
function transformByRendering(question: FormField) {
  switch (question.questionOptions.rendering as any) {
    // ... existing code ...
    case 'select':
      setFirstDropdownOptionToNoop(question);
      break;
    // ... existing code ...
  }
  return question;
}

We then adjust the input:

   <DropdownInput
          id={question.id}
          // other props
          onChange={({ selectedItem }) => handleChange(selectedItem === 'NOOP' ? null : selectedItem)}
         />

Thoughts?? @brandones @arodidev @denniskigen