|
@@ -100,6 +100,11 @@ const myNewComponentTypes = (editor) => {
|
|
|
model: {
|
|
|
defaults: {
|
|
|
traits: [
|
|
|
+ {
|
|
|
+ type: 'text', // Type of the trait
|
|
|
+ name: 'title', // (required) The name of the attribute/property to use on component
|
|
|
+ label: 'title', // The label you will see in Settings
|
|
|
+ },
|
|
|
{
|
|
|
type: 'text', // Type of the trait
|
|
|
name: 'width', // (required) The name of the attribute/property to use on component
|
|
@@ -115,7 +120,7 @@ const myNewComponentTypes = (editor) => {
|
|
|
},
|
|
|
});
|
|
|
};
|
|
|
-
|
|
|
+const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
|
|
|
// 创建 GrapesJS 编辑器实例
|
|
|
const editor = grapesjs.init({
|
|
|
container: '#gjs', // 指定编辑器容器的 DOM 元素
|
|
@@ -125,13 +130,14 @@ const editor = grapesjs.init({
|
|
|
storageManager: false,
|
|
|
panels: panelsConfig,
|
|
|
plugins: [myNewComponentTypes],
|
|
|
- canvas: {
|
|
|
- // 禁用对所有元素的选择
|
|
|
- selectorManager: {
|
|
|
- // 允许选择特定类名的元素
|
|
|
- selector: '.your-class-name',
|
|
|
- }
|
|
|
- }
|
|
|
+ assetManager: {
|
|
|
+ upload: '/dist/visual-editor/upload',
|
|
|
+ uploadName: '_file_',
|
|
|
+ multiUpload:false,
|
|
|
+ headers: {
|
|
|
+ 'X-CSRF-TOKEN': csrfToken,
|
|
|
+ },
|
|
|
+ },
|
|
|
});
|
|
|
const am = editor.AssetManager;
|
|
|
// 锁定整个画布
|
|
@@ -157,15 +163,39 @@ editor.getComponents().each(component => {
|
|
|
// 如果有交集,解锁组件
|
|
|
if (hasIntersection || component.get('attributes').mtb_edit == 'true') {
|
|
|
component.set({ locked: false });
|
|
|
- component.setStyle({
|
|
|
- border: '2px dashed #3b97e3 '
|
|
|
- });
|
|
|
+ setBorder(component);
|
|
|
+ }
|
|
|
+ if (component.get('attributes').mtb_edit == 'false') {
|
|
|
+ component.set({ locked: true });
|
|
|
+ }
|
|
|
+
|
|
|
+ if (component.get('attributes').mtb_edit_this == 'true') {
|
|
|
+ component.set({ locked: false });
|
|
|
+ setBorder(component);
|
|
|
+ //关闭子组件
|
|
|
+ component.forEachChild(child => {
|
|
|
+ child.set({ locked: true });
|
|
|
+ })
|
|
|
+ }
|
|
|
+ if (component.get('attributes').mtb_edit_this == 'false') {
|
|
|
+ component.set({ locked: true });
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
});
|
|
|
|
|
|
+function setBorder(component) {
|
|
|
+ if (component.attributes.tagName == 'a') {
|
|
|
+ component.setStyle({
|
|
|
+ border: '3px dashed #f08300'
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ component.setStyle({
|
|
|
+ border: '1px dashed #3b97e3'
|
|
|
+ });
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
|
|
|
// 监听组件选择事件
|
|
@@ -179,26 +209,13 @@ editor.on('component:selected', (comp) => {
|
|
|
});
|
|
|
|
|
|
//如果是连接与图片,显示右边的属性面板
|
|
|
- let tags = ['a', 'img'];
|
|
|
- const hasScheduleAttribute = selectedComponent.attributes;
|
|
|
- if (tags.includes(selectedComponent.attributes.tagName)) {
|
|
|
- editor.runCommand('open-tm');
|
|
|
- // 获取 .gjs-cv-canvas-bg 元素
|
|
|
- canvasBg = document.querySelector('.gjs-cv-canvas');
|
|
|
- canvasBg.classList.remove('gjs-cv-canvas-bg');
|
|
|
+ // let tags = ['a', 'img'];
|
|
|
+ // const hasScheduleAttribute = selectedComponent.attributes;
|
|
|
+ // if (tags.includes(selectedComponent.attributes.tagName)) {
|
|
|
+ // //editor.runCommand('open-tm');
|
|
|
+ // } else {
|
|
|
+ // }
|
|
|
|
|
|
- var elements = document.querySelectorAll('.gjs-pn-views-container');
|
|
|
- elements.forEach(function(element) {
|
|
|
- element.style.display = 'block'; // 或者 'flex',取决于你希望如何显示这些元素
|
|
|
- });
|
|
|
- } else {
|
|
|
- canvasBg = document.querySelector('.gjs-cv-canvas');
|
|
|
- canvasBg.classList.add('gjs-cv-canvas-bg');
|
|
|
- var elements = document.querySelectorAll('.gjs-pn-views-container');
|
|
|
- elements.forEach(function(element) {
|
|
|
- element.style.display = 'none'; // 或者 'flex',取决于你希望如何显示这些元素
|
|
|
- });
|
|
|
- }
|
|
|
// 双击图片时弹出图片管理器
|
|
|
if (selectedComponent.attributes.tagName == 'img') {
|
|
|
//双击图片时弹出图片管理器
|
|
@@ -221,8 +238,50 @@ editor.on('component:selected', (comp) => {
|
|
|
});
|
|
|
}
|
|
|
//其他
|
|
|
+
|
|
|
+});
|
|
|
+
|
|
|
+var open_tm_show = true;
|
|
|
+var cogIcons = document.querySelectorAll('.fa-cog');
|
|
|
+cogIcons.forEach(function(icon) {
|
|
|
+ icon.addEventListener('click', function() {
|
|
|
+ // 在这里执行你想要的操作
|
|
|
+ if (open_tm_show) {
|
|
|
+ open_tm_show = false;
|
|
|
+ } else {
|
|
|
+ open_tm_show = true;
|
|
|
+ }
|
|
|
+ leftPanelDisplay(open_tm_show);
|
|
|
+ });
|
|
|
});
|
|
|
|
|
|
+function leftPanelDisplay(isShow = true) {
|
|
|
+ if (isShow) {
|
|
|
+ // canvasBg = document.querySelector('.gjs-cv-canvas');
|
|
|
+ // canvasBg.classList.remove('gjs-cv-canvas-bg');
|
|
|
+ let elements1 = document.querySelectorAll('.gjs-pn-views-container');
|
|
|
+ elements1.forEach(function(element) {
|
|
|
+ element.style.display = 'block'; // 或者 'flex',取决于你希望如何显示这些元素
|
|
|
+ });
|
|
|
+ let elements2 = document.querySelectorAll('.gjs-pn-views');
|
|
|
+ elements2.forEach(function(element) {
|
|
|
+ element.style = 'border_bottom: 2px solid var(--gjs-main-dark-color)';
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ // canvasBg = document.querySelector('.gjs-cv-canvas');
|
|
|
+ // canvasBg.classList.add('gjs-cv-canvas-bg');
|
|
|
+ let elements1 = document.querySelectorAll('.gjs-pn-views-container');
|
|
|
+ elements1.forEach(function(element) {
|
|
|
+ element.style.display = 'none'; // 或者 'flex',取决于你希望如何显示这些元素
|
|
|
+ });
|
|
|
+ let elements2 = document.querySelectorAll('.gjs-pn-views');
|
|
|
+ elements2.forEach(function(element) {
|
|
|
+ element.style = 'border:none';
|
|
|
+ });
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
// 监听 load 事件
|
|
|
editor.on('load', () => {
|
|
|
// 在这里执行你的初始化逻辑
|
|
@@ -245,7 +304,7 @@ editor.on('load', () => {
|
|
|
dropdown.innerHTML = options;
|
|
|
// 将下拉选择框插入到目标元素之后
|
|
|
targetElement.insertAdjacentElement('afterend', dropdown);
|
|
|
- //
|
|
|
+
|
|
|
dropdownel = document.getElementById('dropdown');
|
|
|
// 监听 change 事件
|
|
|
dropdownel.addEventListener('change', function () {
|
|
@@ -262,12 +321,42 @@ editor.on('load', () => {
|
|
|
window.location.href = redirectUrl;
|
|
|
}
|
|
|
});
|
|
|
-
|
|
|
});
|
|
|
|
|
|
//更新时调用接口保存数据
|
|
|
editor.on('update', () => {
|
|
|
const html = editor.getHtml();
|
|
|
// 你可以在这里添加自定义逻辑
|
|
|
- console.log('GrapesJS updated the editor content', html);
|
|
|
+ //ajax提交数据
|
|
|
+ $.ajax({
|
|
|
+ url: '/dist/visual-editor/preview-save',
|
|
|
+ type: 'POST',
|
|
|
+ headers: {
|
|
|
+ 'X-CSRF-TOKEN': csrfToken,
|
|
|
+ },
|
|
|
+ data: { // 发送数据
|
|
|
+ html: html
|
|
|
+ },
|
|
|
+ success: function (res) {
|
|
|
+ if (res.status != 1) {
|
|
|
+ //alert('save error');
|
|
|
+ }
|
|
|
+ },
|
|
|
+ error: function (err) {
|
|
|
+ alert(err);
|
|
|
+ }
|
|
|
+ });
|
|
|
+});
|
|
|
+
|
|
|
+// 上传图片时触发
|
|
|
+var layer = layui.layer;
|
|
|
+var loadIndex = null;
|
|
|
+editor.on('asset:upload:start', () => {
|
|
|
+ loadIndex = layer.load(0, {shade: [0.5, '#000']});
|
|
|
});
|
|
|
+
|
|
|
+// The upload is ended (completed or not)
|
|
|
+editor.on('asset:upload:end', () => {
|
|
|
+ layer.close(loadIndex);
|
|
|
+});
|
|
|
+
|