Skip to content

Commit

Permalink
feat: add toggleCorrectResponse method to display correct answer in t…
Browse files Browse the repository at this point in the history
…ext entry interaction
  • Loading branch information
Marcelh1983 committed Feb 14, 2025
1 parent 812eafe commit 52d0c67
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { createRef } from 'lit/directives/ref.js';
import { Interaction } from '../../../exports/interaction';
import styles from './qti-text-entry-interaction.styles';

import type { ResponseVariable } from '../../../exports/variables';
import type { CSSResultGroup } from 'lit';
@customElement('qti-text-entry-interaction')
export class QtiTextEntryInteraction extends Interaction {
Expand Down Expand Up @@ -59,6 +60,33 @@ export class QtiTextEntryInteraction extends Interaction {
return this._value !== '' && input.checkValidity();
}

public toggleCorrectResponse(responseVariable: ResponseVariable, show: boolean): void {
const input = this.shadowRoot.querySelector('input');
if (show && responseVariable.correctResponse) {
const text = responseVariable.correctResponse.toString();
if (text) {
if (!input.nextElementSibling?.classList.contains('correct-option')) {
const textSpan = document.createElement('span');
textSpan.classList.add('correct-option');
textSpan.textContent = text;

// Apply styles
textSpan.style.border = '1px solid var(--qti-correct)';
textSpan.style.borderRadius = '4px';
textSpan.style.padding = '2px 4px';
textSpan.style.margin = '4px';
textSpan.style.display = 'inline-block';

input.insertAdjacentElement('afterend', textSpan);
}
} else if (input.nextElementSibling?.classList.contains('correct-option')) {
input.nextElementSibling.remove();
}
} else {
input.nextElementSibling.remove();
}
}

override render() {
return html`
<input
Expand All @@ -83,6 +111,7 @@ export class QtiTextEntryInteraction extends Interaction {
<div part="correct">${this._correctResponse}</div>
`;
}

protected textChanged(event: Event) {
if (this.disabled || this.readonly) return;
const input = event.target as HTMLInputElement;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import meta, {
SelectPointMultipleNoAreaMapping as SelectPointMultipleNoAreaMappingStory,
GraphicOrder as GraphicOrderStory,
GapMatch as GapMatchStory,
TextEntry as TextEntryStory,
GraphicAssociate as GraphicAssociateStory,
Slider as SliderStory
} from './item-show-correct-response.stories';
Expand All @@ -30,6 +31,7 @@ const graphicOrderStory = composeStory(GraphicOrderStory, meta);
const graphicAssociateStory = composeStory(GraphicAssociateStory, meta);
const gapMatchStory = composeStory(GapMatchStory, meta);
const sliderStory = composeStory(SliderStory, meta);
const textEntryStory = composeStory(TextEntryStory, meta);

// Helper function to resolve loaders and render story
async function setupStory(story, canvasElement) {
Expand Down Expand Up @@ -94,6 +96,11 @@ describe.sequential('ItemShowCorrectResponse Suite', () => {
await graphicAssociateStory.play({ canvasElement });
});

test('show correct response - TextEntry', async () => {
await setupStory(TextEntryStory, canvasElement);
await textEntryStory.play({ canvasElement });
});

test('show correct response - GapMatch', async () => {
await setupStory(GapMatchStory, canvasElement);
await gapMatchStory.play({ canvasElement });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,57 @@ export const MultipleResponse: Story = {
}
};

export const TextEntry: Story = {
args: {
'item-url': '/qti-test-package/items/text_entry.xml' // Set the new item URL here
},
render: args =>
html` <qti-item>
<div>
<item-container style="display: block;width: 400px; height: 350px;" item-url=${args['item-url']}>
<template>
<style>
qti-assessment-item {
padding: 1rem;
display: block;
aspect-ratio: 4 / 3;
width: 800px;
border: 2px solid blue;
transform: scale(0.5);
transform-origin: top left;
}
</style>
</template>
</item-container>
<item-show-correct-response ${spread(args)}></item-show-correct-response>
</div>
</qti-item>`,
play: async ({ canvasElement, step }) => {
// wait for qti-simple-choice to be rendered
const canvas = within(canvasElement);
await waitFor(
() => {
const interaction = canvasElement
.querySelector('item-container')
.shadowRoot.querySelector('qti-text-entry-interaction');
if (!interaction) {
throw new Error('interaction not loaded yet');
}
},
{ timeout: 5000 }
);
const interaction = canvasElement
.querySelector('item-container')
.shadowRoot.querySelector('qti-text-entry-interaction');
const showCorrectButton = canvas.getAllByShadowText(/Show correct/i)[0];
await step('Click on the Show Correct button', async () => {
await showCorrectButton.click();
interaction.shadowRoot.querySelector('.correct-option').textContent = 'York';
});
}
};

export const GapMatch: Story = {
args: {
'item-url': '/qti-test-package/items/gap_match.xml' // Set the new item URL here
Expand Down

0 comments on commit 52d0c67

Please sign in to comment.