getProductListJSON need more data - magento

There is a part of the code that calls the getProductListJSON javascript function that looks like this
$.getJSON(storeRootUrl + "jsoncatalog/product/list/id/"+id, function(jsonObj) {
renderProductList(jsonObj,sid);
});
It returns the image, product name, description and id.
I would like it to return a bit more, like the type of product, as in "simple, configurable, etc"
Based on the layout:
<jsoncatalog_product_list>
<reference name="content">
<block type="paypal_catalog/json_product_list" output="toHtml" name="product_list"/>
</reference>
</jsoncatalog_product_list>
Looking at app\code\community\Paypal\Catalog\Block\Json\Product\List.php (hopefully I am looking in the right place), I can see the following code, wich I assume returns the data.
public function _toHtml()
{
try {
$array = array();
$category = Mage::registry('pp_current_category');
if (!is_null($category)) {
$array = Mage::helper('paypal_catalog')->getProducts($category->getId());
$this->setCurrenCategoryKey($category->getId());
} else {
$array = array('category' => '', 'items' => array());
}
return Mage::helper('core')->jsonEncode($array);
} catch (Exception $e) {
Mage::logException($e);
return false;
}
}
Where can I add the extra fields in that I need?
Am I on the right track, or even looking at the right template / php code that returns the data?
Please help me out here, I have not done Magento development for 2 years, so I have to re-learn allot of this stuff again....
Thanks in advance.

This is indeed he place where output is made. However you need to dig deeper. Look at this line:
$array = Mage::helper('paypal_catalog')->getProducts($category->getId());
This fills the array where jsonEncode uses in the output routine. This is probably located somewhere in app/code/community/Paypal/Catalog/Helper/.
Alternatively, you can post-process that $array and add in your fields. However I strongly discourage that as you may have better luck (and performance) inside the helper method getProducts instead.
Good luck.

I ended up with the following code, which is not the most efficient, but there are never more than 5 products in the list of this mobile app solution...
Added code to:
$array = Mage::helper('paypal_catalog')->getProducts($category->getId());
$this->setCurrenCategoryKey($category->getId());
And made it:
$array = Mage::helper('paypal_catalog')->getProducts($category->getId());
foreach ($array['items'] as &$productitem) {
$productId = $productitem['id'];
$product = Mage::getModel('catalog/product')->load($productId);
if(!is_null($product)){
$productitem['type'] = $product->getTypeId();
//Get all options for product
$options = array();
$options = $product->getOptions();
if (count($options) > 0){
$productitem['hasoptions'] = '1';
}
else
{
$productitem['hasoptions'] = '0';
}
$addTocartUrl = $this->helper('checkout/cart')->getAddUrl($product);
$productitem['addTocartUrl'] = $addTocartUrl;
}
else{
$productitem['type'] = 'simple';
$productitem['hasoptions'] = '0';
}
}
$this->setCurrenCategoryKey($category->getId());
I was then able to change my footer.phtml with the following:
<!-- Product List Template -->
<div id="productListTemplate">
<li onclick="checkQuickAdd(jQuery(this),'%url%');">
<div class="product-image">%image%</div>
<div class="product-content">
<div class="product-title">%title%</div>
<div class="product-description"><span class="counter" style="font-weight:bold;font-size:large;"></span> %description%</div>
<div class="product-price">$%price%</div>
<div class="quickadd">+</div>
</div>
<div class="product-id" style="display:none;">%id%</div>
<div class="product-hasoptions" style="display:none">%hasoptions%</div>
</li>
</div>
Which allowed to query the values later on in a js function:
function checkQuickAdd(listitem,url)
{
var hasOptions = jQuery(listitem).find(".product-hasoptions").text();
var productId = jQuery(listitem).find(".product-id").text();
var productTitle = jQuery(listitem).find(".product-title").text();
if (hasOptions == '0'){
try {
jQuery(".ui-loader").css("display","block");
var cartUrl = "/index.php/test/jsoncheckout/cart/add/product/" + productId;
var cartno = jQuery(jQuery('.ui-page-active .menu-bar-item.itemright>div')[0]).attr('id').replace("cartCount","");
var cartCount = jQuery(jQuery('.ui-page-active .menu-bar-item.itemright>div')[0]).text();
jQuery.ajax( {
url : cartUrl,
type: "POST",
dataType : 'json',
contentType: "application/json; charset=utf-8",
async: true,
cache: false,
success : function(data) {
//alert("added");
var counter = 1;
var strCounter = jQuery(listitem).find(".counter").text();
if (strCounter != "") { counter = parseInt(strCounter) + 1; }
if (cartCount != "") {
cartCount = parseInt(cartCount) + 1;
}
else {
cartCount = 1;
}
jQuery(listitem).find(".counter").text(counter);
// update cart number
updateCartCount(cartCount, cartno);
jQuery(".ui-loader").css("display","none");
alert("Added " + productTitle);
},
fail: function (msg) {
jQuery(listitem).find(".product-description").text(msg.d);
jQuery(".ui-loader").css("display","none");
}
});
jQuery(".ui-loader").css("display","none");
}
catch (e) {
alert(e);
jQuery(".ui-loader").css("display","none");
}
}
else{
forwardURL(url);
}
}
This must be the most inefficient code that I have written in a long time, but the time frame was very small to complete this.
I would love to do this in a more efficient way.
Any suggestions would be appreciated!

