Skip to content

Commit

Permalink
Support rate value visibleIf #9267
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewtelnov committed Jan 20, 2025
1 parent 975d8a6 commit 1325b13
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 10 deletions.
10 changes: 8 additions & 2 deletions packages/survey-core/src/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -504,8 +504,14 @@ export class Base {
if(!!calcFunc) {
const newVal = calcFunc();
if(newVal !== undefined) {
this.setPropertyValueDirectly(name, newVal);
return newVal;
if(Array.isArray(newVal)) {
const array = this.createNewArray(name);
array.splice(0, 0, ...newVal);
return array;
} else {
this.setPropertyValueDirectly(name, newVal);
return newVal;
}
}
}
const propDefaultValue = this.getDefaultPropertyValue(name);
Expand Down
47 changes: 42 additions & 5 deletions packages/survey-core/src/question_rating.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { ISurveyImpl } from "./base-interfaces";
import { IsTouch } from "./utils/devices";
import { ITheme } from "./themes";
import { DomDocumentHelper } from "./global_variables_utils";
import { HashTable } from "./helpers";

export class RenderedRatingItem extends Base {
private onStringChangedCallback() {
Expand Down Expand Up @@ -121,7 +122,6 @@ export class QuestionRatingModel extends Question {
this.updateRateCount();
this.setIconsToRateValues();
}

private _syncPropertiesChanging: boolean = false;
private registerSychProperties(names: Array<string>, func: any) {
this.registerFunctionOnPropertiesValueChanged(names,
Expand Down Expand Up @@ -344,8 +344,40 @@ export class QuestionRatingModel extends Question {
if (!this.useRateValues() && newValue !== undefined) this.autoGenerate = false;
super.itemValuePropertyChanged(item, name, oldValue, newValue);
}
protected runConditionCore(values: HashTable<any>, properties: HashTable<any>): void {
super.runConditionCore(values, properties);
this.runRateItesmCondition(values, properties);
}
protected runRateItesmCondition(values: HashTable<any>, properties: HashTable<any>): void {
if(!this.useRateValues()) return;
let isChanged = false;
if(this.survey?.areInvisibleElementsShowing) {
this.rateValues.forEach(item => {
isChanged = isChanged || !item.isVisible;
item.setIsVisible(item, true);
});
} else {
isChanged = ItemValue.runConditionsForItems(this.rateValues, undefined, undefined, values, properties, true);
}
if(isChanged) {
this.resetRenderedItems();
if(!this.isEmpty() && !this.isReadOnly) {
const item = ItemValue.getItemByValue(this.rateValues, this.value);
if(item && !item.isVisible) {
this.clearValue();
}
}
}
}
private getRateValuesCore(): Array<ItemValue> {
return this.useRateValues() ? this.rateValues : this.createRateValues();
if(!this.useRateValues()) return this.createRateValues();
const items = new Array<ItemValue>();
this.rateValues.forEach(item => {
if(item.isVisible) {
items.push(item);
}
});
return items;
}
private calculateRateValues(): Array<ItemValue> {
let rateValues = this.getRateValuesCore();
Expand All @@ -355,7 +387,7 @@ export class QuestionRatingModel extends Question {
private calculateRenderedRateItems() : Array<RenderedRatingItem> {
const rateValues = this.calculateRateValues();
return rateValues.map((v, i) => {
let renderedItem = null;
let renderedItem: RenderedRatingItem = null;
if (this.displayRateDescriptionsAsExtremeItems) {
if (i == 0) renderedItem = new RenderedRatingItem(v, this.minRateDescription && this.locMinRateDescription || v.locText);
if (i == rateValues.length - 1) renderedItem = new RenderedRatingItem(v, this.maxRateDescription && this.locMaxRateDescription || v.locText);
Expand All @@ -368,13 +400,18 @@ export class QuestionRatingModel extends Question {
const rateValues = this.calculateRateValues();
return rateValues.map((i, idx) => this.getRatingItemValue(i, idx));
}
private iCounter = 0;
private resetRenderedItems() {
if (this.autoGenerate) {
const rateValues = this.getRateValuesCore();
this.rateMax = rateValues[rateValues.length - 1].value;
}
this.resetPropertyValue("renderedRateItems");
this.resetPropertyValue("visibleChoices");
if(Array.isArray(this.getPropertyValueWithoutDefault("renderedRateItems"))) {
this.setArrayPropertyDirectly("renderedRateItems", this.calculateRenderedRateItems());
}
if(Array.isArray(this.getPropertyValueWithoutDefault("visibleChoices"))) {
this.setArrayPropertyDirectly("visibleChoices", this.calculateVisibleChoices);
}
}
public get renderedRateItems(): Array<RenderedRatingItem> {
return this.getPropertyValue("renderedRateItems", undefined, () => this.calculateRenderedRateItems());
Expand Down
54 changes: 51 additions & 3 deletions packages/survey-core/tests/question_ratingtests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -304,10 +304,13 @@ QUnit.test("Check rateValues on text change", (assert) => {
const survey = new SurveyModel(json);
const q1 = <QuestionRatingModel>survey.getQuestionByName("q1");
assert.equal(q1.rateValues.length, 0);
var oldRendered = q1.renderedRateValues;
let oldRendered = q1.renderedRateItems;
q1.visibleRateValues[0].text = "abc";
assert.equal(q1.rateValues.length, 5);
assert.equal(q1.renderedRateValues, oldRendered, "renderedRateValues is not cloned");
assert.strictEqual(q1.renderedRateItems, oldRendered, "renderedRateItems is cloned");
oldRendered = q1.renderedRateItems;
q1.visibleRateValues[1].text = "abc";
assert.strictEqual(q1.renderedRateItems, oldRendered, "renderedRateItems is not cloned");
});
QUnit.test("Check cssClasses update when dropdownListModel is set", (assert) => {
var json = {
Expand Down Expand Up @@ -1763,4 +1766,49 @@ QUnit.test("Check dropdown rating text, #8953", function (assert) {
});
const question = <QuestionRatingModel>survey.getAllQuestions()[0];
assert.deepEqual(question.visibleChoices.map(c => c.text), ["Label0", "Label1"]);
});
});
QUnit.test("Ranking: items visibleIf and value, Bug#5959", function(assert) {
var survey = new SurveyModel({
elements: [
{ type: "checkbox", name: "q1", choices: [1, 2] },
{
type: "rating",
name: "q2",
rateValues: [
{ value: "a", visibleIf: "{q1} contains 1" },
{ value: "b", visibleIf: "{q1} contains 1" },
{ value: "c", visibleIf: "{q1} contains 2" },
{ value: "d", visibleIf: "{q1} contains 2" },
{ value: "e", visibleIf: "{q1} contains 1" },
]
}
]
});
const q1 = survey.getQuestionByName("q1");
const q2 = <QuestionRatingModel>survey.getQuestionByName("q2");
assert.equal(q2.visibleRateValues.length, 0, "visibleRateValues #1");
assert.equal(q2.renderedRateItems.length, 0, "renderedRateItems #1");
q1.value = [1];
assert.equal(q2.visibleRateValues.length, 3, "visibleRateValues #2");
assert.equal(q2.renderedRateItems.length, 3, "renderedRateItems #2");
q1.value = [2];
assert.equal(q2.visibleRateValues.length, 2, "visibleRateValues #3");
assert.equal(q2.renderedRateItems.length, 2, "renderedRateItems #3");
q1.value = [1, 2];
assert.equal(q2.visibleRateValues.length, 5, "visibleRateValues #4");
assert.equal(q2.renderedRateItems.length, 5, "renderedRateItems #4");
q1.value = [];
assert.equal(q2.visibleRateValues.length, 0, "visibleRateValues #5");
assert.equal(q2.renderedRateItems.length, 0, "renderedRateItems #5 ");
survey.showInvisibleElements = true;
assert.equal(q2.renderedRateItems.length, 5, "renderedRateItems #6");
survey.showInvisibleElements = false;
assert.equal(q2.renderedRateItems.length, 0, "renderedRateItems #7");
q1.value = [1];
assert.equal(q2.renderedRateItems.length, 3, "renderedRateItems #8");
q2.value = "b";
assert.deepEqual(q2.value, "b", "value set correctly, #8");
q1.value = [2];
assert.equal(q2.renderedRateItems.length, 2, "renderedRateItems #9");
assert.deepEqual(q2.isEmpty(), true, "value is reset, #9");
});

0 comments on commit 1325b13

Please sign in to comment.