Skip to content

Commit b487f93

Browse files
authored
Merge pull request #691 from theoephraim/uladkasach-vlad/worksheet-add-data-validation
add data validation
2 parents ee618b8 + 3b24e6d commit b487f93

File tree

6 files changed

+191
-8
lines changed

6 files changed

+191
-8
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Full docs available at [https://theoephraim.github.io/node-google-spreadsheet](h
2525

2626
_The following examples are meant to give you an idea of just some of the things you can do_
2727

28-
> **IMPORTANT NOTE** - To keep the examples concise, I'm calling await [at the top level](https://v8.dev/features/top-level-await) which is not allowed by default in most versions of node. If you need to call await in a script at the root level, you must instead wrap it in an async function like so:
28+
> **IMPORTANT NOTE** - To keep the examples concise, I'm calling await [at the top level](https://v8.dev/features/top-level-await) which is not allowed in some older versions of node. If you need to call await in a script at the root level and your environment does not support it, you must instead wrap it in an async function like so:
2929
3030
```javascript
3131
(async function () {

docs/classes/google-spreadsheet-worksheet.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,24 @@ Param|Type|Required|Description
333333

334334
?> The authentication method being used must have write access to the destination document as well
335335

336+
337+
#### `setDataValidation(range, rule)` (async) :id=fn-setDataValidation
338+
> Sets a data validation rule to every cell in the range
339+
340+
Param|Type|Required|Description
341+
---|---|---|---
342+
`range`|Object<br>[GridRange](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/other#GridRange)|✅|Range of cells to apply the rule to, sheetId not required!
343+
`rule`|Object<br>[DataValidationRule](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/cells#DataValidationRule)<br>or `false`|✅|Object describing the validation rule<br/>Or `false` to unset the rule
344+
345+
346+
-**Side Effects -** sheet is copied to the other doc
347+
348+
?> The authentication method being used must have write access to the destination document as well
349+
350+
351+
352+
353+
336354
### Exports
337355

338356
See [Exports guide](guides/exports) for more info.

pnpm-lock.yaml

Lines changed: 16 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/lib/GoogleSpreadsheetWorksheet.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
A1Range, SpreadsheetId, DimensionRangeIndexes, WorksheetDimension, WorksheetId, WorksheetProperties, A1Address,
1313
RowIndex, ColumnIndex, DataFilterWithoutWorksheetId, DataFilter, GetValuesRequestOptions, WorksheetGridProperties,
1414
WorksheetDimensionProperties, CellDataRange, AddRowOptions, GridRangeWithOptionalWorksheetId,
15+
DataValidationRule,
1516
} from './types/sheets-types';
1617

1718

@@ -819,9 +820,22 @@ export class GoogleSpreadsheetWorksheet {
819820
// https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/request#SortRangeRequest
820821
}
821822

822-
async setDataValidation() {
823-
// Request type = `setDataValidation`
824-
// https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/request#SetDataValidationRequest
823+
/**
824+
* Sets (or unsets) a data validation rule to every cell in the range
825+
* @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/request#SetDataValidationRequest
826+
*/
827+
async setDataValidation(
828+
range: GridRangeWithOptionalWorksheetId,
829+
/** data validation rule object, or set to false to clear an existing rule */
830+
rule: DataValidationRule | false
831+
) {
832+
return this._makeSingleUpdateRequest('setDataValidation', {
833+
range: {
834+
sheetId: this.sheetId,
835+
...range,
836+
},
837+
...rule && { rule },
838+
});
825839
}
826840

827841
async setBasicFilter() {

src/lib/types/sheets-types.ts

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,3 +526,88 @@ export type AddRowOptions = {
526526
/** set to true to insert new rows in the sheet while adding this data */
527527
insert?: boolean,
528528
};
529+
530+
/**
531+
* @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/other#ConditionType
532+
*/
533+
export type ConditionType =
534+
| 'NUMBER_GREATER'
535+
| 'NUMBER_GREATER_THAN_EQ'
536+
| 'NUMBER_LESS'
537+
| 'NUMBER_LESS_THAN_EQ'
538+
| 'NUMBER_EQ'
539+
| 'NUMBER_NOT_EQ'
540+
| 'NUMBER_BETWEEN'
541+
| 'NUMBER_NOT_BETWEEN'
542+
| 'TEXT_CONTAINS'
543+
| 'TEXT_NOT_CONTAINS'
544+
| 'TEXT_STARTS_WITH'
545+
| 'TEXT_ENDS_WITH'
546+
| 'TEXT_EQ'
547+
| 'TEXT_IS_EMAIL'
548+
| 'TEXT_IS_URL'
549+
| 'DATE_EQ'
550+
| 'DATE_BEFORE'
551+
| 'DATE_AFTER'
552+
| 'DATE_ON_OR_BEFORE'
553+
| 'DATE_ON_OR_AFTER'
554+
| 'DATE_BETWEEN'
555+
| 'DATE_NOT_BETWEEN'
556+
| 'DATE_IS_VALID'
557+
| 'ONE_OF_RANGE'
558+
| 'ONE_OF_LIST'
559+
| 'BLANK'
560+
| 'NOT_BLANK'
561+
| 'CUSTOM_FORMULA'
562+
| 'BOOLEAN'
563+
| 'TEXT_NOT_EQ'
564+
| 'DATE_NOT_EQ'
565+
| 'FILTER_EXPRESSION';
566+
567+
/**
568+
* @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/other#relativedate
569+
*/
570+
export type RelativeDate =
571+
| 'PAST_YEAR'
572+
| 'PAST_MONTH'
573+
| 'PAST_WEEK'
574+
| 'YESTERDAY'
575+
| 'TODAY'
576+
| 'TOMORROW';
577+
578+
/**
579+
* @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/other#ConditionValue
580+
*/
581+
export type ConditionValue =
582+
| { relativeDate: RelativeDate, userEnteredValue?: undefined }
583+
| { relativeDate?: undefined, userEnteredValue: string };
584+
585+
/**
586+
* @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/other#BooleanCondition
587+
*/
588+
export type BooleanCondition = {
589+
/** The type of condition. */
590+
type: ConditionType;
591+
/**
592+
* The values of the condition.
593+
* The number of supported values depends on the condition type. Some support zero values, others one or two values, and ConditionType.ONE_OF_LIST supports an arbitrary number of values.
594+
*/
595+
values: ConditionValue[];
596+
};
597+
598+
/**
599+
* @see https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/cells#DataValidationRule
600+
*
601+
* example:
602+
* - https://stackoverflow.com/a/43442775/3068233
603+
*/
604+
export type DataValidationRule = {
605+
/** The condition that data in the cell must match. */
606+
condition: BooleanCondition;
607+
/** A message to show the user when adding data to the cell. */
608+
inputMessage?: string;
609+
/** True if invalid data should be rejected. */
610+
strict: boolean;
611+
/** True if the UI should be customized based on the kind of condition. If true, "List" conditions will show a dropdown. */
612+
showCustomUi: boolean;
613+
};

src/test/manage.test.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,60 @@ describe('Managing doc info and sheets', () => {
190190
});
191191
});
192192

193+
describe.only('data validation rules', () => {
194+
let sheet: GoogleSpreadsheetWorksheet;
195+
196+
beforeAll(async () => {
197+
sheet = await doc.addSheet({ title: 'validation rules test' });
198+
});
199+
afterAll(async () => {
200+
await sheet.delete();
201+
});
202+
203+
204+
it('can set data validation', async () => {
205+
// add a dropdown; ref: https://stackoverflow.com/a/43442775/3068233
206+
await sheet.setDataValidation(
207+
{
208+
startRowIndex: 2,
209+
endRowIndex: 100,
210+
startColumnIndex: 3,
211+
endColumnIndex: 4,
212+
},
213+
{
214+
condition: {
215+
type: 'ONE_OF_LIST',
216+
values: [
217+
{
218+
userEnteredValue: 'YES',
219+
},
220+
{
221+
userEnteredValue: 'NO',
222+
},
223+
{
224+
userEnteredValue: 'MAYBE',
225+
},
226+
],
227+
},
228+
showCustomUi: true,
229+
strict: true,
230+
}
231+
);
232+
});
233+
234+
it('can clear a data validation', async () => {
235+
await sheet.setDataValidation(
236+
{
237+
startRowIndex: 2,
238+
endRowIndex: 100,
239+
startColumnIndex: 3,
240+
endColumnIndex: 4,
241+
},
242+
false
243+
);
244+
});
245+
});
246+
193247
describe('deleting a sheet', () => {
194248
let sheet: GoogleSpreadsheetWorksheet;
195249
let numSheets: number;

0 commit comments

Comments
 (0)