Related

How to pass all loop value and pass to ajax?

Why it returns only the last number of my database? I wanted to return all value inside the div. Help me.
Ajax
$.ajax({
url : 'Test.php',
method : 'post',
data : {id: id},
success : function(response)
{
var x = $.parseJSON(response);
for (var a in b)
{
$('#allValue').html(b[a]);
}
}
});
PHP
if(isset($_POST['id']))
{
$query = mysqli_query($conn, "SELECT * FROM tbl_reservation");
while ($row = mysqli_fetch_array ($query))
{
$result[] = array($row['ID_reservation']);
}
echo json_encode($result);
}
By doing
$("#element").html("TEST");
The HTML method removes any existing content and replaces it with "TEST". If you want to append text you could first get the HTML value, but better yet:
var x = $.parseJSON(response);
var text = "";
for (var a in b)
{
text += b[a];
}
$('#allValue').html(text);

How do I add html tags in jquery plugins?

I am doing the live search using the jquery plugins. When I tried to search that doesn't exist, it only shows the table. I would like to put some message "No result found" if it doesnt exist. The question is how can I add message "No result found"
Note: In my codes I add some validation, the user need input minimum of 3 characters
/**
**options to have following keys:
**searchText: this should hold the value of search text
**searchPlaceHolder: this should hold the value of search input box placeholder
**/
(function($)
{
$.fn.tableSearch = function(options)
{
if(!$(this).is('table'))
{
return;
}
var tableObj = $(this),
searchText = (options.searchText)?options.searchText:'Search: ',
searchPlaceHolder = (options.searchPlaceHolder)?options.searchPlaceHolder:'',
divObj = $('<div style="font-size:20px;">'+searchText+'</div><br /><br />'),
inputObj = $('<input style="min-width:25%;max-width:50%;margin-left:1%" type="text" placeholder="'+searchPlaceHolder+'" />'),
caseSensitive = (options.caseSensitive===true)?true:false,
searchFieldVal = '',
pattern = '';
inputObj.off('keyup').on('keyup', function(){
searchFieldVal = $(this).val();
if(searchFieldVal.length == 0)
{
tableObj.find('tbody tr').show();
}
else if(searchFieldVal.length >= 3)
{
pattern = (caseSensitive)?RegExp(searchFieldVal):RegExp(searchFieldVal, 'i');
tableObj.find('tbody tr').hide().each(function()
{
var currentRow = $(this);
currentRow.find('td').each(function()
{
var result = "No result";
$("tbody tr").append(result);
if(pattern.test($(this).html()))
{
currentRow.show();
return false;
}
});
});
}
});
tableObj.before(divObj.append(inputObj));
return tableObj;
}
}(jQuery));
Here into JQ plugin(Posted at your question), the handler for empty result is exist. See piece of code from it.
else if(searchFieldVal.length >= 3)
{
pattern = (caseSensitive)?RegExp(searchFieldVal):RegExp(searchFieldVal, 'i');
tableObj.find('tbody tr').hide().each(function()
{
var currentRow = $(this);
currentRow.find('td').each(function()
{
var result = "No result";
$("tbody tr").append(result);
if(pattern.test($(this).html()))
{
currentRow.show();
return false;
}
});
});
}
Paraphrase you mistaken at your end. Re check it.

