Ajax in a Joomla 3.x component's view - ajax

I'm building a Component for Joomla 3.x and I encounter a problem handling an ajax request.
The source is available on Github: JomCity
My request is made from the venues view : /com_jomcity/site/views/venues/tmpl/default.php
<script type="text/javascript">
jQuery(document).ready(function () {
jQuery('#main_search_request').keyup(function() {
var request_content = jQuery(this).val();
jQuery.get(
// Specify the server URL and the $_GET datas to send
'index.php?option=com_jomcity&task=searchVenues&format=json',
{ search: request_content },
// The server will respond with some data encoded in JSON
function(data){
jQuery('#results').html('');
for (var i = 0; i < data.venues.length; i++) {
var venue = data.venues[i];
console.log(venue);
jQuery('#results').append(
'<div class="grid-item">' +
'<a href="#">' +
'<img src="http://placekitten.com/g/80/80" alt="">' +
'<div>' +
'<div>' +
'<h3>'+venue.name+'</h3>' +
'<span>* * * * *</span>' +
'</div>' +
'<div>Short descrption</div>' +
'</div>' +
'</a>' +
'</div>'
);
}
}
);
});
});
</script>
This ajax script communicate with the main controller of the component (site part), so I'm wondering how can I get the values from the model com_jomcity/site/models/venues.php.
Is it possible with this code ? Or should I handle the ajax request in the controller of the view (I didn't find how to do that) ?

Thanks #Torreto and #GDP for your participation.
I finally kept on creating a task in the main controller exchanging with the database directly, so without using any model. I think it should exist a better and cleaner way to code this ajax call, so I'm open to any advice for further improvement.
The code I used, if it can help someone :
In /com_jomcity/site/views/venues/tmpl/default.php:
<script type="text/javascript">
jQuery(document).ready(function () {
jQuery('#main_search_request').keyup(function() {
var request_content = jQuery(this).val();
jQuery.get(
// Specify the server URL and the $_GET datas to send
'index.php?option=com_jomcity&task=searchVenues&format=json',
{ search: request_content },
// The server will respond with some data encoded in JSON
function(data){
// Clean the #result div between two search results
jQuery('#results').html('');
// Read and display each objects returned in the json response
for (var i = 0; i < data.length; i++) {
var venue = data[i];
jQuery('#results').append(
'<div class="grid-item">' +
'<a href="#">' +
'<img src="http://placekitten.com/g/80/80" alt="">' +
'<div>' +
'<div>' +
'<h3>'+venue.en_name+'</h3>' +
'<span>* * * * *</span>' +
'</div>' +
'<div>Short descrption</div>' +
'</div>' +
'</a>' +
'</div>'
);
}
}
);
});
});
</script>
In /com_jomcity/site/controller.php:
class JomCityController extends JControllerLegacy
{
/**
* Search in all the venues
* #return string The message to be displayed to the user
*/
public function searchVenues() {
if (isset($_GET['search'])) {
// Get a db connection
$db = JFactory::getDBO();
// Create a new query object
$query = $db->getQuery(true);
// Select all records from the jomcity_venues_items table
// Where the name or the description correspond to the user's search keywords
// Order it by the en_score field
$query
->select('*')
->from('#__jomcity_venues_items')
->where('`local_name` like "%'.$_GET['search'].'%" OR `en_name` like "%'.$_GET['search'].'%" OR `description` like "%'.$_GET['search'].'%"')
->order('en_name ASC');
// Reset the query using our newly populated query object
$db->setQuery((string)$query);
// Load the results as a list of stdClass objects.
$this->venues = $db->loadObjectList();
}
echo json_encode($this->venues);
}
}

Related

Shopify: How can I render the recommended products?

I am trying to use Shopify Ajax API to get recommended products inside the cart. I am able to get the recommended product's json but not the section rendering.
The script (note section_id):
jQuery.getJSON('/cart.js', function(cart) {
// first recommendation
jQuery.getJSON("/recommendations/products.json?product_id=" + cart.items[0].product_id + "&limit=6&section_id=recommended_first", function(
response
) {
var recommendedProducts = response.products;
}
});
})
The HTML:
<div id="recommended_first" class="upsell_product">
</div>
I get some messages in the console:
Error: ShopifyAnalytics.meta.page.pageType is empty: undefined
Fallback logic initiated
What am I missing? I didn't find any examples in the Shopify doc.
Thanks a lot!
Your code will not work because you have an extra } on line 7. Assuming the cart request returns valid data, the following code should work (also a good idea to check if the cart request returns any items before using the cart.items variable):
jQuery.getJSON('/cart.js', function(cart) {
jQuery.getJSON("/recommendations/products.json?product_id=" + cart?.items?[0]?.product_id + "&limit=6&section_id=recommended_first", function(response) {
var recommendedProducts = response.products;
var recommendedProductsHTML = "";
for (i = 0; i < recommendedProducts.length; i++) {
recommendedProductsHTML += `<div>${recommendedProducts[i].title}</div>`;
}
$("#recommended_first").html(recommendedProductsHTML);
});
});

