Dcat Admin 为form组件editor添加短代码插入功能,表单动态显示

一直做虚拟资源网站,现在自己学习PHP一个月,接触到Laravel 又接触到Dcat admin 目前只要能够实现自己的需求就可以,不要求代码写的多漂亮,虽然我知道这不是最优解决方案。

之前虚拟资源站都是用WordPress搭建的,也可以看见很多WordPress的编辑器都有如下按钮向编辑器插入短代码内容

这对于我们资源站来说,比较有用的,自己在新项目中也想实现这样的功能!原来也想通过编辑器插件的形式实现这个功能,可是研究半天(不会)!就想起dcat admin 的工具表单功能,接下来就开始了!

实现效果


首先在app/Admin/Forms/下创建一个工具表单
我的路径是app/Admin/Forms/djsystem/editorAdd.php

<?php

namespace App\Admin\Forms\djsystem;

use App\Admin\Controllers\DjTool\DJ;
use Dcat\Admin\Widgets\Alert;
use Dcat\Admin\Widgets\Form;
use Dcat\Admin\Widgets\Radio;

class editorAdd extends Form
{
    public function handle(array $input)
    {
//        dd($input);
        $text = '';
        $type = $input['type'];
        switch ($type) {
            case "dj-reply-hide":
                $text = '[dj-reply-hide]' . $input['dj-reply-hide'] . '[/dj-reply-hide]';
                $msg = '评论可见内容插入成功';
                break;
            case "dj-buttons":
                $text = '[dj-reply-hide]' . $input['dj-reply-hide'] . '[/dj-reply-hide]';
                $msg = '评论可见内容插入成功';
                break;
            case "dj-login-hid":
                $text = '[dj-login-hid]' . $input['dj-login-hid'] . '[/dj-login-hid]';
                $msg = '登录可见内容插入成功';
                break;
            case "dj-video":
                $text = '[dj-video url="' . $input['url'] . '" pic="' . $input['pic'] . '"]';
                $msg = '视频播放器插入成功';
                break;
            case "dj-alerts":
                $text = '[dj-alerts color="' . $input['color'] . '"]' . $input['content'] . '[/dj-alerts]';
                $msg = '提示框插入成功';
                break;
            case "djhide":
                $text = '[djhide]' . $input['djhide'] . '[/djhide]';
                $msg = '付费隐藏内容插入成功';
                break;
            case "dj-accordions":
                $text = '';
                foreach (json_decode($input['dj-accordions']) as $key => $value) {
                    $text .= '[dj-accordions title="' . htmlspecialchars($value->title) . '"]' . htmlspecialchars($value->content) . '[/dj-accordions]';
                }
                $msg = '列表内容插入成功';
                break;
            default:
                echo "你喜欢的颜色不是 红, 蓝, 或绿色!";
        }
        return $this->response()->script(
            <<<JS
tinymce.init({selector:'textarea[name=post_content]',});function insertTextIntoEditor(text){var textarea=document.querySelector('textarea[name=post_content]');if(textarea){var editor=tinymce.get(textarea.id);if(editor){editor.insertContent(text)}else{tinymce.editors.forEach(function(editorInstance){if(editorInstance.getElement()===textarea){editorInstance.insertContent(text);return}})}}else{console.error('Textarea with name "post_content" not found!')}}
insertTextIntoEditor('{$text}');
$('.close').click();
JS
        )->success($msg);
    }

