HTML File doesnt update with PHP and JQuery .load() - javascript

Please help, this really made me stuck. I have HTML file "newsfeed.html" that loads onto another page using JQuery .load() and I have PHP file "ajax_fetch_posts.php". My HTML file uses XMLHTTPREQUEST Object to fetch data from my PHP file, my problem begun when I noticed that everytime I update my HTML file code and HIT refresh on my browsers reload, that page doesn't change at all, whatever I do it keeps on displaying the same all over and over again. I also tried to clear my browser cache or cookies but it's useless. Is this some sort of <meta> tag? or header() in php? It seemed my page being kept as cached copy or is this some sort of virus?
Here is my html code so far:
<div id="newsfeed_container" class="newsfeed-container">
<div id="post">
<ul>
<li>
<table border="0">
<tr>
<tr><!-- RESERVED! --></tr>
<tr>
<td style="font: 11px 'lucida grande', tahoma, verdana, arial, sans-serif;width:360px;">
<div style='width:207px;word-wrap: break-word;white-space: pre-wrap;border:0px solid; font-size: 11px;position:relative;z-index:10;margin:4px 0px 0px 7px;width:280px;display:inline-block;width:300px;background-color:#f7f2f1;box-shadow:-1px 1px 0px #eec7c7;-moz-box-shadow:-1px 1px 0px #eec7c7;-webkit-box-shadow:-1px 1px 0px #eec7c7;padding: 3px;left:50px;' id='div_shout_handle'>this is an example</div>
</td>
</tr>
<tr>
<td>
<img src='images/default.jpg' height='50' style='border:1px solid #CDB3AB'/>
<img src="images/asset/shout-body-tail.png" style="position:relative;top:-20px;"/>
</td>
</tr>
<tr><!-- RESERVED! --></tr>
</tr>
</table>
</li>
</ul>
</div>
</div>
Here's JavaScript:
$(document).ready(function() {
var xhr = new XMLHttpRequest();
var form = new FormData();
form.append('EmailAd', EmailAd);
form.append('UserID', UserID);
form.append('Studentnumber', Studentnumber);
xhr.open('POST', 'ajax/ajax_fetch_post.php', true);
xhr.onload = function() {
var div_shout_handle = document.getElementById('div_shout_handle');
div_shout_handle.innerHTML = this.response;
}
xhr.send(form);
});
PHP File:
<?php
include '../include/class.inc.php';
$array_post = array();
if($_SERVER['REQUEST_METHOD'] == 'POST') {
$pdo = new dbConnection;
$pdo->dbInstance($db);
$stmt = $db->prepare("SELECT * FROM posts");
$stmt->setFetchMode(PDO::FETCH_ASSOC);
$stmt->execute();
while($row = $stmt->fetch()) {
array_push($array_post, $row['Content']);
}
echo json_encode(array('Posts' => $array_post));
}
?>
Please help, this probably sound so easy.

Related

Cordova/PhoneGap rendering local PHP?

