How to handle click events on div - javascript

I have a data set of items coming from a SQL database. Those items are displayed in multiple divs like:
<?php
$url = 'DataBase';
$json_response = file_get_contents ( $url );
$json_arr = json_decode ( $json_response, true );
for($i = count ( $json_arr )-1; $i > 0; $i--) {
$json_obj = $json_arr [$i];
echo '<div id="MyDIV">';
echo $json_obj ['id'] ;
echo $json_obj ['title'];
echo $json_obj ['article'];
echo '<button id="read_more_btn">Read more</button>';
echo '</div>'
}
?>
My problem is that I cannot handle click events for EACH div, so I cannot identify which item has been clicked. I’ve been searching for a solution for quite a while, but haven’t found anything. So my question is – how can I identify the clicked item?
EDIT
I have no idea how I can dynamically assign an ID to a button

You could use a data attributes (HTML5 assumed) to attach the Id as meta data to your divs. Your PHP (note I am adding data-id attributes):
<?php
$url = 'DataBase';
$json_response = file_get_contents ( $url );
$json_arr = json_decode ( $json_response, true );
for($i = count ( $json_arr )-1; $i > 0; $i--) {
$json_obj = $json_arr [$i];
echo '<div data-id="' . $json_obj['id'] . '">';
echo $json_obj ['id'] ;
echo $json_obj ['title'];
echo $json_obj ['article'];
echo '<button id="read_more_btn">Read more</button>';
echo '</div>'
}
?>
JS - simple click handler attachment, using jQuery .data() [docs] to get data attribute:
$('div').click(function(e) {
var id = $(this).data("id");
alert(id);
});
JSFiddle Demo

