Ajax ile post etmekten bahsediyorsanız şöyle bir örnek vereyim:
<form id="userForm">
<input id="username" type="text" value="mek" />
<button>Gönder</button>
</form>
İçinde sadece 1 input olan formumuzu ajax ile post etmek istiyoruz.
var $userForm = $("#userForm");
var $usernameInput = $userForm.find("#username");
$userForm.on("submit", function(e) {
e.preventDefault(); // formun direkt gönderilmesini engelliyoruz.
if($userForm.hasClass("waiting")) return; // Eğer formda "waiting" adında bir class varsa hiçbir işlem yapılmasın.
if($usernameInput.val().trim()==="") { alert("Kullanıcı adı zorunludur!"); return; } // Kullanıcı adı boş gönderilemesin.
$userForm.addClass("waiting"); // artık ajax isteğinden sonuç bekleyeceğimiz için forma "waiting" class'ını ekleyebiliriz.
var username = $usernameInput.val().trim();
$.ajax({
url: "add_user.php",
type:"post",
data: { username: username },
success:function(response) {
// Örnek olarak gelen yanıta göre işlemler yapıyorum:
if(response.type==="error") alert(response.errorMessage);
else if(response.type==="success") {
alert(username+" adlı kullanıcı başarıyla eklendi.");
$usernameInput.val("");
}
else alert("Bilinmeyen bir sonuç döndü.");
// Artık yanıttan cevap döndüğüne göre formu "waiting" class'ından arındıralım.
$userForm.removeClass("waiting");
},
error: function() {
alert("Bir sorunla karşılaşıldı.");
$userForm.removeClass("waiting");
}
});
});
Böylece, form ajax ile submit edilirken yanıt dönene kadar form'a "waiting" class'ı atamış olduk. Butona tıklandığında da eğer formda "waiting" class'ı varsa işlem yapmamasını söyledik. Artık kullanıcı firebug üzerinden kodla müdahale etmediği sürece tekrar tekrar butona tıklanmasının bir anlamı olmayacak. Biz yine de CSS yardımıyla da butona basılmasını önleyelim.
* { margin:0; padding:0; box-sizing:border-box; outline:none; }
#userForm { display:flex; flex-direction:row; align-items:center; justify-content:center; }
#userForm #username { width:100px; height:30px; text-indent:10px; border:1px solid #777; border-radius:5px 0 0 5px; }
#userForm button { width:80px; height:30px; border:1px solid #777; background-color:#ccc; border-radius:0 5px 5px 0; border-left:none; transition:color ease .3s, background-color ease .3s; }
/* #userForm eğer .waiting class'ına sahipse butona tıklanamasın: */
#userForm.waiting button { pointer-events: none; background-color:#eee; color:#aaa; }
Yine waiting class'ının varlığına göre farklı stiller (loading gif'i göstermek gibi) yapılabilir.
Buton yerine span kullanıp yazıyı span içinde kullanırsanız yazıları da ortalamış olursunuz. Belki bir ihtimal ortalanmazsa span'a display:inline-block stili vermeniz gerekebilir.
Butonun kapsayıcısına position: relative; dedikten sonra butona şu stili verebilirsiniz:
position: absolute;
left:50%;
top:50%;
transform:translateX(-50%) translateY(-50%);
inline olarak stil verecekseniz:
<div class="container">
<div class="row mt-4" style="margin-bottom: 0 !important; margin-right: 0 !important; margin-left: 0 !important; width: 100%;">
<div class="col-12 align-items-center" style="width: 100%; position:relative;">
<button type="button" class="btn" style="position: absolute !important; left:50%; top:50%; transform:translateX(-50%) translateY(-50%);" onclick="location='videos.php'">VİDEO GALERİ</button>
</div>
</div>
</div>
Alternatif olarak flex tasarımın nimetlerinden yararlanın. position:absolute çoğunlukla başka problemler yaratabilir.
Ama flex tasarım bootstrap'ta asıl tepki verir bilemem. Denemek lazım.
Bu durumda kapsayıcıya stil vermeniz yeterli:
<div class="container">
<div class="row mt-4" style="margin-bottom: 0 !important; margin-right: 0 !important; margin-left: 0 !important; width: 100%;">
<div class="col-12 align-items-center" style="width: 100%; display:flex; align-items:center; justify-content:center;">
<button type="button" class="btn" onclick="location='videos.php'">VİDEO GALERİ</button>
</div>
</div>
</div>
Merhaba. Twitter front-end'i için react kullanıyor. Bu işlemi aslında react yapıyor. React'ın bunu yapmasının amacı da aslında bir şifreleme yapmaktan ziyade, bileşenlerin sınıflarının birbiriyle çakışmamasını sağlamak.
Eğer siz bunu mutlaka yapmak istiyorsanız bunu ancak sunucu tarafında yapabilirsiniz ancak bu da çok çetrefilli bir iş olur.
Mesela sunucu tarafında PHP kullanıyorsanız stil dosyalarınız dahil tüm dosyalarınızın .php uzantılı olması ve header'larla bunun istemcilere css dosyası gibi gönderilmesi gerekir. Aynı durum, elementleri sınıf adlarıyla seçtiğiniz js dosyaları için de geçerli.
Sonrasında her bir sınıf adına bambaşka bir php dosyasında oluşturacağınız rastgele değer atarsınız ve bu sınıfın kullanıldığı tüm html, css, js dosyalarına da bu değişkeni yazdırırsınız.
Yani yapılabilir mi? Evet. Ama çok uzun iş.
window["this"]["returnTree"]("false", 1);
satırı sorun çıkarıyor olmalı. window objesinin this diye bir key'i yok. Kodunuzun geri kalanını bilmiyorum ama bulunduğunuz blokta this ile returnsTree fonksiyonuna erişebiliyorsanız bunu doğrudan yapmalısınız:
this["returnTree"]("false", 1);
Eğer ajax'tan sınıf adı olarak size this geliyorsa, ajax'ın success() fonksiyonu içinde olduğunuz için burada this anahtar sözcüğü muhtemelen sizin kastettiğiniz this ile aynı değeri taşımıyor. Siz burada this kullandığınızda ajax'ın sınıfına ulaşıyorsunuz.
Çözüm olarak, eğer size this geliyorsa bunu hangi sınıfı kastediyorsanız onun değişkenini kullanarak çalıştırmalısınız. Mesela this aslında app anlamına geliyorsa bir if koşuluyla kontrol sağlamalısınız.
Bootstrap kullanmadığım için bilemiyorum ama şu şekilde bir çözüm olabilir gibi görünüyor:
Sanırım şu adreste ne yapabileceğiniz anlatılmış: getbootstrap.com/docs/4.6/utilities/flex/#align-items
stackoverflow.com'da da sizinkine benzer bir soru sorulmuş: How to make Bootstrap 4 cards the same height in card-columns?
Sorununuzu çözecek class adı sanıyorum ki: d-flex align-items-stretch
Şöyle bir örnek verilmiş:
<div class="container">
<div class="row">
<div class="col-lg-4 d-flex align-items-stretch">
<!--CARD HERE-->
</div>
<div class="col-lg-4 d-flex align-items-stretch">
<!--CARD HERE-->
</div>
<div class="col-lg-4 d-flex align-items-stretch">
<!--CARD HERE-->
</div>
</div>
</div>
Merhaba. Siz Products class'ınızın fetchProducts() fonksiyonunda asenkron bir işlem yapıyorsunuz. Bu nedenle siz console.log yaptığınız sırada henüz https://fakestoreapi.com/products adresine yaptığınız isteğe yanıt dönmemiş oluyor. Promise yardımıyla cevabın dönmesini beklemeli, ürünleri daha sonra yazdırmalısınız.
class Product {
constructor(id, title, price, image, description, category) {
this.id = id;
this.title = title;
this.image = new URL(image, import.meta.url);
this.price = price;
this.description = description;
this.category = category;
}
}
class Products {
constructor () {
this.products = []; // Kurucu fonksiyonlarda asenkron işlemlere izin verilmiyor.
}
fetchProducts() { // fetch() fonksiyonunu return etmem gerekiyor.
return fetch('https://fakestoreapi.com/products').then(res => res.json()).then(json => {
json.forEach(element => {
this.products.push(new Product(element.id, element.title, element.price, element.description, element.category))
});
});
}
}
const test = new Products();
new Promise(async function() { // fonksiyonumuz asenkron bir fonksiyon
await test.fetchProducts(); // önce fetchProducts() fonksiyonunun sonuç dönmesini bekliyoruz.
console.log(test.products); // sonra ürünleri konsola yazdırabiliyoruz.
});
Merhaba. Soru-cevap bölümünü kullanırken karşılaştığım önemli bir ihtiyaç var.
Biri benim adımı @ebykdrms diye etiketlediğinde bana bildirim gelmeli. Bir cevabımda anlaşılmayan bi'şey olduğunda kullanıcılar bunu bana ana soruya cevap olarak soruyorlar ve bana bildirim gelmediği için bu durumu kaçırıyorum. Böyle olunca kullanıcılar yeni sorularını boş yere yeni bir başlık açarak sormak zorunda kalıyorlar.
Eğer benim cevabıma karşılık yeni bir soru soracaklarsa bunu adımı etiketleyerek yapabilirler. Ben de bildirim aldığımda cevap verebilirim.
Kısacası, bir kullanıcı bir cevap yazarken veya cevap düzenlerken benim kullanıcı adımı etiketlerse bana bildirim gelmesi gerekiyor.
Merhaba,
örnek kodunuzu inceledim. countdownInterval değişkenini IftarSahurHesapla fonksiyonu içinde tanımladığınız için SetInterval fonksiyonunuzda aslında istediğiniz countdownInterval değişkenine değer atamıyorsunuz. Aslında yeni bir countdownInterval değişkeni oluşturuyorsunuz. Aynı şekilde StopInterval fonksiyonunuzda da countdownInterval değişkenine ulaşamadığınız için istediğiniz interval'i durduramamış oluyorsunuz.
countdownInterval değişkenini, 3 fonksiyonun da kapsayıcısı olan bir blokta tanımlamalısınız. Yani aslında function IftarSahurHesapla() satırınızın bir satır üstünde tanımlarsanız 3 fonksiyon da aynı değişkene ulaşabilecektir.
function IftarSahurHesapla(targetLocationId)
{
var countdownInterval = null;
var $test = $("#imsakiye").eq(0);
//...
yerine
var countdownInterval = null;
function IftarSahurHesapla(targetLocationId)
{
var $test = $("#imsakiye").eq(0);
//...
Bir de interval'i durdurduktan sonra yeniden başlatmalısınız. Yani
if(countdownInterval == null) {
SetInterval(BugunImsakDate, bugunAksamDate, yarinImsakDate, $countdown);
}
else{
StopInterval(countdownInterval);
}
yerine
if(countdownInterval == null) {
SetInterval(BugunImsakDate, bugunAksamDate, yarinImsakDate, $countdown);
}
else{
StopInterval(countdownInterval);
SetInterval(BugunImsakDate, bugunAksamDate, yarinImsakDate, $countdown);
}
veya SetInterval fonksiyonu her halükârda çalıştırılacağı için şu 2 satır da aynı işi görür:
if(countdownInterval) StopInterval(countdownInterval);
SetInterval(BugunImsakDate, bugunAksamDate, yarinImsakDate, $countdown);
Bir hata yapmış olmalısınız. Verdiğiniz linkte JS kodlarını şu şekilde düzenlediğimde bir sorunla karşılaşmadım:
$(function(){
IftarSahurVakti(9146);
$('#sehirler option[value="9402"]').prop("selected", true);
});
// global olarak interval'i tutacak bir değişken oluşturuyorum:
var countdownInterval = null;
function IftarSahurVakti(targetLocationId)
{
var $test = $("#imsakiye").eq(0);
$countdownName = $test.find("#test-countdown-name");
$countdown = $test.find("#test-countdown");
var now = new Date();
var tomorrow = new Date(now);
tomorrow.setDate(tomorrow.getDate()+1);
$.ajax({
type:"get",
url:"https://namaz-vakti-api.herokuapp.com/data?region="+targetLocationId,
success:function(response){
var todayImsak = response[0][1].split(":");
var todayAksam = response[0][5].split(":");
var tomorrowImsak = response[1][1].split(":");
var todayImsakDate = new Date(now.getFullYear(), now.getMonth(), now.getDate(), todayImsak[0], todayImsak[1], 0);
var todayAksamDate = new Date(now.getFullYear(), now.getMonth(), now.getDate(), todayAksam[0], todayAksam[1], 0);
var tomorrowImsakDate = new Date(tomorrow.getFullYear(), tomorrow.getMonth(), tomorrow.getDate(), tomorrowImsak[0], tomorrowImsak[1], 0);
if(now <= todayImsakDate) $countdownName.text("Sahura kalan süre:");
else if(now > todayImsakDate && now <=todayAksamDate) $countdownName.text("İftara kalan süre:");
else $countdownName.text("Sahura kalan süre:");
calculateCountdown(todayImsakDate, todayAksamDate, tomorrowImsakDate, $countdown);
// daha önce oluşturulmuş bir interval varsa onu kaldırıyorum.
if(countdownInterval) clearInterval(countdownInterval);
// Yeni oluşturacağım interval'i global interval değişkenime atıyorum.
countdownInterval = setInterval(function() {
calculateCountdown(todayImsakDate, todayAksamDate, tomorrowImsakDate, $countdown);
},1000);
}
});
}
function calculateCountdown(imsakDate, aksamDate, tomorrowImsakDate, $element) {
now = new Date();
var targetDate = null;
if(now <= imsakDate) targetDate = imsakDate;
else if(now > imsakDate && now <=aksamDate) targetDate = aksamDate;
else targetDate = tomorrowImsakDate;
var hours = parseInt((targetDate - now) / (1000 * 60 * 60) % 24);
var minutes = parseInt((targetDate.getTime() - now.getTime()) / (1000 * 60) % 60);
var seconds = parseInt((targetDate.getTime() - now.getTime()) / (1000) % 60);
$element.text(hours + " saat " + minutes + " dakika " + seconds + " saniye");
}