I am developing a website using php & MySQL, i have two functions
1. Grab data from database,
2. display HTML view codes with a link to view individual product details using $_GET variable.
Everything works perfectly. But i want the product details to load without the page being refreshed. I understand Ajax is capable in handling the task but i am not knowledgeable in Ajax. Any assistance would be appreciated.
Below are my codes example:
//Main product view
function product_view($product) {
$output = "";
$output = $output . '<li class="col-sx-12 col-sm-3">';
$output = $output . '<div class="product-container">';
$output = $output . ' product name';
$output = $output . '----';
$output = $output . '----';
$output = $output . '----';
$output = $output . '</div>';
$output = $output . '</li>';
return $output;
}
//Main product display
function get_products() {
require(ROOT_PATH ."inc/db_connect.php");
$sql = "SELECT * FROM products WHERE status='Active'";
$query = mysqli_query($db_connect, $sql);
return $query;
}
//View page
$products = get_products();
if (!empty($products)) {
foreach ($products as $product) {
echo product_view($product);
}
}
To use AJAX as suggested in some comments of your question, you can use this sample code in your client side:
$(document).ready(function(){
$.ajax({
url: 'products.php',
method: 'GET'
}).then(function(data){
for(int i=0; i < data.length; i++){
$('body').append('<li class="col-sx-12 col-sm-3"><div class="product-container>...'+data[i].attribute+'</div></li>');
//append all information that you need
}
})
});
at your backend you need to return the JSON so:
$products = get_products();
header('Content-Type: application/json; charset=utf-8');
echo json_encode($products);
Related
I try search value (ean) and if exist in database return title product assigned to this ean.
I've 2 tables:
products
product_details
in products table I have EAN and in product_details I've title.
products.id = product_details.product_id
View:
<div class="form-group">
<label><?= trans("search"); ?></label>
<input type="text" id="input_product_exist" class="form-control" placeholder="<?= trans("category_name"); ?>">
<div id="product_search_result" class="category-search-result"></div>
</div>
Script in view:
<script>
$(document).on("input", "#input_product_exist", function () {
var val = $(this).val();
val = val.trim();
if (val.length > 1) {
var data = {
"ean": val,
"sys_lang_id": sys_lang_id
};
data[csfr_token_name] = $.cookie(csfr_cookie_name);
$.ajax({
type: "POST",
url: base_url + "ajax_controller/search_products",
data: data,
success: function (response) {
var obj = JSON.parse(response);
if (obj.result == 1) {
document.getElementById("product_search_result").innerHTML = obj.content;
}
}
});
} else {
document.getElementById("product_search_result").innerHTML = "";
}
});
ajax_controller:
//search products
public function search_products()
{
$ean = $this->input->post('ean', true);
$products = $this->category_model->search_products_by_ean($product_ean);
$content = '<ul>';
if (!empty($products)) {
foreach ($products as $item) {
$content .= '<li>' . html_escape($item->name) . ' - <strong>' . trans("id") . ': ' . $item->id . '</strong></li>';
}
$content .= '</ul>';
} else {
$content = '<p class="m-t-15 text-center text-muted">' . trans("no_records_found") . '</p>';
}
$data = array(
'result' => 1,
'content' => $content
);
echo json_encode($data);
}
category_model.php
//search products by ean
public function search_products_by_ean($product_ean)
{
$this->db->select('products.id, product_details.title as name');
$this->db->join('product_details', 'product_details.product_id = products.id');
$this->db->like('name', clean_str($product_ean));
//$this->db->where('visibility', 1);
//$this->db->order_by('categories.parent_id');
$this->db->order_by('name');
$query = $this->db->get('products');
return $query->result();
}
Now I try start search: white page.
I check in log console:
jquery.min.js:4 POST https://thisismywebsite.com/ajax_controller/search_products 500
send # jquery.min.js:4
ajax # jquery.min.js:4
(anonymous) # add-product:1581
dispatch # jquery.min.js:3
q.handle # jquery.min.js:3
#update:
I think still I have any issue in step 3, category_model/search_products_by_ean
Here I build working query in phpmyadmin:
SELECT products.ean, product_details.title FROM products INNER JOIN product_details ON products.id = product_details.product_id;
and I get correct output:
#update
you can enable php errors with
error_reporting(E_ALL);
ini_set('display_errors', 1);
for view current error not 500
in ajax controller your must send $ean not $product_ean
//search products
public function search_products()
{
$ean = $this->input->post('ean', true);
// $products = $this->category_model->search_products_by_ean($product_ean);
$products = $this->category_model->search_products_by_ean($ean);//istead $product_ean
$content = '<ul>';
if (!empty($products)) {
foreach ($products as $item) {
$content .= '<li>' . html_escape($item->name) . ' - <strong>' . trans("id") . ': ' . $item->id . '</strong></li>';
}
$content .= '</ul>';
} else {
$content = '<p class="m-t-15 text-center text-muted">' . trans("no_records_found") . '</p>';
}
$data = array(
'result' => 1,
'content' => $content
);
echo json_encode($data);
}
I'm performing an Ajax request to a php file called save_tags.php this is the content of the file:
$id = $_POST['id'];
$name = $_POST['name'];
$type = $_POST['type'];
$tags = json_decode(stripslashes($_POST['tags'])); //Should be an Array but is a String...
$removeTags = json_decode(stripslashes($_POST['removeTags']));
//Type can be company, contact, column, supplement, programme.
if($type == 'company'){
$tagObject = new DirectoryCompany($id);
}elseif($type == 'contact'){
$tagObject = new DirectoryContact($id);
}elseif($type == 'column'){
$tagObject = new Column($id);
}elseif($type == 'supplement'){
$tagObject = new Supplement($id);
}elseif($type == 'programme'){
$tagObject = new Programme($id);
}elseif($type == 'list'){
$tagObject = new DirectoryContactList($id);
}
//Add and Remove Tags by looping through the Arrays.
foreach($tags as $tag){
$tagObject->addTag($tag, $id);
}
foreach($removeTags as $tag){
$tagObject->deleteTag($tag, $id);
}
//Get the tags associated with the object
$tagarray = $tagObject->getTags($id);
// Add Tags to All contacts on the list
$tagObject->getAllcontactsAndAddTags($id);
//Build HTML output
$output = "<ul>";
foreach($tagarray as $tag){
$output .= "<li>". $tag .'[X]'."</li>";
}
$output .= "</ul>";
echo $output;
?>
The purpose of the file is to apply the tags a user has checked and apply them to the object being worked on. Currently the above code is working, as in the tags are being applied and saved. however what is not working is that the $output variable is not being echoed and I can't figure out why.
Also when I check my console via the browser window I can see that there was a 500 error when requesting the file.
I'd appreciate any help.
<ul> this is tag html, check source page
and check alert(data)
$.ajax({
type: 'POST',
url: 'url',
data: { },
success: function(data) {alert(data)}
});
$output = "<ul>";
foreach($tagarray as $tag){
$output .= "<li>". $tag .'[X]'."</li>";
}
$output .= "</ul>";
echo $output;
if $tagarray is null echo = <ul></ul> invisible on the page
500 errors usually means that there's something wrong with your php code. Make sure that the code doesn't error out. Try to go to it in your browser and confirm that there are no errors.
First, try to put a few var_dumps here and there to see if you data is correct. An statuscode 500 means that there was most likely a fatal error in your script. This can be either in this php file or in one of your classes.
Most likely you will find the answer in a few minutes. To check if your script even works, try to echo some simple like "test" and comment everything else.
I have 2 pieces of code from a simple plugin that work independently from each other but don't work together.
if(isset($_POST['submit'])){
if(has_presence($_POST['product_name'])){
insert_row_into_table('CAL_products');
show_errors();
if(has_presence($wpdb->last_query)) {
echo "Update Successful";
} else {
echo "Update Failed";
}
} else {
echo "The field 'Product Name' cannot be blank.";
}
}
And this one
$results_array = $wpdb->get_results("SELECT * FROM wpCMS_CAL_products ORDER BY id ASC");
echo build_table_from_results_array($results_array);
The functions are included at the bottom.
The problem I have is that when the page loads there is no $_POST so it skips over the if statement and builds the table. This table builds fine.
When the form is submitted the if statements come back true and the new value is added to the database successfully, but then the table doesn't build until the page is refreshed. If the code to build the table is put at the top above the if statement it builds fine but doesn't include the new value until the page is refreshed.
Is it possible to add a new item to the database table before the results are populated to the HTML table?
function insert_row_into_table($table_name){
global $wpdb;
$prefix = $wpdb->prefix; //Define the wordpress table prefix
$table = $prefix . $table_name; //Build the table name
unset($_POST['submit']);
echo print_r($_POST);
$data = $_POST; //collect the data from post
$wpdb->insert( $table, $data ); //insert data into the table
}
function show_errors(){
echo $wpdb->show_errors();
echo $wpdb->print_error();
}
function has_presence($value) {
return isset($value) && $value !== "";
}
function build_table_from_results_array($results_array) {
$out = "";
$out .= "<table class=\"widefat\">";
$out .= "<thead>";
foreach($results_array[0] as $key => $element) {
if($key == "id") {
$out .= "<th class=\"id-column\">";
$out .= strtoupper($key);
$out .= "</th>";
} else {
$out .= "<th>";
$out .= ucwords(str_replace("_", " ", $key));
$out .= "</th>";
}
}
$out .= "</thead>";
$out .= "<tbody>";
$i = 0;
foreach($results_array as $key => $element){
if($i % 2 === 0) $extraclass= "alternate";
$out .= "<tr class=\"$extraclass\">";
$i++;
$extraclass="";
foreach($element as $subkey => $subelement){
$out .= "<td>$subelement</td>";
}
$out .= "<td>EDIT</td>";
$out .= "</tr>";
}
$out .= "</tbody>";
$out .= "</table>";
return $out;
}
A general pattern for this type of page is Post-Redirect-Get. You could, for instance, pull the if(isset($_POST['submit'])) block out into a separate file called processForm.php. The form's action parameter is changed to processForm.php. The form sends $_POST data to processForm which inserts the new database records, and processForm in turn redirects the user back to the original page which gets the results.
If you want a one-page solution using the above code, add this code at the very top of the file, before you output anything at all. This starts the output buffer, which is usually necessary if you want to use the header() command to redirect.
ob_start();
Then edit the if(isset) block:
if(isset($_POST['submit'])){
if(has_presence($_POST['product_name'])){
insert_row_into_table('CAL_products');
show_errors();
if(has_presence($wpdb->last_query)) {
echo "Update Successful";
header("Location: index.php"); //change index.php to the current page
//header("Location: ".$from); //or use a variable
} else {
echo "Update Failed";
}
} else {
echo "The field 'Product Name' cannot be blank.";
}
}
Finally, add this at the very end of the script to close the output buffer:
ob_end_flush();
Essentially, this code refreshes the page on success after the new entries are inserted into the database. This should allow your table to include the new records.
I'm fairly new to both PHP and Javascript, so please forgive my ignorance and poor use of terminology, but I'll do my best to explain exactly what I'm struggling to achieve.
I have information stored in a PHP array that I call to my index page using the function below (the code below is in a separate PHP file called articles.php that's included in my index.php) :
<?php
function get_news_feed($article_id, $article) {
$output = "";
$output .= '<article class="img-wrapper">';
$output .= '<a href="article.php?id=' . $article_id . '">';
$output .= '<div class="news-heading">';
$output .= "<h1>";
$output .= $article["title"];
$output .= "</h1>";
$output .= "<p>";
$output .= "Read more...";
$output .= "</p>";
$output .= "</div>";
$output .= '<div id="news-img-1">';
$output .= "</div>";
$output .= "</a>";
$output .= "</article>";
return $output;
}
$articles = array();
$articles[] = array(
"title" => "Andy at NABA",
"description" => "Docendi, est quot probo erroribus id.",
"img" => "img/gym-01.jpg",
"date" => "05/04/2013"
);
$articles[] = array(
"title" => "Grand Opening",
"description" => "Docendi, est quot probo erroribus id.",
"img" => "img/gym-01.jpg",
"date" => "05/04/2013"
);
?>
My index.php looks like the following minus some HTML that plays no role in this process:
<?php
include("inc/articles.php");
?>
<?php
$pageTitle = "Home";
include("inc/header.php");
?>
<section class="col-4 news">
<?php
$total_articles = count($articles);
$position = 0;
$news_feed = "";
foreach($articles as $article_id => $article) {
$position = $position + 1;
if ($total_articles - $position < 2) {
$news_feed .= get_news_feed($article_id, $article);
}
}
echo $news_feed;
?>
</section>
I am aiming to dynamically change the CSS Background-Image property of the div element with ID news-img-1 using Javascript.
I have tried such things as:
document.getElementById('news-img-1').style.backgroundImage = 'url('<?php $article["img"]; ?>')';
document.getElementById('news-img-1').style.backgroundImage = 'url('http://www.universalphysique.co.uk/' + '<?php $article["img"]; ?>')';
document.getElementById('news-img-1').style.backgroundImage = 'url('window.location.protocol + "//" + window.location.host + "/" + '<?php $article["img"]; ?>')';
.....but I'm getting nowhere!! My code in practise works because the following Javascript inserts an image correctly:
document.getElementById('news-img-1').style.backgroundImage = 'url("img/gym-01.jpg")';
Here is my site up and running, the images should be placed in the empty circles you'll see! Any help would be great, this ones tough for me!!
comparing the hard coded javascript to ones that don't work, I notice that you are not including the double-quotes around the <?php $article["img"]; ?> snippet. The hard coded one shows
= 'url("img/gym-01.jpg")'
but the ones with the php snippet will produce
= 'url(img/gym-01.jpg)'
so perhaps if you modify it to
document.getElementById('news-img-1').style.backgroundImage = 'url("'<?php $article["img"]; ?>'")';
OR
edit the get_news_feed function as follows:
replace these lines
$output .= '<div id="news-img-1">';
$output .= "</div>";
with
$output .= '<div class="news-img"><img src="' . $article["img"] . '"></div>' ;
and change your css like so:
article.img-wrapper {
position: relative;
}
div.news-img {
position: absolute;
top: 0;
z-index: -1000;
}
OR
Modify your get_news_feed function, change the statement for the <div id="news-img-1"> output to include a data-url attribute like:
$output .= '<div class="news-img" data-url="' . $article["img"] . '">';
Then add a jquery statement like:
$(".news-img").each( function() {
$(this).css("background-image", "url(" + $(this).data("url") +")" );
});
The jquery statement goes in a static js file as opposed to generating the script in php.
You need to remove the quotes from your PHP tags and see if it works!
Do it like this:
document.getElementById('news-img-1').style.backgroundImage = 'url(' + <?php $article["img"]; ?> + ')';
Hope it helps.
I am creating a site where users can upload there own background images, after upload they see each background they uploaded in a menu represented by a number, clicking on the number will in theory load in the new background, however I have noticed that does this calls in the view again as well (the view is already loaded from another function, is there a ways I can pass the data to the view without loading the view, can I do it with ajax? if so how?
My code currently
public function set_background() {
$this->load->model('image_model');
if($query = $this->image_model->get_background_by_id($this->uri->segments[3])) {
if($query) {
$data['new_background'] = $query;
}
}
$this->load->view('template/background-select', $data);
}
My Model:
public function get_background_by_id($background_id) {
$this->db->select('background_name');
$this->db->from('background');
$this->db->where('background_id', $background_id);
$query = $this->db->get();
return $query->result_array();
}
My View
<div id="background-select">
<?php
$count = 0;
if(isset($special)) {
foreach ($special as $row) {
$count ++;
print '<div class="select">';
print "<a class='background_btn' href='index.php/home/set_background/".$row['background_id']."'>$count</a>";
print '</div>';
if($count == 1) {
$background = $row['background_name'];
}
}
}
if(isset($generic)) {
foreach ($generic as $row) {
$count ++;
print '<div class="select">';
print "<a class='background_btn' href='index.php/home/set_background/".$row['background_id']."'>$count</a>";
print '</div>';
if($count == 1) {
$background = $row['background_name'];
}
}
}
if(isset($user_background)) {
foreach ($user_background as $row) {
$count ++;
print '<div class="select">';
print "<a class='background_btn' href='index.php/home/set_background/".$row['background_id']."'>$count</a>";
print '</div>';
if($count == 1) {
$background = $row['background_name'];
}
}
}
?>
</div>
<div id="wrapper" style=<?php echo"background:url(/media/uploads/backgrounds/".$background.");";?>>
The view gets loaded in originally here
public function index() {
// $this->output->enable_profiler(TRUE);
$data = array();
if($query = $this->category_model->get_all_online()) {
$data['main_menu'] = $query;
}
$this->load->model('image_model');
/*
* Sort out the users backgrounds, basically do a check to see if there is a 'special' background
* if there is not a 'special' background then IF the user is logged in and has a background of there
* own show that one, if not show a generic one, if they are not logged in show a bang one
*/
$image = array();
if ($query = $this->image_model->get_special_backgrounds()) {
$image['special'] = $query;
} elseif(!isset($image['special']) && !isset($this->session->userdata['user_id'])) {
if($query = $this->image_model->get_bang_background()) {
$image['generic'] = $query;
}
}
if(isset($this->session->userdata['user_id'])) {
if($query = $this->image_model->get_user_backgrounds($this->session->userdata['user_id'])) {
$image['user_background'] = $query;
}
}
$data = array_merge($data, $image);
$this->load->view('home/main_page.php', array_merge($data, $image));
}
Hope some can help thanks
This may be too much 'out of the box' and not faithful enough to your code to be useful, but here goes:
Given the description of what the code is supposed to do, you could always have your PHP output the list of background images into a JavaScript snippet on the view (To pseudocode very roughly: <script><?php echo phpArrayToJavaScriptArray($images, $varName); ?></script>), then have javascript dynamically create your list of background-changing links client-side and each click just change the background image with JavaScript (<a href="javascript:changeBackgroundImage('url')"> setting document.getElementById('wrapper')'s background image).
No Ajax necessary.
With that concept in mind, the simplest adjustment to your code I can concot in a hurry is this:
Instead of passing the IDs to the view, pass the URLs to the view (you'd have to adjust your querying accordingly, of course), and change:
"<a
class='background_btn'
href='index.php/home/set_background/" . $row['background_id'] . "'>"
. $count
. "</a>"
to something like
"<a
class='background_btn'
href=\"javascript:changeBackgroundImage('"
. htmlspecialchars($row['background_url'], ENT_QUOTES, 'utf-8')
. "')\">"
. $count
. "</a>"
The JavaScript function would be something like this:
<script language="javascript">
function changeBackgroundImage(url) {
var wrapper = document.getElementById('wrapper');
wrapper.style = "background-image:url(" + url + ")";
}
</script>
Mind, the lot of that is still pseudocode, I doubt it'll run out of the box, my JS is very rusty, and this is meant to be an idea-share more than an outright fix. :) But I hope that it'll help you tackle your issue!
Is that kind of approach feasible for you?