How about when creating the html in the php, you echo the id inside the class.
echo '<div id="mydiv-' . $json_obj['id'] . '">';
So now in the html, it's going to look like
<div id="mydiv-1"> ... </div>
<div id="mydiv-2"> ... </div>
<div id="mydiv-3"> ... </div>
etc.
And then in Javascript, you could access them the same way you access any tag.
$('#mydiv-1').click(function(e){
console.log('a div was clicked');
console.log($(this))
});
So in order to assign listeners to each div, you could do a loop
for(var i = 1;$('#mydiv-container').children().length >= i,i++)
{
$('#mydiv-' + i).click(function(){
}
Make sure to add a container for all the divs.

Give each div a unique numeric class, so your jquery will be
$('div').click(function() {
var item_id = $(this).attr("class");
//do stuff here
});
or
$('div').click(function() {
var item_id = this.className;
//do stuff here
});

Related

JavaScript / jQuery concatenating variables

To start with this. I have an associative array named $body (PHP).
Let's say I want to get the value of $body[1] or $body[2], depending on the id of an element.
So here's my code.
$(document).ready(function() {
$('.messages').on('click', function() {
var id = $(this).attr('id');
$('#generic-modal-title').html('Message Preview');
$('#generic-modal-body').html('" . $body[-concatenate id here-] . "');
});
})"
What I tried doing (doesn't work):
$('#generic-modal-body').html('" . $body["id"] . "');
Check this out i have tested this working fine as you required
<?php $body = array(0 => "content") ?>
<script>
$(document).ready(function() {
var id = 0;
<?php echo "var body = " . json_encode($body) .";"; ?>
$('#generic-modal-body').html(body[id]);
});
<div id="generic-modal-body"></div>

JQuery calling a PHP function issue

I'm sure I'm not doing this in the correct manner, but I just experimenting to find out the best way to get this done.
Basically, I am using Wordpress, I have created my own theme, based on Thematic.
I have a loop, that is displaying posts from a category.
At the top of the page, I have a menu, which i am trying to use as a filter. So when a user clicks on one of the menu items, it takes the ID of that item, which is the category ID, and then I am trying to use JQuery to replace the contents of a div with the new categories posts.
When i tried using AJAX to load the content, i was getting undefined function errors. So I tried putting the loop into a PHP function inside functions.php.
Here is the function:
function get_vehicle_filter() {
$f = 0;
query_posts( array('cat' => '47', 'orderby' => 'ID', 'order' => 'ASC'));
while ( have_posts() ) : the_post();
$postid = get_the_ID();
$site_url = get_site_url();
$src = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), array( 200,200 ), false, '' );
echo "<a href='$site_url/vehicles-sale-info/?post_id=$postid'>";
echo "<div class='job_image_holder'>";
echo "<img src='$src[0]' class='attachment-post-thumbnail wp-post-image' />";
echo "<div class='job_image_title'>";
the_title( "<p class='white center'>", "</p>" );
echo "</div>";
echo "</div>";
echo "</a>";
$f++;
endwhile;
wp_reset_query();
}
I'm using this to display the loop on the page, which works fine:
<script>
jQuery(document).ready(function(jQuery) {
jQuery("#filtered_vehicles").html("<?php get_vehicle_filter() ?>");
});
</script>
But when i try to get the ID of the clicked menu item into the php function, I am falling down. This is the latest version:
jQuery('.vehicle_filter_item').click(function() {
// capture id from clicked button
var filterCat = jQuery(this).attr('id');
jQuery('#filtered_vehicles').fadeOut('fast', function() {
jQuery("#filtered_vehicles").html('<?php $filterCat = ' + filterCat + '; get_vehicle_filter($filterCat) ?>').fadeIn('fast');
});
});
I know thats not right, and it obviously doesnt work!!
But I've been breaking it down to see what is and isnt working, and if i try to call the function in its simplest form, as I have above when the page is loading, like below, it doesnt work?
jQuery('.vehicle_filter_item').click(function() {
// capture id from clicked button
var filterCat = jQuery(this).attr('id');
jQuery('#filtered_vehicles').fadeOut('fast', function() {
jQuery("#filtered_vehicles").html('<?php get_vehicle_filter() ?>').fadeIn('fast');
});
});
As this works when the page loads, why doesnt it work when replacing with JQuery, the exact same code?
Can anyone point me in the right direction please.
Thanking you!
PHP executes on the server. So when you serve the page, the content inside the jQuery html() is already written. Your function get_vehicle_filter() has been called and the return is what appears inside your jQuery("#filtered_vehicles").html().
What you need to do is inside the click event, make an AJAX call to a file that returns the get_vehicle_filter(). Something like that:
jQuery('.vehicle_filter_item').click(function() {
// capture id from clicked button
var filterCat = jQuery(this).attr('id');
$.ajax({
method: "POST",
url: "file_that_calls_get_vehicle_filter.php",
data: { filter: filterCat }
})
.done(function( result ) {
jQuery('#filtered_vehicles').fadeOut('fast', function() {
jQuery("#filtered_vehicles").html(result).fadeIn('fast');
});
});
});
Hope it sends you on the right path.
Right, this is how I got this working.
Ajax call:
jQuery('.vehicle_filter_item').click(function() {
// capture id from clicked button
var filterCat = jQuery(this).attr('id');
jQuery.ajax({
method: "POST",
url: "ajax-functions.php",
data: "filterCat="+ filterCat,
})
.done(function( result ) {
jQuery('#filtered_vehicles').fadeOut('fast', function() {
jQuery("#filtered_vehicles").html(result).fadeIn('fast');
});
});
});
Function: (which is called on page load)
function get_vehicle_filter() {
$f = 0;
query_posts( array('cat' => '47', 'orderby' => 'ID', 'order' => 'ASC'));
while ( have_posts() ) : the_post();
$postid = get_the_ID();
$site_url = get_site_url();
$src = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), array( 200,200 ), false, '' );
echo "<a href='$site_url/vehicles-sale-info/?post_id=$postid'>";
echo "<div class='job_image_holder'>";
echo "<img src='$src[0]' class='attachment-post-thumbnail wp-post-image' />";
echo "<div class='job_image_title'>";
the_title( "<p class='white center'>", "</p>" );
echo "</div>";
echo "</div>";
echo "</a>";
$f++;
endwhile;
wp_reset_query();
}
Function called through AJAX ajax-functions.php
define('WP_USE_THEMES', false);
require_once('../../../wp-blog-header.php');
if($_POST['filterCat'] == "") {
$filterCat = '47';
} else {
$filterCat = $_POST['filterCat'];
}
$f = 0;
query_posts( array('cat' => $filterCat, 'orderby' => 'ID', 'order' => 'ASC'));
while ( have_posts() ) : the_post();
$postid = get_the_ID();
$site_url = get_site_url();
$src = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), array( 200,200 ), false, '' );
echo "<a href='$site_url/vehicles-sale-info/?post_id=$postid'>";
echo "<div class='job_image_holder'>";
echo "<img src='$src[0]' class='attachment-post-thumbnail wp-post-image' />";
echo "<div class='job_image_title'>";
the_title( "<p class='white center'>", "</p>" );
echo "</div>";
echo "</div>";
echo "</a>";
$f++;
endwhile;
wp_reset_query();
So, basically, the reason I could not get this working was because on the AJAX call, which was a separate file, i was missing these 2 lines at the top:
define('WP_USE_THEMES', false);
require_once('../../../wp-blog-header.php');

