Skip to content

Commit

Permalink
Adds Selectize support for array and select editors
Browse files Browse the repository at this point in the history
  • Loading branch information
Phil Ostler committed Sep 14, 2015
1 parent 729b587 commit 475405f
Show file tree
Hide file tree
Showing 8 changed files with 570 additions and 4 deletions.
2 changes: 2 additions & 0 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,12 @@ module.exports = function(grunt) {
'src/editors/multiple.js',
'src/editors/enum.js',
'src/editors/select.js',
'src/editors/selectize.js',
'src/editors/multiselect.js',
'src/editors/base64.js',
'src/editors/upload.js',
'src/editors/checkbox.js',
'src/editors/array/selectize.js',

// All the themes and iconlibs
'src/theme.js',
Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ The following are not required, but can improve the style and usability of JSON
* [EpicEditor](http://epiceditor.com/) for editing of Markdown content
* [Ace Editor](http://ace.c9.io/) for editing code
* [Select2](http://ivaynberg.github.io/select2/) for nicer Select boxes
* [Selectize](http://brianreavis.github.io/selectize.js/) for nicer Select & Array boxes

Usage
--------------
Expand Down Expand Up @@ -1144,6 +1145,15 @@ The possibilities are endless. Some ideas:
* Better editor for arrays of strings (tag editor)
* Canvas based image editor that produces Base64 data URLs

Select2 & Selectize Support
----------------
Select2 support is enabled by default and will become active if the Select2 library is detected.

Selectize support is enabled via the following snippet:
```js
JSONEditor.plugins.selectize.enable = true;
```
See the demo for an example of the `array` and `select` editor with Selectize support enabled.

Custom Validation
----------------
Expand Down
21 changes: 20 additions & 1 deletion demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@

<style>[class*="foundicon-"] {font-family: GeneralFoundicons;font-style: normal;}</style>
<script src='dist/jsoneditor.js'></script>

<script src="dist/selectize-0.11.2-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/selectize.js/0.12.1/js/standalone/selectize.js"></script>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/selectize.js/0.12.1/css/selectize.bootstrap3.css">

<script>
/**
* LZString compression library
Expand Down Expand Up @@ -82,6 +85,11 @@ <h2>Options</h2>
<option value='never'>Never</option>
</select>
</div>
<div>
<label>
<input id='selectize_support' type='checkbox'> Selectize Support
</label>
</div>
<div>
<label>Boolean options</label>
<select multiple size=9 id='boolean_options' style='width: 100%;' class='form-control'>
Expand Down Expand Up @@ -189,6 +197,13 @@ <h2>Code</h2>
type: "string",
enum: ["male", "female"]
},
interests: {
type: "array",
items: {
type: "string"
},
default: ["Squash", "Badminton", "Rugby"]
},
location: {
type: "object",
title: "Location",
Expand Down Expand Up @@ -395,6 +410,10 @@ <h2>Code</h2>
JSONEditor.defaults.options.show_errors = this.value;
reload(true);
});
document.getElementById('selectize_support').addEventListener('change',function() {
JSONEditor.plugins.selectize.enable = (this.value === 'on');
reload(true);
});
document.getElementById('boolean_options').addEventListener('change',function() {
refreshBooleanOptions();
});
Expand Down
85 changes: 85 additions & 0 deletions examples/selectize.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>JSON Editor Selectize Integration Example</title>
<script src="../dist/jsoneditor.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/selectize.js/0.12.1/js/standalone/selectize.js"></script>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/selectize.js/0.12.1/css/selectize.bootstrap3.css">
</head>
<body>
<h1>JSON Editor Selectize Integration Example</h1>

<p style='margin-bottom:20px;'>This example demonstrates JSONEditor's integration with Selectize</p>

<div id='editor_holder'></div>
<button id='submit'>Submit (console.log)</button>

<script>
// Global selectize options
JSONEditor.plugins.selectize.enable = true;

// Initialize the editor with a JSON schema
var editor = new JSONEditor(document.getElementById('editor_holder'),{
schema: {
type: "object",
title: "Text",
required: ["fontSize","color","font","weight","possibleFonts"],
properties: {
fontSize: {
type: "integer",
enum: [10,11,12,14,16,18,20,22,24,36,48,60,72,100],
default: 24,
},
color: {
type: "string",
enum: ["black","red","green","blue","yellow","orange","purple","brown","white","cyan","maagenta"],
options: {
// Override defaullt options
selectize_options: {
create: true,
sortField: 'text'
}
}
},
font: {
type: "string",
enumSource: "possible_fonts",
watch: {
"possible_fonts": "root.possibleFonts"
},
},
weight: {
type: "string",
enum: ["normal","bold","bolder","lighter"],
options: {
enum_titles: ["Normal (400)","Bold (700)","Bolder (900)","Lighter (200)"]
}
},
possibleFonts: {
type: "array",
format: 'table',
items: {
type: "string"
},
default: ["Arial","Times","Helvetica","Comic Sans"],
options: {
collapsed: true
}
}
}
},
startval: {
color: "red"
}
});

// Hook up the submit button to log to the console
document.getElementById('submit').addEventListener('click',function() {
// Get the value from the editor
console.log(editor.getValue());
});
</script>
</body>
</html>
3 changes: 3 additions & 0 deletions src/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,9 @@ JSONEditor.prototype = {
});

if(!classname) throw "Unknown editor for schema "+JSON.stringify(schema);
if(classname === "array" && JSONEditor.plugins.selectize.enable) {
classname = classname + "Selectize";
}
if(!JSONEditor.defaults.editors[classname]) throw "Unknown editor "+classname;

return JSONEditor.defaults.editors[classname];
Expand Down
8 changes: 5 additions & 3 deletions src/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ JSONEditor.plugins = {
},
select2: {

},
selectize: {
}
};

Expand Down Expand Up @@ -196,7 +198,7 @@ JSONEditor.defaults.resolvers.unshift(function(schema) {
return "checkbox";
}
// Otherwise, default to select menu
return "select";
return (JSONEditor.plugins.selectize.enable) ? 'selectize' : 'select';
}
});
// Use the multiple editor for schemas where the `type` is set to "any"
Expand Down Expand Up @@ -226,7 +228,7 @@ JSONEditor.defaults.resolvers.unshift(function(schema) {
});
// Use the `select` editor for dynamic enumSource enums
JSONEditor.defaults.resolvers.unshift(function(schema) {
if(schema.enumSource) return "select";
if(schema.enumSource) return (JSONEditor.plugins.selectize.enable) ? 'selectize' : 'select';
});
// Use the `enum` or `select` editors for schemas with enumerated properties
JSONEditor.defaults.resolvers.unshift(function(schema) {
Expand All @@ -235,7 +237,7 @@ JSONEditor.defaults.resolvers.unshift(function(schema) {
return "enum";
}
else if(schema.type === "number" || schema.type === "integer" || schema.type === "string") {
return "select";
return (JSONEditor.plugins.selectize.enable) ? 'selectize' : 'select';
}
}
});
Expand Down
99 changes: 99 additions & 0 deletions src/editors/array/selectize.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
JSONEditor.defaults.editors.arraySelectize = JSONEditor.AbstractEditor.extend({
build: function() {

var self = this;

this.title = this.theme.getFormInputLabel(this.getTitle());

this.title_controls = this.theme.getHeaderButtonHolder();
this.title.appendChild(this.title_controls);
this.error_holder = document.createElement('div');

if(this.schema.description) {
this.description = this.theme.getDescription(this.schema.description);
}

this.input = document.createElement('input');
this.input.setAttribute('type', 'text');

var group = this.theme.getFormControl(this.title, this.input, this.description);

this.container.appendChild(group);
this.container.appendChild(this.error_holder);

window.jQuery(this.input).selectize({
delimiter: ',',
createOnBlur: true,
create: true
});


},
postBuild: function() {
var self = this;
this.input.selectize.on('change', function(event) {
self.refreshValue();
self.onChange(true);
});
},
destroy: function() {
this.empty(true);
if(this.title && this.title.parentNode) this.title.parentNode.removeChild(this.title);
if(this.description && this.description.parentNode) this.description.parentNode.removeChild(this.description);
if(this.input && this.input.parentNode) this.input.parentNode.removeChild(this.input);

this._super();
},
empty: function(hard) {},
setValue: function(value, initial) {
var self = this;
// Update the array's value, adding/removing rows when necessary
value = value || [];
if(!(Array.isArray(value))) value = [value];

this.input.selectize.clearOptions();
this.input.selectize.clear(true);

value.forEach(function(item) {
self.input.selectize.addOption({text: item, value: item});
});
this.input.selectize.setValue(value);

this.refreshValue(initial);
},
refreshValue: function(force) {
this.value = this.input.value.split(',');
},
showValidationErrors: function(errors) {
var self = this;

// Get all the errors that pertain to this editor
var my_errors = [];
var other_errors = [];
$each(errors, function(i,error) {
if(error.path === self.path) {
my_errors.push(error);
}
else {
other_errors.push(error);
}
});

// Show errors for this editor
if(this.error_holder) {

if(my_errors.length) {
var message = [];
this.error_holder.innerHTML = '';
this.error_holder.style.display = '';
$each(my_errors, function(i,error) {
self.error_holder.appendChild(self.theme.getErrorMessage(error.message));
});
}
// Hide error area
else {
this.error_holder.style.display = 'none';
}
}
}
});
Loading

0 comments on commit 475405f

Please sign in to comment.