question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Multi Select: display only selected items count after x number of items are selected/shown in chips

See original GitHub issue

Thank you for all of the work you do on RS 😃

I am looking to customize the multiselect and wondering if you have a recommendation for how to achieve the desired results.

Right now, with many selections the select component takes up a prohibitive amount of space for certain UIs. I’d like to utilize the chip display within the input but show only a few selected options (like 3/4 max) and then add a “badge” count for the number of selected options that aren’t shown in the value container in the input. The options that are selected but are past the max number of chips allowed to show in the input should show as selected within the dropdown list. I’ve implemented part of this with using a custom ValueContainer to show only the first few chip selections, and then add a count of additional selections. I’m unsure of how I can utilize prop hideSelectedOptions to achieve this to show selected items in the list only when my max is met…

Here’s what I have so far: https://codesandbox.io/s/custom-react-select-sjtib

Current: Screen Shot 2019-11-14 at 4 42 53 PM

Desired: Screen Shot 2019-11-14 at 4 41 22 PM

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:11

github_iconTop GitHub Comments

14reactions
thiagopnobrecommented, Dec 15, 2020

I was trying to do the same in an AsyncSelect and I managed to create a solution based on @ebonow 's solution.

So, I’m sharing a partial example of what I did to make it work, because this might help others:

import React from 'react';
import AsyncSelect from 'react-select/async';
import { components } from 'react-select';

const LimitedChipsContainer = ({ children, hasValue, ...props }) => {
  if (!hasValue) {
    return (
      <components.ValueContainer {...props}>
        {children}
      </components.ValueContainer>
    );
  }

  const CHIPS_LIMIT = 2;
  const [chips, otherChildren] = children;
  const overflowCounter = chips.slice(CHIPS_LIMIT).length;
  const displayChips = chips.slice(overflowCounter, overflowCounter + CHIPS_LIMIT);

  return (
    <components.ValueContainer {...props}>
      {displayChips}

      {overflowCounter > 0 && `+ ${overflowCounter}`}

      {otherChildren}
    </components.ValueContainer>
  );
};

export default ({ loadOptions, placeholder, ...selectSearchProps }) => (
  <AsyncSelect
    className="select-search"
    classNamePrefix="select-search"
    placeholder={placeholder}
    loadOptions={loadOptions}
    hideSelectedOptions={false}
    isMulti
    components={{ ValueContainer: LimitedChipsContainer }}
    {...selectSearchProps}
  />
);

The trick here is to understand that the first child of the ValueContainer is the array of selected options when the input has values. With this in mind, I could just make a slice (in my case showing the last two selected options) and return the chips, the counter and the remaning children after it.

But, do notice this: when the hasValue returns false you can’t do a slice because the first child is not the array of selected options. Hence the guard-clause.

Hope this helps.

7reactions
ebonowcommented, Oct 8, 2021

I noticed that there was a bug so I made an update to the above sandbox to instead use the MultiValue instead of the ValueContainer.

https://codesandbox.io/s/custom-visible-multivalues-8zh8c?file=/example.js

const MoreSelectedBadge = ({ items }) => {
  const style = {
    marginLeft: "auto",
    background: "#d4eefa",
    borderRadius: "4px",
    fontFamily: "Open Sans",
    fontSize: "11px",
    padding: "3px",
    order: 99
  };

  const title = items.join(", ");
  const length = items.length;
  const label = `+ ${length} item${length !== 1 ? "s" : ""} selected`;

  return (
    <div style={style} title={title}>
      {label}
    </div>
  );
};

const MultiValue = ({ index, getValue, ...props }) => {
  const maxToShow = 3;
  const overflow = getValue()
    .slice(maxToShow)
    .map((x) => x.label);

  return index < maxToShow ? (
    <components.MultiValue {...props} />
  ) : index === maxToShow ? (
    <MoreSelectedBadge items={overflow} />
  ) : null;
};

const App = () => {
  return <Select components={{ MultiValue }} {...otherProps} />
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

How to render "N items selected" rather than the list of N ...
Here I'm showing the first three selections normally, and then "N items selected" when 4+ items have been selected. It makes no sense...
Read more >
Multi Select: display only selected items count ... - Bountysource
Multi Select : display only selected items count after x number of items are selected/shown in chips.
Read more >
Multi Select custom way to display multiple options – iTecNote
I've implemented part of this with using a custom ValueContainer to show only the first few chip selections, and then adding a count...
Read more >
Combine selected items into a count in Kendo UI for jQuery
I am wanting to combine all selected items into a "item name" + "number of items selected" format instead of displaying every single...
Read more >
How to show all selected options in Multiselect
Now shows how many options selected (more than 5 options selected) is great, and i also want if any js config to trigger...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found