Continue part 1 when we have halfway completed when the requirements are completed:
- create checkbox
- submit the form:
{categories: [1, 2, 3, 4]
- multi checkbox
In this article we will complete the remaining requirements.
Request:
- Create form for 2 types of text input and checkbox + submit button
- The form submission data has the form (only need console.log in the executable function):
{categories: [1, 2, 3, 4], meta: ["a", "b", "c"]}
- The meta cannot contain empty data
- Allow add or remove input text
- multi checkbox
Start !!!
I used the code of part 1, so you guys can go back to part 1 and review the code for me
form.tsx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | <span class="token operator">...</span> <span class="token comment">//tạo 1 state với số lượng input</span> <span class="token keyword">const</span> <span class="token punctuation">[</span> inputs <span class="token punctuation">,</span> setInputs <span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span> <span class="token punctuation">(</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> id <span class="token punctuation">:</span> <span class="token number">1</span> <span class="token punctuation">,</span> content <span class="token punctuation">:</span> <span class="token string">""</span> <span class="token punctuation">}</span> <span class="token punctuation">]</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token operator">...</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> <span class="token keyword">const</span> onAddClick <span class="token operator">=</span> <span class="token keyword">async</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token function-variable function">onRemoveClick</span> <span class="token operator">=</span> index <span class="token operator">=></span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> <span class="token operator">...</span> <span class="token operator"><</span> Grid container direction <span class="token operator">=</span> <span class="token string">"column"</span> <span class="token operator">></span> <span class="token operator"><</span> FormComponent categories <span class="token operator">=</span> <span class="token punctuation">{</span> categories <span class="token punctuation">}</span> inputs <span class="token operator">=</span> <span class="token punctuation">{</span> inputs <span class="token punctuation">}</span> onAddClick <span class="token operator">=</span> <span class="token punctuation">{</span> onAddClick <span class="token punctuation">}</span> onRemoveClick <span class="token operator">=</span> <span class="token punctuation">{</span> onRemoveClick <span class="token punctuation">}</span> handleChange <span class="token operator">=</span> <span class="token punctuation">{</span> handleChange <span class="token punctuation">}</span> handleSubmit <span class="token operator">=</span> <span class="token punctuation">{</span> handleSubmit <span class="token punctuation">}</span> setInputs <span class="token operator">=</span> <span class="token punctuation">{</span> setInputs <span class="token punctuation">}</span> <span class="token operator">/</span> <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> Grid <span class="token operator">></span> |
FormComponent.tsx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | <span class="token operator">...</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> DynamicInput <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">"./DynamicInput"</span> <span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> CategoryType <span class="token punctuation">,</span> InputType <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">"../types/form"</span> <span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">const</span> FormComponent <span class="token operator">=</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> <span class="token operator">...</span> inputs <span class="token punctuation">,</span> onAddClick <span class="token punctuation">,</span> onRemoveClick <span class="token punctuation">,</span> setInputs <span class="token punctuation">}</span> <span class="token punctuation">:</span> <span class="token punctuation">{</span> <span class="token operator">...</span> inputs <span class="token punctuation">:</span> InputType <span class="token punctuation">[</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> onAddClick <span class="token punctuation">:</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token keyword">void</span> <span class="token punctuation">;</span> onRemoveClick <span class="token punctuation">:</span> <span class="token punctuation">(</span> index <span class="token punctuation">:</span> number <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token keyword">void</span> <span class="token punctuation">;</span> setInputs <span class="token punctuation">:</span> <span class="token punctuation">(</span> value <span class="token punctuation">:</span> InputType <span class="token punctuation">[</span> <span class="token punctuation">]</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token keyword">void</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token operator"><</span> <span class="token operator">></span> <span class="token operator"><</span> form onSubmit <span class="token operator">=</span> <span class="token punctuation">{</span> handleSubmit <span class="token punctuation">}</span> <span class="token operator">></span> <span class="token operator">...</span> <span class="token operator"><</span> Grid container direction <span class="token operator">=</span> <span class="token string">"column"</span> <span class="token operator">></span> <span class="token operator"><</span> Grid item <span class="token operator">></span> <span class="token operator"><</span> h3 <span class="token operator">></span> Meta <span class="token operator"><</span> <span class="token operator">/</span> h3 <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> Grid <span class="token operator">></span> <span class="token operator"><</span> Grid container direction <span class="token operator">=</span> <span class="token string">"column"</span> <span class="token operator">></span> <span class="token punctuation">{</span> inputs <span class="token punctuation">.</span> <span class="token function">map</span> <span class="token punctuation">(</span> <span class="token punctuation">(</span> input <span class="token punctuation">:</span> InputType <span class="token punctuation">,</span> index <span class="token punctuation">:</span> number <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token operator"><</span> DynamicInput key <span class="token operator">=</span> <span class="token punctuation">{</span> input <span class="token punctuation">.</span> id <span class="token punctuation">}</span> onRemoveClick <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token function">onRemoveClick</span> <span class="token punctuation">(</span> index <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token operator">/</span> <span class="token operator">></span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token operator"><</span> <span class="token operator">/</span> Grid <span class="token operator">></span> <span class="token operator"><</span> Grid container justify <span class="token operator">=</span> <span class="token string">"center"</span> style <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token punctuation">{</span> marginTop <span class="token punctuation">:</span> <span class="token number">20</span> <span class="token punctuation">,</span> marginBottom <span class="token punctuation">:</span> <span class="token number">20</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> xs <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token number">10</span> <span class="token punctuation">}</span> <span class="token operator">></span> <span class="token operator"><</span> Button variant <span class="token operator">=</span> <span class="token string">"outlined"</span> onClick <span class="token operator">=</span> <span class="token punctuation">{</span> onAddClick <span class="token punctuation">}</span> <span class="token operator">></span> Add <span class="token operator"><</span> <span class="token operator">/</span> Button <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> Grid <span class="token operator">></span> <span class="token comment">//button submit</span> <span class="token operator"><</span> <span class="token operator">/</span> Grid <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> form <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> <span class="token operator">></span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> |
InputType
1 2 3 4 5 6 7 | <span class="token operator">...</span> <span class="token keyword">export</span> type InputType <span class="token operator">=</span> <span class="token punctuation">{</span> id <span class="token punctuation">:</span> number <span class="token punctuation">;</span> content <span class="token punctuation">:</span> string <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> |
And finally, DynamicInput
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span> <span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> Grid <span class="token punctuation">,</span> OutlinedInput <span class="token punctuation">,</span> Button <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">"@material-ui/core"</span> <span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">const</span> DynamicInput <span class="token operator">=</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> onRemoveClick <span class="token punctuation">}</span> <span class="token punctuation">:</span> <span class="token punctuation">{</span> onRemoveClick <span class="token punctuation">:</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token keyword">void</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token operator"><</span> Grid container spacing <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token number">2</span> <span class="token punctuation">}</span> alignItems <span class="token operator">=</span> <span class="token string">"center"</span> <span class="token operator">></span> <span class="token operator"><</span> Grid item xs <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token number">10</span> <span class="token punctuation">}</span> <span class="token operator">></span> <span class="token operator"><</span> OutlinedInput id <span class="token operator">=</span> <span class="token string">"my-input"</span> style <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token punctuation">{</span> marginBottom <span class="token punctuation">:</span> <span class="token number">10</span> <span class="token punctuation">,</span> marginTop <span class="token punctuation">:</span> <span class="token number">10</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> placeholder <span class="token operator">=</span> <span class="token string">"Type any thing in here"</span> fullWidth required <span class="token operator">/</span> <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> Grid <span class="token operator">></span> <span class="token operator"><</span> Grid item xs <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token number">2</span> <span class="token punctuation">}</span> <span class="token operator">></span> <span class="token operator"><</span> Button variant <span class="token operator">=</span> <span class="token string">"outlined"</span> onClick <span class="token operator">=</span> <span class="token punctuation">{</span> onRemoveClick <span class="token punctuation">}</span> <span class="token operator">></span> Remove <span class="token operator"><</span> <span class="token operator">/</span> Button <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> Grid <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> Grid <span class="token operator">></span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> |
ok we have the following interface
Next as the topic is that we can add input every time we click the Add
button and remove that input with the Remove
button, we modified the above 2 functions offline
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <span class="token operator">...</span> <span class="token keyword">const</span> onAddClick <span class="token operator">=</span> <span class="token keyword">async</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">//chèn thêm 1 object input mới mỗi khi click butotn `Add`</span> <span class="token keyword">let</span> newInput <span class="token punctuation">:</span> InputType <span class="token operator">=</span> <span class="token punctuation">{</span> id <span class="token punctuation">:</span> inputs <span class="token punctuation">.</span> length <span class="token punctuation">,</span> content <span class="token punctuation">:</span> <span class="token string">""</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> <span class="token function">setInputs</span> <span class="token punctuation">(</span> <span class="token punctuation">[</span> <span class="token operator">...</span> inputs <span class="token punctuation">,</span> newInput <span class="token punctuation">]</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> <span class="token comment">//xóa input đó đi với vị trí index được click</span> <span class="token keyword">const</span> <span class="token function-variable function">onRemoveClick</span> <span class="token operator">=</span> index <span class="token operator">=></span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">let</span> newInputs <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token operator">...</span> inputs <span class="token punctuation">]</span> <span class="token punctuation">;</span> newInputs <span class="token punctuation">.</span> <span class="token function">splice</span> <span class="token punctuation">(</span> index <span class="token punctuation">,</span> <span class="token number">1</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token function">setInputs</span> <span class="token punctuation">(</span> newInputs <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> <span class="token operator">...</span> |
And this is the result
So it’s almost done, but suddenly realized that if we have more than 1 input, what if we want to edit the text of input 1 and input 2? What will the current code look like? What is the value going into state inputs
? Sure, if you run the project now and enter the input, the state inputs
field content of the inputs will have no content, so to fix this error we do the following:
Add the onChange function to DynamicInput
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <span class="token operator">...</span> <span class="token operator"><</span> DynamicInput key <span class="token operator">=</span> <span class="token punctuation">{</span> input <span class="token punctuation">.</span> id <span class="token punctuation">}</span> onChange <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token punctuation">(</span> e <span class="token punctuation">:</span> React <span class="token punctuation">.</span> ChangeEvent <span class="token operator"><</span> HTMLInputElement <span class="token operator">></span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token comment">//set lại value input mỗi khi thay đổi dựa theo index của input được chọn </span> <span class="token comment">//với index đã có trong state `inputs`</span> <span class="token function">setInputs</span> <span class="token punctuation">(</span> inputs <span class="token punctuation">.</span> <span class="token function">map</span> <span class="token punctuation">(</span> <span class="token punctuation">(</span> value <span class="token punctuation">,</span> inputSelector <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> index <span class="token operator">===</span> inputSelector <span class="token punctuation">)</span> value <span class="token punctuation">.</span> content <span class="token operator">=</span> e <span class="token punctuation">.</span> target <span class="token punctuation">.</span> value <span class="token punctuation">;</span> <span class="token keyword">return</span> value <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> onRemoveClick <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token function">onRemoveClick</span> <span class="token punctuation">(</span> index <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token operator">/</span> <span class="token operator">></span> <span class="token operator">...</span> |
DynamicInput
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <span class="token operator">...</span> <span class="token keyword">export</span> <span class="token keyword">const</span> DynamicInput <span class="token operator">=</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> <span class="token operator">...</span> onChange <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token punctuation">:</span> <span class="token punctuation">{</span> <span class="token operator">...</span> onChange <span class="token punctuation">:</span> <span class="token punctuation">(</span> event <span class="token punctuation">:</span> object <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token keyword">void</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token operator"><</span> OutlinedInput <span class="token operator">...</span> onChange <span class="token operator">=</span> <span class="token punctuation">{</span> onChange <span class="token punctuation">}</span> <span class="token operator">/</span> <span class="token operator">></span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> |
So has finished processing, handle a bit onSubmit function to see any results
1 2 3 4 5 6 7 | <span class="token keyword">const</span> <span class="token function-variable function">handleSubmit</span> <span class="token operator">=</span> event <span class="token operator">=></span> <span class="token punctuation">{</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token string">"categories"</span> <span class="token punctuation">,</span> categoriesSelector <span class="token punctuation">)</span> <span class="token punctuation">;</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token string">"-------------------------------"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token string">"meta"</span> <span class="token punctuation">,</span> <span class="token function">getMeta</span> <span class="token punctuation">(</span> inputs <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> event <span class="token punctuation">.</span> <span class="token function">preventDefault</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> |
getMeta
helper function
1 2 3 4 5 6 7 8 | <span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">getMeta</span> <span class="token operator">=</span> arrInputs <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> result <span class="token operator">=</span> arrInputs <span class="token punctuation">.</span> <span class="token function">map</span> <span class="token punctuation">(</span> input <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> input <span class="token punctuation">.</span> content <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">return</span> result <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> |
Run again and see if the result is right for the request . And this is the Source code for both parts.
Have a nice day!
Welcome to ReactJS !!!