Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add container component #140

Open
zach2825 opened this issue Jun 22, 2021 · 8 comments
Open

Add container component #140

zach2825 opened this issue Jun 22, 2021 · 8 comments

Comments

@zach2825
Copy link

I have a need to add a container that can house components. Could you describe the process for creating that component that even is part of the form builder? I can add that. I feel like it would use some sort of recursion.

My use-case is that I have rules around a group of components or I could auto-repeat the group

For example in email list
[ first_name | last_name | email]
[ first_name | last_name | email]
[ first_name | last_name | email]
[ first_name | last_name | email]
an another entry could be added to the end.

@zach2825
Copy link
Author

I'm happy to build it out, I'm just not sure how involved it might be.

@zach2825
Copy link
Author

@Kiho does this sound reasonable?

@Kiho
Copy link
Owner

Kiho commented Jun 25, 2021

I don't like infinity level of recursion, probably you can create 2 sub form components, one for form builder and another for form generator which could be repeatable.
Or create repeatable container component based on MultiColumnRow, it might be simpler UI but I think that will be hard to persist data in reasonable format.

@zach2825
Copy link
Author

zach2825 commented Jun 30, 2021

He @Kiho hope your well,

I've created the single-column row component using the multi-column row component. I've also tried to add a button that would allow me to add another null child item to the array, but it's not propagating the change. So I tried a few things like triggering store events but I haven't had any luck. Do you know what would be stopping that?

Right now it has some debug output, I'll clean it up when its working.

const OneColumnRow = ({ data, class_name, ...rest }) => {
  const {editModeOn = false} = rest;

  useEffect(() => {
    console.log({ ['data.childItems']: data.childItems }, {data, class_name, rest});
  }, [data]);

  const className = class_name || 'col-md-12';
  if (!data.childItems) {
    // eslint-disable-next-line no-param-reassign
    data.childItems = [null];
    data.isContainer = true;
  }

  const addAnotherInput = () => {
    if(editModeOn) {
      console.log("addAnotherInput.before", data.childItems);
      data.childItems.push(null);

      // store.dispatch('updateOrder', data);
    }else{
      // duplicate the whole element maybe use a callback. This duplication only
      // happens so an array of answers can be collected.
    }
  }

  return (
    <div>
      <button onClick={addAnotherInput}>
        {editModeOn? 'add another input': '+'}
      </button>
      <MultiColumnRow {...rest} className={className} data={data} />
    </div>
  );
};

@Kiho
Copy link
Owner

Kiho commented Jul 1, 2021

You need to setup updateOrder function in preview.jsx

  _onUpdateOrder() {
    const newData = this.state.data.slice(0);
    store.dispatch('updateOrder', newData);
    this.setState({ data: newData });
  }

in constructor bind updateOrder to instance

    this._onUpdateOrder = this._onUpdateOrder.bind(this);

inject function to components

  getElement(item, index) {
    ...
    return <SortableFormElement id={item.id} seq={this.seq} index={index} moveCard={this.moveCard} insertCard={this.insertCard} mutable={false} parent={this.props.parent} editModeOn={this.props.editModeOn} isDraggable={true} key={item.id} sortData={item.id} data={item} getDataById={this.getDataById} setAsChild={this.setAsChild} removeChild={this.removeChild} _onDestroy={this._onDestroy} _onUpdateOrder={this._onUpdateOrder} />;
  }

Then you should useState to update data in OneColumnRow

const OneColumnRow = ({ data, class_name, _onUpdateOrder, ...rest }) => {
  const { editModeOn = false } = rest;
  const [colData, setColData] = useState(data);

  useEffect(() => {
    console.log({ 'data.childItems': data.childItems }, { data, class_name, rest });
  }, [data]);

  const className = class_name || 'col-md-12';
  if (!data.childItems) {
    // eslint-disable-next-line no-param-reassign
    data.childItems = [null];
    data.isContainer = true;
  }

  const addAnotherInput = () => {
    if (editModeOn) {
      console.log('addAnotherInput.before', data.childItems);
      data.childItems.push(null);
      _onUpdateOrder();
      setColData({ ...data });
      // store.dispatch('updateOrder', data);
    } else {
      // duplicate the whole element maybe use a callback. This duplication only
      // happens so an array of answers can be collected.
    }
  };

  return (
    <div>
      <button onClick={addAnotherInput}>
        {editModeOn ? 'add another input' : '+'}
      </button>
      <MultiColumnRow {...rest} className={className} data={colData} />
    </div>
  );
};

@zach2825
Copy link
Author

zach2825 commented Jul 1, 2021 via email

@zach2825
Copy link
Author

zach2825 commented Jul 1, 2021

Wow, this works perfectly, thank you so much!

@zach2825
Copy link
Author

zach2825 commented Jul 1, 2021

I just need to figure out now how to make inputs in the group save to an array. I have a need when filling out the form to be able to duplicate the whole group.

so input name first_name in the group name user would save something like this form.user[0].first_name and form.user[1].first_name

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants