Skip to content

Commit d3aeafc

Browse files
authored
Merge pull request #5 from germanbisurgi/master
custo ckeditor and selectize editors
2 parents 65ef9d3 + c660729 commit d3aeafc

File tree

4 files changed

+363
-0
lines changed

4 files changed

+363
-0
lines changed

src/JsonEditorPluginsAsset.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
/**
3+
* @link http://www.diemeisterei.de/
4+
* @copyright Copyright (c) 2018 diemeisterei GmbH, Stuttgart
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
namespace dmstr\jsoneditor;
11+
12+
use yii\web\AssetBundle;
13+
use dosamigos\selectize\SelectizeAsset;
14+
use yii\web\JqueryAsset;
15+
use dosamigos\ckeditor\CKEditorAsset;
16+
17+
class JsonEditorPluginsAsset extends AssetBundle
18+
{
19+
public $sourcePath = '@dmstr/jsoneditor/assets/';
20+
21+
public $js = [
22+
'editors/filefly.js',
23+
'editors/ckeditor.js',
24+
];
25+
26+
public $depends = [
27+
SelectizeAsset::class,
28+
CKEditorAsset::class,
29+
JqueryAsset::class
30+
];
31+
32+
}

src/JsonEditorWidget.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,13 @@ class JsonEditorWidget extends BaseWidget
7272
*/
7373
public function init()
7474
{
75+
// if set use CKEditor configurations from settings module else use default configuration.
76+
$json = \Yii::$app->settings->get('ckeditor.config', 'widgets');
77+
$ckeditorConfiguration = isset($json->scalar) ? $json->scalar : "{}";
78+
$script = "window.CKCONFIG = {$ckeditorConfiguration};";
79+
\Yii::$app->view->registerJs($script, \yii\web\View::POS_HEAD);
80+
81+
7582
if ($this->name === null && !$this->hasModel() && $this->selector === null) {
7683
throw new InvalidConfigException("Either 'name', or 'model' and 'attribute' properties must be specified.");
7784
}
@@ -101,6 +108,7 @@ public function init()
101108

102109
parent::init();
103110
JsonEditorAsset::register($this->getView());
111+
JsonEditorPluginsAsset::register($this->getView());
104112
}
105113

