survey-creator icon indicating copy to clipboard operation
survey-creator copied to clipboard

Matrix dynamic in property grid rendered incorrectly

Open SamMousa opened this issue 9 months ago • 5 comments

Describe the bug I'm rendering a matrix dynamic question inside the property grid, but it renders incorrectly:

  • The add row button is missing
  • The delete row button has no styling

Steps to reproduce

See https://plnkr.co/edit/smcxH7T8pxw0IqSw

Expected behavior I'd expect to be able to use a matrixdynamic question.

Screenshots

Image

Please complete the following information:

  • Browser: Firefox, Chromium
  • Browser version: latest
  • JS framework/library: React / knockout / vanilla
  • SurveyJS version: latest
  • Device: PC

Additional context

SamMousa avatar Feb 19 '25 12:02 SamMousa

@SamMousa It is better to inherited from PropertyGridEditorMatrix class to edit an array of objects. What is your goal? What type of objects in array do you have?

Thank you, Andrew

andrewtelnov avatar Feb 20 '25 08:02 andrewtelnov

I'll describe the full feature (in hopes you want to mainstream it ;-))

  1. Page blocks, a survey has a list of page blocks, each has a name and randomizationGroup property
  2. Each page has 2 properties, randomizationGroups and block
  3. Before the survey starts I use this to randomize pages.

Example, I have pages p1 - p10. I have blocks P234 and P678, both have randomization group R1. Pages 2, 3 and 4 belong to block P234 and pages 6, 7 and 8 belong to P678.

Page 10 also has randomization group R1.

Before the survey start I create a list of spots:

let spots = [page1, "R1", page5, "R1", page9, "R1"];
// Now I randomly assign a page or page block to these spots.
let filled = [page1, P678, page5, page10, page9, P234];
// Expand the blocks
let expanded = [page1, page6, page7, page8, page10, page9, page2, page3, page4]

Note that within blocks I do the same logic for randomization groups so pages within a block could also be randomized.

Anyway, to support this in a user friendly way I have added a blocks property:

Serializer.addClass('blockitemvalue', [
		{
			name: 'value',
			visible: true,
			isLocalizable: false,
			isUnique: true
		},
		{
			name: 'randomizationGroup',
			visible: true,
			type: 'string',
			isLocalizable: false,
			default: '',
			displayName: 'Randomization group',
			isRequired: false
		}
	]);
Serializer.addProperty('survey', {
		name: 'blocks',
		displayName: 'Page blocks',
		isLocalizable: false,
		type: 'blockitemvalue[]',
		category: 'pages'
	});

Now I need to set up the creator so the property grid supports this properly. I'd expect to be able to set that up like this:

PropertyGridEditorCollection.register({
		fit(prop) {
			if (['blockitemvalue[]'].includes(prop.type)) {
				return true;
			}

			return false;
		},
		createPropertyEditorSetup: () => {
			// This is actually not used
			return {
				editSurvey: {} as SurveyModel,
				apply: () => false
			};
		},
		showModalPropertyEditor: (_editor, _property) => {
			// This is actually not used
			return {
				editSurvey: {} as SurveyModel,
				apply: () => false
			};
		},
		isPropertyEditorSetupEnabled() {
			return false;
		},
		getJSON() {
			return {
				type: 'matrixdynamic',
				columns: [
					{
						name: 'value'
					},
					{
						name: 'randomizationGroup'
					}
				],
				rowCount: 0,
				cellType: 'text'
			};
		}
	});

I'd rather not inherit from third party code, it's a brittle approach, further more, above is the documented way of setting op property grid editors right?

SamMousa avatar Feb 20 '25 09:02 SamMousa

@SamMousa Sorry for the delay. Here is the working code and example:

import { Serializer } from "survey-core"
Serializer.addClass('blockitemvalue', [
		{
			name: 'randomizationGroup',
			displayName: 'Randomization group'
		}
	], undefined, "itemvalue");
["text", "visibleIf", "enableIf"].forEach(name => {
  Serializer.getProperty("blockitemvalue", name).visible = false;
})

Serializer.addProperty('survey', {
		name: 'blocks',
		displayName: 'Page blocks',
		type: 'blockitemvalue[]',
		category: 'pages'
	});

Thank you, Andrew

andrewtelnov avatar Mar 18 '25 14:03 andrewtelnov

The example does not work. The link doesn't work, but trying it locally it looks like this:

Image

Note there is no way to add a new option and the quick add (which I don't need) is greyed out.

SamMousa avatar Mar 24 '25 16:03 SamMousa

@SamMousa Sorry, I missed this one. I have updated the example.

Thank you, Andrew

andrewtelnov avatar Apr 28 '25 10:04 andrewtelnov