multiple tabs with one form (submit/reset)

When I open the modal dialog and it opens 4 tabs. I tried to click all tabs and then click close which will dismiss the dialog then open the modal dialog again then the first tab remains same (unchanged). As for the rest of tabs (2nd to 4th), it is acting weird. Dropdown, checkboxes are not displaying correctly. I discovered a bug.


When I click close the modal, it will render multiple divs over and again. If I remove these "multiple divs" before I open the modal dialog, it worked perfectly. I am wondering how can I do a workaround to make the divs disappear or make all of tabs displaying correctly.

Advice will be appreciated. Thanks expert. :)

14 Replies

KV Karthikeyan Viswanathan Syncfusion Team September 18, 2018 09:28 AM UTC

Hi DeBao, 

Thanks for contacting Syncfusion support. 

We have prepared a sample based on your scenario. But, we were unable to find out the exact root cause of this issue. 


So, please share the below details it will help us to provide a solution at earlier. 

  • Share the issue reproducing sample if possible.
  • Share the shared sample as issue reproducible one.
  • Share the code snippet which will help to reproduce this issue.


Regards, 
Karthikeyan V. 



DC DeBao Chua September 18, 2018 09:50 AM UTC

Hi Karthikeyan V,

Thank you for your reply.

Well, it is not what I am looking for. I will explain clearly again and hopefully you get my point this time. :)

Scenario:
Step 1: Click "Open Modal" on main page
Step 2. It will pop up dialog with 4 tabs on main page that consists of many components like textfield, dropdownlist, checkbox, multiselect.
Step 3. Whenever I click each tab for the first time -- all components look fine.
Step 4. I click Cancel button that will dismiss the modal -- return back to main page
Step 5. Repeat from no 1 to 4 again which is 2nd time so the pop up dialog (1st tab) -- components look fine.
Step 6. I click 2nd/3rd/4th tab and the components disappear -- not working properly.

I discovered some bugs when I look at the development tool. At Step 4, when I click cancel button that will dismiss the modal, it will make a copy of div id (Refer to Problem_1.jpg) automatically. Then I continue to click Open modal again, the first tab looks ok but not the second, third and 4th tab. I click cancel again then it will make another copy of div id (Refer to Problem_2.jpg).

I tried to remove these "duplicate div IDs" on development tool and played around with it. It works perfectly that surprised me. I guess the problem is unmount component where I need to call DOM element to remove the child div but I cannot find the solution.

Example code like:
public componentWillUnmount() {

const node = ReactDOM.findDOMNode(this).parentNode as HTMLDivElement;
console.log("findDOMNode - " + node);

// ReactDOM.unmountComponentAtNode(document.getElementById("VertragEditForm_Zahlung"));

ReactDOM.unmountComponentAtNode(node);

// ReactDOM.unmountComponentAtNode(this.props.containerId);

// ReactDOM.unmountComponentAtNode(document.getElementById('Root'));
// ReactDOM.unmountComponentAtNode(document.getElementById('newRoot'));
}

Attachment: Problem_9b727ca6.zip


SK Sebastian Knoche September 18, 2018 11:54 PM UTC

The provided sample relies on render functions for the tabs content, in our case (I am a co-worker of DeBao) we are utilizing final-form for form-state management, this presents us with a a problem.

react-final-form requires all Field components to be nested within the actual Form component (each tab contains several fields). Since the Tab component renders it's content outside of the parent's component hierarchy we tried to escape this trap by rendering the content separately including id's on a nesting div and utilize a content="#idofcontainer" on the TabItemDirective.

Additionally we use conditional rendering to let react render this Dialog only under certain circumstances (instead of hiding/showing it).

Is there an alternative approach, to place the content generated by the render function within the hosting component instead?


SK Sebastian Knoche September 19, 2018 12:14 PM UTC

This is the component structure (from react dev tools) the TabItemsDirective generates - FormContent is generated by the render function used by the tab.


Even if the tab content will be rendered somewhere else in the DOM, the component hierarchy should nest them (react portal). Otherwise react components depending on their context will not be able to maintain functionality.


BS Buvana Sathasivam Syncfusion Team September 19, 2018 04:55 PM UTC

Hi DeBao/Sebastian,  
  
Thanks for your update. 
  
After checked your shared images we can able to get this issue and your requirement.  The issue is “duplicate div IDs” rendered on the DOM whenever the Tab is destroyed on Dialog close. This issue will occur if the content of the Tab is rendered as a template rendering(i.e content as id reference) instead of the Native React template(i.e using separate functions) rendering. 
  
The following issue is replicated in the below sample.  
  
  
This issue will not be replicated if we use the react based rendering for using other components in the tab like below in our previous shared sample. 
  
  
  
  
  
We have made the destroyed items to be appended to the body because in order to reuse those elements as the content of the Tab again when the control is re imitated. Hence it is not an issue and as told, you can use the React template rendering method to resolve this.  
  
Also, our Tab takes the items only on the load on demand approach only. So if all the Tabs are opened by clicking the header only it will load its contents from the body.  So only opening the corresponding Tab only will load its form contents. 
  
Please check the above shared details and let us know whether it solves our issue?. If not, please share an issue reproducible sample with more details to validate further on this issue. 
  
Regards, 
Buvana S 



SK Sebastian Knoche September 19, 2018 09:49 PM UTC

