İnceleyebilmeniz için bir örnek:
https://codepen.io/ebykdrms/pen/LYrWEaY
İleride CodePen'den silme ihtimalime karşı kodları buraya da bırakıyorum:
<div id="steps">
<div class="step" data-step-name="step-1">
<label>
<span>Ad</span>
<input name="name" required />
</label>
<label>
<span>Soyad</span>
<input name="surname" required />
</label>
<label>
<span>E-posta</span>
<input name="email" />
</label>
<label>
<span>Cinsiyet</span>
<select name="gender" required>
<option value="" disabled selected>Seçiniz</option>
<option value="Kadın">Kadın</option>
<option value="Erkek">Erkek</option>
</select>
</label>
<button class="nextStepButton">
Devam
<i class="fa-solid fa-chevron-right"></i>
</button>
</div>
<div class="step" data-step-name="step-2" data-step-by="Erkek">
<h2 class="hello"></h2>
<label>
<span>Yaş</span>
<input name="age" />
</label>
<div class="stepButtons">
<button class="prevStepButton">
<i class="fa-solid fa-chevron-left"></i>
Geri
</button>
<button class="nextStepButton">
Devam
<i class="fa-solid fa-chevron-right"></i>
</button>
</div>
</div>
<div class="step" data-step-name="step-2" data-step-by="Kadın">
<h2 class="hello"></h2>
<label>
<span>Maaş</span>
<input name="salary" />
</label>
<div class="stepButtons">
<button class="prevStepButton">
<i class="fa-solid fa-chevron-left"></i>
Geri
</button>
<button class="nextStepButton">
Devam
<i class="fa-solid fa-chevron-right"></i>
</button>
</div>
</div>
<div class="step" data-step-name="step-3">
<div class="info"></div>
<div class="stepButtons">
<button class="prevStepButton">
<i class="fa-solid fa-chevron-left"></i>
Geri
</button>
<button class="nextStepButton">
Onayla
<i class="fa-solid fa-check"></i>
</button>
</div>
</div>
</div>
.step {
display:flex;
flex-direction:column;
padding:5px;
border:1px solid #ddd;
margin:10px;
max-width:300px;
opacity:0;
pointer-events:none;
transition:opacity .3s ease 0s;
}
.step.active {
pointer-events:auto;
opacity:1;
}
.step h2 {
padding:10px 5px;
font-weight:bold;
border-bottom:1px solid #ddd;
margin-bottom:5px;
}
.step label {
display:flex;
flex-direction:column;
padding:5px;
}
.step label input,
.step label select {
padding:5px;
margin-top:5px;
border:1px solid #ccc;
outline:none;
}
.step label input.required,
.step label select.required {
border-color:red;
}
.step .stepButtons {
display:flex;
flex-direction:row;
}
.step button {
cursor:pointer;
transition:opacity ease .1s;
}
.step button:active {
opacity:0.5;
}
.step .nextStepButton {
padding:10px;
margin:5px;
margin-top:20px;
border:1px solid #000;
background:#000;
color:#fff;
flex:2;
}
.step .prevStepButton {
padding:10px;
margin:5px;
margin-top:20px;
border:1px solid #000;
background:#fff;
color:#000;
flex:1;
}
.step .nextStepButton i,
.step .prevStepButton i {
margin:0 5px;
}
.step .info table {
margin:5px;
border:1px solid #ddd;
border-bottom:none;
width:calc(100% - 10px);
}
.step .info table tr td {
padding:5px;
border-bottom:1px solid #ddd;
}
function doValidation($wrapper) {
const $inputs = $wrapper.find("input[required],select[required]");
let validationStatus = true;
for(let i=0; i < $inputs.length; i++) {
const $input = $inputs.eq(i);
console.log($input.val())
if(!$input.val() || $input.val().trim()=="") {
validationStatus = false;
$input.addClass("required");
$input.one("input change", function() {
$(this).removeClass("required");
});
}
}
return validationStatus;
}
const $stepsWrapper = $("#steps");
const $steps = $stepsWrapper.find(".step").clone();
$(".step").remove();
const stepDatas = {};
const getStep = (stepName, stepBy=null) => {
const stepNameQuery = `[data-step-name="${stepName}"]`;
const stepByQuery = stepBy ? `[data-step-by="${stepBy}"]` : "";
return $steps.filter(stepNameQuery+stepByQuery);
}
const activeStep = ($step) => {
$(".step").removeClass("active").remove();
$stepsWrapper.append($step);
setTimeout(()=>{$step.addClass("active");},10);
}
$(document).on("click", ".step .nextStepButton", function(){
const $currentStep = $(this).closest(".step");
if(!doValidation($currentStep)) return;
const stepName = $currentStep.attr('data-step-name');
const stepBy = $currentStep.attr('data-step-by');
if(stepName=="step-1") {
stepDatas.name = $currentStep.find(`input[name="name"]`).val();
stepDatas.surname = $currentStep.find(`input[name="surname"]`).val();
stepDatas.email = $currentStep.find(`input[name="email"]`).val();
stepDatas.gender = $currentStep.find(`select[name="gender"]`).val();
const $targetStep = getStep("step-2", stepDatas.gender);
$targetStep.find('h2').text(`Merhaba ${stepDatas.name} ${stepDatas.surname} ${stepDatas.gender=="Kadın"?"Hanım":"Bey"}`);
activeStep($targetStep);
return;
}
if(stepName=="step-2") {
if(stepBy=="Kadın") {
stepDatas.salary = $currentStep.find(`input[name="salary"]`).val();
}
else {
stepDatas.age = $currentStep.find(`input[name="age"]`).val();
}
const $targetStep = getStep("step-3");
const name = `${stepDatas.name} ${stepDatas.surname}`;
const email = stepDatas.email;
const gender = stepDatas.gender=="Kadın" ? "Hanım" : "Bey";
const salary = stepDatas.salary ?? "";
const age = stepDatas.age ?? "";
$targetStep.find('.info').html(`
<table>
<tr><td>Üye</td><td>${name} ${gender}</td></tr>
<tr><td>E-posta</td><td>${email}</td></tr>
<tr><td>Maaş</td><td>${salary}</td></tr>
<tr><td>Yaş</td><td>${age}</td></tr>
</table>
`);
activeStep($targetStep);
return;
}
if(stepName=="step-3") {
alert("Tamam");
activeStep(getStep("step-1"));
return;
}
});
$(document).on("click", ".step .prevStepButton", function(){
const $currentStep = $(this).closest(".step");
const stepName = $currentStep.attr('data-step-name');
const stepBy = $currentStep.attr('data-step-by');
if(stepName=="step-2") {
activeStep(getStep("step-1"));
return;
}
if(stepName=="step-3") {
activeStep(getStep("step-2", stepDatas.gender));
return;
}
});
activeStep(getStep("step-1"));
SQL sorgunuzdan DISTINCT ifadesini kaldırıp deneyebilirsiniz.
array_merge() fonksiyonu ile tek satırda bu birleştirmeyi yapabilirsiniz.
Buradaki mantıkta dizyi ... operatörü ile açıyoruz ve ortaya çıkan dizileri birleştiriyoruz. PHP 7.4 veya üstü için geçerli
$arr = [
['2020-07','2020-08'],
['2020-09','2020-10'],
['2021-01','2021-02','2021-03']
];
$flattenArr = array_merge(...$arr);
$flattenArr dizisinin çıktısı:
['2020-07', '2020-08', '2020-09', '2020-10', '2021-01', '2021-02', '2021-03']
array_merge() fonksiyonu: https://www.php.net/manual/en/function.array-merge.php
spread operatörü (...): https://www.phptutorial.net/php-tutorial/php-spread-operator
LastInsertId() yerine lastInsertId() yazmanız gerekiyor olabilir.
Teşekkürler yalnız bir sorun var. Puanları eksik hesaplıyor. Bazı öğretmenler bir sınıf iki puan verdikleri için birini geçersiz sayıyor.
SQL sorgunuzda DISTINCT sinif dediğiniz için veritabanından aynı sınıf sadece 1 kez dönüyor olabilir.
<?php
$classes = [];
foreach($sql as $row) {
if(!isset($classes[$row['sinif']])) $classes[$row['sinif']] = 0;
$classes[$row['sinif']] += intval($row['soru1']) + intval($row['soru2']);
}
?>
<table>
<thead>
<th>
<td>SINIF</td>
<td>T_PUAN</td>
</th>
</thead>
<tbody>
<?php foreach($classes as $className => $totalPuan) { ?>
<tr>
<td><?=$className?></td>
<td><?=$totalPuan?></td>
</tr>
<?php } ?>
</tbody>
</table>
$birlesen = [];
foreach($yetkilerListe as $item) {
if(isset($yetkiler[$item])) $birlesen[$item] = $yetkiler[$item];
else $birlesen[$item] = ["view" => 0, "add" => 0, "edit" => 0, "delete" => 0];
}
let listType = $(".filter-action a.active").attr("data-value");
const $listTypeButtons = $(".filter-action a").on("click",function(){
listType = $(this).attr('data-value');
});
function Data_Send(query = '', page = 1) {
var action = 'UListPost';
var min_fiyat = $('#min_fiyat').val();
var max_fiyat = $('#max_fiyat').val();
var durumtag = Filtre('durumtag');
var kategori = Filtre('kategori');
var ozellik = Filtre('ozellik');
var goster = $("#UrunShow").val();
var Liste = listType;
$.ajax({
url:"/Data",
method:"POST",
dataType: "json",
data:{Liste, goster, query, page, action, min_fiyat, max_fiyat, durumtag, kategori, ozellik},
success:function(data){
$('.cikti').html(data.avg);
$('#sayfalama').html(data.pagination);
$('span#toplam').html(data.total);
}
});
}
function Data_Send(query = '', page = 1) {
var action = 'UListPost';
var min_fiyat = $('#min_fiyat').val();
var max_fiyat = $('#max_fiyat').val();
var durumtag = Filtre('durumtag');
var kategori = Filtre('kategori');
var ozellik = Filtre('ozellik');
var goster = $("#UrunShow").val();
var Liste = $(".filter-action a.active").attr("data-value");
$.ajax({
url:"/Data",
method:"POST",
dataType: "json",
data:{Liste, goster, query, page, action, min_fiyat, max_fiyat, durumtag, kategori, ozellik},
success:function(data){
$('.cikti').html(data.avg);
$('#sayfalama').html(data.pagination);
$('span#toplam').html(data.total);
}
});
}
O zaman post işleminden hemen önce input'ları seçmeli, boş olup olmadıklarını kontrol etmeli, boş olan varsa post işlemini yapmayıp input'lara bir uyarı amaçlı stillendirilmiş bir class atamalısınız.
Öncelikle input ekleme işlemi aşağıdaki gibi yapılıyor diyelim.
const $packetFrom = $('#packetFrom');
let counter = 1;
function addPacket() {
$packetFrom.append(`
<div class="row hidden_envelope" id="newPacket${counter}">
<input type="text" name="kullanici_id[]" required>
</div>
`);
counter++;
}
Bir doğrulama fonksiyonu oluşturalım. Bu fonksiyon,
- parametrede kendisine verilen elementin içindeki tüm input'ları kontrol etsin.
- required attribute'sine sahip input'ların boş olup olmadığını kontrol etsin.
- Eğer boş bir input'a rastlarsa ona "required" diye bir class atasın.
- Eğer boş bir input varsa fonksiyon false dönsün. Yoksa true dönsün.
function validation($wrapper) {
const $inputs = $wrapper.find("input[required]");
let validationStatus = true;
for(let i=0; i < $inputs.length; i++) {
const $input = $inputs.eq(i);
if($input.val().trim()=="") {
valitadionStatus = false;
$input.addClass("required");
$input.one("input", function(){ $(this).removeClass("required") });
}
}
return validationStatus;
}
Artık bu fonksiyonu submit işleminden önce çalıştırabiliriz. Eğer fonksiyon false dönerse submit yapmayız.
if(!validation($packetFrom)) {
// Doğrulama başarısız olduysa çalışacak kodlar...
return;
}
// Doğrulama başarılıysa çalışacak kodlar...
Ayrıca doğrulama başarısız olduğunda input'lara "required" diye bir class basılıyor. Bu class'a stil vererek zorunlu input'u kullanıcıya belirtebilirsiniz.