shaman
Aşağıdaki yapı işinizi görür umarım Yapay Zeka O1 pro versiyonu ile kodlandı.
Düzenlemenin Videosu
Anladığınız üzere, tablonuzdaki satırları silme işlemi sırasında rowspan
değerlerinin doğru şekilde yönetilmemesi nedeniyle tablo yapısı bozuluyor. Bu sorunu çözmek için JavaScript fonksiyonunu daha sağlam hale getirerek, tüm olası silme senaryolarını ele alacak şekilde güncelleyeceğiz.
Aşağıda, tabloda rastgele herhangi bir "Delete" butonuna basıldığında tablo yapısını bozmadan doğru şekilde satırları kaldıran ve rowspan
değerlerini dinamik olarak güncelleyen tam teşekküllü bir kod sunuyorum.
Güncellenmiş Kod:
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dinamik Tablo</title>
<style>
table {
width: 100%;
border-collapse: collapse;
}
th, td {
border: 1px solid black;
padding: 8px;
text-align: center;
}
th {
background-color: #4CAF50;
color: white;
}
button {
cursor: pointer;
padding: 5px 10px;
background-color: #f44336;
color: white;
border: none;
border-radius: 4px;
}
button:hover {
background-color: #d32f2f;
}
img {
max-width: 50px;
}
</style>
</head>
<body>
<table id="productTable">
<thead>
<tr>
<th>PRODUCT COLOR</th>
<th>PRODUCT IMAGES</th>
<th>SIZE</th>
<th>PRICE</th>
<th>REMOVE ROW</th>
</tr>
</thead>
<tbody>
<tr data-group="1">
<td rowspan="3">Red</td>
<td rowspan="3"><img src="image1.jpg" alt="Product Image"></td>
<td>S</td>
<td>400</td>
<td><button class="delete-btn">Delete</button></td>
</tr>
<tr data-group="1">
<td>M</td>
<td>400</td>
<td><button class="delete-btn">Delete</button></td>
</tr>
<tr data-group="1">
<td>X</td>
<td>500</td>
<td><button class="delete-btn">Delete</button></td>
</tr>
<tr data-group="2">
<td rowspan="2">Blue</td>
<td rowspan="2"><img src="image2.jpg" alt="Product Image"></td>
<td>S</td>
<td>800</td>
<td><button class="delete-btn">Delete</button></td>
</tr>
<tr data-group="2">
<td>M</td>
<td>500</td>
<td><button class="delete-btn">Delete</button></td>
</tr>
</tbody>
</table>
<script>
document.addEventListener('DOMContentLoaded', function() {
const tableBody = document.querySelector("#productTable tbody");
// Event delegation for delete buttons
tableBody.addEventListener('click', function(event) {
if (event.target && event.target.classList.contains('delete-btn')) {
deleteRow(event.target);
}
});
function deleteRow(button) {
const row = button.closest('tr');
const group = row.getAttribute("data-group");
const groupRows = Array.from(tableBody.querySelectorAll(`tr[data-group="${group}"]`));
// Bulunan gruptaki satır sayısı
const totalRows = groupRows.length;
// Satırın gruptaki sırası (indeksi)
const rowIndex = groupRows.indexOf(row);
// İlk satırın olup olmadığını kontrol et
const isFirstRow = rowIndex === 0;
// Satırı DOM'dan kaldır
tableBody.removeChild(row);
if (totalRows === 1) {
// Eğer sadece bir satır varsa ve silindiyse, tüm grubu kaldırmak yeterli
return;
}
if (isFirstRow) {
// Silinen satır grup içindeki ilk satırsa
const newFirstRow = groupRows[1]; // Silindikten sonra ikinci satır yeni ilk satır olacak
// İlk satırın rowspan hücrelerini al
const firstRowColorCell = row.querySelector('td[rowspan]');
const firstRowImageCell = row.querySelector('td[rowspan] + td');
if (firstRowColorCell && firstRowImageCell) {
// Yeni ilk satır için rowspan değerini güncelle
const newRowspan = parseInt(firstRowColorCell.getAttribute('rowspan')) - 1;
// Yeni ilk satırın renk ve resim hücrelerini oluştur
const colorText = firstRowColorCell.textContent;
const imageSrc = firstRowImageCell.querySelector('img') ? firstRowImageCell.querySelector('img').getAttribute('src') : '';
// Yeni ilk satırın renk hücresi
const newColorCell = document.createElement('td');
newColorCell.textContent = colorText;
newColorCell.setAttribute('rowspan', newRowspan);
newFirstRow.insertBefore(newColorCell, newFirstRow.firstChild);
// Yeni ilk satırın resim hücresi
const newImageCell = document.createElement('td');
newImageCell.innerHTML = `<img src="${imageSrc}" alt="Product Image">`;
newImageCell.setAttribute('rowspan', newRowspan);
newFirstRow.insertBefore(newImageCell, newFirstRow.children[1]);
// Orijinal ilk satırın hücrelerini kaldır
firstRowColorCell.remove();
firstRowImageCell.remove();
}
} else {
// Silinen satır grup içindeki ilk satır değilse
// Grubun ilk satırındaki rowspan değerini azalt
const firstRow = groupRows[0];
const firstRowColorCell = firstRow.querySelector('td[rowspan]');
const firstRowImageCell = firstRow.querySelector('td[rowspan] + td');
if (firstRowColorCell && firstRowImageCell) {
let currentRowspan = parseInt(firstRowColorCell.getAttribute('rowspan'));
firstRowColorCell.setAttribute('rowspan', currentRowspan - 1);
firstRowImageCell.setAttribute('rowspan', currentRowspan - 1);
}
}
}
});
</script>
</body>
</html>
Açıklamalar ve Yapılan Değişiklikler:
Event Delegation Kullanımı:
- Neden? Her "Delete" butonuna ayrı ayrı event listener eklemek yerine, event delegation kullanarak daha verimli bir yöntem benimsedik.
- Nasıl?
tableBody
üzerine bir click
event listener ekledik ve tıklanan elemanın .delete-btn
sınıfına sahip olup olmadığını kontrol ettik.
deleteRow
Fonksiyonunun Güncellenmesi:
- Grubu Belirleme: Silinecek satırın
data-group
özelliğini alarak hangi gruba ait olduğunu belirledik.
- Grup Satırlarını Alma: Belirlenen gruba ait tüm satırları bir diziye dönüştürdük.
- Satırın İlk Satır mı Olduğunu Kontrol Etme: Silinen satırın grubun ilk satırı olup olmadığını belirledik.
- Satırı Silme: Belirlenen satırı DOM'dan kaldırdık.
- Rowspan Yönetimi:
- Grubun İlk Satırı Silindiyse:
- Yeni ilk satırı belirledik.
- Eski ilk satırın
rowspan
hücrelerini (renk ve resim hücrelerini) yeni ilk satıra ekledik ve rowspan
değerini güncelledik.
- Eski ilk satırın
rowspan
hücrelerini kaldırdık.
- Grubun İlk Satırı Değilse:
- Grubun ilk satırındaki
rowspan
değerini bir azaltarak kalan satır sayısına uyum sağladık.
Dinamik Rowspan Güncelleme:
- Grubun İlk Satırı Silindiğinde: Yeni ilk satırın
rowspan
hücrelerini güncelleyerek tablo yapısını koruduk.
- Grubun Diğer Satırı Silindiğinde: Grubun ilk satırındaki
rowspan
değerini azalttık, böylece tablo yapısı bozulmadı.
CSS İyileştirmeleri:
- Buton Stilleri: Silme butonlarına daha belirgin bir görünüm kazandırmak için CSS ile stiller ekledik.
- Görseller: Ürün görselleri için
<img>
etiketi kullanarak tabloya görsel ekledik ve görsellerin genişliğini kontrol etmek için CSS'de max-width
özelliği kullandık.
Kodun Okunabilirliğini Artırmak İçin Düzenlemeler:
- Kodun daha anlaşılır ve bakımı kolay olması için düzenlemeler yaptık.
querySelector
ve querySelectorAll
kullanarak DOM elemanlarını daha etkin bir şekilde seçtik.
Kullanım Notları:
Test Edilmesi Gereken Senaryolar:
Grubun İlk Satırını Silmek:
- Grubun ilk satırındaki "Delete" butonuna tıklayın.
- Yeni ilk satırın
rowspan
hücrelerinin doğru şekilde güncellenip güncellenmediğini kontrol edin.
Grubun Ortasındaki Satırı Silmek:
- Grubun ortasındaki herhangi bir satırdaki "Delete" butonuna tıklayın.
- Grubun ilk satırındaki
rowspan
değerinin doğru şekilde azaldığından emin olun.
Grubun Son Satırını Silmek:
- Grubun son satırındaki "Delete" butonuna tıklayın.
- Grubun ilk satırındaki
rowspan
değerinin doğru şekilde azaldığından emin olun.
Grubun Tek Satırını Silmek:
- Grubun tek satırındaki "Delete" butonuna tıklayın.
- Grubun tamamen kaldırıldığını ve tablonun düzeninin bozulmadığını kontrol edin.
Bu güncellenmiş kod ile tablo içerisindeki herhangi bir "Delete" butonuna basıldığında tablo yapısının bozulmadan, rowspan
değerlerinin dinamik olarak doğru şekilde güncellendiğinden emin olabilirsiniz. Herhangi bir sorun yaşarsanız veya ek özellikler eklemek isterseniz, lütfen bana bildirin. Size yardımcı olmaktan memnuniyet duyarım!