Merhabalar, bugün beraber autocomplate yapımını işleyeceğiz. Yazının sonunda istersek autocomplate ile çıkarılan sonuçlara ikon ya da resim ekleyebileceğiz. Hemen konuya geçiyorum.

Öncelikle sıfırdan autocomplate yazmayacağız. Daha önce yazılmış olan bir plugin üzerinde değişiklikler yapıp sonra da veritabanımızdan getirdiğimiz verileri bu pluginle göstereceğiz.

Bahsettiğim pluginin adı MagicSuggest. Hemen şuradan github sayfasına ulaşabilirsiniz. Buradanda benim github hesabımdan projenin kodlarına ulaşabilirsiniz.

Hemen bir index.php oluşturarak işe başlayalım. Bu sayfada jQuery, Bootstrap ve MagicSuggest’i sayfaya dahil edelim daha sonra da magicsuggest ID’sine sahip bir div oluşturalım ardından da autocomplate için gerekli olan MagicSuggest kodlarını script taglarının içine yazalım. Sonuç olarak şöyle bir sayfamız olacaktır.

index.php

<!DOCTYPE HTML>
<html>

<head>
	<link rel="stylesheet" href="assets/css/magicsuggest-min.css">
	<link rel="stylesheet" href="assets/css/main.css">
	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">

</head>

<body>
	<h1 class="text-center">JQuery ile Autocomplate</h1>
	<hr class="mb-5">
	<center>
		<div class="w-50">
			<div id="magicsuggest"></div>
		</div>
	</center>
</body>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js" integrity="sha512-bLT0Qm9VnAYZDflyKcBaQ2gg0hSYNQrJ8RilYldYQ1FxQYoCLtUjuuRuZo+fjqhx/qtq/1itJ0C2ejDxltZVFg==" crossorigin="anonymous"></script>
<script src="assets/js/magicsuggest-min.js"></script>

<script>
	$base_url = window.location.origin + "/autocomplate/"; //Base URL. E.g https://hasanberkm.com/autocomplate
	$ms = ""; //For MagicSuggest

	//Starting Magicsuggest Plugin
	//The search bar will be automatically added to Magicsuggest
	$(function() {
		$ms = $('#magicsuggest').magicSuggest({
			data: 'api/transactions.php', //API URL
			method: "post", //Method
			allowDuplicates: false, //Disallow re-enter the same entry multiple times.
			allowFreeEntries: false, //Don't let the user enter a value other than the recommended values
			maxSuggestions: 2, //How many values at most should be displayed in the textarea?
			noSuggestionText: "Eşleşen Sonuç Bulunamadı.", //Use this attribute to show a message when there are no suggestions.
			placeholder: "Bir Ürün Arayın...", //Use this attribute to show a placeholder in MagicSuggest textarea.
			minChars: 2, //Minimum number of characters to enter

			//Sets the helper message for input that is too short of the minChars attribute.
			minCharsRenderer: function(v){
				return 'Lütfen en az ' + v + " karakter daha girin.";
			},
			
			//Render the plugin.
			//'data' variable in the function holds the result.
			renderer: function(data) {
				return '<a href="' + $base_url + 'result.php?s=' + data.name + '"><div class="result">' +
				'<div class="name" style="width: calc(100% - 102px); float: left; height: 50px;"><img src="assets/uploads/' + data.image + '" class="result_image"/>' + data.name + '</div>' +
				'<div class="wishlist" style="display: inline-block; font-size: 11px; float: right; height: 50px; text-align: center; line-height: 50px;color: #d1d1d1"></div>' +
				'<div style="clear:both;"></div>' +
				'<div style="clear:both; border-bottom: 1px solid #f5f5f5"></div>' +
				'</div></a>';

				data = "";
			}
		});

		//Redirect to Result Page with the searched word when ENTER key is pressed.
		$($ms).on('selectionchange', function(){
			window.location.href = $base_url +  'result.php?s=' + $ms.getData()[0].name;
		});
	});
</script>
</html>

Kısaca burayı anlatmak gerekirse:
1. head etiketleri arasında bizim için gerekli olan css dosyalarını ekledik,
2. body etiketleri arasında ise bir başlık ekledik ve altına da MagicSuggest plugininin textbox’ı basacağı #magicsuggest divini oluşturduk,
3. script tagları arasına ise bizim için gerekli olan js dosyalarını ve MagicSuggest kodlarını ekledik.