JQueryMobile: page with data (from ajax) doesn't change

function returnQueryResultJson(url,callback) {
return $.ajax({
url: url,
type: "GET",
dataType: "json",
success: function(response) {
callback(response);
}
});
}
function showCategory(url,hash, options) {
var cat = hash.replace(/.*category=/, "");
if (cat == '#page1') {
cat = '';
}
var a = returnQueryResultJson('http://www.placetowebservice.nl/categories.php?category=' + cat,function(res) {
var
category = res,
pageSelector = hash.replace(/\?.*$/, ""),
$page = $(pageSelector),
$header = $page.children(":jqmData(role=header)"),
$content = $page.children(":jqmData(role=content)"),
markup = '<ul data-role="listview" data-theme="c" data-dividertheme="b">';
var cItems = category;
var headername = category.name;
var numItems = cItems.length;
if (cat == '') {
markup = '<ul data-role="listview" data-theme="c" data-dividertheme="b" style="min-height:100%;">';
}
for (var i=0;i<numItems;i++) {
markup += '<li><h3>' + cItems[i].title + '</h3><p>' + cItems[i].description + '</p></li>';
}
markup += "</ul>";
$header.find("h1").html(headername);
$content.html(markup);
$page.page();
$content.find(":jqmData(role=listview)").listview();
options.dataUrl = url;
options.changeHash = true;
options.reloadPage = true;
console.log($page);
$.mobile.changePage($page, options);
//}
});
}
$(document).bind("pagebeforechange", function(e,data) {
if (typeof data.toPage === "string") {
var
uz = $.mobile.path.parseUrl(data.toPage),
re = /^#category-item/,
re2 = /^#page1/
;
if (uz.hash.search(re) !== -1 || uz.hash.search(re2) !== -1) {
showCategory(uz.href,uz.hash,data.options);
e.preventDefault();
}
}
});
I have got this code, and it works pretty good (first time). I first load a page with:
$(document).ready(function(){
$.mobile.changePage('index.html#page1',{ dataUrl: "index.html#page1?category=", transition: "fade" });
});
It works, it loads the ajax-data in the page with id="page1".
Then I click on a link (category 1) and it shows the second page (with id="category-item") and fills it with the right data (category 1: sub 1, category 1: sub 2). Then I go back and it shows the categories again.
Now the problem appears, when I click on the next category (category 2). When I go to that page, it gives the right data from ajax (I used console.log to check this), but the data on the screen remains the data from category 1.
So the content from the first category you click on remains, even though you afterwards went to another category. It will remain showing the category you first clicked on.
What am I doing wrong?
It worked When I did this:
$page.page();
$page.trigger('create'); // added this one
$content.find(":jqmData(role=listview)").listview();
$content.find(":jqmData(role=listview)").listview("refresh"); // added this one

AJAX loop for WordPress (posts from different categories)

