Sharlaan / material-ui-superselectfield

multiselection autocomplete dropdown component for Material-UI
https://sharlaan.github.io/material-ui-superselectfield
MIT License
266 stars 92 forks source link

selectionsRenderer doesn't have label #9

Closed patrickml closed 7 years ago

patrickml commented 7 years ago

Label is missing from the selectionsRenderer function

we have

options={
   segments.map((p) => (
      <div value={p.id} key={p.id} label={p.name}>
        {p.name}
      </div>
    ))
}

And the label works for the autocomplete perfectly but when the values are rendered it is showing value not label

I tried adding this function

const renderSelected = (values, hintText) => {
  console.log(values, hintText);
  if (!values || !values.length) return hintText;
  const { value, label } = values;
  if (Array.isArray(values)) return values.map((v) => v.label || v.value).join(', ');
  else if (label || value) return label || value;
  return hintText;
};

but when i console.log(values) there is no label key

Sharlaan commented 7 years ago

Here a working example, hope it helps :

import React, { Component } from 'react'
import SuperSelectField from './SuperSelectField'

const segments = [
  { id: 1, name: 'name1' },
  { id: 2, name: 'name2' },
  { id: 3, name: 'name3' },
  { id: 4, name: 'name4' }
]

class CodeExample extends Component {
  state = { value: null }

  handleSelection = (value) => this.setState({ value })

  renderSelected = (values, hintText) => {
    console.log('values', values, '\nhintText', hintText)
    if (!values) return hintText
    const { value, label } = values
    if (Array.isArray(values)) {
      return values.length
        ? values.map(({ value, label }) => label || value).join(', ')
        : hintText
    }
    else if (label || value) return label || value
    else return hintText
  }

  render () {
    const { value } = this.state

    const options = segments.map(({ id, name }) => (
      <div key={id} value={id} label={name}>
        {name}
      </div>
    ))

    return (
      <section style={{ margin: 40 }}>

        <p>Selection: {value && value.label}</p>

        <SuperSelectField
          onChange={this.handleSelection}
          value={value}
          selectionsRenderer={this.renderSelected}
          style={{ width: 150 }}
        >
          {options}
        </SuperSelectField>

      </section>
    )
  }
}

export default CodeExample

Tell me if that works.

patrickml commented 7 years ago

@Sharlaan sadly it isn't :/

image

patrickml commented 7 years ago

I think it maybe that we don't store the label in state, because we use redux form. I tried to check onChange for the label, but it didn't contain label as an option either

Sharlaan commented 7 years ago

Can you show me the whole component context where u use superSelectField please ?

I'll try to replicate and hopefully fix it.

patrickml commented 7 years ago

Absolutely! Thanks for getting back to me so quickly btw.

               <FieldArray
                    name="segmentIds"
                    label="Segments"
                    component={MultiSelect}
                    multiple
                    hintText="Segment Name"
                    showAutocompleteTreshold={1}
                    hintTextAutocomplete="Enter Segment Name"
                    innerDivStyle={{ paddingLeft: '55px', height: '50px' }}
                    options={
                      segments.map((p) => (
                        <div value={p.id} key={p.id} label={p.name}>
                          {p.name}
                        </div>
                      ))
                    }
                  />

This is the redux form translation of the field

import React, { PropTypes, Component } from 'react';
import MultiSelect from 'material-ui-superselectfield';
import { css } from 'aphrodite';
import styles from './styles';

class MultiSelectInput extends Component {
  constructor(props, context) {
    super(props, context);
    this.onChange = this.onChange.bind(this);
  }

  onChange(vals) {
    this.props.fields.removeAll();
    vals.forEach((v) => this.props.fields.push(v.value));
  }

  render() {
    const { fields, label, meta: { touched, error, warning }, options, ...rest } = this.props;
    const values = fields && fields.getAll();
    return (
      <div>
        <p className={css(styles.label)}>{label}</p>
        <MultiSelect
          floatingLabelText={label}
          errorText={touched && error || ''}
          hintText={touched && warning || ''}
          hintTextAutocomplete={touched && warning || ''}
          value={values && values.toJS().map((v) => ({ value: v })) || []}
          onChange={this.onChange}
          {...rest}
        >
          {options}
        </MultiSelect>
      </div>
    );
  }
}