106114
/**

src/assets/editors/ckeditor.js

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
JSONEditor.defaults.editors.ckeditor = JSONEditor.AbstractEditor.extend({
2+
setValue: function(value) {
3+
if (value === null) {
4+
value = '';
5+
}
6+
7+
if(this.value === value) {
8+
return;
9+
}
10+
this.input.value = value;
11+
this.value = value;
12+
this.onChange();
13+
},
14+
register: function() {
15+
this._super();
16+
if(!this.input) return;
17+
this.input.setAttribute('name', this.formname);
18+
},
19+
unregister: function() {
20+
this._super();
21+
if(!this.input) return;
22+
this.input.removeAttribute('name');
23+
},
24+
getNumColumns: function() {
25+
if(!this.enum_options) return 3;
26+
var longest_text = this.getTitle().length;
27+
for(var i=0; i<this.enum_options.length; i++) {
28+
longest_text = Math.max(longest_text,this.enum_options[i].length+4);
29+
}
30+
return Math.min(12,Math.max(longest_text/7,2));
31+
},
32+
getValue: function() {
33+
if (!this.value) {
34+
this.value = '';
35+
}
36+
return this.value;
37+
},
38+
build: function() {
39+
var self = this;
40+
41+
if (!this.options.compact) {
42+
this.header = this.label = this.theme.getFormInputLabel(this.getTitle());
43+
}
44+
45+
if (this.schema.description) {
46+
this.description = this.theme.getFormInputDescription(this.schema.description);
47+
}
48+
49+
if (this.options.infoText) {
50+
this.infoButton = this.theme.getInfoButton(this.options.infoText);
51+
}
52+
53+
if (this.options.compact) {
54+
this.container.classList.add('compact');
55+
}
56+
57+
this.input = this.theme.getFormInputField('text');
58+
59+
60+
if(this.schema.readOnly || this.schema.readonly) {
61+
this.always_disabled = true;
62+
this.input.disabled = true;
63+
}
64+
65+
this.input.addEventListener('change',function(e) {
66+
e.preventDefault();
67+
e.stopPropagation();
68+
self.onInputChange();
69+
});
70+
71+
this.control = this.theme.getFormControl(this.label, this.input, this.description, this.infoButton);
72+
this.container.appendChild(this.control);
73+
74+
this.initCKEditor();
75+
},
76+
postBuild: function() {
77+
this._super();
78+
this.theme.afterInputReady(this.input);
79+
},
80+
initCKEditor: function() {
81+
var self = this;
82+
if (window.CKCONFIG) {
83+
self.instance = CKEDITOR.replace(self.input, window.CKCONFIG);
84+
} else {
85+
self.instance = CKEDITOR.replace(self.input);
86+
}
87+
88+
CKEDITOR.on('instanceReady', function(evt) {
89+
if (evt.editor === self.instance) {
90+
evt.editor.setData(self.value);
91+
}
92+
});
93+
self.instance.on('change', function () {
94+
self.input.value = self.instance.getData();
95+
self.onInputChange();
96+
});
97+
},
98+
onInputChange: function() {
99+
this.setValue(this.input.value);
100+
this.onChange(true);
101+
},
102+
onMove: function() {
103+
this.destroyCKEditor();
104+
this.initCKEditor();
105+
},
106+
enable: function() {
107+
if(!this.always_disabled) {
108+
this.input.disabled = false;
109+
if(this.instance) {
110+
this.instance.setReadOnly(false);
111+
}
112+
this._super();
113+
}
114+
},
115+
disable: function(always_disabled) {
116+
if(always_disabled) this.always_disabled = true;
117+
this.input.disabled = true;
118+
if(this.instance) {
119+
self.instance.setReadOnly(true);
120+
}
121+
this._super();
122+
},
123+
destroy: function() {
124+
if(this.label && this.label.parentNode) this.label.parentNode.removeChild(this.label);
125+
if(this.description && this.description.parentNode) this.description.parentNode.removeChild(this.description);
126+
if(this.input && this.input.parentNode) this.input.parentNode.removeChild(this.input);
127+
this.destroyCKEditor();
128+
this._super();
129+
},
130+
destroyCKEditor: function() {
131+
if(this.instance) {
132+
this.instance.destroy();
133+
this.instance = null;
134+
}
135+
}
136+
});
137+
138+
// Make it compatible with old widgets
139+
JSONEditor.defaults.resolvers.unshift(function(schema) {
140+
if(schema.format === "html") {
141+
return "ckeditor";
142+
}
143+
});

src/assets/editors/filefly.js

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
JSONEditor.defaults.editors.filefly = JSONEditor.AbstractEditor.extend({
2+
setValue: function(value) {
3+
if (value === null) {
4+
value = '';
5+
}
6+
7+
if(this.value === value) {
8+
return;
9+
}
10+
this.input.value = value;
11+
this.onChange();
12+
},
13+
register: function() {
14+
this._super();
15+
if(!this.input) return;
16+
this.input.setAttribute('name', this.formname);
17+
},
18+
unregister: function() {
19+
this._super();
20+
if(!this.input) return;
21+
this.input.removeAttribute('name');
22+
},
23+
getNumColumns: function() {
24+
if(!this.enum_options) return 3;
25+
var longest_text = this.getTitle().length;
26+
for(var i=0; i<this.enum_options.length; i++) {
27+
longest_text = Math.max(longest_text,this.enum_options[i].length+4);
28+
}
29+
return Math.min(12,Math.max(longest_text/7,2));
30+
},
31+
getValue: function() {
32+
if (!this.value) {
33+
this.value = '';
34+
}
35+
return this.value;
36+
},
37+
build: function() {
38+
var self = this;
39+
40+
if (!this.options.compact) {
41+
this.header = this.label = this.theme.getFormInputLabel(this.getTitle());
42+
}
43+
44+
if (this.schema.description) {
45+
this.description = this.theme.getFormInputDescription(this.schema.description);
46+
}
47+
48+
if (this.options.infoText) {
49+
this.infoButton = this.theme.getInfoButton(this.options.infoText);
50+
}
51+
52+
if (this.options.compact) {
53+
this.container.classList.add('compact');
54+
}
55+
56+
this.input = this.theme.getFormInputField('text');
57+
58+
59+
if(this.schema.readOnly || this.schema.readonly) {
60+
this.always_disabled = true;
61+
this.input.disabled = true;
62+
}
63+
64+
this.input.addEventListener('change',function(e) {
65+
e.preventDefault();
66+
e.stopPropagation();
67+
self.onInputChange();
68+
});
69+
70+
this.control = this.theme.getFormControl(this.label, this.input, this.description, this.infoButton);
71+
this.container.appendChild(this.control);
72+
73+
this.initSelectize();
74+
},
75+
postBuild: function() {
76+
this._super();
77+
this.theme.afterInputReady(this.input);
78+
},
79+
initSelectize: function() {
80+
var self = this;
81+
this.path = this.schema.path || '/filefly/api';
82+
83+
this.selectize = $(this.input).selectize({
84+
valueField: 'path',
85+
labelField: 'path',
86+
searchField: 'path',
87+
placeholder: 'Select a file...',
88+
maxItems: 1,
89+
plugins: ['remove_button'],
90+
preload: true,
91+
options: [],
92+
create: false,
93+
render: {
94+
item: function (item, escape) {
95+
return '<div class="" style="height: 70px">' +
96+
'<img class="pull-left img-responsive" alt="filefly image" style="max-width: 100px; max-height: 70px" src="' + self.path + '?action=stream&path=' + (item.path) + '" />' +
97+
'<span class="">' + escape(item.path) + '</span><br/>' +
98+
'<span class="">' + 'banana' + '</span><br/>' +
99+
'</div>';
100+
},
101+
option: function (item, escape) {
102+
return '<div class="col-xs-6 col-sm-4 col-md-3 col-lg-2" style="height: 150px">' +
103+
'<img class="img-responsive" alt="filefly image" style="max-height: 100px" src="' + self.path + '?action=stream&path=' + (item.path) + '" />' +
104+
'<span class="">' + escape(item.path) + '</span>' +
105+
106+
'</div>';
107+
}
108+
},
109+
load: function (query, callback) {
110+
var selectize = this;
111+
$.ajax({
112+
url: self.path,
113+
type: 'GET',
114+
dataType: 'json',
115+
data: {
116+
action: 'search',
117+
q: query,
118+
page_limit: 20
119+
},
120+
error: function (e) {
121+
},
122+
success: function (data) {
123+
callback(data);
124+
selectize.setValue(self.input.value); // set initial value
125+
self.onInputChange();
126+
}
127+
});
128+
},
129+
onDropdownClose: function () {
130+
self.input.value = this.getValue();
131+
self.onInputChange();
132+
}
133+
});
134+
},
135+
onInputChange: function() {
136+
this.value = this.input.value;
137+
this.onChange(true);
138+
},
139+
onMove: function() {
140+
this.destroySelectize();
141+
this.initSelectize();
142+
},
143+
enable: function() {
144+
if(!this.always_disabled) {
145+
this.input.disabled = false;
146+
if(this.selectize) {
147+
this.selectize[0].selectize.unlock();
148+
}
149+
this._super();
150+
}
151+
},
152+
disable: function(always_disabled) {
153+
if(always_disabled) this.always_disabled = true;
154+
this.input.disabled = true;
155+
if(this.selectize) {
156+
this.selectize[0].selectize.lock();
157+
}
158+
this._super();
159+
},
160+
destroy: function() {
161+
if(this.label && this.label.parentNode) this.label.parentNode.removeChild(this.label);
162+
if(this.description && this.description.parentNode) this.description.parentNode.removeChild(this.description);
163+
if(this.input && this.input.parentNode) this.input.parentNode.removeChild(this.input);
164+
this.destroySelectize();
165+
this._super();
166+
},
167+
destroySelectize: function() {
168+
if(this.selectize) {
169+
this.selectize[0].selectize.destroy();
170+
this.selectize = null;
171+
}
172+
}
173+
});
174+
175+
// Make it compatible with old widgets
176+
JSONEditor.defaults.resolvers.unshift(function(schema) {
177+
if(schema.type === "string" && schema.format === "filefly") {
178+
return "filefly";
179+
}
180+
});

0 commit comments

Comments
 (0)