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

renderButton not called in dropdown menus - insert image doesn't work #1094

Open
rquast opened this issue Jul 28, 2017 · 2 comments
Open

renderButton not called in dropdown menus - insert image doesn't work #1094

rquast opened this issue Jul 28, 2017 · 2 comments

Comments

@rquast
Copy link
Contributor

rquast commented Jul 28, 2017

screen shot 2017-07-28 at 10 55 24 pm

Nothing in the console.log output happens below.. but the command is executed before there is file input.

import { ToggleTool } from '../../ui'

class InsertImageTool extends ToggleTool {

  getClassNames() {
    return 'sc-insert-image-tool'
  }

  renderButton($$) {
    console.log('RENDERING BUTTON');
    let button = super.renderButton($$)
    let input = $$('input').attr('type', 'file').ref('input')
      .on('change', this.onFileSelect)
    return [button, input]
  }

  onClick() {
    console.log('ON CLICK');
    this.refs.input.click()
  }

  onFileSelect(e) {
    let files = e.currentTarget.files
    this.executeCommand({
      files: Array.prototype.slice.call(files)
    })
  }

}
@rquast
Copy link
Contributor Author

rquast commented Jul 28, 2017

To clarify, drag and drop of images works fine, it's just the file input click that's not working.

@rquast
Copy link
Contributor Author

rquast commented Jul 28, 2017

Here is a solution to get around the issue:

import { InsertNodeCommand } from '../../ui'
import insertImage from './insertImage'

export default class InsertImageCommand extends InsertNodeCommand {

  /**
   * Inserts file and image nodes
   */
  execute(params) {
    this.params = params;
    if (!this.params.files || this.params.files.length === 0) {
      if (!this.uploadFileForm) {
        this.uploadFileForm = document.createElement('form')
        this.uploadFileEl = document.createElement('input')
        this.uploadFileEl.type = 'file'
        this.uploadFileEl.multiple = 'multiple'
        this.uploadFileForm.appendChild(this.uploadFileEl)
      }
      this.uploadFileForm.addEventListener('change', this.changeFn, false)
      this.uploadFileEl.click()
    } else {
      this.params.editorSession.transaction((tx) => {
        this.params.files.forEach((file) => {
          insertImage(tx, file)
        })
      })
    }
  }

  changeFn = (event) => {
    this.params.editorSession.transaction((tx) => {
      if (this.uploadFileEl.files && this.uploadFileEl.files[0]) {
        for (let i = 0; i < this.uploadFileEl.files.length; i++) {
          insertImage(tx, this.uploadFileEl.files[i])
        }
      }
      this.uploadFileForm.reset()
    })
    event.preventDefault()
    this.uploadFileForm.removeEventListener('change', this.changeFn)
  }

}

The advantages are - it doesn't require a button for the input click, it can be launch straight from the command (works with command keys and file drops, etc).

Is that okay?

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

No branches or pull requests

1 participant