0

I started to integrate a WYSIWYG into my blog project by using React Quill and I have no experience with it before and tried to do the most from the help of internet. Actually everything is working fine from loading images(using Image Handler) to saving it to database(PostgreSQL in Rails).I am saving the contents in HTML and not in Delta format but whenever i try to view it by loading it from database, all the formatting, alignment, and indentation are all gone but (header, italic, underline, bold, text-color) are present ,and everything is left aligned

Any help would be appreciated.

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

I'm using React + Rails

this is my code (I'll show only relevant code):

CreateBlog.jsx file

import axios from 'axios'
import React, { useState } from "react";
import PageLoader from '../PageLoader'
import CreateForm from './CreateForm'

export default function CreateBlog({history}) {
    const [title, setTitle] = useState("")
    const [body, setBody] = useState("")
    const [loading, setLoading] = useState(false)

    const handleChange = (value)=>{
        setBody(value)
        console.log(value)
    }

    const handleSubmit = async (event) => {
        event.preventDefault()
        const variables = {
            title: title,
            body: body,
        }
        try{
            const response = await axios.post("/blogs",variables)
            setLoading(false)           
            history.push("/blogs")

        } catch(error){
            console.log(error)
            setLoading(false)                   
        }        
    }

    return (
        <CreateForm 
                setTitle={setTitle}
                setBody={setBody}
                body={body}
                loading={loading}
                handleSubmit={handleSubmit}  
                handleChange={handleChange} 
            />
    )
}

CreateForm.jsx file

import React,{useMemo,useRef} from 'react'
import Input from '../Input'
import Button from '../Button'
import 'react-quill/dist/quill.snow.css'
import ReactQuill,{Quill} from "react-quill";
import ImageResize from 'quill-image-resize-module-react';
import Editor from "./Editor";

Quill.register('modules/imageResize', ImageResize);

export default function CreateForm(
    {
    type="create",
    setTitle,setBody,loading,handleSubmit,
    handleChange,body
    }) {

    const editorRef = useRef(null);

    const modules = useMemo(()=>({
      imageResize: {
        parchment: Quill.import('parchment'),
        modules: ['Resize', 'DisplaySize', 'Toolbar']
     },
        toolbar:{
            container: [  
                [{ 'header': [1, 2, 3, 4, 5, 6, false] }],  
                ['bold', 'italic', 'underline'],  
                [
                    { 'list': 'ordered' },
                    { 'list': 'bullet' },
                    { 'indent': "-1" },
                    { 'indent': "+1" }
                ],  
                [{ 'align': [] }],  
                ['link', 'image', 'video'],  
                ['clean'],  
                [{ 'color': [] }]  
              ],

              handlers: {
                  image: imageHandler,
              },
              clipboard: {
                matchVisual: false,
              }
        }
    }));
    
    const imageHandler = (a) => {
        const input = document.createElement("input");
        input.setAttribute("type", "file");
        input.setAttribute("accept", "image/*");
        input.click();

        input.onchange = () => {
            const file = input.files[0];

            // file type is only image.
            if (/^image\//.test(file.type)) {
                console.log("image file type",file)
                saveToServer(file);
            } else {
                console.warn("You could only upload images.");
            }
        };
    };

    function saveToServer(file) {
        const fd = new FormData();
        fd.append("upload", file);  
        const xhr = new XMLHttpRequest();
        xhr.open("POST", "/blogs", true);

        xhr.upload.onprogress = function(event){
            const progress =event.loaded / event.total * 100;

        }

        xhr.onload = () => {
            if (xhr.status === 201) {
                const data = JSON.parse(xhr.responseText);
                const url = data.url
                console.log("Image url",url)
                setImage(url)
                insertToEditor(url);
            }
        };
        xhr.send(fd);
        console.log("formdata",fd)
    }

    function insertToEditor(url) {
        editorRef.current.getEditor().insertEmbed(null, "image", url);
    }

    return (
        <form className="max-w-full" onSubmit={handleSubmit}>
            <Input
                label="Title"
                placeholder="Blog Title (Max 50 Characters Allowed)"
                onChange={e => setTitle(e.target.value)}
            />
            
             <ReactQuill 
                theme="snow"
                placeholder="Write your story" 
                modules={modules}
                forwardedRef={editorRef}
                onChange={handleChange}
                value={body}        
            /> 

            <Button
                type="submit"
                buttonText={type === "create" ? "Create Blog" : "Update Blog"}
                loading={loading}
            />
        </form>
    )
}

Everything is working perfectly when i am editing the contents like the one in this image While editing enter image description here

But after saving the post and again viewing it , its something like this (but bold, italics, underline) are showing as desired but ordered lists nand unordered lists, alignment, quotes... etc are not showing as desired.
View after saving

enter image description here

For viewing the contents code is ShowBlog.jsx

import React,{useState,useEffect} from 'react'
import { useParams } from 'react-router-dom'
import blogsApi from '../apis/blogs'
import axios from 'axios'
import parse from 'html-react-parser';


export default function ShowBlog() {
    const componentMounted = true
    const {id} = useParams()
    const [blogDetails, setBlogDetails] = useState([])
    const [loading, setLoading] = useState(true)
    const [blogCreator, setBlogCreator] = useState('')

    const source = axios.CancelToken.source()

    const fetchBlogDetails = async()=>{
        try{
            const response = await axios.get(`/blogs/${id}`,       {cancelToken:source.token})
            setBlogDetails(response.data.blog)
            setBlogCreator(response.data.blog_creator)
            setLoading(false)
            console.log("Show Blog details",response)
        } catch(error){
            if(axios.isCancel(error)){
                console.log('cancelled')
            }else{
                throw error
            }
            console.log(error)
        } finally {
            setLoading(false)
        }
    }
    
    useEffect(()=>{
        fetchBlogDetails()
        return () => {
            source.cancel()
        }
    }, [])

    if(loading){
        return <PageLoader />
    }


    return (

        <div className="bg-white">
            <div className="max-w-6xl mx-auto mt-10">
                <div className="relative max-w-4xl mx-auto items-center justify-between">
                    
                    <div className="flex flex-col ">
                        <div className="w-full ">
                            <h2 className="text-gray-800 ">
                                {blogDetails?.title}
                            </h2>
                            <div className="flex ">
                                <span>by {blogCreator?.username}</span> 
                            </div>
                            <div>
                               {parse(blogDetails.body)} 
                            </div>
                            
                        </div>  
                    </div>
                    
                 
                </div>
            </div>
        </div>
    )
}

Inspect enter image description here

Abhishek Singh
  • 563
  • 1
  • 6
  • 18
  • `WYSIWYG` is an ambiguous term, like `web-based` or `object oriented`, not a component. Is your actual question why the reloaded text doesn't appear the same as the original? What *does* the saved text look like? Does it use styles that are missing perhaps? Are the styles stored in a `head` element that doesn't work inside a `div` ? Was there a Javascript error that was logged in the Javascript console? You can check why the lines appear this way using the element inspector in the browser's Developer Tools. You can check for errors in the Dev Tools Console window – Panagiotis Kanavos Aug 25 '21 at 05:59
  • Yes the reloaded text doesn't appear the same as the original,and i have posted image of saved text w.r.t. edited text. Yes i have used the styles(like h1 tag, ol tag text color …etc) and the styles which i used in quill editor are visible in element inspector but arent reflected on view page and there is no JavaScript errors in console window. – Abhishek Singh Aug 25 '21 at 06:25
  • As i told there's no error of any sort , but i dont know much regarding this so i am guess it may be something off in the mapping between DOM content and Visible content – Abhishek Singh Aug 25 '21 at 06:31
  • Which you can inspect using the Element inspection tab in Developer Tools, or by right-clicking on the line and selecting `Inspect` from the menu. The image doesn't show the HTML elements, the styles used or what was disabled – Panagiotis Kanavos Aug 25 '21 at 06:32
  • As i earlier mentioned that's not the issue and i am adding screenshot for the same inspect element – Abhishek Singh Aug 25 '21 at 07:21
  • Actually, I see that this is very much the issue. The image shows that `list-style` for `ol` and `ul` is `none` and the margin and padding are `0`. The CSS rule was defined in `base.css`, at line `1...` - the rest of the image was cropped – Panagiotis Kanavos Aug 25 '21 at 07:27
  • ohh, ok , then how do i make the change in quill editor or where should i update the changes – Abhishek Singh Aug 25 '21 at 07:30
  • As i am using tailwind css and i can see its because of `@tailwind base;` which is causing the issue, so how or what should i do? and Thank you so much for pointing out the issue, i am new to all this so i am unable to catch these errors – Abhishek Singh Aug 25 '21 at 07:50
  • Thanks for helping out, the problem can be resolved by add `preflight: false,` in tailwind config file – Abhishek Singh Aug 25 '21 at 09:05

0 Answers0