Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to control events in the content? #205

Open
petkovic43 opened this issue Jun 17, 2020 · 3 comments
Open

How to control events in the content? #205

petkovic43 opened this issue Jun 17, 2020 · 3 comments
Labels

Comments

@petkovic43
Copy link

Hello, I'm having trouble changing the content from a user action within the content itself. I am creating an input similar to facebook, that when the user informs a url, the system obtains the page's meta tags and a card is created as in the image below. However, by clicking on the "x" on the card I would like it to be removed, but I can't change the text.current anymore. Does anyone have any idea how to solve? Follow my code

Captura de Tela 2020-06-17 às 16 33 07


import React, { useRef, useState, memo } from 'react';
import ContentEditable from 'react-contenteditable'
import sanitizeHtml from 'sanitize-html';
import { MdPhotoCamera, MdOndemandVideo, MdLink } from 'react-icons/md'
import api from 'lib/api';

const clean = content => sanitizeHtml(content, {
  allowedTags: ['h5', 'p', 'a', 'nl', 'hr', 'br', 'div', 'iframe', 'img', 'button', 'span'],
  disallowedTagsMode: 'discard',
  allowedAttributes: {
    a: ['href', 'name'],
    iframe: ['src', 'width', 'height', 'frameborder', 'allow', 'allowfullscreen'],
    img: ['src', 'style', 'class', 'alt'],
    div: ['contenteditable', 'class', 'style'],
    h5: ['class'],
    p: ['class'],
    button: ['class', 'type'],
    span: ['aria-hidden', 'class']
  },
  // Lots of these won't come up by default because we don't allow them
  selfClosing: ['img', 'br', 'hr'],
  // URL schemes we permit
  allowedSchemes: ['http', 'https', 'data'],
  allowedSchemesByTag: {},
  allowedSchemesAppliedToAttributes: ['href', 'src'],
  allowProtocolRelative: true,
  enforceHtmlBoundary: false,
  allowedIframeHostnames: ['www.youtube.com', 'player.vimeo.com'],
  transformTags: {
    'img': (tagName, attribs) => ({
      tagName,
      attribs: {
        ...attribs,
        style: 'max-width: 100%;',
      }
    }),
    'iframe': (tagName, attribs) => ({
      // My own custom magic goes here
      tagName,
      attribs: {
        ...attribs,
        width: '100%;',
        height: '300',
        frameborder: '0',
        allow: "accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture",
        allowfullscreen: true
      }
    })
  }
});

const NewPost = () => {
  const [loading, setLoading] = useState(false)
  const text = useRef(clean(''))
  const [loadedDiv, setLoadedDiv] = useState(false)
  const handleChange = async ({ target: { value } }) => {
    const href = value.match(/href="([^"]*")/g)
    if (href) {
      if (!loadedDiv) {
        setLoading(true)
        text.current = clean([value, bounce].join(''));
        const { data } = await api.get(`/meta?url=${href[0].split('"')[1]}`)
        text.current = clean([value, card(data)].join(''));
        setLoading(false)
        setLoadedDiv(true)
      } else {
        text.current = clean(value);
      }
    } else {
      setLoadedDiv(false)
      text.current = clean(value);
    }
  };


  const handleClick = ({ target: { className } }) => {
    console.log(className)
    if (className === "close text-white position-absolute pos-top pos-right p-2 m-1 mr-2" || className === 'close_card_url') {
      console.log(text);
      text.current = '';
    }
  }


  return (
    <div className="card border mb-g">
      <div className="card-body pl-4 pt-4 pr-4 pb-0">
        <div className="d-flex flex-column">

          <div className="d-flex flex-row border-top-0 border-left-0 border-right-0 mb-3">
            <div className="d-inline-block align-middle mr-3">
              <span className="profile-image rounded-circle d-block" style={{ backgroundImage: 'url("img/demo/avatars/avatar-admin.png")', backgroundSize: 'cover' }} />
            </div>
            <h5 className="mb-0 flex-1 text-dark fw-500">
              Nome
            <small className="m-0 l-h-n">
                No que voçê está pensando?
            </small>
            </h5>
            <span className="text-muted fs-xs opacity-70">
              Agora
          </span>
          </div>

          <ContentEditable
            className="form-control p-3 h-auto border"
            onClick={handleClick}
            html={text.current}
            disabled={loading}
            onChange={handleChange} />

          <div className="py-2 d-flex flex-row align-items-center flex-wrap flex-shrink-0">
            <button className="btn btn-icon mr-2" onClick={e => e.preventDefault()}>
              <MdLink className="text-muted" size={24} />
            </button>
            <button className="btn btn-icon mr-2" onClick={e => e.preventDefault()}>
              <MdPhotoCamera className="text-muted" size={24} />
            </button>
            <button className="btn btn-icon" onClick={e => e.preventDefault()}>
              <MdOndemandVideo className="text-muted" size={24} />
            </button>

            <button className="btn btn-dark shadow-0 ml-auto px-3">Publicar</button>
          </div>
        </div>
      </div>
    </div>
  )
}

export default memo(NewPost);
@lovasoa
Copy link
Owner

lovasoa commented Jun 18, 2020

You can use innerRef to get a reference to the editable DOM element. But in my opinion, your ssmart card should not be part of the contenteditable element.

@hussamkhatib
Copy link

@lovasoa
i Have similar query
I want to change the content with events based on conditions .
i am able to alter text.current but the same is not rendered in the UI.

coinsider this example for illustration purpose.

     const handleChange = evt => {
            text.current = evt.target.value + 'A'
        console.log(text.current);   // gives  evt.target.value + 'A'   but renders only evt.target.value
  }
     <ContentEditable 
                 html={text.current} 
                 onChange={handleChange} 
                 onBlur={handleBlur}
                '/>

@MatheusRoichman
Copy link

same problem here. any updated?

@lovasoa i Have similar query I want to change the content with events based on conditions . i am able to alter text.current but the same is not rendered in the UI.

coinsider this example for illustration purpose.

     const handleChange = evt => {
            text.current = evt.target.value + 'A'
        console.log(text.current);   // gives  evt.target.value + 'A'   but renders only evt.target.value
  }
     <ContentEditable 
                 html={text.current} 
                 onChange={handleChange} 
                 onBlur={handleBlur}
                '/>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants