Filter clear button

582

📘

Components

  •       components/Facet/index.ts
    
  •       components/Facet/view.tsx 
    

Within our filters we could add a button that will clear all checked items for just a specific filter at a time.

To do this:

  • import withHandlers to components/Facet/index.tsx
  • Create a helper withHandlers with an onReset method to components/Facet/index.tsx
withHandlers({
    onReset: ({ update, meta, item }) => () =>  update('filters', f => f && f.delete(item.get('name'))) // Reset values
  }),

Don't forget to connect the component to @findify/react-connect in components/Facet/index.ts in order to be able to use the update function.

import { connectFacets } from '@findify/react-connect';

// ... some code ...

export default compose(  
  connectFacets,

// ... some code ...

)(view);

Then you should create your button in components/Facet/view.tsx and add the method onReset to be called on click.

<Text primary uppercase className={theme.text}>{ title } 
  <span display-if={filtersSelected > 0 } onClick={onReset} class="findify-clear-checkbox">(Clear)</span>
</Text>

Final Version

/**
 * @module components/Facet
 */

import React from 'react';
import Button from 'components/Button';
import Text from 'components/Text';
import Icon from 'components/Icon';
import Component from 'components/Facet/Component';
import { ThemedSFCProps, IFacet, MJSConfiguration } from 'types';

/** Props that Facet view accepts */
export interface IFacetProps extends ThemedSFCProps {
  /** Facet component to render */
  FacetComponent: React.Component<any>;
  /** Flag to show open / closed state of facet */
  isOpen?: boolean;
  /** Flag to show if facet is opened on mobile */
  isMobile?: boolean;
  /** Title of facet */
  title: string;
  /** Facet object */
  item: IFacet;
  /** MJS Configuration */
  config: MJSConfiguration;
  /** Filters selected in facet */
  filtersSelected: number;
  /** Function to toggle open / closed state of facet */
  toggleFacet: () => any
}

const FacetView = ({
  FacetComponent,
  isOpen,
  theme,
  title,
  item,
  config,
  filtersSelected,
  toggleFacet,
  onReset // add function defined in index.ts
}: IFacetProps) => (
  <div className={theme.root}>
    <div className="findify-category-wrapper">
      <Button className={theme.title} onClick={toggleFacet}>
       // call onReset on click
      <Text primary uppercase className={theme.text}>{ title } 
        <span display-if={filtersSelected > 0 } onClick={onReset} class="findify-clear-checkbox"> (Clear)</span>
      </Text>
      <Icon name={isOpen ? 'Minus' : 'Plus'} className={theme.icon} />
    </Button>
    </div>
    <Component
      display-if={isOpen}
      facet={item}
      config={config}
      theme={{ root: theme.body }}
      isMobile={true} />
  </div>
)

export default FacetView;
/**
 * @module components/Facet
 */
import React from 'react';
import { compose, setDisplayName, withStateHandlers, withPropsOnChange, withHandlers, branch } from 'recompose';
import withEvents from 'helpers/withEvents';
import pure from 'helpers/pure';

import view from 'components/Facet/view';
import withTheme from 'helpers/withTheme';

import styles from 'components/Facet/styles.css';

// connect to @findify/react-connect
import { connectFacets } from '@findify/react-connect';


export default compose(
  pure,
  
  // add connectFacets
  connectFacets,

  setDisplayName('Facet'),

  withTheme(styles),

  withPropsOnChange(['config'], ({ config, item }) => ({
    title: config.getIn(['facets', 'labels', item.get('name')], item.get('name')),
  })),

  withStateHandlers(
    ({ config, item }: any) => {
      const facetType = config.getIn(['facets', 'types', item.get('name')]) || item.get('type')
      const isOpen = config.getIn(['facets', facetType, 'initiallyExpanded'], config.getIn(['facets', 'initiallyExpanded', true]))
      return { isOpen }
    },
    {
      showFacet: () => () => ({ isOpen: true }),
      hideFacet: () => () => ({ isOpen: false }),
      toggleFacet: ({ isOpen }) => () => ({ isOpen: !isOpen })
    }
  ),
  
  // add a function onReset that can be imported in view.tsx
  withHandlers({
    onReset: ({ update, meta, item }) => () =>  update('filters', f => f && f.delete(item.get('name'))) // Reset values
  }),

  withEvents({
    showFacets: ({ showFacet, item }) => (name) =>
      (!name || item.get('name') === name) && showFacet(),
    hideFacets: ({ hideFacet, item }) => (name) =>
      (!name || item.get('name') === name) && hideFacet(),
  }),

  withPropsOnChange(['item'], ({ item }) => ({
    filtersSelected: item.get('values').filter(item => item.get('selected')).size
  }))
)(view);