jQuery does not apply code to content outputted by PHP - php

I am really stuck on an issue. I have some PHP code that outputs correctly to HTML and displays as it should in the browser (and firebug shows the source is correct), but because the information is sent by PHP to display a list of clients, my jQuery on click 'Options' menu will not work - it gets ignored. If the rows are written in flat HTML, the jQuery on click works for the 'Options' menu, so I know the jQuery is fine. On click of 'Options', the 'action-menu' ul list should toggle its display and go from none to block.
PHP:
<?php
include('dbConfig.php');
$term = $_POST['searchit'];
if($term == ''){
echo '<div class="row"><div class="col-2"></div>Enter a search term</div>';
} else {
if($client = $db->prepare("SELECT client_id, client_unique_id, client_first_name, client_last_name, client_organisation_name, client_telephone, client_list_all FROM clients WHERE client_unique_id LIKE ? OR client_first_name LIKE ? OR client_last_name LIKE ? OR client_organisation_name LIKE ? OR client_address_line_1 LIKE ? OR client_list_all LIKE ? ORDER BY client_id DESC")){
$client->bind_param('ssssss', $term, $term, $term, $term, $term, $term);
$client->execute();
$client->bind_result($client_id, $client_unique_id, $client_first_name, $client_last_name, $client_business, $client_telephone, $client_list_all);
$client->store_result();
$string = '';
if($client->num_rows > 0){
while($client->fetch()){
$properties = $db->prepare("SELECT property_id FROM properties WHERE property_client_id = ? LIMIT 1");
$properties->bind_param('i', $client_id);
$properties->execute();
$properties->store_result();
$properties->bind_result($property_id);
if($properties->num_rows > 0 ){
$active = '<span class="label label-success">ACTIVE</span>';
} else {
$active = '<span class="label label-warning">INACTIVE</span>';
}
if(!$client_business){
$client_business = 'N/A';
}
$properties->close();
$string .= '<div class="row">';
$string .= '<div class="col-2">'.$client_unique_id.'</div>';
$string .= '<div class="col-3">'.$client_first_name.' '.$client_last_name.'</div>';
$string .= '<div class="col-3">'.$client_business.'</div>';
$string .= '<div class="col-2">'.$client_telephone.'</div>';
$string .= '<div class="col-2 align-center">';
$string .= '<div class="action">Options<span class="action-arrow"><i class="fa fa-caret-down"></i></span>';
$string .= '<ul class="action-menu">';
$string .= '<li><i class="fa fa-folder-open-o"></i>View client</li>';
$string .= '<li><i class="fa fa-pencil-square-o"></i>Edit client</li>';
$string .= '<li><a onclick="deleteItem($(this))" style="cursor: pointer;" data-client-id="'.$client_id.'"><i class="fa fa-trash-o"></i>Delete client</a></li>';
$string .= '</ul>';
$string .= '</div>';
$string .= '</div>';
$string .= '</div>';
}
$client->close();
} else {
$string = '<div class="row"><div class="col-2"></div>No record found</div>';
}
echo $string;
} else {
echo '<div class="row"><div class="col-2"></div>ERROR: Could not prepare SELECT Client SQL statement.</div>';
}
}
?>
And the jQuery:
$(document).ready(function () {
$('.action').on('click', function () {
$('.action-menu').fadeToggle(200);
$(this).toggleClass('action-on');
});
});

Try changing your jQuery like this:
$(document).ready(function () {
$('div.row').on('click', '.action', function () {
$('.action-menu').fadeToggle(200);
$(this).toggleClass('action-on');
});
});
This will target the .action class elements no matter when they are loaded. Adding the selector parameter into the .on() method lets jQuery find elements that match no matter when they are created. If you have .action elements outside of the .row element, select for an element that contains them all. If all else fails, use body.

If you are adding the HTML dynamically, you can add the onclick event to any reliable parent that would exist on DOM load (eg:body).
Try to change the onclick like below,
$('body').on('click', '.action', function ()
{
$('.action-menu').fadeToggle(200);
$(e.target).toggleClass('action-on');
});

Thanks for all the support. The jQuery code that required this to work needed to be placed in the actual HTML file at the end of the PHP script - for reasons unknown, as it would not listen to the same code in the javascript.js file

Related

Dynamic ID with JQUERY functions