I try to implement AJAX posts loop for WordPress from Tuts+
I want this loop to show under comments form in single post page in three columns (each for another category)
In single.php I have divs (numbers comes from category):
<div class="news_posts-6"></div>
<div class="news_posts-3"></div>
<div class="news_posts-2"></div>
My ajaxLoop:
jQuery(function($){
var page = 1;
var loading = true;
var $window = $(window);
var cat = [6,3,2];
var load_posts= jQuery.each(cat, function(){
var $content = $(".news_posts-" + this);
$.ajax({
type : "GET",
data : {numPosts: 2, pageNumber: page, cat: this},
dataType : "html",
url : "http://127.0.0.1:4001/wordpress/wp-content/themes/twentyeleven-child-theme/loopHandler.php",
beforeSend : function(){
if(page != 1){
$content.append('<div id="temp_load" style="text-align:center">\
<img src="/images/ajax-loader.gif" />\
</div>');
}
},
success : function(data){
$data = $(data);
if($data.length){
$data.hide();
$content.append($data);
$data.fadeIn(500, function(){
$("#temp_load").remove();
loading = false;
});
} else {
$("#temp_load").remove();
}
},
error : function(jqXHR, textStatus, errorThrown) {
$("#temp_load").remove();
alert(jqXHR + " :: " + textStatus + " :: " + errorThrown);
}
});
});
$window.scroll(function() {
var content_offset = $content.offset();
console.log(content_offset.top);
if(!loading && ($window.scrollTop() +
$window.height()) > ($content.scrollTop() + $content.height() + content_offset.top)) {
loading = true;
page++;
load_posts();
}
});
load_posts();
});
Part of loopHandler.php:
$numPosts = (isset($_GET['numPosts'])) ? $_GET['numPosts'] : 0;
$page = (isset($_GET['pageNumber'])) ? $_GET['pageNumber'] : 0;
$cat = (isset($_GET['cat'])) ? $_GET['cat'] : 0;
echo $numPosts;
echo $page;
query_posts(array(
'posts_per_page' => $numPosts,
'paged' => $page,
'cat' => $cat
));
I tried use simple array containing categories numbers but it doesn't work. Depends on
data : {numPosts: X, pageNumber: page, cat: this},
there is X post displaying in each column (same posts from first category).
I guess I need to use JSON, which I tried, but it was total disaster (I don't know how to put it together). I just need to call AJAX for three different arguments.
Thanks for any help
Well, there are various ways you can go about this.
One way is looping over your categories client side first, and make separate request per category. This is what you are essentially doing in your code. You are iterating over an array of categories and making a request for each.
Another way is to pass that array of categories to your handler. All you need to do is modify your handler to accept an array of integers or categories. Then you can return a JSON object. But this involves a lot more editing and on top of that it does not solve the issue of having different sizes and heights for each section.
Thus, below, I have modified the code a little bit to also keep track of multiple sections. There are just a few small edits we need:
Each section needs to have a category number, pagination number, content section, and a flag whether its loading or not. Each needs to be stored in a single list for tracking.
We need to iterate over each category to initialize it.
We need to iterate over each category on window scroll and check if the next item should be loaded
We need to make sure that each request relates to the requested category
Start by modifying your divs a little (this is just a matter of preference, i prefer storing metadata like this in an attribute instead of a class):
<div class="news_posts" data-category="6"></div>
<div class="news_posts" data-category="3"></div>
<div class="news_posts" data-category="2"></div>
Here's a modified JS (please be aware that I changed up some variable and function names):
jQuery(function($){
var $window = $(window);
var cats = [];
var contentDivs = $(".news_posts");
var initializeCats = function(){
// adds category objects to a list for tracking
for(var i = 0; i < contentDivs.length; i++){
var catNum = $(contentDivs[i]).attr("data-category");
var cat = {
catNum : catNum,
catPage : 1,
loading : true,
catDiv : $(contentDivs[i]);
};
cats.push(cat);
load_post(cat);
}
};
var load_post = function(cat) {
$.ajax({
type : "GET",
data : {
numPosts : 2,
pageNumber : cat.catPage,
cat : cat.catNum
},
dataType : "html",
url : "http://127.0.0.1:4001/wordpress/wp-content/themes/twentyeleven-child-theme/loopHandler.php",
beforeSend : function(){
if(page != 1){
// this was a bad idea when i wrote the article originally
// never concatenate strings on multiple lines by escaping
// the carriage return
// $content.append('<div id="temp_load" style="text-align:center">\
// <img src="/images/ajax-loader.gif" />\
// </div>');
cat.catDiv.append("<div class='temp_load' style='text-align:center'>" +
"<img src='/images/ajax-loader.gif' />" +
"</div>");
}
},
success : function(data){
$data = $(data);
if($data.length){
$data.hide();
cat.catDiv.append($data);
$data.fadeIn(500, function(){
cat.catDiv.find(".temp_load").remove();
cat.loading = false;
});
} else {
cat.catDiv.find(".temp_load").remove();
}
},
error : function(jqXHR, textStatus, errorThrown) {
cat.catDiv.find(".temp_load").remove();
alert(jqXHR + " :: " + textStatus + " :: " + errorThrown);
}
});
});
var onWindowScroll = function(){
for(var i = 0; i < cats.length; i++){
var cat = cats[i];
var contentDiv = cat.catDiv;
var content_offset = contentDiv.offset();
if( !cat.loading &&
($window.scrollTop() + $window.height()) >
(contentDiv.scrollTop() + contentDiv.outerHeight() + content_offset.top)
) {
cat.loading = true;
cat.catPage++;
load_post(cat);
}
}
}
initializeCats();
$window.scroll(onWindowScroll);
});
The PHP file is pretty much the same, just comment out the echo $numPosts line:
$numPosts = (isset($_GET['numPosts'])) ? $_GET['numPosts'] : 0;
$page = (isset($_GET['pageNumber'])) ? $_GET['pageNumber'] : 0;
$cat = (isset($_GET['cat'])) ? $_GET['cat'] : 0;
// echo $numPosts;
echo $page;
query_posts(array(
'posts_per_page' => $numPosts,
'paged' => $page,
'cat' => $cat
));
This is just something quick I whipped up. I HAVE NOT TESTED IT. Try it out, watch out for syntax errors, and cross your fingers :). I hope this will work for you and if it does not, we can look into modifying it so that it does.