I am sorry, that my previous post lead to some confusion...

Actually we are facing a problem, since react components depending on the react component hierarchy are disconnected from their parents.
react-final-form (a library for managing form state / validation / derived field values / etc) depends that Field components are placed within their parent Form component (two HOL's without presentation in the DOM).

When we try to render Tabs with template render functions, these Fields get disconnected from their parent Form component and are unable to update their values.

My previous post suggested, that these rendered elements (even though they are not nested within the Tab components should be logically nested within (react portals) to maintain their logical hierarchy within react.

Best regards,
Sebastian


DL Deepa Loganathan Syncfusion Team September 20, 2018 12:19 PM UTC

Hi Sebastian,   
  
Thanks for contacting Syncfusion Support.    
  
We have tried to reproduce the reported issue and unable to reproduce at our end. All tab component contents are placed properly inside the tab root element.     
  
We have prepared sample with tab component using react-final-form in which we have created another react page content into tab component content and this react page content contains react-final-form.     
  
Please find the below video for your reference.   
  
  
   
   
Please refer to the above shared stackblitz link for your reference.  If you still, face any issue using tab component, then reproduce your issue on above shared stackblitz link or share your code or which type of issue you are facing with clear description/video.  So, that we will check and provide a prompt solution at earliest.   


 
 
Regards,   
Deepa L.   



SK Sebastian Knoche September 20, 2018 01:17 PM UTC

Thanks for your reply.

We are working on a single Form containing multiple Tabs. As soon as try to utilize the Tab component within a Form (we are trying to structure about 140 fields into multiple tabs) the Fields are placed outside of the ReactFinalForm component and therefore disconnected (take a look at the previous screenshot - the FormContent component is generated by the TabItemDirectives template rendering).


You will find a sample of reproducing our problem here:
https://stackblitz.com/edit/react-ts-tgugkg


Best regards,
Sebastian



DC DeBao Chua September 21, 2018 09:21 AM UTC

Hi Deepa L.,

My team member, Sebastian and I are encountering some issues. It is about a single form (only one submit/reset) that contains multiple tabs (many fields).

Based on two links I sent, you will notice that the values cannot be entered on the fields because the fields are placed outside of ReactFinalForm components. It should be nested within react components so that the values can be entered. We hope you will understand this issue and we also hope to have a solution for this issue.

You will find a sample of reproducing our problems here:
1. https://stackblitz.com/edit/react-ts-tgugkg
2. https://stackblitz.com/edit/react-ts-qxnmrx

Thanks expert. :)


BS Buvana Sathasivam Syncfusion Team September 21, 2018 06:04 PM UTC

Hi DeBao, 

Thanks for your update. 

We checked your sample, here inputs are unable to accessible. It occurs when you load content using itemsDirective. We will check this case and update you more details on Sep 25, 2018. 

We suggest you to use template rendering way for both tab and accordion component to reuse a `Field` from external component. 

We have modified the sample using template rendering, check on this. 


 
Regards, 
Buvana S 



DC DeBao Chua September 24, 2018 12:09 PM UTC

Hi Buvana,

Thank you for the updates.

I have tested the source codes and it looks perfect. I understand about the issue (template rendering) you explained. You mentioned you will update me more details on Sep 25, 2018 so I shall hear about it from you soon.

Thank you expert.


BS Buvana Sathasivam Syncfusion Team September 26, 2018 02:29 AM UTC

Hi DeBao, 

Thanks for your update. 

Query: “I understand about the issue (template rendering) you explained.” 

To be clearer, in tab component rendering with template is working fine.   

If you are using tabItemsDirective for rendering tab items, you can facing the console error.  As mentioned in the forum 139919, tab itemDirective is used to directly compile the tab content and placed inside the tab content DOM element.  If you are placing Field inside the tab content, it shows console error on “Warning: Field must be used inside of a ReactFinalForm component”.  This error is because of itemDirective is directly compiled on Field react component without using react-final-form and then append into tab content DOM HTML element.  React-final-form is considered after append into Tab content DOM element.  So, we suggested to use template element for tab content.  

In template element, tab component header section must be enclosed within a wrapper element using ‘e-tab-header’ class and corresponding content must be mapped with ‘e-content’ class.  You can follow the below structure of HTML element to render the tab. 

Tab.tsx 

  <TabComponent heightAdjustMode='Auto' id='defaultTab'>  
                <div className="e-tab-header">  // Tab header 
                  <div>tab1</div> 
                  <div>tab2</div> 
                  <div>tab3</div> 
                </div> 
                <div className="e-content">  // Tab content 
                  <div> 
                    <ReactTabforms /> 
                  </div> 
                  <div> 
                    <Accordion /> 
                  </div> 
                  <div> 
                    <ReactTabforms /> 
                  </div> 
                </div> 
        </TabComponent> 



Please find the below stackblitz link. 

Regards, 
Buvana S 



DC DeBao Chua September 26, 2018 06:52 AM UTC

Hello Buvana,

Thank you for your explaination and the links.

It works very well. I understand about the tab and accordion components.

Thank you expert.


DL Deepa Loganathan Syncfusion Team September 27, 2018 06:37 PM UTC

Hi DeBao,  
Thanks for the update. Please let us know if you have any further queries.  
Regards,  
Deepa L. 


Loader.
Up arrow icon