javascript - How to format text and embed a video with Quill? - Stack Overflow

I started to integrate a WYSIWYG into a blog project, I'm using Quill for this (I had no experienc

I started to integrate a WYSIWYG into a blog project, I'm using Quill for this (I had no experience with it before). I was able to customize my editor the way it was required, what I don't understand is how to deal with text format and embed videos. I have two fields in my post form, "preview" and "content" (two quill editors) while introducing the text I can give format to it (header, italic, underline...etc) and when click the embed video option the editor allows me to add the link and visualize the embed video in that moment. When I press my save button it stores the post in my db but in my single post page I visualize all the fields without format (header, italic, underline...etc) and also no embed video. How can I give format and show the video? Any help would be appreciated.

I read the Quill documentation and tried to understand how to deal with this using deltas but I don't know how to make this work.

I'm using Meteor + React, this is my code (I'll show only relevant code):

This is my lib, quill.jsx

import React, { Component } from 'react';
import QuillLib from './vendor/quill.js';
import { ud } from '/helpers/lib/main.jsx';

class Quill extends Component {
  constructor(props) {
    super(props);
    this.id = ud.shortUID();
}

ponentDidMount() {
  const that = this;
  const toolbarOptions = [
    [{ font: [] }],
    [{ header: 1 }, { header: 2 }],
    [{ header: [1, 2, 3, 4, 5, 6, false] }],
    [{ align: [] }],
    ['bold', 'italic', 'underline', 'strike'],
    ['blockquote', 'code-block'],
    [{ script: 'sub' }, { script: 'super' }],
    [{ indent: '-1' }, { indent: '+1' }],
    [{ color: [] }, { background: [] }],
    ['video'],
    ['image'],
];

const quill = new QuillLib(`#quill-editor-container-${this.id}`, {
  modules: {
    toolbar: toolbarOptions,
  },
  theme: 'snow',
});
const content = this.props.content;
  quill.setContents(content);
  quill.on('text-change', (delta) => {
    if (that.props.onChange) {
      that.props.onChange(quill);
    }
  });
}

render() {
  return (
    <div className="wysiwyg-wrapper">
      <div id={`quill-editor-container-${this.id}`}></div>
    </div>
  );
 }
}
export default Quill;

This is my input form ponent, list.jxs

import { Meteor } from 'meteor/meteor';
import { PostSchema } from '/modules/blog/lib/collections.jsx';
import Quill from '/modules/quill/client/main.jsx';

export class BlogCategory extends Component {
  constructor(props) {
    super(props);
    this.state = {
      post: {
        content: '',
        preview: '',
      },
    };
    this.onPreviewChange = this.onPreviewChange.bind(this);
    this.onContentChange = this.onContentChange.bind(this);
  }

  onPreviewChange(content) {
    this.state.post.preview = content.getText();
    this.setState(this.state);
  }
  onContentChange(content) {
    this.state.post.content = content.getText();
    this.setState(this.state);
  }

  save() {
    const content = this.state.post.content;
    const preview = this.state.post.preview;
    const post = new PostSchema();
    post.set({
      content,
      preview,
    });
    if (post.validate(false)) {
      const id = post.save(); 
    }
    console.log(post.getValidationErrors(false));
  }

  renderCreatePostForm() {
   let content;
   if (this.state.showForm) {
     content = (
      <form action="">
        <Quill 
           content={this.state.post.preview} 
           onChange={this.onPreviewChange}
        />
        <Quill
           content={this.state.post.content}
           onChange={this.onContentChange}
        />
      </form>
     );
    }
    return content;
  }
  render() {
    let content = (
      <div className="col-xs-12">
        {this.renderActions()}
      </div>
    );
   if (!this.props.ready) {
    content = <p>LOADING...</p>;
   }
   return content;
  }
}
export default createContainer(() => {
  const handleValidPost = Meteor.subscribe('posts');
  return {
    ready: handleValidPost.ready(),
    posts: PostSchema.find({}).fetch(),
  };
}, BlogCategory);

And finally my collections.jsx

import { Mongo } from 'meteor/mongo';
export const PostCollection = new Mongo.Collection('Posts');
export const PostSchema = Astro.Class({
  name: 'PostSchema',
  collection: PostCollection,
  fields: {
    content: {
     validator : Validators.and([
       Validators.required(),
       Validators.string(),
       Validators.minLength(3)
     ])
    },
    preview: {
     validator : Validators.and([
       Validators.required(),
       Validators.string(),
       Validators.minLength(3)
     ])
    },
  }
});

I started to integrate a WYSIWYG into a blog project, I'm using Quill for this (I had no experience with it before). I was able to customize my editor the way it was required, what I don't understand is how to deal with text format and embed videos. I have two fields in my post form, "preview" and "content" (two quill editors) while introducing the text I can give format to it (header, italic, underline...etc) and when click the embed video option the editor allows me to add the link and visualize the embed video in that moment. When I press my save button it stores the post in my db but in my single post page I visualize all the fields without format (header, italic, underline...etc) and also no embed video. How can I give format and show the video? Any help would be appreciated.

