NomEditor

NomEditor plugin

Trình soạn thảo gắn trên <textarea>: textarea gốc ẩn đi, nội dung luôn được ghi lại vào textarea.value, nên form submit, asp-for dùng như bình thường. Core có đậm, nghiêng, gạch chân, tiêu đề, danh sách, căn lề; các chức năng khác là plugin, bỏ một dòng <script> plugin thì nút tương ứng biến mất khỏi toolbar.

Nạp thư viện

<script src="~/nom/js/nom.js"></script>
<script src="~/nom/js/nom.editor.js"></script>          <!-- core -->
<script src="~/nom/js/nom.editor.font.js"></script>     <!-- plugin: thứ tự không quan trọng -->
<script src="~/nom/js/nom.editor.color.js"></script>
<script src="~/nom/js/nom.editor.href.js"></script>
<script src="~/nom/js/nom.editor.image.js"></script>
<script src="~/nom/js/nom.editor.youtube.js"></script>
<script src="~/nom/js/nom.editor.table.js"></script>
<script src="~/nom/js/nom.editor.seo.js"></script>
<script src="~/nom/js/nom.filemanager.js"></script>   <!-- thư viện ảnh cho plugin image -->

Khởi tạo

// Hai cách tương đương; gọi lại trên cùng textarea trả về instance cũ.
var ed  = nom('#content').editor({ placeholder: 'Nhập nội dung...', height: 300 });
var ed2 = NomEditor('basic', { height: 180, plugins: [] });   // id không có '#'

Plugin

Tuỳ chọn plugins: null (mặc định) là mọi plugin đã nạp; [] chỉ core; ['href', 'image'] chọn lọc. Danh sách dưới đây đánh dấu plugin có nạp trên trang này.

1. Toolbar đầy đủ

Không truyền plugins: dùng mọi plugin đã nạp.

nom('#full').editor({ placeholder: 'Nhập nội dung 1...', height: 300 });

2. Toolbar cơ bản

plugins: []: chỉ các nút của core, hợp cho ô mô tả ngắn.

NomEditor('basic', { placeholder: 'Mô tả...', height: 180, plugins: [] });

3. Chọn plugin

Chỉ bật một số plugin: ở đây là font, màu và chèn liên kết.

nom('#pick').editor({ height: 180, plugins: ['font', 'color', 'href'] });

4. Thư viện ảnh, AI

Plugin image mở NomFileManager (trang quản lý tệp có các handler ListImages, Upload, Delete, Rename); nút AI chỉ hiện khi có ai.url, gửi POST JSON { prompt } kèm token antiforgery và chèn kết quả vào editor.

nom('#fullWithImage').editor({
    height: 220,
    fileManager: {
        url: '/AdminPanel/Media',
        publicUrl: 'https://localhost:51061',   // gốc tệp tĩnh: đường dẫn ảnh thành tuyệt đối
        listImagesUrl: '?handler=ListImages',
        uploadUrl: '?handler=Upload',
        deleteUrl: '?handler=Delete',
        renameUrl: '?handler=Rename',
        kind: 'image',                          // editor chỉ chèn ảnh
        pageSize: 24
    },
    ai: {
        url: '/TestAi?handler=Generate',
        field: 'prompt',
        csrf: { header: 'RequestVerificationToken', selector: "input[name='__RequestVerificationToken']" }
    }
});

5. Kiểm tra SEO

seoCheck đối chiếu nội dung với tiêu đề, từ khoá, mô tả của trang (truyền id các ô nhập) và chấm điểm ngay khi soạn.

nom('#seoContent').editor({
    seoCheck: { title: 'seo_title', keyword: 'seo_keyword', description: 'seo_description' }
});

6. CSS nội dung (applyCss)

applyCss cho vùng soạn hiển thị giống trang thật (URL, mảng URL hoặc chuỗi CSS); CSS tự giới hạn trong vùng soạn, không ảnh hưởng toolbar và hộp thoại.

nom('#styled').editor({
                height: 220,
                applyCss: ['../nom/css/nom.css','../nom/css/nom-ui.css', '../css/site.css']
    // hoặc applyCss: '/css/site.css'  |  ['/css/site.css', '/css/content.css']
});

7. API instance

Thử các hàm trên editor của mục 1 (#full). setHTML, insertHTML lọc nội dung theo các thẻ core và plugin đang bật.

Kết quả…
var ed = nom('#full').editor();          // lấy lại instance đã tạo
ed.getHTML(); ed.setHTML(html); ed.getText(); ed.insertHTML(html); ed.insertText(text);
ed.clear(); ed.focus(); ed.sync(); ed.undo(); ed.redo(); ed.toggleCode(true); ed.destroy();

Gửi form

Mọi editor trên trang nằm chung một form; bấm gửi để xem dữ liệu (nội dung editor được ghi về textarea gốc).

Chưa gửi.

Mẹo sử dụng

  • Nút ▦ chèn bảng; chuột phải trong bảng, trên liên kết, ảnh, video để có menu chỉnh sửa (chỉ trong vùng soạn).
  • Dán từ nơi khác tự bỏ định dạng, chỉ giữ đoạn văn, ngắt dòng và tiêu đề (h1–h6). pasteAsText: true để dán chữ thuần.
  • Enter tạo đoạn <p> mới; nội dung luôn được lọc theo danh sách thẻ cho phép của core và plugin.
  • Viết plugin mới bằng NomEditor.registerPlugin({ name, order, button, allowTags, onClick, init }).