Return array from php to ajax success

I want to return an array from a php function to my ajax call. After that I want to use the array values from the page the ajax call is made.
So this is my ajax call:
$(function() {
$("#find").click(function() {
var url = $("#form_url").val();
var dataString = 'url=' + url;
$.ajax({
type: "POST",
url: "/ajax/add_url.php",
data: dataString,
}).done(function( result ) {
myresult(result);
});
return false;
});
});
function myresult(result) {
var result_lines = result.split("<splitter>");
if (result_lines[0] == '1') {
$('#content_error').html(result_lines[1]).fadeIn(250);
$('#content_error').delay(1500).fadeOut(500);
} else if (result_lines[0] == '2') {
$('#content_success').html('Succesfully get images').fadeIn(250);
$('#url_result').delay(500).fadeIn(500);
$('#content_success').delay(1500).fadeOut(500);
alert(eval(data));
}
return true;
}
and this is my php script:
if($_POST['url']) {
$url = $Db->escape($_POST['url']);
$html = file_get_html($url);
$count = 0;
$goodfiles = array();
foreach($html->find('img') as $element) {
$pic = url_to_absolute($url, $element->src);
if(!empty($pic)){
$pics = parse_url($pic);
list($width, $height, $type, $attr) = getimagesize($pic);
if($pics["scheme"]=="http" && $width >= 300 && $height >= 250) {
array_push($goodfiles,$pic);
$_SESSION['pictures'] = $goodfiles;
$count++;
}
}
}
if($count == 0){
$_SESSION['count'] = 'empty';
echo "1<splitter>";
echo "No items found with the correct size";
}else{
$_SESSION['count'] = $count;
echo "2<splitter>";
echo json_encode($_SESSION['pictures']);
}
$_SESSION['url'] = $url;
$html->clear();
$empty = 1;
}
}
when the ajax call is successful I use json_encode on the array to use it on my php page. But I don't know how I get this array to a javascript on the page the ajax call was made of.
right now I'm receiving the following content:
["image.jpeg","image.jpg"]
And I want to put this in a javascript array...
The error is this with this line:
var result_lines = result.split("<splitter>");
result (the AJAX response) is an object or array (depending on the nature of your JSON) but you are trying to call a string method (split()) on it.
This would cause an error in your JS console - always check the console.
Finally, eval() is evil and almost never required except in exceptional circumstances. Try to avoid it.
I don't know how to work with $.ajax but here is an alternative.
Replace this
$.ajax({
type: "POST",
url: "/ajax/add_url.php",
data: dataString,
}).done(function( result ) {
myresult(result);
});
with
$.post("/ajax/add_url.php",{dataString:dataString},function(data){
alert(data['you array index']);
},'json')
I repeat ,this is my alternative so don't take it hard!

Resources