Burada yazdığımız js kodlarını inceleyelim biraz.
$base_url değişkeni bizim bulunduğumuz sunucunun ana URL’sini tutacak.
$ms değişkeni ise bizim magicsuggest fonksiyonumuzu barındıracak çünkü bu fonksiyonu az sonra yazacağım kod içerisinde kullanmamız gerekecek.

MagicSuggest fonksiyonunun içindeki attribute’lere bakalım birazda…

data: ‘api/transactions.php’, //Aranacak kelimeyi göndereceğimiz URL
method: “post”, //Gönderme işlemini yaparken kullanacağımız metot.
allowDuplicates: false, //Kullanıcının aynı veriyi birden fazla girmesini engeller.
allowFreeEntries: false, //Kullanıcı girilen kelimeyle eşleşen sonuçlar dışında bir veri eklemesini engeller. Çünkü aslında bu plugin inputbox içine girilen kelimeleri tag olarak ekleyen bir combobox plugini fakat ben js dosyasında değişiklik yaparak hem combobox özelliğini textboxa çevirdim hemde girilen kelimeyi tag olarak eklemeden kelimeyi result.php’ye yönlendiriyorum.
maxSuggestions: 2, //Girilen kelimeyle eşleşen verilerin maksimum kaç tanesinin gösterileceğini belirler.
noSuggestionText: “Eşleşen Sonuç Bulunamadı.”, //Eğer girilen kelimeyle eşleşen bir sonuç yoksa ekrana basılacak olan string.
placeholder: “Bir Ürün Arayın…”, //Textbox’a veri girilmediğinde yazacak olan string.
minChars: 2, //Textbox’a en az kaç karakter girdikten sonra sonuçlar çıkarılacağını belirler.
minCharsRenderer: function(v){
return ‘Lütfen en az ‘ + v + ” karakter daha girin.”;
}, //minChars attributesinde belirlediğimiz minimum karakterden daha az karakter içeren bir metin girildiğinde ekrana basılacak metin.

renderer: function(data) {
   return '<a href="' + $base_url + 'result.php?s=' + data.name + '"><div       
   class="result">' + '<div class="name" style="width: calc(100% - 102px);
   float: left; height: 50px;"><img src="assets/uploads/' + data.image + '"
   class="result_image"/>' + data.name + '</div>' + '<div class="wishlist"
   style="display: inline-block; font-size: 11px; float: right; height:
   50px; text-align: center; line-height: 50px;color: #d1d1d1"></div>' +
   '<div style="clear:both;"></div>' + '<div style="clear:both; border
   bottom: 1px solid #f5f5f5"></div>' + '</div></a>';
   
   data = "";
}//data attributesinde belirlediğimiz URL'ye post ettikten sonra verileri textbox'un altında sıralayacak olan attribute.

Son olarakta eğer enter tuşuna basarsak seçilen itemi result sayfasında aratalım. Bunun içinde şu kodu yazabiliriz.

$($ms).on('selectionchange', function(){
   window.location.href = $base_url +  'result.php?s='+$ms.getData([0].name;
});

Frontend kısmını bitirdik şimdi sırada backend kısmı var. Öncelikle veritabanına bağlanabilmek için gerekli PDO yapısını kuralım. db.php dosyasının içine şu kodları yazalım (benim db.php dosyam autocomplate>api dosyasının içinde):

db.php

<?php
	//Connecting the database 
	$host = "localhost"; //Server where the database is located
	$db="autocomplate"; //The database name
	$user="root"; //The Database Username
	$pw=""; //The Database password
	$charset="utf8"; //You required a charset for right CRUD process. you can search the internet for character sets that support your language

	$pdo = new PDO("mysql:host=$host;dbname=$db;charset=$charset", $user, $pw); //Database connection
	$pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );

	//Bypass Access Control Allow Origin Error
	header("Access-Control-Allow-Origin: Access-Control-Allow-Origin: *");
?>

Buradaki kodları daha önceki yazılarımda açıklamıştım. Dilerseniz önceki bloglarıma bakabilirsiniz 🙂

Şimdi de bir kelime girdiğimizde girilen kelimenin post edildiği transactions.php dosyasına bakalım (Bu da db.php ile aynı klasörde).

transactions.php

<?php
include_once("db.php");

$sql = $pdo->prepare("SELECT name, image FROM products WHERE name LIKE ?");
$sql->execute([ "%".$_POST["query"]."%" ]);

