Skip to content
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

Fix rating navigation inside matrix #8173

Merged
merged 1 commit into from Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -2,7 +2,7 @@
<label [style]="model.getItemStyle(item.itemValue, item.highlight)" [class]="model.getItemClass(item.itemValue, item.highlight)" (mouseover)="model.onItemMouseIn(item)" (mouseout)="model.onItemMouseOut(item)" (mousedown)="model.onMouseDown()">
<input type="radio"
class="sv-visuallyhidden"
[attr.name]="model.name" [attr.id]="model.getInputId(index)" [value]="item.value" [attr.aria-required]="model.ariaRequired" [attr.aria-label]="model.ariaLabel" [attr.aria-invalid]="model.ariaInvalid" [attr.aria-errormessage]="model.ariaErrormessage"
[attr.name]="model.questionName" [attr.id]="model.getInputId(index)" [value]="item.value" [attr.aria-required]="model.ariaRequired" [attr.aria-label]="model.ariaLabel" [attr.aria-invalid]="model.ariaInvalid" [attr.aria-errormessage]="model.ariaErrormessage"
[disabled]="model.isInputReadOnly" [checked]="model.value === item.value" (click)="onClick($event)"
/>
<svg [iconName]="model.getItemSmileyIconName(item.itemValue)" [size]="'auto'" [title]="item.text" sv-ng-svg-icon></svg>
Expand Down
Expand Up @@ -2,7 +2,7 @@
<label [class]="model.getItemClass(item.itemValue, item.highlight)" (mouseover)="model.onItemMouseIn(item)" (mouseout)="model.onItemMouseOut(item)" (mousedown)="model.onMouseDown()">
<input type="radio"
class="sv-visuallyhidden"
[attr.name]="model.name" [attr.id]="model.getInputId(index)" [value]="item.value" [attr.aria-required]="model.ariaRequired" [attr.aria-label]="model.ariaLabel" [attr.aria-invalid]="model.ariaInvalid" [attr.aria-errormessage]="model.ariaErrormessage"
[attr.name]="model.questionName" [attr.id]="model.getInputId(index)" [value]="item.value" [attr.aria-required]="model.ariaRequired" [attr.aria-label]="model.ariaLabel" [attr.aria-invalid]="model.ariaInvalid" [attr.aria-errormessage]="model.ariaErrormessage"
[disabled]="model.isInputReadOnly" [checked]="model.value === item.value" (click)="onClick($event)"
/>
<svg [iconName]="model.itemStarIcon" [size]="'auto'" [title]="item.text" [class]="'sv-star'" sv-ng-svg-icon></svg>
Expand Down
Expand Up @@ -2,7 +2,7 @@
<label [class]="model.getItemClassByText(item.itemValue, item.text)" (mousedown)="model.onMouseDown()">
<input type="radio"
class="sv-visuallyhidden"
[attr.name]="model.name" [attr.id]="model.getInputId(index)" [value]="item.value" [attr.aria-required]="model.ariaRequired" [attr.aria-label]="model.ariaLabel" [attr.aria-invalid]="model.ariaInvalid" [attr.aria-errormessage]="model.ariaErrormessage"
[attr.name]="model.questionName" [attr.id]="model.getInputId(index)" [value]="item.value" [attr.aria-required]="model.ariaRequired" [attr.aria-label]="model.ariaLabel" [attr.aria-invalid]="model.ariaInvalid" [attr.aria-errormessage]="model.ariaErrormessage"
[disabled]="model.isInputReadOnly" [checked]="model.value === item.value" (click)="onClick($event)"
/>
<span [class]="model.cssClasses.itemText" [model]="item.locText" sv-ng-string></span>
Expand Down
Expand Up @@ -7,7 +7,7 @@
<input
type="radio"
class="sv-visuallyhidden"
:name="question.name"
:name="question.questionName"
:id="question.getInputId(index)"
:value="item.value"
:disabled="question.isInputReadOnly"
Expand Down
Expand Up @@ -10,7 +10,7 @@
<input
type="radio"
class="sv-visuallyhidden"
:name="question.name"
:name="question.questionName"
:id="question.getInputId(index)"
:value="item.value"
:disabled="question.isInputReadOnly"
Expand Down
Expand Up @@ -9,7 +9,7 @@
<input
type="radio"
class="sv-visuallyhidden"
:name="question.name"
:name="question.questionName"
:id="question.getInputId(index)"
:value="item.value"
:disabled="question.isInputReadOnly"
Expand Down
2 changes: 1 addition & 1 deletion src/knockout/components/rating/rating-item-smiley.html
Expand Up @@ -2,7 +2,7 @@
<input
type="radio"
class="sv-visuallyhidden"
data-bind="attr: { name: question.name, id: question.getInputId(index), value: item.value, 'aria-required': question.ariaRequired, 'aria-label': question.ariaLabel, 'aria-invalid': question.ariaInvalid, 'aria-errormessage': question.ariaErrormessage }, checkedValue: item.value, enable: !question.isInputReadOnly, event: { click: function(data, event) { question.setValueFromClick(event.target.value); return true; } }"
data-bind="attr: { name: question.questionName, id: question.getInputId(index), value: item.value, 'aria-required': question.ariaRequired, 'aria-label': question.ariaLabel, 'aria-invalid': question.ariaInvalid, 'aria-errormessage': question.ariaErrormessage }, checkedValue: item.value, enable: !question.isInputReadOnly, event: { click: function(data, event) { question.setValueFromClick(event.target.value); return true; } }"
/>
<!-- ko component: { name: 'sv-svg-icon', params: { iconName: question.getItemSmileyIconName(item.itemValue), size: 'auto', title: item.text } } --><!-- /ko -->
</label>
2 changes: 1 addition & 1 deletion src/knockout/components/rating/rating-item-star.html
Expand Up @@ -2,7 +2,7 @@
<input
type="radio"
class="sv-visuallyhidden"
data-bind="attr: { name: question.name, id: question.getInputId(index), value: item.value, 'aria-required': question.ariaRequired, 'aria-label': question.ariaLabel, 'aria-invalid': question.ariaInvalid, 'aria-errormessage': question.ariaErrormessage }, checkedValue: item.value, enable: !question.isInputReadOnly, event: { click: function(data, event) { question.setValueFromClick(event.target.value); return true; } }"
data-bind="attr: { name: question.questionName, id: question.getInputId(index), value: item.value, 'aria-required': question.ariaRequired, 'aria-label': question.ariaLabel, 'aria-invalid': question.ariaInvalid, 'aria-errormessage': question.ariaErrormessage }, checkedValue: item.value, enable: !question.isInputReadOnly, event: { click: function(data, event) { question.setValueFromClick(event.target.value); return true; } }"
/>
<!-- ko component: { name: 'sv-svg-icon', params: { css: 'sv-star', iconName: question.itemStarIcon, size: 'auto', title: item.text } } --><!-- /ko -->
<!-- ko component: { name: 'sv-svg-icon', params: { css: 'sv-star-2', iconName: question.itemStarIconAlt, size: 'auto', title: item.text } } --><!-- /ko -->
Expand Down
2 changes: 1 addition & 1 deletion src/knockout/components/rating/rating-item.html
Expand Up @@ -2,7 +2,7 @@
<input
type="radio"
class="sv-visuallyhidden"
data-bind="attr: { name: question.name, id: question.getInputId(index), value: item.value, 'aria-required': question.ariaRequired, 'aria-label': question.ariaLabel, 'aria-invalid': question.ariaInvalid, 'aria-errormessage': question.ariaErrormessage }, checkedValue: item.value, enable: !question.isInputReadOnly, event: { click: function(data, event) { question.setValueFromClick(event.target.value); return true; } }"
data-bind="attr: { name: question.questionName, id: question.getInputId(index), value: item.value, 'aria-required': question.ariaRequired, 'aria-label': question.ariaLabel, 'aria-invalid': question.ariaInvalid, 'aria-errormessage': question.ariaErrormessage }, checkedValue: item.value, enable: !question.isInputReadOnly, event: { click: function(data, event) { question.setValueFromClick(event.target.value); return true; } }"
/>
<span data-bind="css: question.cssClasses.itemText">
<!-- ko template: { name: 'survey-string', data: item.locText } -->
Expand Down
3 changes: 3 additions & 0 deletions src/question_rating.ts
Expand Up @@ -413,6 +413,9 @@ export class QuestionRatingModel extends Question {
public getInputId(index: number): string {
return this.inputId + "_" + index;
}
public get questionName() {
return this.name + "_" + this.id;
}
supportGoNextPageAutomatic(): boolean {
return this.isMouseDown === true || this.renderAs === "dropdown";
}
Expand Down
2 changes: 1 addition & 1 deletion src/react/components/rating/rating-item-smiley.tsx
Expand Up @@ -18,7 +18,7 @@ export class RatingItemSmiley extends RatingItemBase {
<input
type="radio"
className="sv-visuallyhidden"
name={this.question.name}
name={this.question.questionName}
id={this.question.getInputId(this.index)}
value={this.item.value}
disabled={this.isDisplayMode}
Expand Down
2 changes: 1 addition & 1 deletion src/react/components/rating/rating-item-star.tsx
Expand Up @@ -17,7 +17,7 @@ export class RatingItemStar extends RatingItemBase {
<input
type="radio"
className="sv-visuallyhidden"
name={this.question.name}
name={this.question.questionName}
id={this.question.getInputId(this.index)}
value={this.item.value}
disabled={this.isDisplayMode}
Expand Down
2 changes: 1 addition & 1 deletion src/react/components/rating/rating-item.tsx
Expand Up @@ -41,7 +41,7 @@ export class RatingItem extends RatingItemBase {
<input
type="radio"
className="sv-visuallyhidden"
name={this.question.name}
name={this.question.questionName}
id={this.question.getInputId(this.index)}
value={this.item.value}
disabled={this.isDisplayMode}
Expand Down
2 changes: 1 addition & 1 deletion src/vue/components/rating/rating-item-smiley.vue
@@ -1,7 +1,7 @@
<template>
<label :key="item.value" @mousedown="question.onMouseDown()" :style="question.getItemStyle(item.itemValue, item.highlight)" :class="question.getItemClass(item.itemValue, item.highlight)" @mouseover="(e) => question.onItemMouseIn(item)"
@mouseleave="(e) => question.onItemMouseOut(item)">
<input type="radio" class="sv-visuallyhidden" :name="question.name" :id="question.getInputId(index)"
<input type="radio" class="sv-visuallyhidden" :name="question.questionName" :id="question.getInputId(index)"
:value="item.value" :disabled="question.isInputReadOnly" @click="(e) => question.setValueFromClick(e.target.value)"
:aria-required="question.ariaRequired" :aria-label="question.ariaLabel" :aria-invalid="question.ariaInvalid"
:aria-errormessage="question.ariaErrormessage" />
Expand Down
2 changes: 1 addition & 1 deletion src/vue/components/rating/rating-item-star.vue
Expand Up @@ -2,7 +2,7 @@
<label :key="item.value" @mousedown="question.onMouseDown()" :class="question.getItemClass(item.itemValue)"
@mouseover="(e) => question.onItemMouseIn(item)"
@mouseleave="(e) => question.onItemMouseOut(item)">
<input type="radio" class="sv-visuallyhidden" :name="question.name" :id="question.getInputId(index)"
<input type="radio" class="sv-visuallyhidden" :name="question.questionName" :id="question.getInputId(index)"
:value="item.value" :disabled="question.isInputReadOnly" @click="(e) => question.setValueFromClick(e.target.value)"
:aria-required="question.ariaRequired" :aria-label="question.ariaLabel" :aria-invalid="question.ariaInvalid"
:aria-errormessage="question.ariaErrormessage" />
Expand Down
2 changes: 1 addition & 1 deletion src/vue/components/rating/rating-item.vue
@@ -1,6 +1,6 @@
<template>
<label :key="item.value" @mousedown="question.onMouseDown()" :class="question.getItemClassByText(item.itemValue, item.text)">
<input type="radio" class="sv-visuallyhidden" :name="question.name" :id="question.getInputId(index)"
<input type="radio" class="sv-visuallyhidden" :name="question.questionName" :id="question.getInputId(index)"
:value="item.value" :disabled="question.isInputReadOnly"
@click="(e) => question.setValueFromClick(e.target.value)" :aria-required="question.ariaRequired"
:aria-label="question.ariaLabel" :aria-invalid="question.ariaInvalid"
Expand Down
59 changes: 58 additions & 1 deletion testCafe/questions/rating.js
Expand Up @@ -223,4 +223,61 @@ frameworks.forEach((framework) => {
});
});
});
});
frameworks.forEach(framework => {
fixture`${framework} ${title}`.page`${url}${framework}`.beforeEach(
async t => {
await initSurvey(framework, {
"logoPosition": "right",
"pages": [
{
"name": "page1",
"elements": [
{
"type": "matrixdropdown",
"name": "question1",
"columns": [
{
"name": "col1",
"cellType": "rating",
"rateType": "stars"
},
],
"choices": [
1,
2,
3,
4,
5
],
"rows": [
"row1",
"row2"
]
}
]
}
]
});
}
);

test("check keynavigation inside matrixdropdown", async t => {
await t
.pressKey("tab")
.pressKey("right")
.pressKey("tab")
.pressKey("right")
.pressKey("right");

await t.click("input[value=Complete]");
const surveyResult = await getSurveyResult();

await t.expect(surveyResult).eql({
question1: {
row1: { col1: 2 },
row2: { col1: 3 }
}
});
});
});
});
58 changes: 29 additions & 29 deletions tests/markup/snapshots/rating-as-wrappable.snap.html
@@ -1,30 +1,30 @@
<div class="sd-rating sd-rating--wrappable sd-scrollable-container">
<fieldset role="radiogroup">
<legend class="sv-hidden" role="presentation">
</legend>
<label class="sd-rating__item sd-rating__item--allowhover sd-rating__item--fixed-size">
<input aria-invalid="false" aria-label="Question title" aria-required="false" class="sv-visuallyhidden" id="testid0i_0" name="name" type="radio" value="1">
<span class="sd-rating__item-text">
<span class="sv-string-viewer">1</span>
</span>
</label>
<label class="sd-rating__item sd-rating__item--allowhover sd-rating__item--fixed-size">
<input aria-invalid="false" aria-label="Question title" aria-required="false" class="sv-visuallyhidden" id="testid0i_1" name="name" type="radio" value="2">
<span class="sd-rating__item-text">
<span class="sv-string-viewer">2</span>
</span>
</label>
<label class="sd-rating__item sd-rating__item--allowhover sd-rating__item--fixed-size">
<input aria-invalid="false" aria-label="Question title" aria-required="false" class="sv-visuallyhidden" id="testid0i_2" name="name" type="radio" value="3">
<span class="sd-rating__item-text">
<span class="sv-string-viewer">3</span>
</span>
</label>
<label class="sd-rating__item sd-rating__item--allowhover sd-rating__item--fixed-size">
<input aria-invalid="false" aria-label="Question title" aria-required="false" class="sv-visuallyhidden" id="testid0i_3" name="name" type="radio" value="4">
<span class="sd-rating__item-text">
<span class="sv-string-viewer">4</span>
</span>
</label>
</fieldset>
<div class="sd-rating sd-rating--wrappable sd-scrollable-container">
<fieldset role="radiogroup">
<legend class="sv-hidden" role="presentation">
</legend>
<label class="sd-rating__item sd-rating__item--allowhover sd-rating__item--fixed-size">
<input aria-invalid="false" aria-label="Question title" aria-required="false" class="sv-visuallyhidden" id="testid0i_0" name="name_testid0" type="radio" value="1">
<span class="sd-rating__item-text">
<span class="sv-string-viewer">1</span>
</span>
</label>
<label class="sd-rating__item sd-rating__item--allowhover sd-rating__item--fixed-size">
<input aria-invalid="false" aria-label="Question title" aria-required="false" class="sv-visuallyhidden" id="testid0i_1" name="name_testid0" type="radio" value="2">
<span class="sd-rating__item-text">
<span class="sv-string-viewer">2</span>
</span>
</label>
<label class="sd-rating__item sd-rating__item--allowhover sd-rating__item--fixed-size">
<input aria-invalid="false" aria-label="Question title" aria-required="false" class="sv-visuallyhidden" id="testid0i_2" name="name_testid0" type="radio" value="3">
<span class="sd-rating__item-text">
<span class="sv-string-viewer">3</span>
</span>
</label>
<label class="sd-rating__item sd-rating__item--allowhover sd-rating__item--fixed-size">
<input aria-invalid="false" aria-label="Question title" aria-required="false" class="sv-visuallyhidden" id="testid0i_3" name="name_testid0" type="radio" value="4">
<span class="sd-rating__item-text">
<span class="sv-string-viewer">4</span>
</span>
</label>
</fieldset>
</div>
58 changes: 29 additions & 29 deletions tests/markup/snapshots/rating-display-mode.snap.html
@@ -1,30 +1,30 @@
<div class="sv_q_rating">
<fieldset role="radiogroup">
<legend class="sv-hidden" role="presentation">
</legend>
<label class="sv_q_rating_item sv_q_rating_item_fixed">
<input aria-invalid="false" aria-label="Question title" aria-required="false" class="sv-visuallyhidden" disabled="" id="testid0i_0" name="name" type="radio" value="1">
<span class="sv_q_rating_item_text">
<span class="sv-string-viewer">1</span>
</span>
</label>
<label class="sv_q_rating_item sv_q_rating_item_fixed">
<input aria-invalid="false" aria-label="Question title" aria-required="false" class="sv-visuallyhidden" disabled="" id="testid0i_1" name="name" type="radio" value="2">
<span class="sv_q_rating_item_text">
<span class="sv-string-viewer">2</span>
</span>
</label>
<label class="sv_q_rating_item sv_q_rating_item_fixed">
<input aria-invalid="false" aria-label="Question title" aria-required="false" class="sv-visuallyhidden" disabled="" id="testid0i_2" name="name" type="radio" value="3">
<span class="sv_q_rating_item_text">
<span class="sv-string-viewer">3</span>
</span>
</label>
<label class="sv_q_rating_item sv_q_rating_item_fixed">
<input aria-invalid="false" aria-label="Question title" aria-required="false" class="sv-visuallyhidden" disabled="" id="testid0i_3" name="name" type="radio" value="4">
<span class="sv_q_rating_item_text">
<span class="sv-string-viewer">4</span>
</span>
</label>
</fieldset>
<div class="sv_q_rating">
<fieldset role="radiogroup">
<legend class="sv-hidden" role="presentation">
</legend>
<label class="sv_q_rating_item sv_q_rating_item_fixed">
<input aria-invalid="false" aria-label="Question title" aria-required="false" class="sv-visuallyhidden" disabled="" id="testid0i_0" name="name_testid0" type="radio" value="1">
<span class="sv_q_rating_item_text">
<span class="sv-string-viewer">1</span>
</span>
</label>
<label class="sv_q_rating_item sv_q_rating_item_fixed">
<input aria-invalid="false" aria-label="Question title" aria-required="false" class="sv-visuallyhidden" disabled="" id="testid0i_1" name="name_testid0" type="radio" value="2">
<span class="sv_q_rating_item_text">
<span class="sv-string-viewer">2</span>
</span>
</label>
<label class="sv_q_rating_item sv_q_rating_item_fixed">
<input aria-invalid="false" aria-label="Question title" aria-required="false" class="sv-visuallyhidden" disabled="" id="testid0i_2" name="name_testid0" type="radio" value="3">
<span class="sv_q_rating_item_text">
<span class="sv-string-viewer">3</span>
</span>
</label>
<label class="sv_q_rating_item sv_q_rating_item_fixed">
<input aria-invalid="false" aria-label="Question title" aria-required="false" class="sv-visuallyhidden" disabled="" id="testid0i_3" name="name_testid0" type="radio" value="4">
<span class="sv_q_rating_item_text">
<span class="sv-string-viewer">4</span>
</span>
</label>
</fieldset>
</div>