MultiSelectInput.propTypes = {
  fields: PropTypes.object,
  label: PropTypes.node,
  type: PropTypes.string,
  meta: PropTypes.object,
  options: PropTypes.any,
};

export default MultiSelectInput;

Let me know if you'd like more information as well or if there is anything i can do to help

Sharlaan commented 7 years ago

i have a few questions :

patrickml commented 7 years ago

The immutable list actually looks like this

image

patrickml commented 7 years ago

This is the result from the console.log in the selections renderer

image

Sharlaan commented 7 years ago

Just wondering: the dropdown menu renders using segments' id or name ?

patrickml commented 7 years ago

They use the name On Tue, Feb 21, 2017 at 11:32 AM Raphaël Morineau notifications@github.com wrote:

Just wondering: the dropdown menu renders using segments' id or name ?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/Sharlaan/material-ui-superselectfield/issues/9#issuecomment-281397609, or mute the thread https://github.com/notifications/unsubscribe-auth/AHOuuZ_8uAZu9NLEqiBLClDWvu8nWQyWks5rexGngaJpZM4MG2q- .

patrickml commented 7 years ago

@Sharlaan were you able to figure anything out?

Sharlaan commented 7 years ago

Not yet sorry i didnot have time for this.

Sharlaan commented 7 years ago

Did you try with current version pushed here in this repo ?

patrickml commented 7 years ago

@Sharlaan i will test it right now, thank you!

patrickml commented 7 years ago

@Sharlaan i am actually getting an error now on all my inputs after upgrading

They also do not open.

image

Sharlaan commented 7 years ago

i included proptypes to warn developer for incorrectly setup values and children.

Do you have any warnings/errors before this one ?

patrickml commented 7 years ago

@Sharlaan no i don't seem to be getting any other errors until i click on the component

My options look like this

placements.map((p) => (
   <div value={p.id} key={p.id} label={p.name}>
     {p.name}
   </div>
))

example data:

[
  {
    "id": "8dddb60e-89ea-4475-b393-00466a0565d5",
    "name": "abc",
    "__typename": "Placement"
  }
]
patrickml commented 7 years ago

Okay so this is what im seeing.

The child here seems to be coming through as an array now. https://github.com/Sharlaan/material-ui-superselectfield/blob/8074b023d0b532bbb47a68810c92b4d14ad76a1a/src/SuperSelectField.js#L339

image

patrickml commented 7 years ago

I have yet to test this, but i think the issue is coming from there only being one child. I found this in the code

      switch (this.state.itemsLength) {
        case 0:
          fixedChildren = false;
          break;
        case 1:
          fixedChildren = [children];
          break;
        default:
          fixedChildren = children;
      }

Which basically looks like if there is only one child then put it in an array?

patrickml commented 7 years ago

Okay after adding more children this does seem to be the case.

image

I am also seeing that the checkbox's are no longer showing up by default in the newest release?

Sharlaan commented 7 years ago

i'm currently modifying CodeExample3.js to make dataSource as an [ {id: , name: }, ... ] in hope to understand why you don't have labels rendered ....

for the checkboxs, check documentation and CodeExmaple2.js. Regarding edge cases, check issue #13 and CodeExample1.js

patrickml commented 7 years ago

@Sharlaan i'm more worried about the other issues i've brought up in this thread.

image

I removed that switch statement and it fixed the issue of only having one option, but it doesn't look pretty.

I hope that all this helps :/ and i appreciate everything you've done thus far creating this great component.

Sharlaan commented 7 years ago

Mmmm i just realized when you pointed that switch: you arenot using correct version from this repo.

patrickml commented 7 years ago

@Sharlaan im using 1.5.1? isn't that the latest?

Sharlaan commented 7 years ago

Sorry for late answer, if you still interested can you recheck your usecase with latest version 1.7.0 please ?

patrickml commented 7 years ago

@Sharlaan I no longer have access to the site this was used on otherwise I would sorry man :/