2018-02-15 18:16:14 +00:00
|
|
|
const { __ } = wp.i18n;
|
2018-11-13 19:21:04 +00:00
|
|
|
const { Component } = wp.element;
|
|
|
|
const { Dashicon } = wp.components;
|
2018-09-05 18:30:46 +00:00
|
|
|
const { apiFetch } = wp;
|
2018-02-15 18:16:14 +00:00
|
|
|
|
2018-04-06 20:12:26 +00:00
|
|
|
/**
|
|
|
|
* Get the identifier for an attribute. The identifier can be used to determine
|
|
|
|
* the slug or the ID of the attribute.
|
|
|
|
*
|
|
|
|
* @param string slug The attribute slug.
|
|
|
|
* @param int|numeric string id The attribute ID.
|
|
|
|
*/
|
|
|
|
export function getAttributeIdentifier( slug, id ) {
|
|
|
|
return slug + ',' + id;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the attribute slug from an identifier.
|
|
|
|
*
|
|
|
|
* @param string identifier The attribute identifier.
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
export function getAttributeSlug( identifier ) {
|
2018-11-13 19:21:04 +00:00
|
|
|
return identifier.split( ',' )[ 0 ];
|
2018-04-06 20:12:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the attribute ID from an identifier.
|
|
|
|
*
|
|
|
|
* @param string identifier The attribute identifier.
|
|
|
|
* @return numeric string
|
|
|
|
*/
|
|
|
|
export function getAttributeID( identifier ) {
|
2018-11-13 19:21:04 +00:00
|
|
|
return identifier.split( ',' )[ 1 ];
|
2018-04-06 20:12:26 +00:00
|
|
|
}
|
|
|
|
|
2018-02-15 18:16:14 +00:00
|
|
|
/**
|
|
|
|
* When the display mode is 'Attribute' search for and select product attributes to pull products from.
|
|
|
|
*/
|
2018-11-13 19:21:04 +00:00
|
|
|
export class ProductsAttributeSelect extends Component {
|
2018-02-20 19:47:50 +00:00
|
|
|
/**
|
|
|
|
* Constructor.
|
|
|
|
*/
|
|
|
|
constructor( props ) {
|
|
|
|
super( props );
|
|
|
|
|
2018-02-26 17:10:45 +00:00
|
|
|
/**
|
2018-04-06 20:12:26 +00:00
|
|
|
* The first item in props.selected_display_setting is the attribute slug and id separated by a comma.
|
|
|
|
* This is to work around limitations in the API which sometimes requires a slug and sometimes an id.
|
|
|
|
* The rest of the elements in selected_display_setting are the term ids for any selected terms.
|
2018-02-21 18:43:21 +00:00
|
|
|
*/
|
2018-02-20 19:47:50 +00:00
|
|
|
this.state = {
|
2018-11-13 19:21:04 +00:00
|
|
|
selectedAttribute: props.selected_display_setting.length ? props.selected_display_setting[ 0 ] : '',
|
2018-02-21 18:43:21 +00:00
|
|
|
selectedTerms: props.selected_display_setting.length > 1 ? props.selected_display_setting.slice( 1 ) : [],
|
2018-02-20 19:47:50 +00:00
|
|
|
filterQuery: '',
|
2018-11-13 19:21:04 +00:00
|
|
|
};
|
2018-02-20 19:47:50 +00:00
|
|
|
|
|
|
|
this.setSelectedAttribute = this.setSelectedAttribute.bind( this );
|
2018-11-13 19:21:04 +00:00
|
|
|
this.addTerm = this.addTerm.bind( this );
|
|
|
|
this.removeTerm = this.removeTerm.bind( this );
|
2018-02-20 19:47:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the selected attribute.
|
|
|
|
*
|
2018-04-06 20:12:26 +00:00
|
|
|
* @param identifier string Attribute slug and id separated by a comma.
|
2018-02-20 19:47:50 +00:00
|
|
|
*/
|
2018-04-06 20:12:26 +00:00
|
|
|
setSelectedAttribute( identifier ) {
|
2018-02-20 19:47:50 +00:00
|
|
|
this.setState( {
|
2018-04-06 20:12:26 +00:00
|
|
|
selectedAttribute: identifier,
|
2018-02-20 19:47:50 +00:00
|
|
|
selectedTerms: [],
|
|
|
|
} );
|
2018-02-21 18:43:21 +00:00
|
|
|
|
2018-04-06 20:12:26 +00:00
|
|
|
this.props.update_display_setting_callback( [ identifier ] );
|
2018-02-20 19:47:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add a term to the selected attribute's terms.
|
|
|
|
*
|
2018-02-21 19:53:36 +00:00
|
|
|
* @param id int Term id.
|
2018-02-20 19:47:50 +00:00
|
|
|
*/
|
2018-02-21 19:53:36 +00:00
|
|
|
addTerm( id ) {
|
2018-11-13 19:21:04 +00:00
|
|
|
const terms = this.state.selectedTerms;
|
2018-02-21 19:53:36 +00:00
|
|
|
terms.push( id );
|
2018-02-20 19:47:50 +00:00
|
|
|
this.setState( {
|
|
|
|
selectedTerms: terms,
|
|
|
|
} );
|
2018-02-21 18:43:21 +00:00
|
|
|
|
|
|
|
let displaySetting = [ this.state.selectedAttribute ];
|
|
|
|
displaySetting = displaySetting.concat( terms );
|
|
|
|
this.props.update_display_setting_callback( displaySetting );
|
2018-02-20 19:47:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Remove a term from the selected attribute's terms.
|
|
|
|
*
|
2018-02-21 19:53:36 +00:00
|
|
|
* @param id int Term id.
|
2018-02-20 19:47:50 +00:00
|
|
|
*/
|
2018-02-21 19:53:36 +00:00
|
|
|
removeTerm( id ) {
|
2018-11-13 19:21:04 +00:00
|
|
|
const newTerms = [];
|
|
|
|
for ( const termId of this.state.selectedTerms ) {
|
2018-02-21 19:53:36 +00:00
|
|
|
if ( termId !== id ) {
|
|
|
|
newTerms.push( termId );
|
2018-02-20 19:47:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this.setState( {
|
|
|
|
selectedTerms: newTerms,
|
|
|
|
} );
|
2018-02-21 18:43:21 +00:00
|
|
|
|
|
|
|
let displaySetting = [ this.state.selectedAttribute ];
|
|
|
|
displaySetting = displaySetting.concat( newTerms );
|
|
|
|
this.props.update_display_setting_callback( displaySetting );
|
2018-02-20 19:47:50 +00:00
|
|
|
}
|
|
|
|
|
2018-02-21 19:53:36 +00:00
|
|
|
/**
|
|
|
|
* Update the search results when typing in the attributes box.
|
|
|
|
*
|
|
|
|
* @param evt Event object
|
|
|
|
*/
|
2018-02-21 19:30:47 +00:00
|
|
|
updateFilter( evt ) {
|
|
|
|
this.setState( {
|
|
|
|
filterQuery: evt.target.value,
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
|
2018-02-20 19:47:50 +00:00
|
|
|
/**
|
|
|
|
* Render the whole section.
|
|
|
|
*/
|
2018-02-15 18:16:14 +00:00
|
|
|
render() {
|
|
|
|
return (
|
2018-02-26 17:10:45 +00:00
|
|
|
<div className="wc-products-list-card wc-products-list-card--taxonomy wc-products-list-card--taxonomy-atributes">
|
2018-02-21 19:30:47 +00:00
|
|
|
<ProductAttributeFilter updateFilter={ this.updateFilter.bind( this ) } />
|
2018-02-20 19:47:50 +00:00
|
|
|
<ProductAttributeList
|
|
|
|
selectedAttribute={ this.state.selectedAttribute }
|
|
|
|
selectedTerms={ this.state.selectedTerms }
|
2018-02-21 19:30:47 +00:00
|
|
|
filterQuery={ this.state.filterQuery }
|
2018-02-20 19:47:50 +00:00
|
|
|
setSelectedAttribute={ this.setSelectedAttribute.bind( this ) }
|
|
|
|
addTerm={ this.addTerm.bind( this ) }
|
|
|
|
removeTerm={ this.removeTerm.bind( this ) }
|
|
|
|
/>
|
2018-02-15 18:16:14 +00:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-20 19:47:50 +00:00
|
|
|
/**
|
|
|
|
* Search area for filtering through the attributes list.
|
|
|
|
*/
|
2018-02-21 19:30:47 +00:00
|
|
|
const ProductAttributeFilter = ( props ) => {
|
2018-02-20 19:47:50 +00:00
|
|
|
return (
|
2018-04-06 22:57:20 +00:00
|
|
|
<div className="wc-products-list-card__input-wrapper">
|
|
|
|
<Dashicon icon="search" />
|
2018-02-26 17:10:45 +00:00
|
|
|
<input className="wc-products-list-card__search" type="search" placeholder={ __( 'Search for attributes' ) } onChange={ props.updateFilter } />
|
2018-02-20 19:47:50 +00:00
|
|
|
</div>
|
|
|
|
);
|
2018-11-13 19:21:04 +00:00
|
|
|
};
|
2018-02-20 19:47:50 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* List of attributes.
|
|
|
|
*/
|
2018-11-13 19:21:04 +00:00
|
|
|
class ProductAttributeList extends Component {
|
2018-09-06 15:40:50 +00:00
|
|
|
/**
|
|
|
|
* Constructor
|
|
|
|
*/
|
|
|
|
constructor( props ) {
|
|
|
|
super( props );
|
|
|
|
this.state = {
|
|
|
|
attributes: [],
|
|
|
|
loaded: false,
|
|
|
|
query: '',
|
2018-02-20 19:47:50 +00:00
|
|
|
};
|
2018-09-06 15:40:50 +00:00
|
|
|
|
|
|
|
this.updatePreview = this.updatePreview.bind( this );
|
|
|
|
this.getQuery = this.getQuery.bind( this );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the preview when component is first loaded.
|
|
|
|
*/
|
|
|
|
componentDidMount() {
|
|
|
|
if ( this.getQuery() !== this.state.query ) {
|
|
|
|
this.updatePreview();
|
2018-02-20 19:47:50 +00:00
|
|
|
}
|
2018-09-06 15:40:50 +00:00
|
|
|
}
|
2018-02-20 19:47:50 +00:00
|
|
|
|
2018-09-06 15:40:50 +00:00
|
|
|
/**
|
|
|
|
* Update the preview when component is updated.
|
|
|
|
*/
|
|
|
|
componentDidUpdate() {
|
|
|
|
if ( this.getQuery() !== this.state.query && this.state.loaded ) {
|
|
|
|
this.updatePreview();
|
2018-02-20 19:47:50 +00:00
|
|
|
}
|
2018-09-06 15:40:50 +00:00
|
|
|
}
|
2018-02-20 19:47:50 +00:00
|
|
|
|
2018-09-06 15:40:50 +00:00
|
|
|
/**
|
|
|
|
* Get the endpoint for the current state of the component.
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
getQuery() {
|
2018-11-30 19:12:56 +00:00
|
|
|
const endpoint = '/wc-pb/v3/products/attributes';
|
2018-09-06 15:40:50 +00:00
|
|
|
return endpoint;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Update the preview with the latest settings.
|
|
|
|
*/
|
|
|
|
updatePreview() {
|
|
|
|
const self = this;
|
|
|
|
const query = this.getQuery();
|
|
|
|
|
|
|
|
self.setState( {
|
2018-11-13 19:21:04 +00:00
|
|
|
loaded: false,
|
2018-09-06 15:40:50 +00:00
|
|
|
} );
|
|
|
|
|
2018-11-13 19:21:04 +00:00
|
|
|
apiFetch( { path: query } ).then( ( attributes ) => {
|
2018-09-06 15:40:50 +00:00
|
|
|
self.setState( {
|
|
|
|
attributes: attributes,
|
|
|
|
loaded: true,
|
2018-11-13 19:21:04 +00:00
|
|
|
query: query,
|
2018-09-06 15:40:50 +00:00
|
|
|
} );
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Render.
|
|
|
|
*/
|
|
|
|
render() {
|
|
|
|
const { selectedAttribute, filterQuery, selectedTerms, setSelectedAttribute, addTerm, removeTerm } = this.props;
|
|
|
|
|
|
|
|
if ( ! this.state.loaded ) {
|
|
|
|
return ( <ul><li>{ __( 'Loading' ) }</li></ul> );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( 0 === this.state.attributes.length ) {
|
|
|
|
return ( <ul><li>{ __( 'No attributes found' ) }</li></ul> );
|
|
|
|
}
|
2018-02-21 19:30:47 +00:00
|
|
|
|
|
|
|
const filter = filterQuery.toLowerCase();
|
2018-11-13 19:21:04 +00:00
|
|
|
const attributeElements = [];
|
2018-09-06 15:40:50 +00:00
|
|
|
|
2018-11-13 19:21:04 +00:00
|
|
|
for ( const attribute of this.state.attributes ) {
|
2018-02-21 19:30:47 +00:00
|
|
|
// Filter out attributes that don't match the search query.
|
|
|
|
if ( filter.length && -1 === attribute.name.toLowerCase().indexOf( filter ) ) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-06-05 17:06:39 +00:00
|
|
|
attributeElements.push(
|
2018-09-06 15:40:50 +00:00
|
|
|
<ProductAttributeElement
|
|
|
|
attribute={ attribute }
|
|
|
|
selectedAttribute={ selectedAttribute }
|
|
|
|
selectedTerms={ selectedTerms }
|
2018-11-13 19:21:04 +00:00
|
|
|
setSelectedAttribute={ setSelectedAttribute }
|
2018-02-26 17:10:45 +00:00
|
|
|
addTerm={ addTerm }
|
2018-09-06 15:40:50 +00:00
|
|
|
removeTerm={ removeTerm }
|
2018-06-05 17:06:39 +00:00
|
|
|
/>
|
|
|
|
);
|
2018-02-20 19:47:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
2018-02-26 17:10:45 +00:00
|
|
|
<div className="wc-products-list-card__results">
|
2018-02-20 19:47:50 +00:00
|
|
|
{ attributeElements }
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
2018-09-06 15:40:50 +00:00
|
|
|
}
|
2018-02-20 19:47:50 +00:00
|
|
|
|
|
|
|
/**
|
2018-06-05 17:06:39 +00:00
|
|
|
* One product attribute.
|
2018-02-20 19:47:50 +00:00
|
|
|
*/
|
2018-11-13 19:21:04 +00:00
|
|
|
class ProductAttributeElement extends Component {
|
2018-02-20 19:47:50 +00:00
|
|
|
constructor( props ) {
|
|
|
|
super( props );
|
|
|
|
|
|
|
|
this.handleAttributeChange = this.handleAttributeChange.bind( this );
|
2018-11-13 19:21:04 +00:00
|
|
|
this.handleTermChange = this.handleTermChange.bind( this );
|
2018-02-20 19:47:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Propagate and reset values when the selected attribute is changed.
|
|
|
|
*
|
|
|
|
* @param evt Event object
|
|
|
|
*/
|
|
|
|
handleAttributeChange( evt ) {
|
2018-02-21 18:43:21 +00:00
|
|
|
if ( ! evt.target.checked ) {
|
2018-02-20 19:47:50 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-04-06 20:12:26 +00:00
|
|
|
this.props.setSelectedAttribute( evt.target.value );
|
2018-02-20 19:47:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add or remove selected terms.
|
|
|
|
*
|
|
|
|
* @param evt Event object
|
|
|
|
*/
|
|
|
|
handleTermChange( evt ) {
|
|
|
|
if ( evt.target.checked ) {
|
|
|
|
this.props.addTerm( evt.target.value );
|
|
|
|
} else {
|
|
|
|
this.props.removeTerm( evt.target.value );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
2018-04-06 20:12:26 +00:00
|
|
|
const isSelected = this.props.selectedAttribute === getAttributeIdentifier( this.props.attribute.slug, this.props.attribute.id );
|
2018-02-20 19:47:50 +00:00
|
|
|
|
|
|
|
let attributeTerms = null;
|
|
|
|
if ( isSelected ) {
|
2018-11-13 19:21:04 +00:00
|
|
|
attributeTerms = (
|
|
|
|
<AttributeTerms
|
|
|
|
attribute={ this.props.attribute }
|
|
|
|
selectedTerms={ this.props.selectedTerms }
|
|
|
|
addTerm={ this.props.addTerm }
|
|
|
|
removeTerm={ this.props.removeTerm }
|
|
|
|
/>
|
|
|
|
);
|
2018-02-20 19:47:50 +00:00
|
|
|
}
|
|
|
|
|
2018-11-13 19:21:04 +00:00
|
|
|
const cssClasses = [ 'wc-products-list-card--taxonomy-atributes__atribute' ];
|
2018-02-26 17:10:45 +00:00
|
|
|
if ( isSelected ) {
|
|
|
|
cssClasses.push( 'wc-products-list-card__accordion-open' );
|
|
|
|
}
|
|
|
|
|
2018-11-13 19:21:04 +00:00
|
|
|
const valueId = getAttributeIdentifier( this.props.attribute.slug, this.props.attribute.id );
|
2018-02-20 19:47:50 +00:00
|
|
|
return (
|
2018-02-26 17:10:45 +00:00
|
|
|
<div className={ cssClasses.join( ' ' ) }>
|
|
|
|
<div>
|
2018-11-13 19:21:04 +00:00
|
|
|
<label className="wc-products-list-card__content" htmlFor={ `attribute-${ valueId }` }>
|
2018-02-26 17:10:45 +00:00
|
|
|
<input type="radio"
|
2018-11-13 19:21:04 +00:00
|
|
|
id={ `attribute-${ valueId }` }
|
|
|
|
value={ valueId }
|
2018-02-26 17:10:45 +00:00
|
|
|
onChange={ this.handleAttributeChange }
|
2018-02-20 19:47:50 +00:00
|
|
|
checked={ isSelected }
|
|
|
|
/>
|
|
|
|
{ this.props.attribute.name }
|
|
|
|
</label>
|
|
|
|
</div>
|
|
|
|
{ attributeTerms }
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2018-06-05 17:06:39 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The list of terms in an attribute.
|
|
|
|
*/
|
2018-11-13 19:21:04 +00:00
|
|
|
class AttributeTerms extends Component {
|
2018-09-06 15:40:50 +00:00
|
|
|
/**
|
|
|
|
* Constructor
|
|
|
|
*/
|
|
|
|
constructor( props ) {
|
|
|
|
super( props );
|
|
|
|
this.state = {
|
|
|
|
terms: [],
|
|
|
|
loaded: false,
|
|
|
|
query: '',
|
2018-06-05 17:06:39 +00:00
|
|
|
};
|
2018-09-06 15:40:50 +00:00
|
|
|
|
|
|
|
this.updatePreview = this.updatePreview.bind( this );
|
|
|
|
this.getQuery = this.getQuery.bind( this );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the preview when component is first loaded.
|
|
|
|
*/
|
|
|
|
componentDidMount() {
|
|
|
|
if ( this.getQuery() !== this.state.query ) {
|
|
|
|
this.updatePreview();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Update the preview when component is updated.
|
|
|
|
*/
|
|
|
|
componentDidUpdate() {
|
|
|
|
if ( this.getQuery() !== this.state.query && this.state.loaded ) {
|
|
|
|
this.updatePreview();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the endpoint for the current state of the component.
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
getQuery() {
|
2018-11-30 19:12:56 +00:00
|
|
|
const endpoint = '/wc-pb/v3/products/attributes/' + this.props.attribute.id + '/terms';
|
2018-09-06 15:40:50 +00:00
|
|
|
return endpoint;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Update the preview with the latest settings.
|
|
|
|
*/
|
|
|
|
updatePreview() {
|
|
|
|
const self = this;
|
|
|
|
const query = this.getQuery();
|
|
|
|
|
|
|
|
self.setState( {
|
2018-11-13 19:21:04 +00:00
|
|
|
loaded: false,
|
2018-09-06 15:40:50 +00:00
|
|
|
} );
|
|
|
|
|
2018-11-13 19:21:04 +00:00
|
|
|
apiFetch( { path: query } ).then( ( terms ) => {
|
2018-09-06 15:40:50 +00:00
|
|
|
self.setState( {
|
|
|
|
terms: terms,
|
|
|
|
loaded: true,
|
2018-11-13 19:21:04 +00:00
|
|
|
query: query,
|
2018-09-06 15:40:50 +00:00
|
|
|
} );
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Render.
|
|
|
|
*/
|
|
|
|
render() {
|
2018-11-13 19:21:04 +00:00
|
|
|
const { selectedTerms, addTerm, removeTerm } = this.props;
|
2018-09-06 15:40:50 +00:00
|
|
|
|
|
|
|
if ( ! this.state.loaded ) {
|
2018-06-05 17:06:39 +00:00
|
|
|
return ( <ul><li>{ __( 'Loading' ) }</li></ul> );
|
|
|
|
}
|
|
|
|
|
2018-09-06 15:40:50 +00:00
|
|
|
if ( 0 === this.state.terms.length ) {
|
2018-06-05 17:06:39 +00:00
|
|
|
return ( <ul><li>{ __( 'No terms found' ) }</li></ul> );
|
|
|
|
}
|
|
|
|
|
2018-09-06 15:40:50 +00:00
|
|
|
/**
|
|
|
|
* Add or remove selected terms.
|
|
|
|
*
|
|
|
|
* @param evt Event object
|
|
|
|
*/
|
2018-06-05 17:06:39 +00:00
|
|
|
function handleTermChange( evt ) {
|
|
|
|
if ( evt.target.checked ) {
|
|
|
|
addTerm( evt.target.value );
|
|
|
|
} else {
|
|
|
|
removeTerm( evt.target.value );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<ul>
|
2018-11-13 19:21:04 +00:00
|
|
|
{ this.state.terms.map( ( term, i ) => (
|
|
|
|
<li className="wc-products-list-card__item" key={ i }>
|
|
|
|
<label className="wc-products-list-card__content" htmlFor={ `term-${ term.id }` }>
|
2018-06-05 17:06:39 +00:00
|
|
|
<input type="checkbox"
|
2018-11-13 19:21:04 +00:00
|
|
|
id={ `term-${ term.id }` }
|
2018-06-05 17:06:39 +00:00
|
|
|
value={ term.id }
|
|
|
|
onChange={ handleTermChange }
|
|
|
|
checked={ selectedTerms.includes( String( term.id ) ) }
|
|
|
|
/>
|
|
|
|
{ term.name }
|
|
|
|
<span className="wc-products-list-card__taxonomy-count">{ term.count }</span>
|
|
|
|
</label>
|
|
|
|
</li>
|
|
|
|
) ) }
|
|
|
|
</ul>
|
|
|
|
);
|
|
|
|
}
|
2018-09-06 15:40:50 +00:00
|
|
|
}
|