Show/hide div using trigger with specific class to toggle div with same class

I have my triggers and divs to show/hide in a while loop, instead of using div id which has to unique, i've decided to use div class to show/hide a group of content among others.
what i'm trying to achieve:
i'm not at all good with javascript, and i've been trying to achieve this for days. Say i have a trigger with div class="view1-'.$id1.'" where $id1=2 and div class="licom-'.$cc_id.'" where $cc_id=2 to show/hide, is it possible to ensure that my trigger would only show/hide the div class with the same id as 2?.
JavaScript
<html>
<head>
<script language="JavaScript">
$(document).ready(function(){
var showText='View all replies';
var hideText='Hide';
// initialise the visibility check
var is_visible = false;
// append show/hide links
$('.view1').prev().append();
$(".licom").hide();
$(".view1").click(function(){//i need to pass the div class with the variable
// switch visibility
is_visible = !is_visible;
// change the link depending on whether the element is shown or hidden
$(this).html( (!is_visible) ? showText : hideText);
//i also need to pass the right div class with the right variable, and keep the others hidden
$('.licom').toggle(function() {
$(this).closest('view1').find('.licom').hide();
return false;
},
function() {
$(this).closest("view1").next(".licom").show();
return false;
});
});
});
</script>
</head>
<body>
</body>
</html>
info.php
<?php
...........
$stmt = $conn->prepare(
"SELECT *
FROM comment
WHERE post_id = :pid
");
$stmt->bindParam(":pid", $type_id, PDO::PARAM_INT);
$stmt->execute();
while($obj = $stmt->fetch()){
$username = $obj['user_name'];
$comment = $obj['comment'];
$id1 = $obj['id'];
$userimage = $obj['user_image'];
echo '<div class="txt">';
echo '<div class="comment-container">';
echo '<div class="comment-item">';
echo '<div class="comment-avatar">';
echo '<img src="user/user_images/'.$userimage.'" alt="avatar">';
echo '</div>';
echo '<div class="comment-post">';
echo '<span style="font-weight:bold;">'.$username.'&nbsp&nbspsaid....
</span>';
echo '<p style="margin-left:-11px;">'.$comment.'</p>';
echo '<input type="hidden" name="comment_id" value="'.$id.'">';
//trigger to hide/show replies
echo '<span class="view1-'.$id1.'" style="float:right;margin-top:-15px;">View all replies</span>';
//
echo '</div>';
echo '</div>';
echo '</div>';
echo '</div>';
echo '</div>';
//Relpy to comment, show only the first row
$rep = $conn->prepare("SELECT * FROM reply WHERE comment_id = :comid LIMIT 1");
$rep->bindParam(":pid", $id1, PDO::PARAM_INT);
$rep->execute();
while($obj = $rep->fetch()){
//...........same output as first without the view all replies trigger......
//Relpy to comment, show from row 2-
$rep = $conn->prepare("SELECT * FROM reply WHERE comment_id = :comid LIMIT 1,18446744073709551615");
$rep->bindParam(":pid", $id1, PDO::PARAM_INT);
$rep->execute();
while($obj = $rep->fetch()){
$cc_id = $obj['comment_id'];
//div to show/hide
echo '<div class="licom-'.$cc_id.'">';
//...........same output as first without the view all replies trigger......
}
}
}
?>
how do i re-write my JavaScript so that all div of class "licom" are hidden by default, and only the div with the same id as the trigger say 2,3,... as the case maybe would show/hide onClick.
As requested in the comments on question:
"Something like: http://jsfiddle.net/qjadyznh/ ?"
$('a').click(function(){
var id = $(this).attr('id');
if($('.'+id).css('display') == 'none')
{
$('.'+id).css('display','block');
}
else
{
$('.'+id).css('display','none');
}
})
Simple example on how to achieve the goal needed.

jQuery selected button, can't get attribute to be alerted

I'm echoing rows and would like to either delete them or increment them like a thumbs up effect... I can't seem to identify the rows individually.
This is my included jquery source
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
There are no errors in the javascript web console...
This is the click function I'm trying to implement with a test ['clicked']:
<script type="text/javascript">
$(":button").click(function() {
var selectedId = $( this ).attr(id);
alert(selectedId);
alert('clicked');
});
</script>
These are my rows which I have echoed:
<?php
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR.'dbconnect.php');
$link = new mysqli("$servername", "$username", "$password", "$dbname");
$query = "SELECT COUNT(*) FROM entries";
if ($result = $link->query($query)) {
/* fetch object array */
while ($row = $result->fetch_row()) {
if($row[0]==0){
echo "There are no entries.";
}else {
$query2 = "SELECT id,saying,date,thumbs_up,comments FROM entries ORDER by ID ASC ";
if (($result = $link->query($query2))) {
/* fetch object array */
while ($row = $result->fetch_row()) {
echo
'<div class="primary-container" align="center">'.
'<div class="entry-container" align="center">'.
$row[1]." ".
'</div>'.
'<div class="bird" align="center">'.
'Bird Up!'.
'</div>'.
'<div class="birdups" align="center">'.
$row[3].
'</div>'.
'<div class="thumbup" align="center">'.
'<button name="increment" class="button" id="'.$row[0].'">'.
'<img src="bird_up.png" width="100%" height="auto" alt="bird up thumbs up like equivalent thumbnail">'.
'</button>'.
'</div>'.
'</div>'.
'<br>'
;
}
}
}
}
/* free result set */
$result->close();
}
?>
Use event delegation for newly added html elements. And you have missed out put the single quotes for id. I hope it solves your issues thanks
$(document).on("click" , ".button" , function() {
var selectedId = $(this).attr('id');
alert(selectedId);
});

