Filepond: Plugins - show buttons next to each other

Created on 15 Feb 2019  路  5Comments  路  Source: pqina/filepond

I would like to create my own plugins that would have icons as shown in the image below (slim image cropper) - i.e. next to each other.

  • Is that possible with the filepond + doka?
  • Do you have an example of a very simple plugin that shows a button on image load and executes a certain function on click?

Thanks ;)

image

Most helpful comment

Hi, You could use the Image Edit plugin as a starting point. If you just want to show a single button you can remove a lot of the internal code. I've made a start below.

/* eslint-disable */
const isPreviewableImage = file => /^image/.test(file.type);

var plugin$1 = _ => {
  const { addFilter, utils, views } = _;
  const { Type, createRoute, createItemAPI = item => item } = utils;
  const { fileActionButton } = views;

  // called for each view that is created right after the 'create' method
  addFilter('CREATE_VIEW', viewAPI => {
    // get reference to created view
    const { is, view, query } = viewAPI;

    if (
      !is('file') ||
      !query('GET_ALLOW_IMAGE_PREVIEW') ||
      !query('GET_ALLOW_IMAGE_EDIT')
    ) {
      return;
    }

    // opens the editor, if it does not already exist, it creates the editor
    const openEditor = ({ root, props, action }) => {
      const { id } = props;

      // get item
      const item = root.query('GET_ITEM', id);
      if (!item) return;

      // file to open
      const file = item.file;

      // run code here
    };

    /**
     * Image Preview related
     */
    const didPreviewUpdate = ({ root }) => {
      if (!root.ref.buttonEditItem) return;
      root.ref.buttonEditItem.opacity = 1;
    };

    // create the image preview plugin, but only do so if the item is an image
    const didLoadItem = ({ root, props }) => {
      if (!query('GET_IMAGE_EDIT_ALLOW_EDIT')) {
        return;
      }

      const { id } = props;

      // try to access item
      const item = query('GET_ITEM', id);
      if (!item) return;

      // get the file object
      const file = item.file;

      // exit if this is not an image
      if (!isPreviewableImage(file)) {
        return;
      }

      // set preview view
      const buttonView = view.createChildView(fileActionButton, {
        label: 'edit',
        icon: query('GET_IMAGE_EDIT_ICON_EDIT'),
        opacity: 0
      });

      // handle interactions
      root.ref.handleEdit = () => root.dispatch('EDIT_ITEM', { id });
      buttonView.on('click', root.ref.handleEdit);

      root.ref.buttonEditItem = view.appendChildView(buttonView);
    };

    view.registerDestroyer(({ root }) => {
      if (root.ref.buttonEditItem) {
        root.ref.buttonEditItem.off('click', root.ref.handleEdit);
      }
    });

    // start writing
    view.registerWriter(
      createRoute({
        DID_IMAGE_PREVIEW_SHOW: didPreviewUpdate,
        DID_LOAD_ITEM: didLoadItem,
        EDIT_ITEM: openEditor
      })
    );
  });

  // Expose plugin options
  return {
    options: {
      // enable or disable image editing
      allowImageEdit: [true, Type.BOOLEAN],

      // allow editing
      imageEditAllowEdit: [true, Type.BOOLEAN],

      // the icon to use for the edit button
      imageEditIconEdit: [
        '<svg width="26" height="26" viewBox="0 0 26 26" xmlns="http://www.w3.org/2000/svg"><path d="M8.5 17h1.586l7-7L15.5 8.414l-7 7V17zm-1.707-2.707l8-8a1 1 0 0 1 1.414 0l3 3a1 1 0 0 1 0 1.414l-8 8A1 1 0 0 1 10.5 19h-3a1 1 0 0 1-1-1v-3a1 1 0 0 1 .293-.707z" fill="currentColor" fill-rule="nonzero"/></svg>',
        Type.STRING
      ]

    }
  };
};

const isBrowser =
  typeof window !== 'undefined' && typeof window.document !== 'undefined';

if (isBrowser) {
  document.dispatchEvent(
    new CustomEvent('FilePond:pluginloaded', { detail: plugin$1 })
  );
}

export default plugin$1;

All 5 comments

