diff --git a/examples/jspsych-html-button-response.html b/examples/jspsych-html-button-response.html
index 39bdeeaf35..99db2e3a4e 100644
--- a/examples/jspsych-html-button-response.html
+++ b/examples/jspsych-html-button-response.html
@@ -20,6 +20,7 @@
type: jsPsychHtmlButtonResponse,
stimulus: '
GREEN
',
choices: ['Green', 'Blue', 'Red'],
+ button_layout: "flex",
prompt: "What color is this word? (flex layout)
"
});
@@ -31,6 +32,15 @@
prompt: "What color is this word? (grid layout)
"
});
+ timeline.push({
+ type: jsPsychHtmlButtonResponse,
+ stimulus: 'GREEN
',
+ choices: ['Green', 'Blue', 'Red'],
+ button_layout: "grid",
+ button_rows: 2,
+ prompt: "What color is this word? (grid layout, two rows)
"
+ });
+
timeline.push({
type: jsPsychHtmlButtonResponse,
stimulus: 'GREEN
',
diff --git a/packages/jspsych/src/index.scss b/packages/jspsych/src/index.scss
index 4093c9824c..4b6ab3ba4d 100644
--- a/packages/jspsych/src/index.scss
+++ b/packages/jspsych/src/index.scss
@@ -68,7 +68,9 @@
.jspsych-btn-group-grid {
display: grid;
grid-auto-columns: max-content;
- min-width: fit-content;
+ max-width: fit-content;
+ margin-right: auto;
+ margin-left: auto;
}
/* borrowing Bootstrap style for btn elements, but combining styles a bit */
diff --git a/packages/plugin-html-button-response/src/index.ts b/packages/plugin-html-button-response/src/index.ts
index 1ec684a3f7..1f5d61639b 100644
--- a/packages/plugin-html-button-response/src/index.ts
+++ b/packages/plugin-html-button-response/src/index.ts
@@ -51,19 +51,22 @@ const info = {
pretty_name: "Button layout",
default: "grid",
},
- /** The number of grid rows when `button_layout` is "grid" */
+ /** The number of grid rows when `button_layout` is "grid".
+ * Setting to `null` will infer the number of rows based on the
+ * number of columns and buttons.
+ */
button_rows: {
- type: ParameterType.STRING,
+ type: ParameterType.INT,
pretty_name: "Grid rows",
- default: "1",
+ default: 1,
},
/** The number of grid columns when `button_layout` is "grid".
- * Using "auto" will make the number of columns equal the number
- * of buttons. */
+ * Setting to `null` (default value) will infer the number of columns
+ * based on the number of rows and buttons. */
button_cols: {
- type: ParameterType.STRING,
+ type: ParameterType.INT,
pretty_name: "Grid columns",
- default: "auto",
+ default: null,
},
/** If true, then trial will end when user responds. */
response_ends_trial: {
@@ -100,10 +103,21 @@ class HtmlButtonResponsePlugin implements JsPsychPlugin {
buttonGroupElement.id = "jspsych-html-button-response-btngroup";
if (trial.button_layout === "grid") {
buttonGroupElement.classList.add("jspsych-btn-group-grid");
- let n_cols =
- trial.button_cols === "auto" ? trial.choices.length : parseInt(trial.button_cols);
+ if (trial.button_rows === null && trial.button_cols === null) {
+ throw new Error(
+ "You must specify the number of rows or columns when using the grid layout."
+ );
+ }
+ const n_cols =
+ trial.button_cols === null
+ ? Math.ceil(trial.choices.length / trial.button_rows)
+ : trial.button_cols;
+ const n_rows =
+ trial.button_rows === null
+ ? Math.ceil(trial.choices.length / trial.button_cols)
+ : trial.button_rows;
buttonGroupElement.style.gridTemplateColumns = `repeat(${n_cols}, 1fr)`;
- buttonGroupElement.style.gridTemplateRows = `repeat(${trial.button_rows}, 1fr)`;
+ buttonGroupElement.style.gridTemplateRows = `repeat(${n_rows}, 1fr)`;
} else if (trial.button_layout === "flex") {
buttonGroupElement.classList.add("jspsych-btn-group-flex");
}