JS - jQuery Dynamic add remove Input Fields

I have a form where I add Input fields ( groups ) dynamically.
It is quite a complex form, and a PART can be seen here : FIDDLE
The actual error i get on the consul is :
Error: uncaught exception: query function not defined for Select2 s2id_autogen1
When I have fields already in the form ( the first two for example ) the EDIT and REMOVE button will work just fine .
My problem is that the REMOVE button ( styled input field ) is not working for the dynamically ADDED fields ( actually "appended" by JS and populated from PHP )
NOTE on code: I know the code is a mess :-(. It was inherited and will be cleaned soon.
it was copied and pasted from the HTML output.
The ADD , REMOVE and EDIT are actually styled like buttons ( too long and irrelevant to paste )
The actual source is PHP and it is spanning over multiple files ( so is the JS ) , and thus a bit too complicated to show here .
UPDATE : The code as per popular request :-)
public function show_field_repeater( $field, $meta ) {
global $post;
// Get Plugin Path
$plugin_path = $this->SelfPath;
$this->show_field_begin( $field, $meta );
$class = '';
if ($field['sortable'])
$class = " repeater-sortable";
echo "<div class='at-repeat".$class."' id='{$field['id']}'>";
$c = 0;
$meta = get_post_meta($post->ID,$field['id'],true);
if (count($meta) > 0 && is_array($meta) ){
foreach ($meta as $me){
//for labling toggles
$mmm = isset($me[$field['fields'][0]['id']])? $me[$field['fields'][0]['id']]: "";
echo '<div class="at-repater-block at-repater-block-'.$c.$field['id'].'"><h3>'.$mmm.'
<span class="at-re-remove">
<input id="remove-'.$c.$field['id'].'" class="buttom button-primary" type="submitkb" value="Remove '.$field['name'].'" accesskey="x" name="removek">
</span>';
echo '<script>
jQuery(document).ready(function() {
jQuery("#remove-'.$c.$field['id'].'").on(\'click\', function() {
var answer = confirm("Are you sure you want to delete this field ??")
if(!answer){
event.preventDefault();
}
jQuery(".at-repater-block-'.$c.$field['id'].'").remove();
});
});
</script>';
echo '<span class="at-re-toggle">
<input id="edit-'.$field['id'].'" class="buttom button-primary" type="" value="Edit '.$field['name'].'" accesskey="p" name="editk"></h3>
</span>
<span style="display: none;">
<table class="repeate-box wp-list-table widefat fixed posts" >';
if ($field['inline']){
echo '<tr class="post-1 type-post status-publish format-standard hentry category-uncategorized alternate iedit author-self" VALIGN="top">';
}
foreach ($field['fields'] as $f){
//reset var $id for repeater
$id = '';
$id = $field['id'].'['.$c.']['.$f['id'].']';
$m = isset($me[$f['id']]) ? $me[$f['id']]: '';
$m = ( $m !== '' ) ? $m : $f['std'];
if ('image' != $f['type'] && $f['type'] != 'repeater')
$m = is_array( $m) ? array_map( 'esc_attr', $m ) : esc_attr( $m);
//set new id for field in array format
$f['id'] = $id;
if (!$field['inline']){
echo '<tr>';
}
call_user_func ( array( &$this, 'show_field_' . $f['type'] ), $f, $m);
if (!$field['inline']){
echo '</tr>';
}
}
if ($field['inline']){
echo '</tr>';
}
echo '</table></span>
<span class="at-re-toggle"><img src="';
if ($this->_Local_images){
echo $plugin_path.'/images/edit.png';
}else{
echo 'http://i.imgur.com/ka0E2.png';
}
echo '" alt="Edit" title="Edit"/></span>
<img src="';
if ($this->_Local_images){
echo $plugin_path.'/images/remove.png';
}else{
echo 'http://i.imgur.com/g8Duj.png';
}
echo '" alt="'.__('Remove','mmb').'" title="'.__('Remove','mmb').'"></div>';
$c = $c + 1;
}
}
echo '<img src="';
if ($this->_Local_images){
echo $plugin_path.'/images/add.png';
}else{
echo 'http://i.imgur.com/w5Tuc.png';
}
echo '" alt="'.__('Add','mmb').'" title="'.__('Add','mmb').'" ><br/><input id="add-'.$field['id'].'" class="buttom button-primary" type="submitk" value="Add '.$field['name'].'" accesskey="q" name="addk"></div>';
//create all fields once more for js function and catch with object buffer
ob_start();
echo '<div class="at-repater-block">';
echo '<table class="wp-list-table repeater-table">';
if ($field['inline']){
echo '<tr class="post-1 type-post status-publish format-standard hentry category-uncategorized alternate iedit author-self" VALIGN="top">';
}
foreach ($field['fields'] as $f){
//reset var $id for repeater
$id = '';
$id = $field['id'].'[CurrentCounter]['.$f['id'].']';
$f['id'] = $id;
if (!$field['inline']){
echo '<tr>';
}
if ($f['type'] != 'wysiwyg')
call_user_func ( array( &$this, 'show_field_' . $f['type'] ), $f, '');
else
call_user_func ( array( &$this, 'show_field_' . $f['type'] ), $f, '',true);
if (!$field['inline']){
echo '</tr>';
}
}
$js_code2 ='<span class=\"at-re-remove\"><input id="remove-'.$c.$field['id'].'" class="buttom button-primary remove-'.$c.$field['id'].'" type="submi7" value="Removevv " accesskey="7" name="remove7"></span>';
if ($field['inline']){
echo '</tr>';
}
$js_code2 = str_replace("\n","",$js_code2);
$js_code2 = str_replace("\r","",$js_code2);
$js_code2 = str_replace("'","\"",$js_code2);
echo $js_code2;
echo '</table><img src="';
if ($this->_Local_images){
echo $plugin_path.'/images/remove.png';
}else{
echo 'http://i.imgur.com/g8Duj.png';
}
echo '" alt="'.__('Remove','mmb').'" title="'.__('Remove','mmb').'" ></div>';
$counter = 'countadd_'.$field['id'];
$js_code = ob_get_clean ();
$js_code = str_replace("\n","",$js_code);
$js_code = str_replace("\r","",$js_code);
$js_code = str_replace("'","\"",$js_code);
$js_code = str_replace("CurrentCounter","' + ".$counter." + '",$js_code);
echo '<script>
jQuery(document).ready(function() {
var '.$counter.' = '.$c.';
jQuery("#add-'.$field['id'].'").on(\'click\', function() {
'.$counter.' = '.$counter.' + 1;
jQuery(this).before(\''.$js_code.'\');
// jQuery("#'.$field['id'].'").append(\''.$js_code2.'\');
// alert(\''.$js_code2.'\');
update_repeater_fields();
});
});
</script>';
echo '<script>
jQuery(document).ready(function() {
jQuery(".remove-'.$c.$field['id'].'").on(\'click\', function() {
var answer = confirm("Are you sure you want to delete this field ??")
if(!answer){
event.preventDefault();
}
jQuery(".remove-'.$c.$field['id'].'").remove();
});
});
</script>';
echo '<br/><style>
.at-inline{line-height: 1 !important;}
.at-inline .at-field{border: 0px !important;}
.at-inline .at-label{margin: 0 0 1px !important;}
.at-inline .at-text{width: 70px;}
.at-inline .at-textarea{width: 100px; height: 75px;}
.at-repater-block{background-color: #FFFFFF;border: 1px solid;margin: 2px;}
</style>';
$this->show_field_end($field, $meta);
}
OK so as you've already been told, the live is deprecated.
Here's the fiddle of the solution: http://jsfiddle.net/y8JFb/2/
Basically give each new div that you dynamically create a unique ID based on your counter, then give data attribute to your remove counter which contains that ID.
Then you have your click handler:
$( document ).on( "click", ".at-re-remove", function( e ) {
$("#"+$(e.target).data("remove")).remove();
$(e.target).remove();
} );

Categories

Resources