Hi, You could use the Image Edit plugin as a starting point. If you just want to show a single button you can remove a lot of the internal code. I've made a start below.

/* eslint-disable */
const isPreviewableImage = file => /^image/.test(file.type);

var plugin$1 = _ => {
  const { addFilter, utils, views } = _;
  const { Type, createRoute, createItemAPI = item => item } = utils;
  const { fileActionButton } = views;

  // called for each view that is created right after the 'create' method
  addFilter('CREATE_VIEW', viewAPI => {
    // get reference to created view
    const { is, view, query } = viewAPI;

    if (
      !is('file') ||
      !query('GET_ALLOW_IMAGE_PREVIEW') ||
      !query('GET_ALLOW_IMAGE_EDIT')
    ) {
      return;
    }

    // opens the editor, if it does not already exist, it creates the editor
    const openEditor = ({ root, props, action }) => {
      const { id } = props;

      // get item
      const item = root.query('GET_ITEM', id);
      if (!item) return;

      // file to open
      const file = item.file;

      // run code here
    };

    /**
     * Image Preview related
     */
    const didPreviewUpdate = ({ root }) => {
      if (!root.ref.buttonEditItem) return;
      root.ref.buttonEditItem.opacity = 1;
    };

    // create the image preview plugin, but only do so if the item is an image
    const didLoadItem = ({ root, props }) => {
      if (!query('GET_IMAGE_EDIT_ALLOW_EDIT')) {
        return;
      }

      const { id } = props;

      // try to access item
      const item = query('GET_ITEM', id);
      if (!item) return;

      // get the file object
      const file = item.file;

      // exit if this is not an image
      if (!isPreviewableImage(file)) {
        return;
      }

      // set preview view
      const buttonView = view.createChildView(fileActionButton, {
        label: 'edit',
        icon: query('GET_IMAGE_EDIT_ICON_EDIT'),
        opacity: 0
      });

      // handle interactions
      root.ref.handleEdit = () => root.dispatch('EDIT_ITEM', { id });
      buttonView.on('click', root.ref.handleEdit);

      root.ref.buttonEditItem = view.appendChildView(buttonView);
    };

    view.registerDestroyer(({ root }) => {
      if (root.ref.buttonEditItem) {
        root.ref.buttonEditItem.off('click', root.ref.handleEdit);
      }
    });

    // start writing
    view.registerWriter(
      createRoute({
        DID_IMAGE_PREVIEW_SHOW: didPreviewUpdate,
        DID_LOAD_ITEM: didLoadItem,
        EDIT_ITEM: openEditor
      })
    );
  });

  // Expose plugin options
  return {
    options: {
      // enable or disable image editing
      allowImageEdit: [true, Type.BOOLEAN],

      // allow editing
      imageEditAllowEdit: [true, Type.BOOLEAN],

      // the icon to use for the edit button
      imageEditIconEdit: [
        '<svg width="26" height="26" viewBox="0 0 26 26" xmlns="http://www.w3.org/2000/svg"><path d="M8.5 17h1.586l7-7L15.5 8.414l-7 7V17zm-1.707-2.707l8-8a1 1 0 0 1 1.414 0l3 3a1 1 0 0 1 0 1.414l-8 8A1 1 0 0 1 10.5 19h-3a1 1 0 0 1-1-1v-3a1 1 0 0 1 .293-.707z" fill="currentColor" fill-rule="nonzero"/></svg>',
        Type.STRING
      ]

    }
  };
};

const isBrowser =
  typeof window !== 'undefined' && typeof window.document !== 'undefined';

if (isBrowser) {
  document.dispatchEvent(
    new CustomEvent('FilePond:pluginloaded', { detail: plugin$1 })
  );
}

export default plugin$1;

Thanks ;) That helps 馃憤

When I add buttonView.element.dataset.align = 'bottom center' the button overlaps with image edit button. Is there any way to draw the buttons next to each other as is made in slim image cropper?

You'll probably have to override both styles. I would like to make this more flexible in the future by adding some sort of button basket ;-)

So @rikschennink, this code above can be used to add a show button? I want to add a show button where the user can click on it, and the image(s) opens in a lightbox.

You could yes.

Was this page helpful?
0 / 5 - 0 ratings