I'm making a web using PhoneGap. I need to use a PHP page, but I want a real fluid website, so I opted for replacing a div with some PHP using JavaScript when loaded.
When I launch the page "mypage.html" I check the user connection with this function:
<script>
function checkConnection(){
var online, speed;
/*
condizione di controllo per determinare se l'app viene correntemente testata
in un simulatore o dispositivo mobile (quindi utilizzando PhoneGap) o in un normale browser
che supporta l'HTML5
*/
if(typeof cordova != "undefined"){
/*
si tratta di un dispositivo vero e proprio o di un simulatore, quindi
utilizziamo il plugin "Connection" messo a disposizione da Phonegap
*/
var networkState = navigator.connection.type;
var states = {};
states[Connection.UNKNOWN] = 'Unknown';
states[Connection.ETHERNET] = 'Ethernet';
states[Connection.WIFI] = 'WiFi';
states[Connection.CELL_2G] = 'Cell_2G';
states[Connection.CELL_3G] = 'Cell_3G';
states[Connection.CELL_4G] = 'Cell_4G';
states[Connection.CELL] = 'Cell_generic';
states[Connection.NONE] = 'None';
//determino il tipo di connessione in base all'oggetto "states" appena definito grazie al plugin Phonegap
var connType = states[networkState];
if(connType=='None')
online = false;
else{
online = true;
if(connType=="Cell_2g" || connType=="Cell_generic")
speed="slow";
else
speed="fast";
}
}else{
/*
si tratta di un normale browser desktop o mobile, quindi
utilizziamo la funzionalità HTML5
*/
online = navigator.onLine;
if(online){
var conn = navigator.connection || {'bandwidth':'0'};
//utilizziamo il metodo "bandwidth" per determinare la velocità di connessione, il quale restituisce un valore numerico che indica la larghezza di banda della connessione corrente
if(conn.bandwidth>2)
speed="fast";
else
speed="slow";
}
}
return online?speed:false;
}
var deviceConnection = checkConnection();
if(deviceConnection){
if(deviceConnection == "slow"){
//gestione connnessione lenta
}else{
//gestione connnessione veloce
}
}else{
/*
gestione transizioni ed effetti per mostrare all'utente
un gradevole avviso di mancanza di connessione
*/
location.href="errorconnection.html";
}
</script>
This is the AJAX code :
<div id="container">
<script>
$( "#container" ).load("http://www.mywebsite.org/FOLDER/page.php #container");
</script>
</div>
When I launch "mypage.html" on my browser locally it works ok, except for that it shows for a bit of php code. When I launch "mypage.html" on PhoneGap it shows me only a part of the php code and nothing else.
...
</head>
<body style="background-color:#e20a7e">
<div id="navigation">
<table width="100%">
<tr valign="bottom">
<td valign="middle" width="25%" align="center">
</td>
<td valign="bottom" width="50%" align="center">
<img src="IMG/LOGO-WHITE.png" class="logonbar" alt="DONUT"/>
</td>
<td onClick="window.location='loginpage.php'" width="25%" align="center" valign="middle">
<img src="IMG/icon/usr.png" class="icons3"/>
</td>
</tr>
</table>
</div>
<div id="container">
<?php
$DBhost = "localhost";
$DBuser = "xx";
$DBpass = "";
$DBName = "xx";
$table = "Database";
mysql_connect($DBhost,$DBuser,$DBpass) or die("mysql_error()");
#mysql_select_db("$DBName") or die("mysql_error()");
$sqlquery = "SELECT * FROM `Database` ORDER BY data DESC";
$result = mysql_query($sqlquery);
$number = mysql_num_rows($result);
$i = 0;
while ($i < $number) {
$festa[$i] = mysql_result($result,$i,"festa");
$luogo[$i] = mysql_result($result,$i,"luogo");
$idfesta[$i] = mysql_result($result,$i,"ID");
$data[$i] = mysql_result($result,$i,"data");
$nomeimg[$i] = mysql_result($result,$i,"nomeimg");
$data[$i] = data_eng_to_it_($data[$i]);
echo"
<!--INIZIO DIV EVENTO-->
<a href=\"pagevento.html?ID=$idfesta[$i]\">
<div style=\"width:90%; display:block; margin:0 auto;
padding-top:10px; margin-top:10px; padding-left:10px;
background-color:#FFF; padding-bottom:10px;
border-left:solid 5px #e20a7e;
-webkit-box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.7);
-moz-box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.7);
box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.7);\">
<table width=\"100%\" style='table-layout:fixed'>
<tr valign=\"middle\">
<td valign=\"middle\" align=\"center\" class=\"evntfoto\"
style=\"background-image:url(foto/$nomeimg[$i]);
background-position:center;
background-size: cover;\">
</td>
<td valign=\"top\" align=\"left\" id=\"evnttxt\">
<font color=\"#0066FF\" size=\"+2\"> <b> ".$festa[$i]." </b></font> <br>
".$data[$i]." <br>
<font color=\"#585858\"> ".$luogo[$i]." </font> <br>
</td>
</tr>
</table>
</div>
</a>
<!--FINE DIV EVENTO-->
";
$i++;
}
?>
</div>
</div>
</body>
</html>
and when I run the page it shows me:
".$festa[$i]."
".$data[$i]."
".$luogo[$i]."
"; $i++; ?>
but only from PhoneGap. In other browsers, Safari on Mac, Google Chrome on Mac and Safari on iPhone it works correctly, and shows me that code for only a second. What could be the problem?
Summary: You are loading both a local and a server version of a PHP page at the same time, and you are having a CORS issue with the server load on PhoneGap.
I was able to reproduce your unexpected output here (http://jsfiddle.net/Drakes/gq0my18r/). I took your HTML/PHP code and rendered it as HTML only. This was the output:
".$festa[$i]."
".$data[$i]."
".$luogo[$i]."
"; $i++; } ?>
You might be serving a local copy of your PHP file on your phone, and then fetching a server version, or your server is responding with an unprocessed version of your PHP page somehow.
Now, you said something interesting:
... in other browsers, safari on mac, google chrome on mac and safari on iphone it works correctly, and shows me that code for only a second
This leads me to believe that you are rendering the local HTML version, then somehow requesting the server version. I looked at the links you supplied me in the comments and noticed something striking in your HTML that explains everything.
You have
<div id="container">
<script>
$( "#container" ).load("http://www.bparty.org/APP/eventi.php #container");
</script>
</div>
and
<div id="container">
<script>
$( "#container" ).load( "eventi.php #container" );
</script>
</div>
on the same page. There is a myriad of trouble happening here. Now you have multiple container divs with the same id, and there is a race condition to load your local PHP version (which can't render locally), and then it is being replaced with the server version which can render PHP. This explains that one-second lag you described in some browsers.
CORS
However, your huge problem with PhoneGap and PHP is that you cannot simply load external pages into your phone app using AJAX because of something called CORS (Cross-origin resource sharing). It's just disallowed. We're getting into hacky-land now, but you can do some magic and make it work. I'm not recommending this outright, but you can make your setup work by adding this to the top of eventi.php:
<?php
header("Access-Control-Allow-Origin: *");
Also, please, please stop using #container in your fetch URL "http://www.bparty.org/APP/eventi.php #container". Who knows how PhoneGap handles that.
According to the documentation, Phonegap can only handle files with HTML, CSS, and JavaScript. If you want to use PHP or any other language for your application, you have to handle PHP on your server, and from a mobile app request only static data and JS

chat div in ajax using css

Chat div in ajax using css. Am building a chat system using ajax, when the chat text exceeds the length of the screen, the newly text message tends to scroll downward beneath the chat text input form instead of scrolling upward and as a result, newly sent message cannot be been unless you scroll downward. Below is how I built my css. any help will be appreciated
JS:
$(document).ready(function() {
setInterval(function() {
$.ajax({
type: "POST",
url:'chatposts.php',
data:"uname="+uname,
success:function(data) {
$('#chatdisplay').html(data);
} })
var elem = document.getElementById('comdisplay');
elem.scrollTop = elem.scrollHeight;
}, 10000);
});
CSS:
.chatdisplay {
background-color:#FF00FF;
min-width:100px;
height:auto;
margin-left:56px;
padding:10px 0 10px 10px;
margin-top:1px;
font-size:12px;
color:#000;
}
#chatbox {
display:block;
bottom:0;
margin-left: 0px;
position:fixed;
width:100%;
}
HTML:
<div id="chatdisplay" >
Display chat message...
</div>
<div id="chatbox">
<form action="" method="post" name="chat_form">
<input name="chat_comment" class="comment" type="text" id="chat_comment">
<input name="chatBtn" class="chatBtn" id="chatbtn" type="submit" value="Chat" />
</form>
</div>
PHP:
<?php
require('db.php');
$result = $db->prepare('
select * from chat where pid=:pid order by cmid');
$result->execute(array(':pid' => '43'));
$countcom=$result->rowCount();
while ($full = $result->fetch()) {
$cmid=htmlentities($full['cmid'], ENT_QUOTES, "UTF-8");
$cname1=htmlentities($full['comment'], ENT_QUOTES, "UTF-8");
$comment_pic2=htmlentities($full['user_pic66'], ENT_QUOTES, "UTF-8");
$tt=htmlentities($full['c_time'], ENT_QUOTES, "UTF-8");
$bb=htmlentities($full['user_name66'], ENT_QUOTES, "UTF-8");
?>
<div id="chatdisplay<?php echo $cmid;?>" class="chatdisplay" >
<img width="20" height="20" src='http://localhost/sri_chat/db/photo/<?php echo $comment_pic2;?>' />
<?php
echo $bb;
?>: <?php echo $cname1;?>
</div>
<?php }?>
I don't think this is possible with pure CSS. But you could do it with JavaScript.
Example:
HTML: (A bit different than yours, but same concept)
<div class="message">
<p>This was the first message</p>
<p>Another message</p>
<p>A third message about something a bit longer</p>
</div>
<button>New message</button>
JS: (I used jQuery in this example)
var button = $('button');
var container = $(".message");
button.on('click', function() {
container.append('<p> A new message</p>');
container.scrollTop(container[0].scrollHeight);
});
Demo:
http://jsfiddle.net/u4u33286/3/
Well the best way to solve the problem would be to invert how you are putting the messages into the box (newest at top) but if you want them at the bottom.
var chatBox = document.getElementById("chatdisplay");
chatBox.scrollTop = chatBox.scrollHeight;
Should do it.
http://www.w3schools.com/jsref/prop_element_scrolltop.asp
For more info on the Dom property
*Kris beat me to it

pass the url from php via javascript pop-up

url.php
<?php
include "../googlelogin/src/Google_Client.php";
include "../googlelogin/src/contrib/Google_Oauth2Service.php";
include "../fblogin/src/facebook.php";
//FOR FACEBOOK LOGIN//
$fbconfig['appid' ] = "329433909112888";
$fbconfig['secret'] = "ca2bdc9990b0b2ad0763abcka79dce60c91f";
$fbconfig['baseurl'] = "http://localhost/sbs/fblogin/index.php?rd=hm";
$facebook = new Facebook(array(
'appId' => $fbconfig['appid'],
'secret' => $fbconfig['secret'],
'baseurl'=>$fbconfig['baseurl'],
'cookie' => true,
));
$loginUrl = $facebook->getLoginUrl(
array('redirect_uri'=>$fbconfig['baseurl'],
'scope' => 'email,offline_access,publish_stream,user_birthday,user_location,user_work_history,user_about_me, user_hometown,user_photos ,user_work_history',
)
);
//FOR GOOGLE LOGIN//
$client = new Google_Client();
$client->setApplicationName("Google UserInfo PHP Starter Application");
$client->setApprovalPrompt('auto');
$client->setClientId('777637661406-cp7kekelp1l5i0se9f576sqf36a0q4lc.apps.googleusercontent.com');
$client->setClientSecret('uztEmqG1CFt06752lqtRZjZ-');
$client->setState('hm');
$client->setRedirectUri('http://localhost/sbs/googlelogin/index.php');
$client->setDeveloperKey('AIzaSyD3HiHElDciE6Pb5UfZtDdNWe_kiKNk6rg');
$oauth2 = new Google_Oauth2Service($client);
$authUrl = $client->createAuthUrl();
?>
I want to pass the FACEBOOK , TWITTER AND GOOGLE url in via java script in the pop up . I know the PHP part but I don't know the JS part
pop.js
function sin(){
var lbox = new LadduBox();
lbox.init({"width":495, "height":242, "HTML":'<div style="width:495px; height:242px; background-color:#ffffff; border:2px solid orange;"><table cellspacing="0" cellpadding="0" border="0" align="center" width="485" height="152" style="font-family:arial; font-size:20px; font-weight:bold;"><tr><td align="right" colspan="3"><img src="images/untitled-1.png" style="margin:10px; cursor:pointer;" id="btnClose"/></td></tr><tr><td height="30" colspan="3"> <div style="font-family:arial; font-size:20px; color:#ff6c00; padding-left:200px;">SIGN IN</div></td></tr><tr><td><div style="margin:10px; font-size:14px;">EMAIL<br><input type="text"/></div><br><div style="margin-left:10px; margin-top:-10px; font-size:14px;">PASSWORD<br><input type="text"/></div></td><td><img src="images/orbar.png" /></td><td align="center"><img src="images/redfb.png" style="margin-bottom:7px;"/><br><img src="images/redgoogle.png" style="margin-bottom:7px;"/><br><img src="images/redtwitter.png" /></td></tr></div>', 'btnCloseId':'#btnClose'});
lbox.fire();
}
When the user click on the sign-in button , this pop-up will show . I want FACEBOOK , TWITTER AND GOOGLE URL in the pop-up but i don't know how to pass it in javascript .
"When the user click on the sign-in button, this pop-up will show":
Now, the popup code will be inside a PHP file. Include url.php in this file at top, then you can access those $authUrl or $loginUrl anywhere in this file.
Now, in your sin(), you have HTML inside your lbox.init. There you can put these urls as below. BUT, REMOVE sin() FROM INSIDE YOUR JS FILE, AND PUT IT IN THE PHP FILE IN HEAD SECTION. Because, JS file cannot have PHP code.
<div style="width:495px; height:242px; background-color:#ffffff; border:2px solid orange;">Facebook LoginGoogle Login</div>
Just an example, you can put this anywhere you want within the html. If you want to put PHP inside .js file, you have to do something like below:
AddType application/x-httpd-php .js
AddHandler x-httpd-php5 .js
<FilesMatch "\.(js|php)$">
SetHandler application/x-httpd-php
</FilesMatch>
Add the above code in .htaccess file and run php inside js files

Multiple IP Camera Feeds On Same Webpage

I have 2 IP Cameras that have a internal server page (i.e. http:\192.168.1.10\video.html). This page receives jpeg images from the camera and auto-refreshes (loads) using javascript.
Source code from the video.html
<html>
<head>
<title>ipCam - JPEG Video</title>
<style type='text/css'>
html,body
{
background-color:white;
color:black;
font-family:arial;
font-size:12pt;
}
a,a:visited,a:active
{
color:grey;
text-decoration:none;
}
a:hover
{
text-decoration: underline;
}
h1
{
background-color:black;
color:white;
padding:5px;
}
h2
{
background-color:lightgrey;
padding:5px;
}
</style>
<script type='text/javascript'>
function loadImage()
{
var now=new Date();
document.getElementById('the_img').src='image.jpg?'+now.getTime();
}
</script>
</head>
<body>
<img id='the_img' src='image.jpg' onload='loadImage()' onerror='loadImage()'>
<br><br>
<a href='.'>Home</a>
</body>
What I would like to do is build a custom site that has both live feeds in it. I would prefer not to use <iframe>. I would rather use Javascript or something of the sort.
I have a basic understanding of HTML but very little Javascript experience. I can obviously look at the code a get a good idea of what is going on, but this has stumped me!
Any help would be appreciated!
I would guess that you could create a new HTML page (just copy the video.html from one of the cameras) on a local webserver and modify the script to include the ID of the img element you are updating and the IP address of the camera you are grabbing the feed from...something like this (which is set to automatically update the images every 4 seconds) -- (disclaimer: air code, not tested)
Thanks #A.M.K. for fixing some stupid mistakes in my code:
<script type='text/javascript'>
function loadImage(imgID, address)
{
var now=new Date();
document.getElementById(imgID).src='http://' + address + '/image.jpg?'+now.getTime();
}
setInterval(function() {
loadImage("the_img_1", "192.168.0.1");
loadImage("the_img_2", "192.168.0.2");
}, 4000); //Interval to refresh at, in milliseconds
</script>
Then just setup another img tag to receive the image:
<body>
<img id='the_img_1' src='http://192.168.0.1/image.jpg'>
<br><br>
<img id='the_img_2' src='http://192.168.0.2/image.jpg'>
<a href='.'>Home</a>
</body>
Note that you have two img elements now, each with a unique id which is fed to the function along with the IP address of the camera.
That may not work exactly in your situation, but that should give you an idea of how to accomplish it...
// JS 9 CAM...
//LAN.JS add http : // if you need
var URL11='IP:Port/snapshot.cgi?&user=XXXXX&pwd=XXXXX';
var URL12='IP:Port/cgi-bin/CGIProxy.fcgi?cmd=snapPicture2&usr=XXXXX&pwd=XXXXX';
var URL13='IP:Port/cgi-bin/CGIProxy.fcgi?cmd=snapPicture2&usr=XXXXX&pwd=XXXXX';
var URL14='IP:Port/snapshot.cgi?&user=XXXXX&pwd=XXXXX';
var URL15='IP:Port/snapshot.cgi?&user=XXXXX&pwd=XXXXX';
var URL16='IP:Port/snapshot.cgi?&user=XXXXX&pwd=XXXXX';
var URL17='IP:Port/snapshot.cgi?&user=XXXXX&pwd=XXXXX';
var URL18='IP:Port/snapshot.cgi?&user=XXXXX&pwd=XXXXX';
var URL19='IP:Port/snapshot.cgi?&user=XXXXX&pwd=XXXXX';
var L=window.location.search;
L=L.substring(1,5);
if(L=="")L=1;
NewImage=new Image();
var I=new Date().getTime();
var imgW=320*L;
function kamera1011(){document.getElementById("imgDisplay11").src=URL11+'&'+I++;};
function kamera1012(){document.getElementById("imgDisplay12").src=URL12+'&'+I++;};
function kamera1013(){document.getElementById("imgDisplay13").src=URL13+'&'+I++;};
function kamera1014(){document.getElementById("imgDisplay14").src=URL14+'&'+I++;};
function kamera1015(){document.getElementById("imgDisplay15").src=URL15+'&'+I++;};
function kamera1016(){document.getElementById("imgDisplay16").src=URL16+'&'+I++;};
function kamera1017(){document.getElementById("imgDisplay17").src=URL17+'&'+I++;};
function kamera1018(){document.getElementById("imgDisplay18").src=URL18+'&'+I++;};
function kamera1019(){document.getElementById("imgDisplay19").src=URL19+'&'+I++;};
function kamera1020(){document.getElementById("imgDisplay20").src=URL20+'&'+I++;};
function kamera1021(){document.getElementById("imgDisplay21").src=URL21+'&'+I++;};
function kamera1022(){document.getElementById("imgDisplay22").src=URL22+'&'+I++;}
<! HTML-index.htm >
<html>
<script language="JavaScript" src="js/lan.js"></script>
<body onload="kamera1011(); kamera1012(); kamera1013(); kamera1014(); kamera1015(); kamera1016(); kamera1017(); kamera1018(); kamera1019();>
<table border="1" width="100%" cellspacing="1" cellpadding="1">
<tr>
<td width="100%" align="center">
</td>
<td>
<a href="index.htm">
Updates Cams...
</a>
</td>
</tr>
<tr>
<td>
<! Cam 1 >
<img id="imgDisplay11" border="1" width="412" height="318" onload=setTimeout("kamera1011()",10) onerror=setTimeout("kamera1011()",100)>
</td>
<td>
<! Cam 2 >
<img id="imgDisplay12" border="1" width="412" height="318" onload=setTimeout("kamera1012()",10) onerror=setTimeout("kamera1012()",100)>
</td>
<td>
<img id="imgDisplay13" border="1" width="412" height="318" onload=setTimeout("kamera1013()",10) onerror=setTimeout("kamera1013()",100)>
</td>
</tr>
<tr>
<td>
<img id="imgDisplay14" border="1" width="412" height="318" onload=setTimeout("kamera1014()",10) onerror=setTimeout("kamera1014()",100)>
</td>
<td>
<! Cam 5 >
<img id="imgDisplay15" border="1" width="412" height="318" onload=setTimeout("kamera1015()",10) onerror=setTimeout("kamera1015()",100)>
</td>
<td>
<! Cam 6 >
<img id="imgDisplay16" border="1" width="412" height="318" onload=setTimeout("kamera1016()",10) onerror=setTimeout("kamera1016()",100)>
</td>
</tr>
<tr>
<td>
<! Cam 9 >
<img id="imgDisplay17" border="1" width="412" height="318" onload=setTimeout("kamera1017()",10) onerror=setTimeout("kamera1017()",100)>
</td>
<td>
<! Cam 8 >
<img id="imgDisplay18" border="1" width="412" height="318" onload=setTimeout("kamera1018()",10) onerror=setTimeout("kamera1018()",100)>
</td>
<td>
<! Cam 9 >
<img id="imgDisplay19" border="1" width="412" height="318" onload=setTimeout("kamera1019()",10) onerror=setTimeout("kamera1019()",100)>
</td>
</tr>
</table></html>
Just put the following javascript in your page, changing the interval parameter to your like:
<script type='text/javascript'>
var interval = 5; //Interval in seconds, to retrieve images
setInterval(function loadImage() {
var now=new Date();
document.getElementById('the_img').src='image.jpg?'+now.getTime();
}, interval * 1000);
</script>
and in the html just insert the image wherever you want, like this:
<img id='the_img' src='image.jpg'>

Export to csv in jQuery

I am dynamically generating a div which is like :
<div id='PrintDiv'>
<table id="mainTable">
<tr>
<td>
Col1
</td>
<td>
Col2
</td>
<td>
Col3
</td>
</tr>
<tr>
<td>
Val1
</td>
<td>
Val2
</td>
<td>
Val3
</td>
</tr>
<tr>
<td>
Val11
</td>
<td>
Val22
</td>
<td>
Val33
</td>
</tr>
<tr>
<td>
Val111
</td>
<td>
Val222
</td>
<td>
Val333
</td>
</tr>
</table>
</div>
And there are lot more elements on the page as well.
Now, how can i get a csv file like this :
Col1,Col2,Col3
Val1,Val2,Val3
Val11,Val22,Val33
Val111,Val222,Val333
using jQuery ?
need a file save dailog box too,like this :
Thanks.
You can do that in the client side only, in browser that accept Data URIs:
data:application/csv;charset=utf-8,content_encoded_as_url
In your example the Data URI must be:
data:application/csv;charset=utf-8,Col1%2CCol2%2CCol3%0AVal1%2CVal2%2CVal3%0AVal11%2CVal22%2CVal33%0AVal111%2CVal222%2CVal333
You can call this URI by:
using window.open
or setting the window.location
or by the href of an anchor
by adding the download attribute it will work in chrome, still have to test in IE.
To test, simply copy the URIs above and paste in your browser address bar. Or test the anchor below in a HTML page:
<a download="somedata.csv" href="data:application/csv;charset=utf-8,Col1%2CCol2%2CCol3%0AVal1%2CVal2%2CVal3%0AVal11%2CVal22%2CVal33%0AVal111%2CVal222%2CVal333">Example</a>
To create the content, getting the values from the table, you can use table2CSV and do:
var data = $table.table2CSV({delivery:'value'});
$('<a></a>')
.attr('id','downloadFile')
.attr('href','data:text/csv;charset=utf8,' + encodeURIComponent(data))
.attr('download','filename.csv')
.appendTo('body');
$('#downloadFile').ready(function() {
$('#downloadFile').get(0).click();
});
Most, if not all, versions of IE don't support navigation to a data link, so a hack must be implemented, often with an iframe. Using an iFrame combined with document.execCommand('SaveAs'..), you can get similar behavior on most currently used versions of IE.
This is my implementation (based in: https://gist.github.com/3782074):
Usage:
HTML:
<table class="download">...</table>
DOWNLOAD CSV
JS:
$("a[download]").click(function(){
$("table.download").toCSV(this);
});
Code:
jQuery.fn.toCSV = function(link) {
var $link = $(link);
var data = $(this).first(); //Only one table
var csvData = [];
var tmpArr = [];
var tmpStr = '';
data.find("tr").each(function() {
if($(this).find("th").length) {
$(this).find("th").each(function() {
tmpStr = $(this).text().replace(/"/g, '""');
tmpArr.push('"' + tmpStr + '"');
});
csvData.push(tmpArr);
} else {
tmpArr = [];
$(this).find("td").each(function() {
if($(this).text().match(/^-{0,1}\d*\.{0,1}\d+$/)) {
tmpArr.push(parseFloat($(this).text()));
} else {
tmpStr = $(this).text().replace(/"/g, '""');
tmpArr.push('"' + tmpStr + '"');
}
});
csvData.push(tmpArr.join(','));
}
});
var output = csvData.join('\n');
var uri = 'data:application/csv;charset=UTF-8,' + encodeURIComponent(output);
$link.attr("href", uri);
}
Notes:
It uses "th" tags for headings. If they are not present, they are not
added.
This code detects numbers in the format: -####.## (You will need modify the code in order to accept other formats, e.g. using commas).
UPDATE:
My previous implementation worked fine but it didn't set the csv filename. The code was modified to use a filename but it requires an < a > element. It seems that you can't dynamically generate the < a > element and fire the "click" event (perhaps security reasons?).
DEMO
http://jsfiddle.net/nLj74t0f/
(Unfortunately jsfiddle fails to generate the file and instead it throws an error: 'please use POST request', don't let that error stop you from testing this code in your application).
I recently posted a free software library for this: "html5csv.js" -- GitHub
It is intended to help streamline the creation of small simulator apps
in Javascript that might need to import or export csv files, manipulate, display, edit
the data, perform various mathematical procedures like fitting, etc.
After loading "html5csv.js" the problem of scanning a table and creating a CSV is a one-liner:
CSV.begin('#PrintDiv').download('MyData.csv').go();
Here is a JSFiddle demo of your example with this code.
Internally, for Firefox/Chrome this is a data URL oriented solution, similar to that proposed by #italo, #lepe, and #adeneo (on another question). For IE
The CSV.begin() call sets up the system to read the data into an internal array. That fetch then occurs. Then the .download() generates a data URL link internally and clicks it with a link-clicker. This pushes a file to the end user.
According to caniuse IE10 doesn't support <a download=...>. So for IE my library calls navigator.msSaveBlob() internally, as suggested by #Manu Sharma
Here are two WORKAROUNDS to the problem of triggering downloads from the client only. In later browsers you should look at "blob"
1. Drag and drop the table
Did you know you can simply DRAG your table into excel?
Here is how to select the table to either cut and past or drag
Select a complete table with Javascript (to be copied to clipboard)
2. create a popup page from your div
Although it will not produce a save dialog, if the resulting popup is saved with extension .csv, it will be treated correctly by Excel.
The string could be
w.document.write("row1.1\trow1.2\trow1.3\nrow2.1\trow2.2\trow2.3");
e.g. tab-delimited with a linefeed for the lines.
There are plugins that will create the string for you - such as http://plugins.jquery.com/project/table2csv
var w = window.open('','csvWindow'); // popup, may be blocked though
// the following line does not actually do anything interesting with the
// parameter given in current browsers, but really should have.
// Maybe in some browser it will. It does not hurt anyway to give the mime type
w.document.open("text/csv");
w.document.write(csvstring); // the csv string from for example a jquery plugin
w.document.close();
DISCLAIMER: These are workarounds, and does not fully answer the question which currently has the answer for most browser: not possible on the client only
By using just jQuery, you cannot avoid a server call.
However, to achieve this result, I'm using Downloadify, which lets me save files without having to make another server call. Doing this reduces server load and makes a good user experience.
To get a proper CSV you just have to take out all the unnecessary tags and put a ',' between the data.
You can't avoid a server call here, JavaScript simply cannot (for security reasons) save a file to the user's file system. You'll have to submit your data to the server and have it send the .csv as a link or an attachment directly.
HTML5 has some ability to do this (though saving really isn't specified - just a use case, you can read the file if you want), but there's no cross-browser solution in place now.
Hope the following demo can help you out.
$(function() {
$("button").on('click', function() {
var data = "";
var tableData = [];
var rows = $("table tr");
rows.each(function(index, row) {
var rowData = [];
$(row).find("th, td").each(function(index, column) {
rowData.push(column.innerText);
});
tableData.push(rowData.join(","));
});
data += tableData.join("\n");
$(document.body).append('<a id="download-link" download="data.csv" href=' + URL.createObjectURL(new Blob([data], {
type: "text/csv"
})) + '/>');
$('#download-link')[0].click();
$('#download-link').remove();
});
});
table {
border-collapse: collapse;
}
td,
th {
border: 1px solid #aaa;
padding: 0.5rem;
text-align: left;
}
td {
font-size: 0.875rem;
}
.btn-group {
padding: 1rem 0;
}
button {
background-color: #fff;
border: 1px solid #000;
margin-top: 0.5rem;
border-radius: 3px;
padding: 0.5rem 1rem;
font-size: 1rem;
}
button:hover {
cursor: pointer;
background-color: #000;
color: #fff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='PrintDiv'>
<table id="mainTable">
<tr>
<td>Col1</td>
<td>Col2</td>
<td>Col3</td>
</tr>
<tr>
<td>Val1</td>
<td>Val2</td>
<td>Val3</td>
</tr>
<tr>
<td>Val11</td>
<td>Val22</td>
<td>Val33</td>
</tr>
<tr>
<td>Val111</td>
<td>Val222</td>
<td>Val333</td>
</tr>
</table>
</div>
<div class="btn-group">
<button>csv</button>
</div>
Just try the following coding...very simple to generate CSV with the values of HTML Tables. No browser issues will come
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="http://www.csvscript.com/dev/html5csv.js"></script>
<script>
$(document).ready(function() {
$('table').each(function() {
var $table = $(this);
var $button = $("<button type='button'>");
$button.text("Export to CSV");
$button.insertAfter($table);
$button.click(function() {
CSV.begin('table').download('Export.csv').go();
});
});
})
</script>
</head>
<body>
<div id='PrintDiv'>
<table style="width:100%">
<tr>
<td>Jill</td>
<td>Smith</td>
<td>50</td>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td>94</td>
</tr>
<tr>
<td>John</td>
<td>Doe</td>
<td>80</td>
</tr>
</table>
</div>
</body>
</html>

Categories