I have a problem with my JQUERY code. Here's the code:
$maxcounter = $( '.testimonio-popup[id^="popup-"]' ).length;
var i = 0;
while (i < $maxcounter) {
$('#open-'+i).on('click', function() {
$('#popup-'+i).fadeIn('slow');
$('.testimonio-overlay').fadeIn('slow');
$('.testimonio-overlay').height($(window).height());
return false;
});
$('#close-'+i).on('click', function(){
$('#popup-'+i).fadeOut('slow');
$('.testimonio-overlay').fadeOut('slow');
return false;
});
i++;
}
It takes correctly the total of times the .testimonio-popup div is appearing in the site, and the fadeIn action for .testimoniooverlay class works.
But the fadeIn action for #popup-[number] is not working. Any help why?
For further assistance, I attach the PHP code that makes the query:
function get_the_content_with_formatting ($more_link_text = '(more...)', $stripteaser = 0, $more_file = '') {
$content = get_the_content($more_link_text, $stripteaser, $more_file);
$content = apply_filters('the_content', $content);
$content = str_replace(']]>', ']]>', $content);
return $content;
}
add_shortcode( 'testimonios', 'display_testimonios' );
function display_testimonios($atts){
$atributos = shortcode_atts([ 'grupo' => 'PORDEFECTO', ], $atts);
$buffer = '<div class="testimonio-overlay"></div> ';
$contadorid = 0;
$q = new WP_Query(array(
'post_type' => 'test',
'tax_query' => array(
array(
'taxonomy' => 'grupos_testimonios',
'field' => 'slug',
'terms' => $atributos['grupo']
//'terms' => 'grupo-1'
)
)
) );
while ($q->have_posts()) {
$q->the_post();
$buffer .= '<div class="testimonio">';
$buffer .= '<div class="testimonio-img">' . get_the_post_thumbnail($_post->ID).'</div>';
$buffer .= '<div class="testimonio-titulo"><p>' . get_the_title() .'</p></div>';
$buffer .= '<div class="testimonio-intro"><div class="testimonio-parrafo">' . get_the_excerpt() . '</div><button class="testimonio-boton" id="open-'.$contadorid.'">Leer más</button></div></div>';
$buffer .= '<div class="testimonio-popup" id="popup-'.$contadorid.'"><div class="testimonio-popup-contenido"><div class="testimonio-cerrar"><button class="testimonio-boton-cerrar" id="close-'.$contadorid.'">x</button></div>';
$buffer .= '<div class="testimonio-popup-titulo"><p>' . get_the_title() .'</p></div>';
$buffer .= '<div class="testimonio-popup-contenido">' . get_the_content_with_formatting() . '</div></div></div>';
$contadorid = $contadorid + 1;
}
wp_reset_postdata();
return $buffer;
}
Thank you!
Frede
#Rory McCrossan is right (see comment).
I'm not sure what goes wrong there, but I would suggest you change this logic:
$("#open-1").on(....);
$("#open-2").on(....);
$("#open-3").on(....);
$("#close-1").on(....);
$("#close-2").on(....);
$("#close-3").on(....);
$("#popup-1").fadeIn()
$("#popup-2").fadeIn()
to using classes and attributes:
$(".popup-handler").on(.. check if open/close -> then action..);
$(".popup").filter(.. check for specific reference..).fadeIn()
And if you want to interact elements with different classes, add data attributes to them so you can find them when needed. Here is a simple example:
<!-- popup nr 1 -->
<div class="popup-handler" data-rel="1" data-action="open"></div>
<div class="popup" data-rel="1">
<div class="popup-handler" data-rel="1" data-action="close"></div>
</div>
<!-- popup nr 2 -->
<div class="popup-handler" data-rel="2" data-action="open"></div>
<div class="popup" data-rel="2">
<div class="popup-handler" data-rel="2" data-action="close">x</div>
</div>
<!-- jQuery -->
$(".popup-handler").on("click", function() {
/* get popup reference & action */
var rel = $(this).data("rel"),
action = $(this).data("action");
/* find the target popup */
var $popup = $(".popup").filter("[data-rel=" + rel + "]");
if (action == "open") {
$popup.fadeIn("slow");
/* ... other code when opening a popup... */
}
if (action == "close") {
$popup.fadeOut("slow");
/* ... other code when closing a popup... */
}
});
Demo here - 4 popups, working: jsfiddle
(Defining the same functions inside a while loop is generally a bad idea.)

Shortcode is not working correctly if it is used more then one time in a same page

