Skip to content

Commit d080a03

Browse files
committed
feat(transformData): add to every widget using the Template component
- Refactored inside the Template component directly - Changed the RefinementListComponent accordingly - Added to widgets with their associated components: * Stats * Hits * Widgets Closes #116
1 parent 897a767 commit d080a03

File tree

10 files changed

+65
-12
lines changed

10 files changed

+65
-12
lines changed

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ search.addWidget(
227227
// page: number
228228
// processingTimeMS: number
229229
// query: string
230+
transformData: // function to modify the data passed to the template
230231
})
231232
);
232233
```
@@ -312,7 +313,11 @@ search.addWidget(
312313
hit // string (mustache format) or function(hit) return string
313314
},
314315
hitsPerPage: 20,
315-
// cssClass
316+
// cssClass,
317+
// transformData: {
318+
// empty, // function to modify the data passed to the empty template
319+
// hit // function to modify the data passed to the hit template
320+
// }
316321
})
317322
);
318323
```
@@ -356,6 +361,7 @@ search.addWidget(
356361
* @param {String} options.facetName Name of the attribute for faceting (eg. "free_shipping")
357362
* @param {String} options.label Human-readable name of the filter (eg. "Free Shipping")
358363
* @param {String|Function} [options.template] Item template, provided with `label` and `isRefined`
364+
* @param {Function} [options.transformData] Function to change the object passed to the item template
359365
* @param {boolean} [hideIfEmpty=true] Hide the container when no results match
360366
* @return {Object}
361367
*/
@@ -386,6 +392,7 @@ search.addWidget(
386392
<input type="checkbox" value="{{name}}" {{#isRefined}}checked{{/isRefined}} />{{name}} <span>{{count}}</span>
387393
</label>`] Item template, provided with `name`, `count`, `isRefined`
388394
* @param {String|Function} [options.templates.footer] Footer template
395+
* @param {Function} [options.transformData] Function to change the object passed to the item template
389396
* @param {String|Function} [options.singleRefine=true] Are multiple refinements allowed or only one at the same time. You can use this
390397
* to build radio based refinement lists for example
391398
* @param {boolean} [hideIfEmpty=true] Hide the container when no results match
@@ -431,6 +438,7 @@ search.addWidget(
431438
* @param {String|Function} [options.templates.header=''] Header template
432439
* @param {String|Function} [options.templates.item='<a href="{{href}}">{{name}}</a> {{count}}'] Item template, provided with `name`, `count`, `isRefined`
433440
* @param {String|Function} [options.templates.footer=''] Footer template
441+
* @param {Function} [options.transformData] Function to change the object passed to the item template
434442
* @param {boolean} [hideIfEmpty=true] Hide the container when no results match
435443
* @return {Object}
436444
*/

components/Hits.js

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,36 @@ var Template = require('./Template');
55

66
class Hits extends React.Component {
77
renderWithResults() {
8+
var template = this.props.hitTemplate;
9+
var transformData = this.props.hitTransformData;
10+
811
var renderedHits = map(this.props.hits, function(hit) {
9-
return <Template data={hit} key={hit.objectID} template={this.props.hitTemplate} />;
12+
return (
13+
<Template
14+
data={hit}
15+
transformData={transformData}
16+
key={hit.objectID}
17+
template={template}
18+
/>
19+
);
1020
}, this);
1121

1222
return <div>{renderedHits}</div>;
1323
}
1424

1525
renderNoResults() {
26+
var data = this.props.results;
27+
var template = this.props.noResultsTemplate;
28+
var transformData = this.props.noResultsTransformData;
29+
1630
return (
17-
<div><Template data={this.props.results} template={this.props.noResultsTemplate} /></div>
31+
<div>
32+
<Template
33+
data={data}
34+
transformData={transformData}
35+
template={template}
36+
/>
37+
</div>
1838
);
1939
}
2040

@@ -32,10 +52,12 @@ Hits.propTypes = {
3252
React.PropTypes.string,
3353
React.PropTypes.func
3454
]).isRequired,
55+
hitTransformData: React.PropTypes.func,
3556
noResultsTemplate: React.PropTypes.oneOfType([
3657
React.PropTypes.string,
3758
React.PropTypes.func
38-
]).isRequired
59+
]).isRequired,
60+
noResultsTransformData: React.PropTypes.func
3961
};
4062

4163
Hits.defaultProps = {

components/RefinementList.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class RefinementList extends React.Component {
4545
render() {
4646
var facetValues = this.props.facetValues;
4747
var templates = this.props.templates;
48+
var transformData = this.props.transformData;
4849
var rootClass = cx(this.props.cssClasses.root);
4950
var listClass = cx(this.props.cssClasses.list);
5051
var itemClass = cx(this.props.cssClasses.item);
@@ -56,7 +57,11 @@ class RefinementList extends React.Component {
5657
{facetValues.map(facetValue => {
5758
return (
5859
<div className={itemClass} key={facetValue.name} onClick={this.handleClick.bind(this, facetValue.name)}>
59-
<Template data={(this.props.transformData) ? this.props.transformData(facetValue) : facetValue} template={templates.item} />
60+
<Template
61+
data={facetValue}
62+
transformData={transformData}
63+
template={templates.item}
64+
/>
6065
</div>
6166
);
6267
})}

components/Stats.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ class Stats extends React.Component {
77
render() {
88
var template = this.props.template;
99
var templateHelpers = this.props.templateHelpers;
10+
var transformData = this.props.transformData;
1011
var data = {
1112
hasManyResults: this.props.nbHits > 1,
1213
hasNoResults: this.props.nbHits === 0,
@@ -22,6 +23,7 @@ class Stats extends React.Component {
2223
return (
2324
<Template
2425
data={data}
26+
transformData={transformData}
2527
template={template}
2628
templateHelpers={templateHelpers}
2729
/>
@@ -39,6 +41,7 @@ Stats.propTypes = {
3941
React.PropTypes.func,
4042
React.PropTypes.string
4143
]).isRequired,
44+
transformData: React.PropTypes.func,
4245
templateHelpers: React.PropTypes.object,
4346
query: React.PropTypes.string
4447
};

components/Template.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ class Template {
77
var content = renderTemplate({
88
template: this.props.template,
99
templateHelpers: this.props.templateHelpers,
10-
data: this.props.data
10+
data: this.props.transformData ? this.props.transformData(this.props.data) : this.props.data
1111
});
1212

1313
return <div dangerouslySetInnerHTML={{__html: content}} />;
@@ -20,6 +20,7 @@ Template.propTypes = {
2020
React.PropTypes.func
2121
]).isRequired,
2222
templateHelpers: React.PropTypes.object,
23+
transformData: React.PropTypes.func,
2324
data: React.PropTypes.object
2425
};
2526

components/Toggle.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ var debounce = require('lodash/function/debounce');
77
class Toggle extends React.Component {
88
render() {
99
var template = this.props.template;
10+
var transformData = this.props.transformData;
1011
// When a checkbox is wrapped inside a label, click events fire twice, so we
1112
// debounce it to only keep the first one
1213
var toggleFilter = debounce(this.props.toggleFilter, 0, {
@@ -20,7 +21,11 @@ class Toggle extends React.Component {
2021

2122
return (
2223
<span onClick={toggleFilter}>
23-
<Template data={data} template={template} />
24+
<Template
25+
data={data}
26+
transformData={transformData}
27+
template={template}
28+
/>
2429
</span>
2530
);
2631
}
@@ -31,6 +36,7 @@ Toggle.propTypes = {
3136
React.PropTypes.string,
3237
React.PropTypes.func
3338
]).isRequired,
39+
transformData: React.PropTypes.func,
3440
toggleFilter: React.PropTypes.func.isRequired,
3541
label: React.PropTypes.string,
3642
isRefined: React.PropTypes.bool

widgets/hits.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ var utils = require('../lib/utils.js');
55
function hits({
66
container = null,
77
templates = {},
8-
hitsPerPage = 20,
9-
hideIfEmpty = false
8+
transformData = {},
9+
hideIfEmpty = false,
10+
hitsPerPage = 20
1011
}) {
1112
var Hits = require('../components/Hits');
1213

@@ -21,9 +22,11 @@ function hits({
2122
results={results}
2223
helper={helper}
2324
noResultsTemplate={templates.empty}
25+
noResultsTransformData={transformData.empty}
2426
hideIfEmpty={hideIfEmpty}
2527
hasResults={results.hits.length > 0}
2628
hitTemplate={templates.hit}
29+
hitTransformData={transformData.hit}
2730
/>,
2831
containerNode
2932
);

widgets/refinement-list.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ var defaults = require('lodash/object/defaults');
2929
<input type="checkbox" value="{{name}}" {{#isRefined}}checked{{/isRefined}} />{{name}} <span>{{count}}</span>
3030
</label>`] Item template, provided with `name`, `count`, `isRefined`
3131
* @param {String|Function} [options.templates.footer] Footer template
32-
* @param {Function} [options.transformData] Method to change the object passed to the item template
32+
* @param {Function} [options.transformData] Function to change the object passed to the item template
3333
* @param {String|Function} [options.singleRefine=true] Are multiple refinements allowed or only one at the same time. You can use this
3434
* to build radio based refinement lists for example
3535
* @param {boolean} [hideIfEmpty=true] Hide the container when no results match

widgets/stats/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@ var defaultTemplate = require('./template.html');
66
function stats({
77
container = null,
88
template = defaultTemplate,
9+
transformData = null,
910
hideIfEmpty = true
1011
}) {
1112
var Stats = require('../../components/Stats');
1213
var containerNode = utils.getContainerNode(container);
1314

1415
if (container === null) {
15-
throw new Error('Usage: stats({container})');
16+
throw new Error('Usage: stats({container[, template, transformData]})');
1617
}
1718

1819
return {
@@ -29,6 +30,7 @@ function stats({
2930
query={results.query}
3031
templateHelpers={templateHelpers}
3132
template={template}
33+
transformData={transformData}
3234
/>,
3335
containerNode
3436
);

widgets/toggle.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ var defaultTemplate = '<label>{{label}}<input type="checkbox" {{#isRefined}}chec
1111
* @param {String} options.facetName Name of the attribute for faceting (eg. "free_shipping")
1212
* @param {String} options.label Human-readable name of the filter (eg. "Free Shipping")
1313
* @param {String|Function} [options.template] Item template, provided with `label` and `isRefined`
14+
* @param {Function} [options.transformData] Function to change the object passed to the item template
1415
* @param {boolean} [hideIfEmpty=true] Hide the container when no results match
1516
* @return {Object}
1617
*/
@@ -19,12 +20,13 @@ function toggle({
1920
facetName = null,
2021
label = null,
2122
template = defaultTemplate,
23+
transformData = null,
2224
hideIfEmpty = true
2325
}) {
2426
var Toggle = require('../components/Toggle');
2527

2628
var containerNode = utils.getContainerNode(container);
27-
var usage = 'Usage: toggle({container, facetName, label})';
29+
var usage = 'Usage: toggle({container, facetName, label[, template, transformData]})';
2830

2931
if (container === null || facetName === null || label === null) {
3032
throw new Error(usage);
@@ -47,6 +49,7 @@ function toggle({
4749
isRefined={isRefined}
4850
label={label}
4951
template={template}
52+
transformData={transformData}
5053
hideIfEmpty={hideIfEmpty}
5154
hasResults={results.hits.length > 0}
5255
toggleFilter={toggleFilter}

0 commit comments

Comments
 (0)