how to set href attribute in javascript with value to call route

i am trying to set url in jquery ajax, as
$.ajax({
url : "{{url('addtocart')}}",
type : "POST",
data : {_token: CSRF_TOKEN, username:username, userType:userType,
table_no:table_no, order_no:order_no, cname:cname,
tname:tname, dname:dname, dish_qty:dish_qty,
chefnote:chefnote
},
success : function(data){
//console.log(data);
$('#cartOrder').empty();
for (var i = 0; i < data.length; i++) {
drawRow(data[i]);
}
function drawRow(rowData) {
var row = $("<tr />")
row.empty();
$("#cartOrder").append(row);
row.append($("<td contenteditable='true'>" + rowData.dish + "</td>"));
row.append($("<td contenteditable='true'>" + rowData.dish_qty + "</td>"));
row.append($("<td contenteditable='true'>" + rowData.chefnote + "</td>"));
row.append($("<td>" +"<a href='"<?php echo 'Edit';?>"' value='"+rowData.ord_id+"'>" +"Edit | "+"</a>" +"<a href='' value='"+rowData.ord_id+"'>" +"Delete"+"</a>" + "</td>"));
}
}
as there u can see at last line href="Edit", i want to call route on click of that link with value as
<a href="<?php echo 'Editcat/'.RowData->ord_id; ?>"
i know this not the way, how can i do that ?? thank you.
There are many options of achieving this:
First:
You can keep the call url in any of the tag's data attributes, suppose this is your container related to the ajax functionality:
<div class="_cart" data-edit-url="{{route('cart.edit',['id'=>$cartItem->id])}}">
</div>
and access it using the following code:
$('._cart').data('edit-url');
but before executing this line http://stackoverflow.com/users/6285124/rohit-khatri
Define a name for your route, like:
Route::get('Edit/{id}','Controller#function')->name('cart.edit');
Based on your route you just have to change it like this -
Route
Route::get('/Edit/{id}',[
'uses' => 'Controller#function',
'as' => 'Edit',
]);
and than you can use it in your view like this -
Edit
//this is your route ^ here will be your Id ^
than in your Controller for edit you can use this Id -
public function yourEditFunction($id){
//use $id here
}

Coverting AJAX JSON function to return data objects instead of html into a modal window

Background
Okay, I have a page which displays simple information on rows from a mysql database. For example, the table has 7 columns, but only #'s 1, 3 & 4 are displayed on the page. On the right side of the row is a href link to open a modal window, and I am attempting to display all the rows, in a nicely formatted window with html/css/etc...
After spending about 4 hours in tutorials on this, the closest thing I have come up with is the code base below, which does the job of passing the "id" to the json script, (almost) properly pulls the information, puts it in a single object line, and passes it back into my html/php page to be read into the modal window.
I am politely asking for help to convert my codebase so that it transfers all objects individually instead of one gigantic line of php to echo into html (arse-backwards).
I am rather new to JSON/AJAX/jquery, but can navigate and work with the html/css/php once I am able to figure this out.
My apologies if the code examples are a little muffled and poor in syntax, I have spent hours trying to get this work as it is supposed to.
PHP Page With The AJAX
$('.view_information').click(function(e) { // Button which will activate our modal
//On Clicking the function, dynamically load the data for the viewing
var data_id = $(this).data('id');
$.ajax({
url: 'view_agency_info.php',
type: 'POST',
data: {id: data_id},
dataType: 'json',
success: function(data){
$('.view_modal_content').html(data.html); // LOAD THE DATA INTO THIS DIV
//I want to be able to use...
//$('.placeholder_name')xxxx
//$('.placeholder_accountnumber')etc
},
error: function(jqXHR, textStatus, errorThrown){
$('.view_modal_content').html('');
alert('Error Loading Information');
}
});
As you can see from the php page, as of right now, the mysql is being pulled into an array, then inserted individually into a single HTML object, then being passed back into PHP to be outputted. How can I convert this code to output more than just one object?
JSON
<?php
$customer_id=$_SESSION['customer']['customer_id'];
$id = (int)$_POST['id'];
$query = "SELECT * FROM collections_list WHERE id={$id} && customer_id=$customer_id LIMIT 1"; //expecting one row
$result = mysql_query( $query );
//$message = mysql_fetch_assoc( $result ); //expecting just one row
$message=array();
while ($row = mysql_fetch_assoc($result)) {
$message[]=$row['agency_name'];
$message[]=$row['account_number'];
$message[]=$row['phone'];
}
$json = array();
$json['html'] = '<p><pre><code>id:'.$id.'.<br>Agency Name: '.$message[0].'<br>Account Number:'.$message[1]."<br>Phone:".$message[2].'</code></pre></p>'.'<br><br>test';
header('Content-Type: application/json');
echo json_encode( $json );
?>
If I understand this correctly, then I would advise you to change the PHP to generate JSON directly rather than sending back HTML. Something like:
$first = 1;
$json = '[';
while ($row = mysql_fetch_assoc($result)) {
if ($first == 1) $first = 0; else $json = $json + ',';
$json = $json.'{';
$json = $json.'"AgencyName":'.$row['agency_name'];
$json = $json.', "AccountNumber":'.$row[account_number];
$json = $json.', "Phone":'.$row[phone];
$json = $json.'}';
}
$json = $json.']';
I have done this more in MVC and am rusty on PHP syntax, but hopefully this gets the gist across. Then your javascript can parse the results as just JSON. If you have "bad" characters in your data, you may have to html encode some, but the data should be easier to work with as data. You will have to provide template HTML for your modal and then fill it in.
The line:
$json['html'] = '<p><pre><code>id:'.$id.'.<br>Agency Name: '.$message[0].'<br>Account Number:'.$message[1]."<br>Phone:".$message[2].'</code></pre></p>'.'<br><br>test';
only pulls one object from the result "$message[0]" the first elememt of the array.
This is why you are only getting one object returned.
edit:
you'll need to change:
$message=array();
while ($row = mysql_fetch_assoc($result)) {
$message[]= ('name' => $row['agency_name'],
'account' => $row['account_number'],
'phone' => $message[]=$row['phone']
);
}
print json_encode($message);
This will then return a json object that you can parse with js
then in your js:
edit:
then add your html in js if thats how you wanna do it
var html;
$.each(data, function(info) {
html += "<p><pre><code>id:"+ data_id +".<br>Agency Name: "+ info.name +"<br>Account Number:"+ info.number +"<br>Phone:"+ info.phone +"</code></pre></p><br><br>";
});
$('.view_modal_content').html(html);
??????????????????????????????????????????????????????????????????
are you trying to do:
var divObj = {}; //make sure this is in the correct scope
//anonymous array
$.each(data, function(info) {
divObj.push("<p><pre><code>id:"+ data_id +".<br>Agency Name: "+ info.name +"<br>Account Number:"+ info.number +"<br>Phone:"+ info.phone +"</code></pre></p><br><br>");
});
//or associative array
$.each(data, function(info) {
divObj[info.name] ="<p><pre><code>id:"+ data_id +".<br>Agency Name: "+ info.name +"<br>Account Number:"+ info.number +"<br>Phone:"+ info.phone +"</code></pre></p><br><br>";
});
or are you trying to simply update elements of an existing block of code in a div?

AJAX separating the data returned into specific DIVs

AJAX code:
<script type="text/javascript">
function doCalc(){
var roomX = $('#room_str').val();
var heightX = $('#height_str').val();
var widthX = $('#width_str').val();
var prodid = $('#prodid').val();
var qtyX = $('#qty_str').val();
$.post('db_query.php',
{qtyX:qtyX, roomX:roomX, heightX:heightX, widthX:widthX, prodid:prodid},
function(data) {
data = $.parseJSON(data);
$('#width-placeholder').html(data.width);
$('#height-placeholder').html(data.height);
// ...
});
return false;
};
</script>
PHP Code:
<?php
include('db_pbconnection.php');
$query = mysql_query(" SELECT * FROM price_dimensions WHERE prodid = '".$_POST['prodid']."' AND height >= '".$_POST['heightX']."' AND width >= '".$_POST['widthX']."' ORDER BY height ASC, width ASC LIMIT 1 ");
$results = array();
$row = mysql_fetch_array($query);
$results = array(
'width' => $row['width'],
'height' => $row['height'],
'price' => $row['price']
);
$json = json_encode($results);
echo $json;
?>
EDIT: Updated code works successfully thanks to Alex. This uses json_encode to send the data back with ability to assign each SQL row to an identified for placeholders. This is just in case you need to move your data around individually in a layout.
If I'm not mistaken, what you try to do is apply selectors to HTML data coming from AJAX request. Yes? I don't think jQuery would help you here.
An option might be to have this div structure already on page as some template with placeholders. And your AJAX calls should return data in JavaScript native, parsable format - JSON. PHP has a function which will make JSON for you - json_encode. After you get JSON from your server, you can do this:
function(data) {
data = $.parseJSON(data);
$('#width-placeholder').html(data.width);
$('#height-placeholder').html(data.height);
// ...
});
return false;
};

edit-in-place, how to make more db fields editable

Good evening guys!
I just managed to implant a really sweet working edit-in-place function with jQuery and AJAX. I'm able to edit 1 db field. I would like to be able to edit multiple db fields.
These are all the scripts:
Update query (handler.php)
<?php
include('../../core/additional/connect-db.php');
if (isset($_POST['id']) && isset($_POST['firstname'])) {
$firstname = mysql_real_escape_string($_POST['firstname']);
$id = mysql_real_escape_string($_POST['id']);
$query = "UPDATE players SET firstname ='$firstname' WHERE id='$id'";
$result = mysql_query($query) or die ('Query couldn\'t be executed');
if ($result) {echo 1;}
}
?>
And the ajax in the head
<script type="text/javascript">
$(document).ready(function()
{
$(".editable").hover(
function()
{
$(this).addClass("editHover");
},
function()
{
$(this).removeClass("editHover");
}
);
$(".editable").bind("dblclick", replaceHTML);
$(".btnSave, .btnDiscard").live("click", handler);
UI("Ready");
function UI(state)
{
var status = {};
status.Ready = "Ready";
status.Post = "Saving your data. Please wait...";
status.Success = "Success! Your edits have been saved.";
status.Failure = "Attempts to save data failed. Please retry.";
var background = {};
background.Ready = "#E8F3FF";
background.Post = "#FAD054";
background.Success = "#B6FF6C";
background.Failure = "#FF5353";
$("#status").animate({opacity: 0}, 200, function (){$("#status").html(status[state]).css({background: background[state]}).animate({opacity: 1}, 200)});
}
function handler()
{
var selector="";
var code="21";
if ($(this).hasClass("btnSave"))
{
UI("Post");
var str = $(this).siblings("form").serialize();
$.ajax({
type: "POST",
async: false,
timeout: 100,
url: "core/actions/handler.php",
data: str,
success: function(msg){code = msg; $(".message_edit").show(); $(".message_edit").fadeOut(2500);},
});
if(code == 1)
{
UI("Success");
selector = "editBox";
}
else
{
UI("Failure");
selector = "buffer";
}
}
else {selector = "buffer"}
$(this).parent()
.html($(this).siblings("form")
.children("."+selector)
.val())
.removeClass("noPad editHover")
.bind("dblclick", replaceHTML);
return false;
}
function replaceHTML()
{
var buffer = $(this).html()
.replace(/"/g, """);
$(this).addClass("noPad")
.html("")
.html("<form class=\"editor\"><input type=\"text\" name=\"firstname\" class=\"editBox\" value=\"" + buffer + "\" /> <input type=\"hidden\" name=\"buffer\" class=\"buffer\" value=\"" + buffer + "\" /><input type=\"hidden\" name=\"id\" class=\"record\" value=\"" + $(this).attr("id") + "\" /></form>Save Cancel")
.unbind('dblclick', replaceHTML);
}
}
);
</script>
Then the field is displayed and editable by using this:
<td class="editable" id="' .($id). '" width="180">' .($task). ' </td>
I might be able to copy and rename all scripts, but I'm positive that's not the ideal way to do it. I tried to copy the script in the handler.php file and renamed the db fields, and did the same for the ajax script. But it didn't work. I hope my 'problem' is clear to you, any suggestions?
Note: I think the solution lies somewhere in this line (bottom of the ajax script):
.html("<form class=\"editor\"><input type=\"text\" name=\"firstname\" class=\"editBox\" value=\"" + buffer + "\" /> <input type=\"hidden\" name=\"buffer\" class=\"buffer\" value=\"" + buffer + "\" /><input type=\"hidden\" name=\"id\" class=\"record\" value=\"" + $(this).attr("id") + "\" /></form>Save Cancel")
Thanks in advance for helping out! :)
You may want to look at using the Jeditable jQuery plugin (http://www.appelsiini.net/projects/jeditable) and for a good example of various uses you can look at the demo page:
http://www.appelsiini.net/projects/jeditable/default.html
Also, I hope you are not actually going to use that php script to update the database, as that is vulnerable to SQL injection attacks, so it is bad practice.
And I don't see any element with the class editable in the html, just editBox.
And finally, you are submitting all the elements each time there is to be a change? That is quite inefficient, as one advantage of editing in-place is to just send small changes each time.

Resources