    /**
     * Build a form here.
     */
    public function form()
    {

        $this->select('type')
            ->when('dj-reply-hide', function (Form $form) {
                $form->editor('dj-reply-hide', '')->options(['forced_root_block' => false,])->help('[dj-reply-hide]隐藏部分评论后可见内容[/dj-reply-hide]');
            })
            ->when('dj-login-hid', function (Form $form) {
                $form->editor('dj-login-hid', '')->options(['forced_root_block' => false,])->help('[dj-login-hid]隐藏部分评论后可见内容[/dj-login-hid]');
            })
            ->when('dj-video', function (Form $form) {
                $form->text('url', '视频地址')->help('内置videojs播放器,只支持视频真实播放地址,支付mp4,m3u8等格式');
                $form->mediaSelector('pic', '视频封面')->placeholder('选择图片')->options([
                    'area' => ['60%', '98%'], // 弹框大小
                    'limit' => 1, // 媒体数量
                    'types' => ['image'], // 媒体选择类型
                    'sortable' => true, // 排序
                    'move' => json_encode(['dir' => 'dj', 'fileNameIsEncrypt' => true]),// 第一个参数,媒体上传路径。默认media。第二个参数,媒体名称是否加密。默认true
                ]);
            })
            ->when('dj-buttons', function (Form $form) {
                $form->radio('size', '大小')->options(['btn-sm' => '小', '' => '常规', 'btn-lg' => '大']);
                $form->radio('color', '颜色')->options(['primary' => '蓝', 'info' => '浅蓝', 'success' => '绿', 'danger' => '红', 'warning' => '黄', 'secondary' => '灰', 'light' => '浅灰', 'dark' => '黑',]);
                $form->switch('outline', '边框')->help('按钮显示风格为边框模式');
                $form->switch('rounded', '圆角');
                $form->text('href', '链接')->help('按钮显示风格为边框模式');
                $form->switch('blank', '新窗口打开');
                $form->text('content', '名称')->default('这是按钮');

            })
            ->when('dj-alerts', function (Form $form) {
                $form->radio('color', '颜色')->options(['primary' => '蓝', 'info' => '浅蓝', 'success' => '绿', 'danger' => '红', 'warning' => '黄', 'secondary' => '灰', 'light' => '浅灰', 'dark' => '黑',]);
                $form->textarea('content', '内容')->placeholder('这是一条醒目的提示消息')->help('可以插入html代码');
            })
            ->when('dj-accordions', function (Form $form) {
                $form->array('dj-accordions', '列表内容', function ($table) {
                    $table->text('title', '标题');
                    $table->textarea('content', '内容')->help('可以插入html代码');
                })->saveAsJson();
            })
            ->when('djhide', function (Form $form) {
                $form->editor('djhide', '付费隐藏内存')->options(['forced_root_block' => false,])->help('[djhide]隐藏部分付费内容[/djhide]查看价格和权限设置等和付费下载相同');
            })
            ->options([
                'djhide' => '付费隐藏内容',
                'dj-reply-hide' => '评论可见内容[dj-reply-hide]',
                'dj-login-hid' => '登录可见内容[dj-login-hide]',
                'dj-video' => '视频播放器',
                'dj-buttons' => '按钮',
                'dj-alerts' => '提示框',
                'dj-accordions' => '列表内容',
            ])->default('djhide');
        $this->disableSubmitButton();
        $this->disableResetButton();
        $this->html('<div class="text-center"><button type="submit" class="btn btn-primary">插入到文章</button></div>');
    }
}

JS

tinymce.init({
    selector: 'textarea[name=post_content]',
});

function insertTextIntoEditor(text) {
    var textarea = document.querySelector('textarea[name=post_content]');
    if (textarea) {
        var editor = tinymce.get(textarea.id);
        if (editor) {
            editor.insertContent(text)
        } else {
            tinymce.editors.forEach(function(editorInstance) {
                if (editorInstance.getElement() === textarea) {
                    editorInstance.insertContent(text);
                    return
                }
            })
        }
    } else {
        console.error('Textarea with name "post_content" not found!')
    }
}
insertTextIntoEditor('{$text}');
$('.close').click();

selector: ‘textarea[name=post_content]’,
post_content是我们form表单的字段 因为dcat目前发现 编辑器的id是动态的
其实到这里主体已经完成了,因为逻辑都在工具表单中。
在弹出的模态框内用户的数据提交后都会被表单的handle接收,handle处理完逻辑返回需要插入编辑器的文本,通过下面的代码完成插入编辑器动作下面的代码在工具表单中已经存在!

return $this->response()->script(
            <<<JS
tinymce.init({selector:'textarea[name=post_content]',});function insertTextIntoEditor(text){var textarea=document.querySelector('textarea[name=post_content]');if(textarea){var editor=tinymce.get(textarea.id);if(editor){editor.insertContent(text)}else{tinymce.editors.forEach(function(editorInstance){if(editorInstance.getElement()===textarea){editorInstance.insertContent(text);return}})}}else{console.error('Textarea with name "post_content" not found!')}}
insertTextIntoEditor('{$text}');
$('.close').click();
JS
        )->success($msg);
    }

提交成功后执行的js动作,可以直接复制只要修改一下post_content为你的字段就可以

最后一步

在你需要显示这个工具表单的地方放置按钮

                $form->row(function (Form\Row $form) {

                    $model= Modal::make()
                        ->xl()
                        ->scrollable()
                        ->title('<strong>添加内容组件</strong>')
                        ->body(editorAdd::make())
                        ->button('<a class="btn btn-primary btn-outline"><span class="btn-primary btn-outline ">&nbsp;&nbsp;添加内容组件</span></a>');

                    $form->editor('post_content',$model)
                        ->placeholder('文章内容');
                });

我实现了一个model 把它放到了

$form->editor('post_content',$model)->placeholder('文章内容');

最后就实现上面动态图片的效果了!

目前只实现功能就可以,不要求代码质量,因为你得先会,会了才能优化

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!