I have created one shortcode to return a tab content and it is working fine
if I am using one time in a page.But if want one more on this same page it is not working. I have tried in several way but its not giving fruits.
Here is the code
if($tab_box == 'tab_box_1' && $tabs_lay == 'awavc-tabs-pos-left') {
$add_class = rand(99,9999);
$q = rand(99,99999);
$html .= '
<div class="awavc-tabs awavc-tabs-'.$add_class.' '.$tabs_lay.' '.$tab_style.' awavc-tabs-response-to-icons '.$el_class.' ">';
$i = 1;
foreach($tab_contents as $tab_content){
$tab_lable = 'Lable';
$tab_icon = '';
if(!empty($tab_content['tab_lbl'])){$tab_lable = $tab_content['tab_lbl'];}
if(!empty($tab_content['icon'])){$tab_icon = $tab_content['icon'];}
$html .= ' <input type="radio" name="awavc-tabs" checked id="awavc-tab-'.$i.'" class="awavc-tab-content-'.$i.'">
<label for="awavc-tab-'.$i.'"><span><span style="font-size:'.$lable_size.'px;color:'.$lable_clr.';"><i class="'.$tab_icon.'" style="font-size:'.$lable_size.'px;color:'.$icon_clr.';"></i>'.$tab_lable.'</span></span></label>';
$i++;
}
$html .= '
<ul>';
$i = 1;
foreach($tab_contents as $tab_content){
$tab_title = 'Title';
$content = '';
if(!empty($tab_content['title'])){$tab_title = $tab_content['title'];}
if(!empty($tab_content['content'])){$content = $tab_content['content'];}
$html .= '<li class="awavc-tab-content-'.$i.'">
<div class="typography">';
if(!empty($tab_title)){ $html .= '<h1 style="font-size:'.$ttl_size.'px;color:'.$ttl_clr.';">'.$tab_title.'</h1>';}
$html .= '
<p style="font-size:'.$content_size.'px;color:'.$content_clr.';font-style:'.$content_style.';">'.$content.'</p>
</div>
</li>';
$i++;
}
I have tried something like $i.$add_class but...
If you want to use the shortcode multiple times on the same page do it like so:
add_shortcode("fmg_shortcode", "fmg_callback");
function fmg_callback($args) {
ob_start();
$html = "";
//your code here
echo $html;
return ob_get_clean();
}

Why does this block my PHP code?

The query is
$q1 = "SELECT * from `event` ORDER BY `upload_date` DESC";
This is the function
function display_content($r, $dis){
foreach($r as $part) {
$dis .= '<br /><div id="event_box">';
$dis .= '<div id="event_name"> '.$part['name'].'</div>';
$dis .= '<div id="start_date"><b>From: </b>'.$part['start_date'].' </div>';
$dis .= '<div id="end_date"><b>Until: </b>'.$part['end_date'].' </div>';
$dis .= '<div id="event_link"><b>Link: </b>Event Website</div>';
$dis .= '<div id="event_venue"><b>Venue: </b>'.$part['venue'].' </div>';
$a = array(854, 480);
$b = array(300, 300);
$str = $part['embed_code'];
$partVideo = str_replace($a, $b, $str);
$dis .= '<div id="event_video"> '.$partVideo.' </div>';
$dis .= '<div id="event_image"><a href = " http://'.$part['link'].'" target="_blank"><img src = "data:image;base64, '.$part['image'].'"';
$dis .= 'alt = "'.$part['name'].'"></a></div>';
$dis .= '<div id="details"> '.$part['details'].'<br /><br />';
$dis .= '<button class="share2 btn-primary s_twitter">Tweet!</button>&nbsp&nbsp';
$dis .= '<button class="share2 btn-primary s_facebook">Share on Facebook!</button></div>';
$dis .= '</div>';
$dis .= '<br />';
}
echo $dis;
} // close function display content
Later on I call
display_content($r1, $display);
Only the first instance (entry) of an event from the database appears, and it appears fine (name, venue, details etc), but all the other event entries do not appear at all. Like they are 'blocked' maybe.
However, they all appear fine if I remove the line
$dis .= '<div id="event_video"> '.$partVideo.' </div>';
Entries either have a
$dis .= '<div id="event_image"><a href = " http://'.$part['link'].'" target="_blank"><img src = "data:image;base64, '.$part['image'].'"';
$dis .= 'alt = "'.$part['name'].'"></a></div>';
or a
$dis .= '<div id="event_video"> '.$partVideo.' </div>';
'$dis' or what '$dis' represents in the function is defined/instantiated ($dis = '';) outside of the function so should be a global variable.
What is going on and how can I fix it?
I know that they don't all have the same image / video information, which probably means I should normalise my database better (these entries are NULL in the database until I fill them), but shouldn't they all appear / print on screen anyhow?
Why is only the first event appearing?
Thanks!
'<div id="event_video"> '.$partVideo.' </div id="event_video">';
That's not how you close an HTML tag...You should be using:
'<div id="event_video"> '.$partVideo.' </div>';
Double check your code, and make sure you have proper HTML markup. You've done this in multiple locations.
Also, you may want to do a var_dump( $partVideo ) to verify whether or not you can actually concatenate that variable with the string, and to ensure that it isn't responsible for "breaking" the rest of your code.

dynamically changing CSS background-image

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.

PHP jQuery Post - returns too much HTML

I have a problem when using jQuery Post, the PHP returns all the HTML of the page up to the newly created HTML, rather then just the HTML that is output by the PHP.
As an example say the php outputs: '<div>Some Content</div>'
Then the jQuery Post returns: '<html><head>...all the head content...</head><body>...other content...<div>Some Content</div>'
Here's the jQuery (link to full code: http://pastebin.com/U7R8PqX1):
jQuery("form[ID^=product_form]").submit(function() {
var current_url = js_data.current_url;
form_values = jQuery(this).serialize();
jQuery.post(current_url+"?ajax=true", form_values, function(returned_data) {
jQuery('div.shopping-cart').html(returned_data);
}
});
return false;
});
And here's the PHP (version 5.3.6 - link to full code: http://pastebin.com/zjSUUbmL):
function output_cart()
{
ob_start();
echo $this->output_cart_html();
$output = ob_get_contents();
ob_end_clean();
echo $output;
exit();
}
function output_cart_html() {
if (!isset($_SESSION['cart_items']))
{
$output = '<div class="cart_content faded">BASKET - Empty</div>';
return $output;
} else {
$total_items = 0;
$total_items = 0;
$items_in_cart = $_SESSION['cart_items'];
// work out total price and total items
foreach ($items_in_cart as $item_in_cart) {
$total_items += $item_in_cart['quantity'];
$total_price += floatval($item_in_cart['updated_price']*$item_in_cart['quantity']);
}
$template_url = get_bloginfo('template_directory');
$output = '';
$output_price = $dp_shopping_cart_settings['dp_currency_symbol'].number_format($total_price,2);
if($total_items == 1){ $item_text = ' Item'; } else { $item_text = ' Items'; }
$output .= $total_items . $item_text;
$output .= ' <span class="bullet"></span> Total '.$output_price;
// empty cart btn
$output .= '<form action="" method="post" class="empty_cart">
<input type="hidden" name="ajax_action" value="empty_cart" />
<span class="emptycart"> <img src="'.$template_url.'/images/empty.png" width="9" height="9" title="Empty Your Items" alt="Empty Your Items" />Empty Your Cart</span>
</form>';
// check out btn
$output .= ' <span class="bullet"></span> <span class="gocheckout">'.$this->output_checkout_link().' </span>';
return $output;
}
}
You need to check if the form has been posted yet with the PHP. To do this, just check if the 'ajax' parameter is there, or send another $_GET variable if you wish (by adding &anotherparementer=1 to the end of the jQuery post URL). Example:
<?php
if(isset($_GET['ajax'])) {
//your PHP code here that submits the form, i.e. the functions that you have, etc.
}
else {
?>
<html>
<head>
head content here...
</head>
<body>
body content here...
</body>
</html>
<?php
}
?>
I hope this helps.
Ok it turns out my problem was with the way Wordpress processes AJAX requests. The plugin I was building on top of was using AJAX but didn't have these issues (I'm not sure why maybe because they were using eval), so I hadn't realised there was a correct way of using AJAX with Wordpress. Here's a bunch of information if anyone else has similar problems:
http://codex.wordpress.org/AJAX_in_Plugins
http://byronyasgur.wordpress.com/2011/06/27/frontend-forward-facing-ajax-in-wordpress/
(this one really helped me out, a very simple example that I was able to adapt)
-- sorry I couldn't post more links because I'm too new on this site, but check out the links at the bottom of the first link above, especially the '5 Tips'.
As I'm using classes I instantiated the class from the index file of my plugin with this:
if ($_POST['action'] === 'action_name') {
$class_obj = new \namespace_name\class();
add_action('wp_ajax_action_name', array($class_obj, 'method_name'));
add_action('wp_ajax_nopriv_action_name', array($class_obj, 'method_name'));
}

Categories