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
Related
html (quotazioni.php)
<?php
$azioni = $db_handle->runQuery("SELECT idAzione,nome,prezzo FROM azioni");
foreach($azioni as $azione){
?>
<tr>
<td style="text-align:center;border-bottom:#F0F0F0 1px solid;"><?php echo $azione["nome"]; ?></td>
<td style="text-align:center;border-bottom:#F0F0F0 1px solid;"><?php echo $azione["prezzo"]; ?></td>
<td style="text-align:center;border-bottom:#F0F0F0 1px solid;">
<a href="compraVendi.php?action=segui&idAzione=<?=$azione["idAzione"]?>" id="<?=$azione["nome"]?>" style="text-decoration:none;" class="preferiti" >
<span style="color:yellow;font-size:200%;" id="<?=$azione["idAzione"]?>" >☆</span>
</a>
</td>
</tr>
<?php
}
?>
php (compraVendi.php)
case "segui":
$db_handle->query("INSERT INTO preferiti (visibile,idAzione) VALUES (1,'".$_GET["idAzione"]."')");
header("location: quotazioni.php");
break;
javascript
$(document).ready(function(){
<?php
$preferiti = $db_handle->runQuery("SELECT * FROM preferiti");
foreach($preferiti as $preferito){
if ($preferito["visibile"]==1){
?>
var element = document.getElementById(<?=$preferito["idAzione"]?>);
element.hide();
<?php
}
}
?>
});
I must hide the span inside the link after I click on it. How do I keep the span disabled considering the page contains an automatic refresh? I provide an example of code which not work, please help me to solve the problem. In the sql database, the table preferiti contains idPreferito,visibile and idAzione. The row preferito contains 1 if i clicked on the respective prefer.
When user clicks on the the star - you need to save this data to a persistent storage, e,g your backend. This is the only way you will be able to regain this state after page refresh.
So when serving the page to the client, you will consider another field, for example 'disabled' which contains string 'disabled'
It could be something like this:
<a href="#" id="<?=$azione["nome"]?>" class="preferiti" >
<span class="favourites-star <?=$azione["disabled"]?>" id="<?=$azione["idAzione"]?>" >☆</span>
</a>
Consider not using insline styles and instead using classes for styling - this is a general good practice.
.favourites-star {
color:yellow;
font-size:200%;
}
Classes are also better when dealing with events.
$(document).ready(function(){
$('.prefereti').on('click', function(evt){
// Save the state first and then disable the star - try it yourself!
$.post()
.done(function () {
$(evt.currentTarget).addClass('disable');
})
.fail(function () {
// Don't disable - instead show error
});
});
});
One more thing that you need to keep in mind while the state is being saved, your page might reload - so you might like to prohibit it from reloading for that time.
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.
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
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
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>