Skip to content

Handle const like enum with only one option #1446

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

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/editors/enum.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ export class EnumEditor extends AbstractEditor {

this.options.enum_titles = this.options.enum_titles || []

this.enum = this.schema.enum
if (this.schema.const) {
this.enum = [this.schema.const]
} else {
this.enum = this.schema.enum
}
this.selected = 0
this.select_options = []
this.html_values = []
Expand Down
7 changes: 6 additions & 1 deletion src/editors/multiselect.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,12 @@ export class MultiSelectEditor extends AbstractEditor {

let i
const itemsSchema = this.jsoneditor.expandRefs(this.schema.items || {})
const e = itemsSchema.enum || []
let e
if (itemsSchema.const) {
e = [itemsSchema.const]
} else {
e = itemsSchema.enum || []
}
const oe = itemsSchema.options ? itemsSchema.options.enum || [] : []
/* fallback to enum_titles, when options.enum is not present */
const t = itemsSchema.options ? itemsSchema.options.enum_titles || [] : []
Expand Down
10 changes: 8 additions & 2 deletions src/editors/select.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,14 @@ export class SelectEditor extends AbstractEditor {
this.hasPlaceholderOption = this.schema?.options?.has_placeholder_option || false
this.placeholderOptionText = this.schema?.options?.placeholder_option_text || ' '

/* Enum options enumerated */
if (this.schema.enum) {
/* Const value */
if (this.schema.const) {
const value = this.schema.const
this.enum_options = [`${value}`]
this.enum_display = [`${this.translateProperty(value) || value}`]
this.enum_values = [this.typecast(value)]
/* Enum options enumerated */
} else if (this.schema.enum) {
const display = (this.schema.options && this.schema.options.enum_titles) || []

this.schema.enum.forEach((option, i) => {
Expand Down
4 changes: 2 additions & 2 deletions src/resolvers.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ const enumSource = schema => {

/* Use the `enum` or `select` editors for schemas with enumerated properties */
const enumeratedProperties = schema => {
if (schema.enum) {
if (schema.enum || schema.const) {
if (schema.type === 'array' || schema.type === 'object') return 'enum'
if (schema.type === 'number' || schema.type === 'integer' || schema.type === 'string') {
if (schema.format === 'radio') return 'radio'
Expand All @@ -75,7 +75,7 @@ const arraysOfStrings = (schema, je) => {
/* if 'selectize' enabled it is expected to be selectized control */
if (schema.format === 'selectize') return 'arraySelectize'
if (schema.format === 'select2') return 'arraySelect2'
if (schema.items.enum) return 'multiselect' /* otherwise it is select */
if (schema.items.enum || schema.items.const) return 'multiselect' /* otherwise it is select */
}
}
}
Expand Down
49 changes: 14 additions & 35 deletions tests/codeceptjs/core_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -245,71 +245,52 @@ Scenario('should display anyOf and oneOf error messages in the correct places @8
I.dontSeeElement('[data-schemapath="root.list_group"] .invalid-feedback', DEFAULT_WAIT_TIME)
})

Scenario('Should switch between all json 7 data types in @oneof and display error messages for each one @core', async ({ I }) => {
Scenario('Should switch between all json 7 data types in @oneof and set value according to specified constant for each one @core', async ({ I }) => {
I.amOnPage('oneof-2.html')
I.waitForElement('.je-ready')

I.selectOption('.je-switcher', 'Value, string')
I.waitForValue('#value', '{"test":""}')
I.waitForText('Value must validate against exactly one of the provided schemas.')
I.waitForText('Value must be the constant value')
I.waitForValue('#value', '{"test":"test"}')

I.selectOption('.je-switcher', 'Value, boolean')
I.waitForValue('#value', '{"test":false}')
I.waitForText('Value must validate against exactly one of the provided schemas.')
I.waitForText('Value must be the constant value')
I.waitForValue('#value', '{"test":true}')

I.selectOption('.je-switcher', 'Value, array')
I.waitForValue('#value', '{"test":[]}')
I.waitForText('Value must validate against exactly one of the provided schemas.')
I.waitForText('Value must be the constant value')
I.waitForValue('#value', '{"test":[0]}')

I.selectOption('.je-switcher', 'Value, object')
I.waitForValue('#value', '{"test":{}}')
I.waitForText('Value must validate against exactly one of the provided schemas.')
I.waitForText('Value must be the constant value')
I.waitForText('Object is missing the required property \'test\'')
I.waitForValue('#value', '{"test":{"test":"test"}}')

I.selectOption('.je-switcher', 'Value, number')
I.waitForValue('#value', '{"test":0}')
I.waitForText('Value must validate against exactly one of the provided schemas.')
I.waitForText('Value must be the constant value')
I.waitForValue('#value', '{"test":1.1}')

I.selectOption('.je-switcher', 'Value, integer')
I.waitForValue('#value', '{"test":0}')
I.waitForText('Value must validate against exactly one of the provided schemas.')
I.waitForText('Value must be the constant value')
I.waitForValue('#value', '{"test":1}')

I.selectOption('.je-switcher', 'Value, null')
I.waitForValue('#value', '{"test":null}')
})

Scenario('Should switch between all json 7 data types in @anyof and display error messages for each one @core', ({ I }) => {
Scenario('Should switch between all json 7 data types in @anyof and set value according to specified constant for each one @core', ({ I }) => {
I.amOnPage('anyof-2.html')
I.waitForElement('.je-ready')

I.waitForValue('#value', '{"test":""}')
I.waitForText('Value must validate against at least one of the provided schemas')
I.waitForValue('#value', '{"test":"test"}')

I.selectOption('.je-switcher', 'Value, boolean')
I.waitForValue('#value', '{"test":false}')
I.waitForText('Value must validate against at least one of the provided schemas')
I.waitForValue('#value', '{"test":true}')

I.selectOption('.je-switcher', 'Value, array')
I.waitForValue('#value', '{"test":[]}')
I.waitForText('Value must validate against at least one of the provided schemas')
I.waitForValue('#value', '{"test":[0]}')

I.selectOption('.je-switcher', 'Value, object')
I.waitForValue('#value', '{"test":{}}')
I.waitForText('Value must validate against at least one of the provided schemas')
I.waitForValue('#value', '{"test":{"test":"test"}}')

I.selectOption('.je-switcher', 'Value, number')
I.waitForValue('#value', '{"test":0}')
I.waitForText('Value must validate against at least one of the provided schemas')
I.waitForValue('#value', '{"test":1.1}')

I.selectOption('.je-switcher', 'Value, integer')
I.waitForValue('#value', '{"test":0}')
I.waitForText('Value must validate against at least one of the provided schemas')
I.waitForValue('#value', '{"test":1}')

I.selectOption('.je-switcher', 'Value, null')
I.waitForValue('#value', '{"test":null}')
Expand Down Expand Up @@ -433,7 +414,6 @@ Scenario('should override error messages if specified in schema options @core @e
I.waitForText('Error Messages')

I.waitForText('CUSTOM EN: Value required')
I.waitForText('CUSTOM EN: Value must be the constant value')
I.waitForText('CUSTOM EN: Value must be at least 6 characters long')
I.waitForText('CUSTOM EN: Value must be at most 6 characters long')
I.waitForText('CUSTOM EN: Value must validate against at least one of the provided schemas')
Expand Down Expand Up @@ -467,7 +447,6 @@ Scenario('should override error messages if specified in schema options @core @e
I.click('Switch to ES')

I.waitForText('CUSTOM ES: Value required')
I.waitForText('CUSTOM ES: Value must be the constant value')
I.waitForText('CUSTOM ES: Value must be at least 6 characters long')
I.waitForText('CUSTOM ES: Value must be at most 6 characters long')
I.waitForText('CUSTOM ES: Value must validate against at least one of the provided schemas')
Expand Down
9 changes: 9 additions & 0 deletions tests/codeceptjs/editors/array_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,15 @@ Scenario('should work well with multiselect editors', async ({ I }) => {
I.dontSee('Multiselect 3')
})

Scenario('should handle const well in multiselect editor', async ({ I }) => {
I.amOnPage('array-multiselects-const.html')
I.click('Add Multiselect')
I.seeElement('[data-schemapath="root.0"]')
I.selectOption('[name="root[0]"]', 'abc')
I.click('.get-value')
I.waitForValue('.debug', '[["abc"]]')
})

Scenario('should work well with object editors', async ({ I }) => {
I.amOnPage('array-objects.html')
I.click('Add Object')
Expand Down
6 changes: 6 additions & 0 deletions tests/codeceptjs/editors/select_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,9 @@ Scenario('should be disabled if "readonly" is specified', async ({ I }) => {
I.amOnPage('read-only.html')
I.seeDisabledAttribute('[name="root[select]"]')
})

Scenario('should handle const like enum with 1 item', async ({ I }) => {
I.amOnPage('select-const.html')
I.click('.get-value')
I.waitForValue('.value', '{"constval":"constant"}')
})
2 changes: 1 addition & 1 deletion tests/pages/anyof-2.html
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ <h1>Test</h1>
{
'type': 'integer',
'title': 'Value, integer',
'const': 1.1
'const': 1
},
{
'type': 'null',
Expand Down
43 changes: 43 additions & 0 deletions tests/pages/array-multiselects-const.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<script src="../../dist/jsoneditor.js"></script>
</head>
<body>

<textarea class="debug" cols="30" rows="10"></textarea>
<button class='get-value'>Get Value</button>
<div class='container'></div>

<script>
var container = document.querySelector('.container');
var debug = document.querySelector('.debug');
var schema = {
"type": "array",
"title": "Selects",
"items": {
"title": "Multiselect",
"type": "array",
"format": "multiselect",
"uniqueItems": true,
"items": {
"type": "string",
"const": "abc"
}
}
};

var editor = new JSONEditor(container, {
schema: schema
});

document.querySelector('.get-value').addEventListener('click', function () {
debug.value = JSON.stringify(editor.getValue());
});

</script>

</body>
</html>

2 changes: 1 addition & 1 deletion tests/pages/oneof-2.html
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ <h1>Test</h1>
{
'type': 'integer',
'title': 'Value, integer',
'const': 1.1
'const': 1
},
{
'type': 'null',
Expand Down
40 changes: 40 additions & 0 deletions tests/pages/select-const.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>wysiwyg-sceditor</title>
<script src="../../dist/jsoneditor.js"></script>
</head>
<body>

<textarea class="value" cols="30" rows="10"></textarea>
<button class='get-value'>Get Value</button>
<div class='container'></div>

<script>
var container = document.querySelector('.container');
var value = document.querySelector('.value');

var schema = {
"type": "object",
"properties": {
"constval": {
"type": "string",
"const": "constant"
}
}
};

var editor = new JSONEditor(container, {
schema: schema
});

document.querySelector('.get-value').addEventListener('click', function () {
value.value = JSON.stringify(editor.getValue());
console.log(editor.getValue());
});

</script>

</body>
</html>