Instantsearch.js: connectHits sortable table access to helper

Created on 24 Oct 2017  路  13Comments  路  Source: algolia/instantsearch.js

What is your use case for such a feature?
I would like to build a sortable table custom widget that combines the functionality of the hits and sort widgets.

What is your proposed API entry? The new option to add? What is the behavior?
All that is needed is to add the helper object to the init parameters in src/connectors/hits/connectHits.js This would allow the custom widget to call the setIndex().search() method to trigger the search, sort and redraw.

(If there's a better way, I'm all ears)

Question

Most helpful comment

But then I don't know what is your need for reusability or If it needs to be configurable and managed by some end-users. Is it the case?

Either approach works for us, it just seemed like an opportunity to share a configurable widget with the community, as it seemed like there were quite a few people asking for a "sortable IS table" widget.

All 13 comments

Working on this with @rogerroelofs, would love to find a solution!

Hi @rogerroelofs and @timkelty, thanks for opening this issue.

We've chosen to make the API of the connectors an abstraction over the Helper. Adding it would be practical but not in the spirit of the connectors.

Why not use the hits widget for the body of the table and use a custom widget (based on connectors) for the each column header?

@bobylito So you're suggesting something like this? (pseudocode)

<table>
    <thead>
        <tr>
            <td>{{ customWidget({asc: 'productsAsc', desc: 'productsDesc'}))}}</td>
            <td>{{ customWidget({asc: 'productsPriceAsc', desc: 'productsPriceDesc'}))}}</td>
        </tr>
    </thead>
    <tbody>
        {{ hitsWidget }}
    </tbody>
</table>

We were trying to create a single widget for the entire thing, so that we could pass a single columns array and not have to worry as much about our column counts lining up.

I thought you wanted to have custom sort for each column. I had some excel / spreadsheet layout in mind, I was wrong :)

Can you show me what the design should be?

I thought you wanted to have custom sort for each column.

@bobylito No, that's what we're after - I think you had it right鈥ere's our mockup:
https://www.evernote.com/l/AAL7CNj5QzlOi7n8JkMr3UAv_sPy1imVArM

We could achieve this using the hits widget as-is, and creating a "toggle index" widget that would toggle between sorted/slave indexes.

The drawback to this managing & lining up the columns between the templating. For this reason, we wanted to create a single widget that accepted settings like:

{
    container: someDomElement,
    columns: [
        {
            templates: {
                header: ``,
                cell: ``,
            },
            ascIndex: 'productsByRatingAsc',
            descIndex: 'productsByRatingDesc',
        },
    ],
}

So yes I would for what I proposed first. It is the most straightforward approach.

But then I don't know what is your need for reusability or If it needs to be configurable and managed by some end-users. Is it the case?

But then I don't know what is your need for reusability or If it needs to be configurable and managed by some end-users. Is it the case?

Either approach works for us, it just seemed like an opportunity to share a configurable widget with the community, as it seemed like there were quite a few people asking for a "sortable IS table" widget.

The other option of course is to just not use (or use a forked version of) connectHits, which is what we're doing. We just wanted it to behave as much like hits as possible.

We'll proceed with this route, but if you have any other ideas how we might leverage connectHits, let us know!

I'm wondering if the "table component" couldn't be

---------------
connectSortBy
---------------
connectHits
---------------

This all together wouldn't be a "single widget", but still something you can import and add options to

Either approach works for us, it just seemed like an opportunity to share a configurable widget with the community, as it seemed like there were quite a few people asking for a "sortable IS table" widget.

That would be a great idea :)

The other option of course is to just not use (or use a forked version of) connectHits, which is what we're doing.

That would be too bad indeed. How do you see the API of a table widget? Why use a connector in this context? I'd be happy to see what you've come up with.

@rogerroelofs is doing the heavy lifting, want to share what the API is currently looking like?

I am modeling after the hits widget as much as possible. If we were just doing a table I might have preferred an api closer to https://github.com/react-tools/react-table but our use case is a bit more complicated than that.

Here's what I have so far. It is the hits api + a columns object

dataTableWidget({
        container: this.$container.find(this.config.selectors.dataTable)[0],
        hitsPerPage: this.config.hitsPerPage,
        transformData: (data) => {
           ...
        },
        templates: {
          allItems: `
        {{#hits}}
          {{#fullWidthAd}}
            <tr>
              <td colspan="{{columns.length}}">{{{ fullWidthAd }}}</td>
            </tr>
          {{/fullWidthAd}}
            <tr>
              <td></td>
              <td>{{ manufacturer.0.title }}</td>
              <td>{{ title }}</td>
              <td>{{ ratingAvg }}</td>
              <td>{{ reviewTotal }}</td>
            </tr>
        {{/hits}}
`,
          empty: config.templates.noResults
        },
        columns: [
          {
            templates: {
              header: ``,
            },
          },
          {
            templates: {
              header: `Brand`,
            },
          },
          {
            templates: {
              header: `Product`,
            },
          },
          {
            templates: {
              header: `Review Score`,
            },
            ascIndex: 'productsByRatingAsc',
            descIndex: 'productsByRatingDesc',
          },
          {
            templates: {
              header: `# of Reviews`,
              cell: `{{ reviewTotal }}`,
            },
            ascIndex: 'productsByReviewTotalAsc',
            descIndex: 'productsByReviewTotalDesc',
          },
        ]
      })

Sorry for not responding further here. IIRC it was taken up via support and now this thread no longer seems useful, which is why I'll close it :)

Was this page helpful?
0 / 5 - 0 ratings