alsoscotland / react-super-select

MIT License
95 stars 33 forks source link

how to auto submit form when onChange, suggest: return element #55

Closed sinkcup closed 8 years ago

sinkcup commented 8 years ago

now onChange(option) only can get a option, like:

{
  id: 1
  name: 'a'
}

can not get the element, so can not get it's parent form and auto submit it.

PS: there are many form(don't have a ref or id) in this page, and many select don't have a ref.

so how to auto submit form when onChange?

like JedWatson/react-select#822

alsoscotland commented 8 years ago

@sinkcup Thank you for the question. I am not entirely sure I understand what you need. The onChange function is a handler that is entirely in your control.

The react-super-select is meant to be a child of a containing form element. In that sense, when you create it, it is usually in a context where you could identify the form. So in a callback you could do anything you want with the form. Typically something along the lines of

onChange: function(selectedOption) {
  //  if "this"  is the parent component that creates your react-super-select
  //  a ref to your parent form would be something like: this.refs.parentForm

  //  pseudo-code here would take your selectedOption and do what you like
  //  then you are free to submit what you like

  this.refs.parentForm.submit();
 }
sinkcup commented 8 years ago

this page have many forms, and every form don't have a "ref" or "id", so I need get the select or option element, but the react-super-select return option value.

code:

testData = [
  {
    id: 1,
    name: 'USA',
  },
  {
    id: 2,
    name: 'UK',
  }
];

selectCountry(data) {
  // data is like { id: 2, name: 'uk' }, I can't get the form
  // if data is element, I can get the form.
}

<form>
name: <input type="text" name="name" value="Jim" />
country: <Select onChange={selectCountry}  dataSource={testData}>
</form>

<form>
name: <input type="text" name="name" value="Tom" />
country: <Select onChange={selectCountry}  dataSource={testData}>
</form>

<form>
name: <input type="text" name="name" value="Lily" />
country: <Select onChange={selectCountry}  dataSource={testData}>
</form>
alsoscotland commented 8 years ago

@sinkcup There is not an underlying html select or option element to pass. The control itself is built on non-form DOM elements and list-items.

I would recommend that you try creating a hidden input in your form that updates when the onChange of the react-super-select fires, then submit your form based on that wrapping element's onChange handler.

sinkcup commented 8 years ago

no, react-select doesn't support this, but react support.

this code can get form and auto submit.

changeCountry(event) {
  console.log(event.target);
  console.log($(event.target).closest('form'));
}

<form>
<input name="name" value="Jim" />
<select onChange={this.changeCountry} name="country">
  <option value="USA">America</option>
</select>
</form>
alsoscotland commented 8 years ago

@sinkcup In your example you are using jQuery which is not a dependency of the react-super-select control

My apologies. I still am not following why the handler you pass as the value to the onChange prop of react-super-select cannot cover this use-case

sinkcup commented 8 years ago

oh, sorry, I hadn't write the whole code, here is:

changeCountry(event) {
  console.log(event.target);
  console.log($(event.target).closest('form'));
  const params = $(event.target).closest('form').serializeObject();
  Request.post('http://example.com/')
        .type('json')
        .send(params)
        .end(function (err, res) {
            console.log('----------result------');
            console.log(res);
        });
}

I don't want to using jquery in react app, but there is no another idea to get many forms with no ref.

sinkcup commented 8 years ago

the problem is react-super-select and react-select can only pass value onchange, can not get parent form, so can't auto submit.

alsoscotland commented 8 years ago

@sinkcup The react-super-select control is not a true form element.
However, if you were to create a wrapping component that links a hidden input's value to the superSelect's onChange return value via component state, I think you could accomplish what you are trying to do.

This is off-the-cuff pseudo-code, but something along the lines of:

// requires dependencies

rssHiddenInputWrapper = React.createClass({

  getInitialState: function() {
    return {
      inputValue: undefined
    };
  },

  submitForm: function() {
    var formData = $(this.refs.inputField).closest('form').serializeObject();
  },

  updateHiddenInput: function(selectedOption) {
    this.setState({
      inputValue: selectedOption
    }, this.submitForm);
  },

  render: function() {
    return (
      <fieldset>
        <input ref="inputField" type="hidden" value={this.state.} />
        <ReactSuperSelect onChange={this.updateHiddenInput} 
          // ...props 
        />
      </fieldset>
    );
  }

});
sinkcup commented 8 years ago

oh no...don't use this.refs.xxx. there are many forms in this page, and every form has no "ref", like "entering students' score", there is a button can add new empty form.

sinkcup commented 8 years ago
<form>
name: <input type="text" name="name" value="Jim" />
country: <Select onChange={selectCountry}  dataSource={testData}>
</form>

<form>
name: <input type="text" name="name" value="Tom" />
country: <Select onChange={selectCountry}  dataSource={testData}>
</form>

<form>
name: <input type="text" name="name" value="Lily" />
country: <Select onChange={selectCountry}  dataSource={testData}>
</form>

<a onClink={this.addNewForm}>add new form</a>

if Jim use "ref" inputField, Tom use "ref" inputField too?

alsoscotland commented 8 years ago

The ref would be internal to the wrapping component. It should not matter. Each of these items would each create one wrapper component like I mentioned above...

<form>
name: <input type="text" name="name" value="Lily" />
country: < rssHiddenInputWrapper {props...} />
</form>
sinkcup commented 8 years ago

great! I will try.