I read the Quill documentation and tried to understand how to deal with this using deltas but I don't know how to make this work.

I'm using Meteor + React, this is my code (I'll show only relevant code):

This is my lib, quill.jsx

import React, { Component } from 'react';
import QuillLib from './vendor/quill.js';
import { ud } from '/helpers/lib/main.jsx';

class Quill extends Component {
  constructor(props) {
    super(props);
    this.id = ud.shortUID();
}

ponentDidMount() {
  const that = this;
  const toolbarOptions = [
    [{ font: [] }],
    [{ header: 1 }, { header: 2 }],
    [{ header: [1, 2, 3, 4, 5, 6, false] }],
    [{ align: [] }],
    ['bold', 'italic', 'underline', 'strike'],
    ['blockquote', 'code-block'],
    [{ script: 'sub' }, { script: 'super' }],
    [{ indent: '-1' }, { indent: '+1' }],
    [{ color: [] }, { background: [] }],
    ['video'],
    ['image'],
];

const quill = new QuillLib(`#quill-editor-container-${this.id}`, {
  modules: {
    toolbar: toolbarOptions,
  },
  theme: 'snow',
});
const content = this.props.content;
  quill.setContents(content);
  quill.on('text-change', (delta) => {
    if (that.props.onChange) {
      that.props.onChange(quill);
    }
  });
}

render() {
  return (
    <div className="wysiwyg-wrapper">
      <div id={`quill-editor-container-${this.id}`}></div>
    </div>
  );
 }
}
export default Quill;

This is my input form ponent, list.jxs

import { Meteor } from 'meteor/meteor';
import { PostSchema } from '/modules/blog/lib/collections.jsx';
import Quill from '/modules/quill/client/main.jsx';

export class BlogCategory extends Component {
  constructor(props) {
    super(props);
    this.state = {
      post: {
        content: '',
        preview: '',
      },
    };
    this.onPreviewChange = this.onPreviewChange.bind(this);
    this.onContentChange = this.onContentChange.bind(this);
  }

  onPreviewChange(content) {
    this.state.post.preview = content.getText();
    this.setState(this.state);
  }
  onContentChange(content) {
    this.state.post.content = content.getText();
    this.setState(this.state);
  }

  save() {
    const content = this.state.post.content;
    const preview = this.state.post.preview;
    const post = new PostSchema();
    post.set({
      content,
      preview,
    });
    if (post.validate(false)) {
      const id = post.save(); 
    }
    console.log(post.getValidationErrors(false));
  }

  renderCreatePostForm() {
   let content;
   if (this.state.showForm) {
     content = (
      <form action="">
        <Quill 
           content={this.state.post.preview} 
           onChange={this.onPreviewChange}
        />
        <Quill
           content={this.state.post.content}
           onChange={this.onContentChange}
        />
      </form>
     );
    }
    return content;
  }
  render() {
    let content = (
      <div className="col-xs-12">
        {this.renderActions()}
      </div>
    );
   if (!this.props.ready) {
    content = <p>LOADING...</p>;
   }
   return content;
  }
}
export default createContainer(() => {
  const handleValidPost = Meteor.subscribe('posts');
  return {
    ready: handleValidPost.ready(),
    posts: PostSchema.find({}).fetch(),
  };
}, BlogCategory);

And finally my collections.jsx

import { Mongo } from 'meteor/mongo';
export const PostCollection = new Mongo.Collection('Posts');
export const PostSchema = Astro.Class({
  name: 'PostSchema',
  collection: PostCollection,
  fields: {
    content: {
     validator : Validators.and([
       Validators.required(),
       Validators.string(),
       Validators.minLength(3)
     ])
    },
    preview: {
     validator : Validators.and([
       Validators.required(),
       Validators.string(),
       Validators.minLength(3)
     ])
    },
  }
});
Share Improve this question edited Aug 23, 2016 at 9:57 Marco Chavez asked Aug 22, 2016 at 12:57 Marco ChavezMarco Chavez 1912 gold badges2 silver badges12 bronze badges 3
  • Can you post a working code example to highlight your problem please? – Daniel Lane Commented Sep 1, 2016 at 8:23
  • If the code was working, he wouldn't be asking – Craig1123 Commented Nov 9, 2016 at 21:48
  • Did you manage to get this working? I guess you could use React Player to display video's or audio links but I wouldn't know how to implement it... – Deelux Commented Dec 3, 2016 at 3:16
Add a ment  | 

1 Answer 1

Reset to default 3

While getting Quill contents by getText, you lost your text format and video information. Using getText, all non-string data will be omitted. Quill data are defined as Delta (which is a JSON object).

You can fix this by updating your onPreviewChange and onContentChange to use getContents instead of getText. Save these Delta to DB and load it again.

  onPreviewChange(content) {
    this.state.post.preview = content.getContents();
    this.setState(this.state);
  }
  onContentChange(content) {
    this.state.post.content = content.getContents();
    this.setState(this.state);
  }

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744229613a4564182.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信