$data = [];

foreach ($sql as $s) {
   array_push($data, $s);
}

echo json_encode( $data );
?>

Burada önce db bağlantımızın olduğu dosyayı include ettik sonrasında ise SQL kodumuzu yazdık. Bu SQL sorgusuyla birlikte PDO ile LIKE kullanımını da görmüş olduk. DB’de aranacak kelimenin başına ve sonuna yüzde(%) işareti koyduğumuzda veritabanında karşılaştırılan ilgili fieldin herhangi bir yerinde girilen değerin geçmesi halinde o satırı al demiş olduk sonra da execute içerisinde aranacak kelimeyi yüzde işaretleriyle göndererek sorgumuzu çalıştırdık. Ardından $data adında bir array oluşturarak foreach ile DB’den gelen bütün verileri içine bastık. En son olarak bu arrayi json_encode() metoduyla JSON formatında bastırdık.

Buraya kadar yaptığımız şeyler şunlar: index dosyamızda arama yapacağımız textbox’ı MagicSuggest kullanarak oluşturduk ve arayacağımız kelimeyi veritabanına gönderip sonucu alacağımız transactions.php ve db.php dosyalarını oluşturduk. Aslında yazıyı burada bitirebililirim fakat son olarak az önce yazdığımız js kodundaki enter tuşuna basınca kelime ile ilgili verileri listeleyebileceğimiz ya da sonuçlardan birine tıkladığımızda açılacak olan result.php sayfasını da yaparak yazıyı bitireceğim.

<?php
if(isset($_GET["s"]) && strlen($_GET["s"]) > 0)
{
	?>
	<!DOCTYPE HTML>
	<html>

	<head>
		<link rel="stylesheet" href="assets/css/magicsuggest-min.css">
		<link rel="stylesheet" href="assets/css/main.css">
		<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
	</head>

	<body>
		<h1 class="text-center mb-5 mt-5"><u class="text-primary"><?= $_GET["s"]; ?></u> ile ilgili sonuçlar</h1>
		<div class="container">
			<div class="card-deck">
				<?php
				include_once("api/db.php");

				$stmt = $pdo->prepare("SELECT * FROM products WHERE name LIKE ?");
				$stmt->execute([ "%". ($_GET["s"]=='all'?'':$_GET["s"]) ."%" ]);

				foreach ($stmt as $search)
				{
					?>
					<div class="card">
						<img class="card-img-top" src="assets/uploads/<?= $search['image']; ?>" alt="Card image cap">
						<div class="card-body">
							<h5 class="card-title"><?= $search['name']; ?></h5>
							<p class="card-text">Stoktaki Ürün: <?= $search['quantity']; ?></p>
						</div>
						<div class="card-footer">
							<small class="text-muted">Eklenme Tarihi: <?= date("d.m.Y", strtotime($search['created_date'])); ?></small>
						</div>
					</div>
					<?php
				}
				?>
			</div>
		</div>
	</body>
	</html>
	<?php
}
else
{
	echo "Bir Sorun Oluştu.";
}
?>

Son olarak bu sayfada ise önce bir GET işlemi yapılmış mı yapıldıysa içi boş mu dolu mu diye bakıyoruz ve eğer boşsa Bir Sorun Oluştu hatasını döndürüyoruz ekrana. Eğer koşullarımız yerine getirildiyse ekrana ilk önce aranan kelimeyi basıyoruz ve ardından ile ilgili sonuçlar yazısını ekliyoruz.
Daha sonra ise db dosyamızı include ederek transactions.php dosyamızda yazdığımız SQL sorgumuzu aynen çalıştırıyoruz. istersek o sayfayı include ederek bir değişkene de atabilir ve o değişken üzerinden foreach yapabilirdik.

Ve son olarak foreach ile verilerimizi döndük ve Bootstrap içerisindeki card classını kullanarak güzel bir tasarımla ekrana verilerimizi bastık.

Evet bu yazımızda autocomplate nasıl yapılır hatta istersek içerisine nasıl görsel ekleyebiliriz sorusunun cevabını aradık. İndex dosyamızda MagicSuggest’in bir attributesi olan renderer’in içinde istersek sadece yazıyı istersekte bizim yaptığımız şekilde görselde ekleyebileceğimizi gördük. Bir sonraki blogumda görüşmek üzere 🙂