Pass value of list view to ajax - javascript

I have a list that is being created dynamically. Part of code that creates a list is:
<ul>
<?
foreach ($folders as $folder)
{
$folder = str_replace("{imap.gmail.com:993/imap/ssl}", "", $folder);
$folder2 = str_replace("[Gmail]/", "", $folder);
?>
<li>
<a><div id="box"><? echo $folder2; ?> </div></a>
</li>
<?}
</ul>
<div id="maillist"></div>
o/p of $folder
GMAIL/All Mail
GMAIL/Drafts
GMAIL/Important
o/p of $folder2
All Mail
Drafts
Important
what i want is that when a user clicks on All Mail, value corresponding to it (in this case: GMAIL/All Mail) should get pass to another script through ajax. The same process should follow for the other values in list also
ajax code
<script>
$(document).ready(function(){
$('#box').change(function(){
var boxid = $('#box').val();
console.log($('#box'))
if(boxid != 0)
{
$.ajax({
type:'post',
url:'a_fetchmaillist.php',
data:{id:boxid},
cache:false,
success: function(returndata){
$('#maillist').html(returndata);
console.log(returndata)
}
});
}
})
})
</script>
Can anyone tell if its possible to do what i want and if yes then how will it be done

First of all do not assign the same id multiple times, instead, set a class (eg box).
Then assign a data attribute for the specific folder ( eg. box-allMails ) and select that attribute on change:
foreach ($folders as $folder)
{
$folder = str_replace("{imap.gmail.com:993/imap/ssl}", "", $folder);
$folder2 = str_replace("[Gmail]/", "", $folder);
?>
<li>
<div class="box" data-folder="<? echo $folder2 ?>"><? echo $folder2; ?></div>
</li>
<?}
Then on change:
$(document).on('click', '.box', function() {
var folder = $(this).attr('data-folder');
// ajax call..
});
UPDATE
Important: You have to listen to 'click' event instead of 'change' because you click on a div, not on an input (I've changed the code).
Event delegation: Take note at the code:
$(document).on('click', '.dynamic-element', function() { .. })
instead of:
$('.element').on('click', function() { .. });
The second will not work because you are creating the elements dynamically.
Clickable: You do not have to insert an anchor tag to make the list item clickable unless you want to redirect to another page. In your case, you can style the .box div in order to get a cursor-pointer like this:
CSS
.box { cursor:pointer }
jQuery will take care of the rest (Check the example)
$(document).on('click', '.box', function() {
var folder = $(this).attr('data-folder');
alert('You clicked on: ' + folder);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul>
<li><div class="box" data-folder="folderOne">Folder One</div></li>
<li><div class="box" data-folder="folderTwo">Folder Two</div></li>
<li><div class="box" data-folder="folderThree">Folder Three</div></li>
<li><div class="box" data-folder="folderFour">Folder Four</div></li>
</ul>

Related

is there a way to update a div with new content only using ajax

This is the div that i am updating
but i want to add a active class to the (li) item
every time the div refreshes the active class goes away
so i don`t want to refresh all the data in the (ul) but
only add (li) if there is a new data in the database,
with out refreshing the previous (li) items
<div id="contacts">
<ul id="rooms" class="rooms">
<!-- This is where the data get inserted -->
<!-- the ajax call and this -->
<li class='contact' data-val='<?php echo $room['id']; ?>'>
<div class='wrap'>
<div class='meta'>
<p class='name'><?php echo $room['sender']; ?></p>
<p class='preview'><?php echo $room['senderemail']; ?></p>
</div>
</div>
</li>
</ul>
</div>
this is my ajax call
$(document).ready(function() {
var interval = setInterval(function(){
$.ajax({
url: 'rooms.php',
success: function(data){
$('#rooms').html(data);
}
});
}, 1000);
});
in the room php
$rooms = get_rooms();
foreach($rooms as $room){
?>
<li class='contact' data-val='<?php echo $room['id']; ?>'>
<div class='wrap'>
<div class='meta'>
<p class='name'><?php echo $room['sender']; ?></p>
<p class='preview'><?php echo $room['senderemail']; ?></p>
</div>
</div>
</li>
<?php
}
the get_rooms() function
function get_rooms() {
$sql = "SELECT id, sender, senderemail FROM chatroom ";
$result = mysqli_query($GLOBALS['dbh'], $sql);
$rooms = array();
while($room = mysqli_fetch_assoc($result)){
$rooms[] = array('id'=>$room['id'], 'sender'=>$room['sender'],
'senderemail'=>$room['senderemail']);
}
return $rooms;
}
You Just need to push new data to the div as below just replace your line with:
$('#rooms').append(data);
this will add new <li> in your existing <div> after the last <li>
jquery append()
To get the id of the last <li>
var lastId = $( "#rooms li" ).last().attr('id');
Once you get the last id then pass it in your ajax call.
If I understand you correctly, your problem is that you lose the active class (which you clicked on the li container) when there is new data.
This has to do with the fact that you exchange all of the content.
There are now three options. Either
You give the rooms.php the id of the currently active li-container
and this script sets the active class for the affected container.
You transfer all the chatrooms (ids) already shown to rooms.php and only
load the new ones (this means effort later with sorting).
You save the active li class and re set it after content changed (this is the fastest)
f.e: in your Ajax succes functions:
let id=0;
let active_li = $('li.active');
if (active_li.length>0) id=active_li.data('val');
$('#rooms').html(data);
if (id!=0) $('li[data-val="'+id+'"]').addClass ('active');
A few other thoughts:
Note the interval of 1000ms. Possible it makes Problems if the request lasts longer than 1000ms. This may still work well in your tests, but maybe not anymore if there are a hundred or 1000 users in your application.
Doesn't it make sense to tell the server when you click the active room and save it in a session so that the server knows which room is active in the client?
You need to simply update your JS code like:
$(document).ready(function() {
var active_list = '';
var interval = setInterval(function(){
$.ajax({
url: 'rooms.php',
beforeSend: function(){
active_list = $('#rooms').find('li.contact.active').attr('data-val');
}
success: function(data){
$('#rooms').html(data);
$(data).find('li[data-val="' + active_list +'"]').addClass('active');
}
});
}, 1000);
});
This should solve your problem and Let me know if you still face any issue.

Prevent animation of list items on div refresh every second

I have a page which lists files from database every second.
DESIRED RESULTS
I want all the li elements to fadeIn one by one on page load.
Then fadeIn only the new li elements when new files are added to the database otherwise no animation to the already listed elements.
To get the fresh list of files I am using setInterval which in turn is causing the all the list items to fadeIn one by one every second. What should I do to achieve the desired results?
TO SUM UP WHAT I AM ASKING
I am asking for a way to show the elements as if they are fading in on by on on page load. Then if new items are added to the database then show them only one by one with the fading effect but at that time the fading effect should not be applied to the older items.
JS
$(document).ready(function() {
var filelist = $('#file_list');
$('#loading').show();
var checkUpdate = function () {
$.ajax({
type: "GET",
url: "generate_list.php",
success: function (result) {
$('#loading').hide();
var arr = JSON.parse(result);
console.log(arr);
if (arr.length > 0) {
$('#empty_storage').hide();
filelist.html(arr);
$('li').each(function (i) {
$(this).delay(400*i).fadeIn(400);
});
}
else {
filelist.html('');
$('#empty_storage').show();
}
},
error: function (response) {
$('#loading').hide();
$.alert({
theme: 'black',
title: false,
content: response
});
}
});
setTimeout(checkUpdate, 1700);
};
setTimeout(checkUpdate, 1700);
});
CSS
#file_list li
{
overflow: hidden;
padding-top: 4px;
padding-bottom: 4px;
margin-bottom: 5px;
display: none;
}
PHP SNIPPET
// Fetching only last 10 records LIFO
$query = $dbh->prepare("SELECT * FROM uploads ORDER BY id DESC LIMIT 10");
$query->execute();
$items = array();
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
// Generate respective data to display
$file_id = $row['id'];
$ico_path = $base_icon_src.get_logo($row['file_ext']);
$full_file_name = $row['file_name'].'.'.$row['file_ext'];
$file_ext = $row['file_ext'];
$file_code = $row['file_code'];
$download_file_path = './storage/'.$file_code.'.'.$file_ext;
$file_size = $row['file_size'];
$file_upload_time = $row['timestamps'];
if(file_exists($download_file_path)) {
// Generating markup
$items[] = '<li>
<div class="f_icon"><img src="' . $ico_path . '"></div>
<div class="left_wing">
<div class="progressbar"></div>
<a class="download_link" href="#" id="'.$file_id.'"><div class="f_name">' . $full_file_name . '</div></a>
<div class="f_time_size">' . date("M d, Y", $file_upload_time) . ' • ' . human_filesize($file_size) . '</div>
</div>
<div class="right_wing">
<div class="f_delete">
<a class="btn btn-danger" href="#" aria-label="Delete" data-id="'.$file_id.'" data-filename="'.$full_file_name.'">
<i class="fa fa-trash-o fa-lg" aria-hidden="true" title="Delete this?"></i>
</a>
</div>
</div>
</li>';
}
}
//content in $items must be in UTF-8
echo json_encode($items);
In general - this is the workflow you should follow:
On page load (first time) get the list of the files you want to preview (it can be all of them, or only the last X). Make sure you have the id (from the database) of the last item (the largest id, if your items are orders). We will call this MAX_ID.
Once loaded - animate them one by one.
Using setTimeout, get the "next bulk" of files (you need to pass to the php script the ID that you saved from #1, so you can get only the files where id > max_id).
If you got new files - add them (you can animate them one by one).
Update the MAX_ID to be the new id you got from the "new bulk".
Inside the success function you should call again (using the setTimeout function to the code the gets the "next bulk" (#3).
Here is a simple example:
$(function() {
$('li').hide();
$($("li").get().reverse()).each(function(i) {
$(this).delay(400*i).fadeIn(400);
});
});
items = ['a', 'b', 'c', 'd']
$('#a1').click(function() {
$(items).each(function(i, val) {
li = $('<li>').text(val).hide();
$('#u1').prepend(li);
li.delay(400*i).fadeIn(400);
});
});
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="u1">
<li>5</li>
<li>4</li>
<li>3</li>
<li>2</li>
<li>1</li>
</ul>
<div id="a1">Click to add more items</div>

jQuery .each not iterating through li

Have a bunch of li's that are essentially true or false questions. Problem is that it is working for the first li but not the next, next, next etc
jquery code is:
<script>
jQuery(document).ready(function() {
//Run the each iteration
jQuery('#question').each(function(i){
// Hide the initial values
jQuery('#true').hide();
jQuery('#false').hide();
var answer = '<?php echo the_sub_field( 'true_or_false' ); ?>';
console.log(answer);
jQuery("#button").click(function($){
$.preventDefault();
if( answer == 'True' ) {
jQuery('#false').hide();
jQuery('#true').show();
}
});
jQuery("#button2").click(function($){
$.preventDefault();
if( answer == 'True' ) {
jQuery('#true').hide();
jQuery('#false').show();
}
});
});
});
</script>
html code is:
<li id="question">
<div id="statement">
<?php the_sub_field( 'question' ); ?>?
</div>
<div id="true">
<?php the_sub_field( 'true_answer' ); ?>
</div>
<div id="false">
<?php the_sub_field( 'false_answer' ); ?>
</div>
true
false
</li>
I'm getting the right values to check against inside the console - however the each doesn't seem to be doing it for "each".
Thanks in advance :)
Here's the raw output:
<ul>
<li id="question">
<div id="question">
George likes to sing?
</div>
<div id="true">
You are correct, even when it's out of tune </div>
<div id="false">
Sadly we wish it was false, but it's true </div>
true
false
</li>
<script>
jQuery(document).ready(function() {
//Run the each iteration
jQuery('#question').each(function(i){
// Hide the initial values
jQuery('#true').hide();
jQuery('#false').hide();
var answer = 'True';
console.log(answer);
jQuery("#button").click(function($){
$.preventDefault();
if( answer == 'True' ) {
jQuery('#false').hide();
jQuery('#true').show();
}
});
jQuery("#button2").click(function($){
$.preventDefault();
if( answer == 'True' ) {
jQuery('#true').hide();
jQuery('#false').show();
}
});
});
});
</script>
<li id="question">
<div id="question">
Aj likes to say the word "WoWoWoWomp"??
</div>
<div id="true">
You are right, almost twenty times a day </div>
<div id="false">
Unfortunately you were wowowo wrong :) </div>
true
false
</li>
<script>
jQuery(document).ready(function() {
//Run the each iteration
jQuery('#question').each(function(i){
// Hide the initial values
jQuery('#true').hide();
jQuery('#false').hide();
var answer = 'False';
console.log(answer);
jQuery("#button").click(function($){
$.preventDefault();
if( answer == 'True' ) {
jQuery('#false').hide();
jQuery('#true').show();
}
});
jQuery("#button2").click(function($){
$.preventDefault();
if( answer == 'True' ) {
jQuery('#true').hide();
jQuery('#false').show();
}
});
});
});
</script>
</ul>
I am assuming this <li> is the pattern for all.
Given this: id is only allowed to be used one time ... either:
Change the id for each type (i.e. id="Question1", id="Question2"), or
Use classes (i.e. class="Question") which will allow for selecting multiple elements at one time.
While I referenced id="Question" above, this pattern should remain true. An id must be unique; this applies for: question, statement, true, false, button, button2, and any other id's you have listed.
You do not need to iterate. Replacing the id with class and rewriting the jquery shortens the code greatly. Here is the HTML output -
<ul>
<li>
<div class="question">George likes to sing?</div>
<div class="true">You are correct, even when it's out of tune</div>
<div class="false">Sadly we wish it was false, but it's true</div> true
false
</li>
<li>
<div class="question">Aj likes to say the word "WoWoWoWomp"??</div>
<div class="true">You are right, almost twenty times a day</div>
<div class="false">Unfortunately you were wowowo wrong :)</div> true
false
</li>
</ul>
Given that you can use this jQuery, which only needs to appear one time, not multiple times as you have done above. One set of functions handles all of the questions / answers. -
jQuery(document).ready(function () {
// hide the answers
jQuery('.true, .false').hide();
// show answer based on click
jQuery('.button').click(function (e) {
e.preventDefault();
jQuery(this).closest('li').find('.true').show();
jQuery(this).closest('li').find('.false').hide();
});
jQuery('.button2').click(function (e) {
e.preventDefault();
jQuery(this).closest('li').find('.false').show();
jQuery(this).closest('li').find('.true').hide();
});
});
You're also running an unnecessary test to see if a variable is set because the variable, being set as it is, is always set, so this has been removed from the code.
Here is a working example.
It's always best to use a class for iterating through items. Id should only be used once (for accessing a unique element). See the following example.
Jquery Code.
$('div#questions ul li.answer').each(function() {
console.log($(this).text());
});
Html.
<div id="questions">
<ul>
<li class="answer">True</li>
<li class="answer">True</li>
<li class="answer">False</li>
<li class="answer">False</li>
<li class="answer">True</li>
</ul>
</div>

How do you apply an item, from a list of results, to the parent Div tag for the current object?

I am trying to build a function for inserting the number of Facebook Likes into a Div tag. So far, I have a script that can get the URL from a Div tag which is inside of another Div tag called 'entry' and then have the .getJSON() method retrieve the number of Facebook likes for each entry.However, I can't get each retrieved value of Facebook Likes to insert into a Div tag for each entry. Please note, I simplified my code to where it alerts each Facebook Like value. This is what I have so far:
<div class="entry">
<div class="fburl">https://graph.facebook.com/zombies</div>
<div class="facebook-likes"></div>
</div>
<div class="entry">
<div class="fburl">https://graph.facebook.com/starwars</div>
<div class="facebook-likes"></div>
</div>
And here's my jQuery:
$(document).ready(function(){
$(".entry").each(function() {
var fbURL = $(this).find(".fburl").html();
$.getJSON(fbURL, function(fbData) {
var fbArr = fbData['likes'];
alert(fbArr);
});
});
});
​So what I am trying to do is iterate through each entry, get the Open Graph URL for it, retrieve the Likes value, and then insert it into the appropriate Div tag, so the code should render as:
<div class="entry">
<div class="fburl">https://graph.facebook.com/zombies</div>
<div class="facebook-likes">2,586 Likes</div>
</div>
<div class="entry">
<div class="fburl">https://graph.facebook.com/starwars</div>
<div class="facebook-likes">8,905,721 Likes</div>
</div>
​
​
$(document).ready(function() {
$('.entry').each(function() {
var $this = $(this),
fbURL = $this.children('.fburl').html();
$.getJSON(fbURL, function(fbData) {
$this.children('.facebook-likes').html(fbData['likes'] + ' Likes')
});
});
});
See: http://api.jquery.com/children
Demo: http://jsfiddle.net/9EALz/2/
Note: Using children() is going to be marginally more efficient than using find() as it limits the DOM traversal to a single level ( http://jsperf.com/find-vs-children/13 ). Cashing the jQuery object $(this) via var $this = $(this) is also slightly more efficient as it prevents unnecessary selector interpretation ( http://jsperf.com/jquery-cache-vs-no-chace ).
You may want this
$(document).ready(function(){
$(".entry").each(function() {
var entry=$(this), fbURL=$(".fburl", entry).html(),
el=$('.facebook-likes', entry);
$.getJSON(fbURL, function(fbData) {
el.html(numberWithCommas(fbData['likes'])+" Likes");
});
});
});​
A thousand separator function from here
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
DEMO.
Update:
Alternatively you can use this too (using data-attribute) without an extra div for fburl, i.e.
<div class="entry">
<div data-fburl="https://graph.facebook.com/zombies" class="facebook-likes"></div>
</div>
JS
$(".entry").each(function() {
var entry=$(this), fbURL = $(".facebook-likes", entry).attr('data-fburl'),
el=$('.facebook-likes', entry);
$.getJSON(fbURL, function(fbData) {
el.html(numberWithCommas(fbData['likes'])+" Likes");
});
});

Get the ID of a sibling after a link is clicked

I use the following code and I would like to be able to get the ID attribute from the <li> (the post ID) that is associated with an <a> when it is clicked, but I cannot figure out how do do this. Is anybody able to help me at all?
<li id="custom_latest_news-5" class="widget custom_widget_latest_news">
<div class="widget-title">
Latest news
</div>
<div class="widget-content">
<ul class="link-list ajax-links">
<li id="post-5521">Last call for self-assessment tax forms</li>
<li id="post-5523">Young drivers gambling on no insurance</li>
<li id="post-5520">Tenants forced to abandon pets</li>
</ul>
</div>
</li>
Here is the JS that I currently have -
/**
* Intercept a click for page refresh and run the page refresh JS
*/
$(function(){
$('.ajax-links').delegate('li a', 'click', function(e){
/** Prevent the click from doing anything */
e.preventDefault();
/** Get the post ID */
var post_id = '???';
});
});
Thanks.
I believe you need
var post_id = $(this).parent().attr('id');
Example: http://jsfiddle.net/FwqGT/
You could use:
var post_id = $(this).parent().attr("id");
If you need to get the following (sibling) <li>, you could also do:
var next_id = $(this).parent().next().attr("id");
The li:s with the post ids in your markup are actually not siblings but parents.
This ought to do it:
var post_id = $(this).parent().attr('id'));

Categories

Resources