React Complex Form
Daha önce acemice kendi yaptığım karmaşık yapılı javascript, jquery, vuejs ve php karışımı olan bir formum mevcut.
Birden fazla sekme (kullanıcının yaptığı tercihlere göre sekme sayısı 2-6 arasında değişiyor) ve sekmelerin içinde birbirini etkileyen ve ilgilendiren seçimler var. Bilgiler static yani herhangi bir apiden beslenmiyor.
Ben bu şekilde birbiri ile alaklı olan karışık yapıdaki formu en doğru mantıklı şekilde nasıl yapabilirim?
Ayrıca çok lisanlı şekilde çalışır durumda. Form doldurulduktan sonra Gönder veya PDF Kaydet gibi iki buton ile farklı işlevselliği olacak.
Mail gönderimi için NodeJS veya PHP ile api yazılacak.
Fakat bu kadar karışık bir formda ilerlemek veya güncelleme yapmak çok zor olacak.
Lisan için bilgiler bu şekilde array içinde tutuyorum.
Genel hatları ile form ve çalışması tamam sadece eksik bilgilerin girilmesi kaldı.
Daha akıllı ve basite indirgenmiş nasıl olabilir.
dependencies
react-bootstrap,
jspdf,
dateformat,
CUSTOMER_FORM_TITLE: [
"Müşteri Bilgileri",
"Customer Information",
"Informations client",
"Kundeninformationen ",
"",
"Информация для покупателей",
"Información de cliente",
"",
],
//Aşağıdaki şekilde kullanıyorum. workLang değişkenimde aktif lisan.
{Constants.CUSTOMER_FORM_TITLE[workLang]}
Örnek form görseli
https://prnt.sc/aioCMIEbi-Y2
Asıl kırılma noktasını TestForm içindeki setField fonksiyonu içinde açıklama olarak yazdım.
Belkide state yönetiminde bir sorun yaşıyorum.
Hatanın olduğu tam nokta Montaj Şeklini Sıvaüstü' nden Sıvaaltı olarak değiştirdiğimde Modeller değişiyor.
Fakat Büküm şekilleri model ModelA için olanlar kalıyor.
Umarım sorunumu doğru birşekilde anlatabilmişimdir.
İlerleyen adımlarda formda yapılan tercihlere göre seçilen lisana göre bir seçenekte sadece PDF dosyası oluşturmak.
Diğer bir seçenekte ise PDF dosya ve tercihlerin tutulduğu text dosyası oluşturmak. Bunların paketlenip zip olarak belirtilen posta adresine mail olarak gönderilmesi olacak.
Daha sonra bu gelen text dosyasını upload ederek tüm seçimleri otomatik olarak geri yüklemek olacak.
Ayrıca formiki tekrar inceleyeceğim. Bunun gibi başka form bileşenleri vardı araştırmalarda görmüştüm.
Fakat ben pure olarak yaparak daha kontrollü ve öğrenerek gitmek istediğim için bu şekilde ilerlemiştim.
Buradaki hata nedir?
const Constants = {
TR: 0, //Turkish
EN: 1, //English
FR: 2, //French
DE: 3, //German
GR: 4, //Greek
RU: 5, //Russian
ES: 6, //Spanish
IT: 7, //Italian
WORKING_LANG_TITLE: [
["TÜRKÇE", "İNGİLİZCE", "FRANSIZCA", "ALMANCA", "YUNANCA", "RUSÇA", "İSPANYOLCA", "İTALYANCA"],
["TURKISH", "ENGLISH", "FRENCH", "GERMAN", "GREEK", "RUSSIAN", "SPANISH", "ITALIAN"],
["TURC", "ANGLAIS", "FRANÇAIS", "ALLEMAND", "GREC", "RUSSE", "ESPAGNOL", "ITALIEN"],
["TÜRKISCH", "ENGLISCH", "FRANZÖSISCH", "DEUTSCH", "GRIECHISCH", "RUSSISCH", "SPANISCH", "ITALIENISCH"],
["", "", "", "", "", "", "", ""],
["ТУРЕЦКИЙ", "АНГЛИЙСКИЙ", "ФРАНЦУЗСКИЙ", "НЕМЕЦКИЙ", "ГРЕЧЕСКИЙ", "РУССКИЙ", "ИСПАНСКИЙ", "ИТАЛЬЯНСКИЙ"],
["TURCO", "INGLÉS", "FRANCÉS", "ALEMÁN", "GRIEGO", "RUSO", "ESPAÑOL", "ITALIANO"],
["", "", "", "", "", "", "", ""],
],
EVET_HAYIR_IDX_HAYIR : 0,
EVET_HAYIR_IDX_EVET : 1,
EVET_HAYIR: [
["Hayır", "Evet"],
["No", "Yes"],
["NON", "OUI"],
["Nein", "Ja"],
["", ""],
["Нet", "ДА"],
["No", "Sí"],
["", ""],
],
COP_TITLE: [
"Kabin Kaseti",
"CAR Operating Panel",
"Panneau de commande CAR",
"Fahrkorb-Bedientableaus",
"",
"Кассета Кабины",
"Panel de Operaciòn de Cabina",
"",
],
LOP_TITLE: [
"Kat Kaseti",
"Landing Operation Panel",
"Panneau d'opération d'atterrissage",
"Etagentableau",
"",
"Напольная кассета",
"Panel de Operación de Aterrizaje",
"",
],
COP_MOUNT_TYPE_TITLE: [
"Montaj Şekli",
"Mount Type",
"Type de montage",
"Typ der Montierung",
"",
"Монтаж Тип",
"Tipo de montaje",
"",
],
COP_MOUNT_TYPE_VAL: ["SURFACE", "FLUSH"],
COP_MOUNT_TYPE_IDX_SURFACE: 0,
COP_MOUNT_TYPE_IDX_FLUSH: 1,
COP_MOUNT_TYPE: [
["Sıva Üstü", "Sıva Altı"],
["Surface Mount", "Flush Mount"],
["Montage en surface", "Montage encastré"],
["Aufputzmontage", "Unterputzmontage"],
["", ""],
["поверхностный Монтаж", "встроенный Монтаж"],
["Montaje en superficie", "Montaje empotrado"],
["", ""],
],
COP_MODEL_TITLE: [
"Model",
"Model",
"Modèle",
"Modell",
"",
"Модель",
"Modelo",
"",
],
COP_MODEL_VAL: ["A", "N", "D", "Y", "B", "P", "V"],
COP_MODEL_IDX_A: 0,
COP_MODEL_IDX_N: 1,
COP_MODEL_IDX_D: 2,
COP_MODEL_IDX_Y: 3,
COP_MODEL_IDX_B: 4,
COP_MODEL_IDX_P: 5,
COP_MODEL_IDX_V: 6,
COP_MODEL: [
["MODEL A", "MODEL N", "MODEL D", "MODEL Y", "MODEL B", "MODEL P", "MODEL V"],
["MODEL A", "MODEL N", "MODEL D", "MODEL Y", "MODEL B", "MODEL P", "MODEL V"],
["MODEL A", "MODEL N", "MODEL D", "MODEL Y", "MODEL B", "MODEL P", "MODEL V"],
["MODEL A", "MODEL N", "MODEL D", "MODEL Y", "MODEL B", "MODEL P", "MODEL V"],
["MODEL A", "MODEL N", "MODEL D", "MODEL Y", "MODEL B", "MODEL P", "MODEL V"],
["MODEL A", "MODEL N", "MODEL D", "MODEL Y", "MODEL B", "MODEL P", "MODEL V"],
["MODEL A", "MODEL N", "MODEL D", "MODEL Y", "MODEL B", "MODEL P", "MODEL V"],
["MODEL A", "MODEL N", "MODEL D", "MODEL Y", "MODEL B", "MODEL P", "MODEL V"],
],
COP_BENDING_TITLE: [
"Büküm",
"Bending",
"Pliant",
"Biegen",
"",
"Изгиб",
"Doblado",
"",
],
COP_BENDING_VAL: ["C1", "C2", "C3", "C4", "C5", "C6", "C7", "C9"],
COP_BENDING_IDX_C1: 0,
COP_BENDING_IDX_C2: 1,
COP_BENDING_IDX_C3: 2,
COP_BENDING_IDX_C4: 3,
COP_BENDING_IDX_C5: 4,
COP_BENDING_IDX_C6: 5,
COP_BENDING_IDX_C7: 6,
COP_BENDING_IDX_C9: 7
}
export default (
Constants
);
import { useEffect, useState } from "react";
import Container from 'react-bootstrap/Container';
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';
import Form from 'react-bootstrap/Form';
import InputGroup from 'react-bootstrap/InputGroup';
import Tabs from 'react-bootstrap/Tabs';
import Tab from 'react-bootstrap/Tab';
import Constants from "../../constants/Constants";
const TestForm = () => {
const [workLang, setWorkLang] = useState(Constants.TR)
const [form, setForm] = useState({})
const [errors, setErrors] = useState({});
function setField(name, value) {
console.log(form.copMountType);
setForm(prev => ({ ...prev, [name]: value }));
if (name === "copMountType") {
console.log(document.getElementById("copMountType"));
if (form.copMountType === Constants.COP_MOUNT_TYPE_VAL[Constants.COP_MOUNT_TYPE_IDX_SURFACE]) {
changeCopModel(Constants.COP_MODEL_VAL[Constants.COP_MODEL_IDX_A])
changeCopBending(Constants.COP_BENDING_VAL[Constants.COP_BENDING_IDX_C6])
//Asıl kırılma noktası buradaki mantıksal işlem
//Montaj Tipi SıvaÜstü olunca
//select option kutusuna MODEL A,N,D,Y geliyor ve ilk seçenek A olarak geliyor.
//ayrıca büküm şekli olarak Model A için C6 ve C9 geliyor olmalı.
//Montaj Tipi SıvaAltı olunca
//select option kutusuna MODEL B,P,V geliyor ve ilk seçenek B olarak geliyor.
//ayrıca büküm şekli olarak Model B için C1,C4 ve C5 geliyor olmalı.
//Diğer bükümlerde Modele göre değişiyor.
//formun devamında büküme ve model göre resimler çıkartacağım.
//asıl formun karıştığı yapılan tercihe göre diğer seçenekler ve seçim değişiklik gösteriyor.
} else if (form.copMountType === Constants.COP_MOUNT_TYPE_VAL[Constants.COP_MOUNT_TYPE_IDX_FLUSH]) {
changeCopModel(Constants.COP_MODEL_VAL[Constants.COP_MODEL_IDX_BELLA])
getCopModelOptions()
changeCopBending(Constants.COP_BENDING_VAL[Constants.COP_BENDING_IDX_C1])
getCopBendingOptions()
};
}
forceFormUpdate()
if (!!errors[name])
setErrors(prev => ({ ...prev, [name]: null }))
}
function forceFormUpdate() {
setForm(prev => {
return { ...prev }
})
}
function changeCopModel(value) {
setForm(prev => ({ ...prev, copModel: value }))
}
function changeCopBending(value) {
setForm(prev => ({ ...prev, copBending: value }))
}
const formInitialize = () => {
setForm({
firm: "",
city: "",
//...to many options
copMountType: Constants.COP_MOUNT_TYPE_VAL[Constants.COP_MOUNT_TYPE_IDX_SURFACE],
copModel: Constants.COP_MODEL_VAL[Constants.COP_MODEL_IDX_A],
copBending: Constants.COP_BENDING_VAL[Constants.COP_BENDING_IDX_C6],
//...to many options
});
}
useEffect(() => {
console.log("initialized");
formInitialize();
}, [])
function getCopModelOptions() {
if (form.copMountType === Constants.COP_MOUNT_TYPE_VAL[Constants.COP_MOUNT_TYPE_IDX_SURFACE]) {
return <>
<option value={Constants.COP_MODEL_VAL[Constants.COP_MODEL_IDX_A]}>{Constants.COP_MODEL[workLang][Constants.COP_MODEL_IDX_A]}</option>
<option value={Constants.COP_MODEL_VAL[Constants.COP_MODEL_IDX_N]}>{Constants.COP_MODEL[workLang][Constants.COP_MODEL_IDX_N]}</option>
<option value={Constants.COP_MODEL_VAL[Constants.COP_MODEL_IDX_D]}>{Constants.COP_MODEL[workLang][Constants.COP_MODEL_IDX_D]}</option>
<option value={Constants.COP_MODEL_VAL[Constants.COP_MODEL_IDX_Y]}>{Constants.COP_MODEL[workLang][Constants.COP_MODEL_IDX_Y]}</option>
</>
} else if (form.copMountType === Constants.COP_MOUNT_TYPE_VAL[Constants.COP_MOUNT_TYPE_IDX_FLUSH]) {
return <>
<option value={Constants.COP_MODEL_VAL[Constants.COP_MODEL_IDX_B]}>{Constants.COP_MODEL[workLang][Constants.COP_MODEL_IDX_B]}</option>
<option value={Constants.COP_MODEL_VAL[Constants.COP_MODEL_IDX_P]}>{Constants.COP_MODEL[workLang][Constants.COP_MODEL_IDX_P]}</option>
<option value={Constants.COP_MODEL_VAL[Constants.COP_MODEL_IDX_V]}>{Constants.COP_MODEL[workLang][Constants.COP_MODEL_IDX_V]}</option>
</>
}
}
function getCopBendingOptions() {
if (form.copModel) {
return Constants.COP_BENDING_VAL.map((item, index) => {
if (item === Constants.COP_BENDING_VAL[Constants.COP_BENDING_IDX_C1]) {
if (form.copModel === Constants.COP_MODEL_VAL[Constants.COP_MODEL_IDX_B] || form.copModel === Constants.COP_MODEL_VAL[Constants.COP_MODEL_IDX_P] || form.copModel === Constants.COP_MODEL_VAL[Constants.COP_MODEL_IDX_V])
return <option key={index} value={item}>{Constants.COP_BENDING_VAL[index]} </option>
} else if (item === Constants.COP_BENDING_VAL[Constants.COP_BENDING_IDX_C2]) {
if (form.copModel === Constants.COP_MODEL_VAL[Constants.COP_MODEL_IDX_D])
return <option key={index} value={item}>{Constants.COP_BENDING_VAL[index]} </option>
} else if (item === Constants.COP_BENDING_VAL[Constants.COP_BENDING_IDX_C4]) {
if (form.copModel === Constants.COP_MODEL_VAL[Constants.COP_MODEL_IDX_N] || form.copModel === Constants.COP_MODEL_VAL[Constants.COP_MODEL_IDX_B] || form.copModel === Constants.COP_MODEL_VAL[Constants.COP_MODEL_IDX_P])
return <option key={index} value={item}>{Constants.COP_BENDING_VAL[index]} </option>
} else if (item === Constants.COP_BENDING_VAL[Constants.COP_BENDING_IDX_C5]) {
if (form.copModel === Constants.COP_MODEL_VAL[Constants.COP_MODEL_IDX_B] || form.copModel === Constants.COP_MODEL_VAL[Constants.COP_MODEL_IDX_P])
return <option key={index} value={item}>{Constants.COP_BENDING_VAL[index]} </option>
} else if (item === Constants.COP_BENDING_VAL[Constants.COP_BENDING_IDX_C6]) {
if (form.copModel === Constants.COP_MODEL_VAL[Constants.COP_MODEL_IDX_A])
return <option key={index} value={item}>{Constants.COP_BENDING_VAL[index]} </option>
} else if (item === Constants.COP_BENDING_VAL[Constants.COP_BENDING_IDX_C7]) {
if (form.copModel === Constants.COP_MODEL_VAL[Constants.COP_MODEL_IDX_A])
return <option key={index} value={item}>{Constants.COP_BENDING_VAL[index]} </option>
} else if (item === Constants.COP_BENDING_VAL[Constants.COP_BENDING_IDX_C9]) {
if (form.copModel === Constants.COP_MODEL_VAL[Constants.COP_MODEL_IDX_Y])
return <option key={index} value={item}>{Constants.COP_BENDING_VAL[index]} </option>
}
})
}
}
return (
<>
<Form>
<Container>
<Row className="text-center">
<Col sm className="text-center mb-3">
<Form.Select
size="sm"
name="workLang"
onChange={(e) => { setWorkLang(e.target.value) }}
>
<option value={Constants.TR}>{Constants.WORKING_LANG_TITLE[workLang][Constants.TR]}</option>
<option value={Constants.EN}>{Constants.WORKING_LANG_TITLE[workLang][Constants.EN]}</option>
<option value={Constants.FR}>{Constants.WORKING_LANG_TITLE[workLang][Constants.FR]}</option>
<option value={Constants.DE}>{Constants.WORKING_LANG_TITLE[workLang][Constants.DE]}</option>
<option value={Constants.RU}>{Constants.WORKING_LANG_TITLE[workLang][Constants.RU]}</option>
<option value={Constants.ES}>{Constants.WORKING_LANG_TITLE[workLang][Constants.ES]}</option>
</Form.Select>
</Col>
</Row>
<Row>
<Col>
<Tabs
defaultActiveKey={"cop"}
id="mytab"
>
<Tab eventKey="cop" title={Constants.COP_TITLE[workLang]} >
<Row className="mb-1">
<Col>
<span className="d-block p-1 bg-secondary text-white text-center">{Constants.COP_TITLE[workLang]}</span>
</Col>
</Row>
<Row className="mb-1">
<Col lg={2} style={{ textAlign: "center" }}>
<div>productImage</div>
</Col>
<Col lg={10}>
<Row>
<Col lg={6}>
<InputGroup size="sm" className="mb-1">
<InputGroup.Text>{Constants.COP_MOUNT_TYPE_TITLE[workLang]}</InputGroup.Text>
<Form.Select
name="copMountType"
value={form.copMountType || ""}
onChange={(e) => { setField(e.target.name, e.target.value) }}
>
<option value={Constants.COP_MOUNT_TYPE_VAL[Constants.COP_MOUNT_TYPE_IDX_SURFACE]}>{Constants.COP_MOUNT_TYPE[workLang][Constants.COP_MOUNT_TYPE_IDX_SURFACE]}</option>
<option value={Constants.COP_MOUNT_TYPE_VAL[Constants.COP_MOUNT_TYPE_IDX_FLUSH]}>{Constants.COP_MOUNT_TYPE[workLang][Constants.COP_MOUNT_TYPE_IDX_FLUSH]}</option>
</Form.Select>
</InputGroup>
<InputGroup size="sm" className="mb-1">
<InputGroup.Text>{Constants.COP_MODEL_TITLE[workLang]}</InputGroup.Text>
<Form.Select
name="copModel"
value={form.copModel || ""}
onChange={(e) => { setField(e.target.name, e.target.value) }}
>
{getCopModelOptions()}
</Form.Select>
</InputGroup>
<InputGroup size="sm" className="mb-1">
<InputGroup.Text>{Constants.COP_BENDING_TITLE[workLang]}</InputGroup.Text>
<Form.Select
name="copBending"
value={form.copBending || ""}
onChange={(e) => { setField(e.target.name, e.target.value) }}
>
{getCopBendingOptions()}
</Form.Select>
</InputGroup>
</Col>
<Col lg={6}>
Ali Veli sonra dolacak
</Col>
</Row>
</Col>
</Row>
</Tab>
<Tab eventKey="lop" title={Constants.LOP_TITLE[workLang]} >
</Tab>
{form.lipUsed === Constants.EVET_HAYIR[Constants.EVET_HAYIR_IDX_EVET] &&
<Tab eventKey="lip" title={Constants.LIP_TITLE[workLang]} >
</Tab>
}
</Tabs>
</Col>
</Row>
</Container>
</Form >
</>
)
}
export default TestForm;