How to build an Ajax search bar with multiple keywords? - javascript

I tried to build an ajax search bar. It works fine with a single keyword but I can't manage to make it work with 2 keywords...
I was thinking about parsing the data in the input field but my knowledge is limited and I didn't manage to find the solution.
Any ideas?
In my main.js I get the data from the input like this:
var kwVal = $(this).val();
if (kwVal.length < 3){
$(".clothes-container").html("");
}
else {
$.ajax({
"url": "ajax/getclothes.php",
"type": "GET",
"data": {
"kw": kwVal
}
})
And this is my sql request
$sql = "SELECT title, description, picture
FROM outfit
WHERE type LIKE :keyword OR
color LIKE :keyword OR
brand LIKE :keyword OR
material LIKE :keyword";
Thanks a lot.

Something like this? Of course, all the SQL literals and strings must be properly escaped (especially the $keyword).
// keywords extracted from user's input
$keywords = array('blue', 'jeans');
// columns, that You want to match against
$columns = array('type', 'color', 'brand', 'material');
// we build the condition for each keyword
$word_conditions = array();
foreach ($keywords as $keyword) {
$conditions = array();
foreach ($columns as $column)
$conditions[] = $column.' LIKE \'%'.$keyword.'%\'';
$word_conditions[] = '('.implode(' OR ', $conditions).')';
}
// we build the query, that requires every item to have all the keywords
$query = 'SELECT * FROM ... WHERE '.implode(' AND ', $word_conditions);

Suppose your keywords are saperated by 'Space' like "ABC DEF GEH".
than on server you can do is,
$keywords = explode(" ", $_POST['data']); //Make it array;
$string = implode(",", $keywords);
$sql = "SELECT title, description, picture
FROM outfit
WHERE type in (".$string.") OR
color in (".$string.") OR
brand in (".$string.") OR
material in (".$string.")";

Related

How to create alphabet and Input Search in CodeIgniter 4

I am new in codeigniter4 I want to filter the list by alphabet and search input. On click of each alphabet, it should sort the list according to the alphabet. In my database product list is stored in JSON array format.
The below image to explain better
For example: If you click on "A" then it will display a list starting with "A" Like ( Apple, Airplane, Adidas ), etc. And the case should be the same when you input in the search input box.
Below is the render function in the controller which is searching particular objects of the JSON array.
public function loadRecord(){
$request = service('request');
$searchData = $request->getGet();
$search = "";
if(isset($searchData) && isset($searchData['search']))
{
$search = $searchData['search'];
}
$model = new PageModel();
if($search == ''){
$paginateData = $model->paginate(5);
} else {
$db=\Config\Database::connect();
$product_array = [];
$query = $db->query('
SELECT description->"$.products_title" as product_titles
FROM iolt_pages
WHERE description->"$.products_title"
LIKE "%'.$search.'%"
AND pg_id=33'
);
$result = $query->getResult();
$productData=json_decode($result[0]->product_titles);
for($i=0;$i<count($productData);$i++)
{
if(strpos($productData[$i], $search) !== false)
{
$product_array[]=$productData[$i];
} else {
//echo "Word Not Found!<br>";
}
}
print_r($product_array);
}
}
You need something like this:
public function loadRecord() {
$request = service('request');
$searchData = $request->getGet();
if(isset($searchData) && isset($searchData['search']))
{
$search = $searchData['search'];
}
$model = new PageModel();
if(!empty($search)) {
$model->like('description', $search, 'after');
}
$data = $model->asArray()->paginate(5);
if(!empty($data)) {
die('word not found');
}
dd($data);
}
There's no need for json for the filter, you can filter that with the like statement and you can keep adding to the model object with if statements and just run the query in the end. This way you don't need to have one query for all records and another for the filter, just add the filter if needed.
Also if you need an array instead of object you can do so in the model by changing the return type, this you can override by using the asArray() method that will return all data as an array. This way you don't need to iterate all the data to transform it from object to array.

Writing SELECT query to loop all the items in a list of items

I have situation where I need to write a sql select query which is technically need to be repeated to all the items in a list.
For example, say I have list like this,
list =[ { item_1: value_11,
item_2: value_12,
item_3: value_13,
item_4: value_14'
},
{ item_1: value_21,
item_2: value_22,
item_3: value_23,
item_4: value_24,
},
{ item_1: value_31,
item_2: value_32,
item_3: value_33,
item_4: value_34,
},
......
];
Now I need to write a SELECT query to get all the related records for each of the item, something like,
//for each item
SELECT * FROM tbl WHERE tbl.fld1 = list[0].item_1 AND tbl.fld2 = list[0].item_2 AND tbl.fld3 = list[0].item_3 AND tbl.fld4 = list[0].item_4;
Is it possible to write a single query for the same within SQL statement (kind of loop) or else does it need to be repeated from the coding side so it will call the db for each items separately.
Please help,
Thank You in advance
As #draz already commented you need to loop over the list to dynamically create the sql statement. You can loop over it in your code and generate a single sql statement that can be send to the database once.
A simple but probably not the nicest idea would be something like:
sql_select = "SELECT * FROM tbl WHERE";
first_item = true;
for (element in list) {
sql_select = (first_item) ? sql_select : sql_select + " OR";
fist_item = false;
where_clause = ` (tbl.fld1 = ${element.item_1} AND tbl.fld2 = ${element.item_2} AND tbl.fld3 = ${element.item_3} AND tbl.fld4 = ${element.item_4})`;
sql_select.concat(where_clause);
}

How to solve "notice array to string conversion in C" error in php and javascript?

So I am trying to send the "id" of a selected row in datatable in javascript to a php page so I could delete it from database.
var ids = $.map(table.rows('.selected').data(), function (item) {
return item[0] });
the variable "ids" is sent by post method
$.post( "deleterow.php", { v1: ids });
but it didn't worked so i try to see the response from post method and it says
"notice array to string conversion in C on line ... "
the line is of php page where i am writing the delete query
$id = $_POST["v1"];
$query = "DELETE FROM `package` WHERE `id` = '$id'";
The whole php page works fine when trying with other values.
Because you send an array here:
$.post( "deleterow.php", { v1: ids });
so v1 contains an array of elements. But in your php code you treat it as a single element:
$id = $_POST["v1"];
Hence the notice array to string conversion.
If you send an array of elements, you have to get it as an array and treat is as an array. To create a correct SQL string you should append each ID, like this:
$ids = json_decode($_POST["v1"]);
$query = "DELETE FROM `package` WHERE";
$first = true;
foreach ($ids as $id) {
if ($first) {
$first = false;
} else {
$query += " OR";
}
$query += " `id` = '$id'"
}
This way you loop the array and append a id = ID for each array element.
Now, this is important, this code is prone to SQL injection, a really bad security problem. Read this to get more info about this: How can I prevent SQL injection in PHP?

AngularJS grouping values and adding them together in ng-repeat

I'm trying to create a total sum of a group in AngularJS. I'm using http to get the results into a html table :
$http({method: 'GET', url: urlpurchasing}).success(function(data) {
$scope.purchasing = data;
})
Which gives the below result :
I want to make a new column called "total stock" and add all of the "Quantity sold" for each group, so for all which have a Desc of the same value i want there "quantity sold" to be added up. For example, the 3 purple rows at the bottom would have "607" in there "total sold" column.
I tried to loop through the data with an angular for-each and add each one up but this involves creating a second array and any kind of filter or change in the main table changes the indexes and it mixes up. Appreciate any assistance.
edit
This is what i have so far (but the totals are incrementing each time :
$http({method: 'GET', url: urlpurchasing}).success(function(data) {
var t = 0;
angular.forEach(data, function(obj){
if($scope.code == obj.GroupCode){
}
else
{
$scope.code = obj.GroupCode;
t = 0;
}
t = (t + parseInt(obj.QuantitySold));
obj.total = t;
});
$scope.purchasing = data;
})
Here is the PHP :
<?php
require_once('sqlconnect.php');
$sqlQuery = "select StockCode,Description,QuantityInStock,QuantitySold,NetAmountSold,GroupCode,color from purchasing order by Description desc";
$result = $unity_connection->query($sqlQuery);
$json1 = array();
while($rows = mysqli_fetch_assoc($result)){
$json1[] = $rows;
}
echo json_encode($json1);
?>
I don't use MySQL, but standard SQL should do the trick here:
SELECT
purchasing.stockcode,
purchasing.description,
purchasing.quantityinstock,
purchasing.quantitysold,
purchasing.netamountsold,
purchasing.groupcode,
purchasing.color,
desc_summary.totalstock
FROM
purchasing join (select description, sum(quantitysold) as TotalStock from purchasing group by descrption) desc_summary on purchasing.description = desc_summary.description
ORDER BY purchasing.description DESC
You can achieve this by multiple ways, either to create extra variable for total in your controller scope or directly in your data\json as well., or by extending $scope.purchansing
OR, if you don't want any further $scope property, then you can invoke a function at run time to calculate the total for each group..
See this fiddle in which I tried with run time function which checks for group total per group.
Updated fiddle to extend your scope data in controller.

PHP: Disambiguating Column Names on Join Using Mysqli

This issue relates to losing data due to conflicting column names in a JOIN. Specifically, using PHP's mysqli and returning the data as a JSON object.
Let's say you have two tables that are related to each other using another lookup table.
For example, let's say you have users:
user
id name
---------------------
1 John Thomas
and recipes:
recipe
id name
---------------------
15 Fried Chicken
and ownership/rights to these recipes is defined in a lookup table:
user_recipe
user recipe
--------------
1 15
So, in this case, John Thomas has rights to view the Fried Chicken recipe.
Let's say you want to get a record with all of this data, so you construct a query like this:
SELECT *
FROM `user_recipe`
INNER JOIN `recipe`
ON `recipe`.id = `user_recipe`.recipe
INNER JOIN `user`
ON `user`.id = `user_recipe`.user;
Now let's also say you're using PHP's mysqli object. Then you use json_encode and hand the data back to your javascript. Great! Except that the data looks like this:
{
id:15,
user:1,
recipe:15,
name:"Fried Chicken"
}
How do you resolve this issue? You could use aliases, but what if there are a lot more columns and you don't want to have to write them all out?
If you make use of mysqli's method fetch_fields, you can separate the data back into groups, or add prefixes to the field names, or whatever else you'd like.
Here's an example:
$sql = '...QUERY...';
$mysqli->query($sql);
$fields = $result->fetch_fields();
$output = array();
while ($row = $result->fetch_array())
{
$newoutput = array();
foreach($row as $key=>$value)
{
if (is_numeric($key))
$newoutput[$fields[$key]->table][$fields[$key]->name] = $value;
}
$output[] = $newoutput;
}
$result->free();
echo json_encode($output);
After doing that, the data will be handed back in this format:
{
user_recipe:{
user:1,
recipe:15
},
user:{
id:1,
name:"John Thomas"
},
recipe:{
id:15,
name:"Fried Chicken"
}
}
Of course, you can build the JSON object however you'd like.

Categories