@dodiş#32055 İki tip input grubunuz olacak; biri mevcut olan kayıtlar, diğeri ise yeni eklenecek olanlar için. İkisinin isimleri farklı olacak. Mevcut olan kayıtlar için olan input grubu şu şekilde olacak ve Delete düğmesi yerine silineceğini belirtebileceğimiz bir checkbox kullanacağız:
$locales = ['en', 'de'];
olmak üzere;
@foreach($optionValues as $value)
<div>
@foreach($locales as $locale)
<input type="text"
name="current_values[{{ $value->id }}][$locale]"
value="{{ $value->name[$locale] ?? null }}" />
@endforeach
<input type="checkbox" name="delete_values[]" value="{{ $value->id }}">
</div>
@endforeach
Yeni eklenecek olan kayıtların ismi ise current_values değil new_values olacak. İsimler size kalmış, ben ilk aklıma gelenleri verdim. Bu new_values ismi ile eklenen inputların ise delete_values şeklinde checkbox ile silme özelliği olmayacak onun yerine mevcuttaki gibi Delete düğmesi koyun, tıklayınca DOM'dan kaldırsın:
<div>
<input type="text" name="new_values[][en]" />
<input type="text" name="new_values[][de]" />
<button type="button">Delete</button>
</div>
Yani ekranda iki satır görüyorsak, üstteki düzenlenecek eski kayıt ve alttaki Add tuşu ile eklenmiş boş/yeni kayıt ise şöyle temel bir html olacak:
<form>
<fieldset>
<div> <!-- id:13 olan OptionValue -->
<input type="text" name="current_values[13][en]" value="Small" />
<input type="text" name="current_values[13][de]" value="Groß" />
<input type="checkbox" name="delete_values[]" value="13">
</div>
<div> <!-- Yeni boş satır -->
<input type="text" name="new_values[][en]" />
<input type="text" name="new_values[][de]" />
<button type="button">Delete</button>
</div>
</fieldset>
<input type="hidden" name="option_id" value="1" />
<button type="button">Add</button>
<button type="submit">Save</button>
</form>
Şimdi siz bu veriyi post ettiğinizde size iki tip input gelecek; biri current_value isimli varolan kayıtlar diğeri ise new_value adı altında yeni eklenecek olan kayıtlar. Ayrıca delete_values isimli silinecek OptionValue id'lerini içeren bir dizi. Kullanıcı mevcut kayıtlı olanları silmek isterse yanlarındaki checkbox'ı işaretleyecek. Yeni olanları kaldırmak isterse zaten o işlemi Delete düğmesi ile yaptırıyorsunuz. Controller tarafında:
$locales = ['en', 'de'];
$currentValues = $request->collect('current_values');
$newValues = $request->collect('new_values');
$deleteValues = $request->collect('delete_values')->values();
$option = Option::findOrFail($request->input('option_id'));
// Herhangi bir hataya karşı veri bütünlüğü bozulmasın diye işlemleri
// transaction içinde yapıyoruz:
DB::transaction(function() use ($currentValues, $newValues, $deleteValues, $option) {
// Güncellenecek olanlardan silinecek olanları temizleyip silinecekleri siliyoruz:
if($deleteValues->isNotEmpty()) {
$currentValues = $currentValues->reject(function($val, $key) use ($deleteValues) {
return in_array($key, $deleteValues);
});
OptionValue::destroy($deleteValues);
}
// Güncellenecek olanları bulup güncelliyoruz:
$option->optionValues()
->findMany($currentValues->keys())
->each(function($value) use ($currentValues) {
if(isset($currentValues[$value->id])) {
$value->name = $currentValues[$value->id];
$value->save();
}
});
// Yeni gelenleri ekliyoruz:
if($newValues->isNotEmpty()) {
$option->optionValues()
->saveMany(
$newValues->map(function($value) {
return new OptionValue([
'name' => $value,
]);
})
);
}
});