I'm trying to make a page which will generate a result-set from a complex database query & php parsing... but that's mainly beside the point... The main point is that this takes a minute or two to complete, and I'm hoping to display a progress bar rather then a generic gif animation "loading..." picture.
A breakdown would be...
User opens Page A.
Page A requests data from Page B (Most likely AJAX).
Page B processes the 100000+ or so entries in the database and parses them.
Page A shows a progress bar which shows roughly how far through the process is
Page B returns the result set.
Page A displays the result set.
I know how to return data to the ajax query, but my issue is I don't know how to continuously return data to show the status of the process (Eg. % of rows scanned).
I've looked into EventSource / Server-Sent-Events, which shows promise, I'm just not too sure how to get it working properly, or if there is a better way to do it.
I've tried making a quick little mock-up page, using just EventSource works fine, but when I split it up into an eventSource call (page which monitors a session variable for change), and an ajax request (the actual data sending/return) it falls apart.
I'm probably missing something obvious, or doing something stupidly wrong, but this is most of what I have anyway... Any help, suggestions, tips, or even suggestions of completely other ways to do it would be awesome :)
User page:
<!DOCTYPE html>
<html>
<head>
<title>Dynamic Progress Bar Example</title>
<script src="script.js"></script>
</head>
<body>
<input type="button" value="Submit" onclick="connect()" />
<progress id='progressor' value="0" max='100' style=""></progress>
</body>
</html>
Javascript
var es;
function connect() {
startListener();
$.ajax({
url: "server.php",
success: function() {
alert("Success");
},
error: function() {
alert("Error");
}
});
}
function startListener() {
es = new EventSource('monitor.php');
//a message is received
es.addEventListener('message', function(e) {
var result = JSON.parse(e.data);
if (e.lastEventId == 'CLOSE') {
alert("Finished!");
es.close();
} else {
var pBar = document.getElementById('progressor');
pBar.value = result;
}
});
es.addEventListener('error', function(e) {
alert('Error occurred');
es.close();
});
}
function stopListener() {
es.close();
alert('Interrupted');
}
function addLog(message) {
var r = document.getElementById('results');
r.innerHTML += message + '<br>';
r.scrollTop = r.scrollHeight;
}
Monitor PHP
<?php
SESSION_START();
header('Content-Type: text/event-stream');
// recommended to prevent caching of event data.
header('Cache-Control: no-cache');
function send_message($id, $data) {
$d = $data;
if (!is_array($d)){
$d = array($d);
}
echo "id: $id" . PHP_EOL;
echo "data: " . json_encode($d) . PHP_EOL;
echo PHP_EOL;
ob_flush();
flush();
}
$run = true;
$time = time();
$last = -10;
while($run){
// Timeout kill checks
if (time()-$time > 360){
file_put_contents("test.txt", "DEBUG: Timeout Kill", FILE_APPEND);
$run = false;
}
// Only update if it's changed
if ($last != $_SESSION['progress']['percent']){
file_put_contents("test.txt", "DEBUG: Changed", FILE_APPEND);
$p = $_SESSION['progress']['percent'];
send_message(1, $p);
$last = $p;
}
sleep(2);
}
?>
EDIT:
I've tried a different approach, where:
Page A AJAX calls page B, which runs the request, and saves the progress to a SESSION variable
Page A AJAX calls page C every 2 seconds, which simply returns the value of the session variable. This loop is terminated when it reaches 100
However, this is not quite working either. It seems that the two AJAX requests, or the two scripts server-side are not running simultaneously.
Looking at debug output: Both AJAX calls are executed at about the same time, but then the page B script runs to completion by itself, and -then- the page C script runs. Is this some limitation of PHP I'm missing???
more code!
Server (Page B) PHP
<?PHP
SESSION_START();
file_put_contents("log.log", "Job Started\n", FILE_APPEND);
$job = isset($_POST['job']) ? $_POST['job'] : 'err_unknown';
$_SESSION['progress']['job'] = $job;
$_SESSION['progress']['percent'] = 0;
$max = 10;
for ($i=0; $i<=$max;$i++){
$_SESSION['progress']['percent'] = floor(($i/$max)*100);
file_put_contents("log.log", "Progress now at " . floor(($i/$max)*100) . "\n", FILE_APPEND);
sleep(2);
}
file_put_contents("log.log", "Job Finished", FILE_APPEND);
echo json_encode("Success. We are done.");
?>
Progress (Page C) PHP
<?php
SESSION_START();
file_put_contents("log.log", "PR: Request Made", FILE_APPEND);
if (isset($_SESSION['progress'])){
echo json_encode(array("job"=>$_SESSION['progress']['job'],"progress"=>$_SESSION['progress']['percent']));
} else {
echo json_encode(array("job"=>"","progress"=>"error"));
}
?>
Index (Page A) JS/HTML
<!DOCTYPE html>
<html>
<head>
<title>Progress Bar Test</title>
</head>
<body>
<input type="button" value="Start Process" onclick="start('test', 'pg');"/><br />
<progress id="pg" max="100" value="0"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script type="text/javascript">
var progress = 0;
var job = "";
function start(jobName, barName){
startProgress(jobName, barName);
getData(jobName);
}
function getData(jobName){
console.log("Process Started");
$.ajax({
url: "server.php",
data: {job: jobName},
method: "POST",
cache: false,
dataType: "JSON",
timeout: 300,
success: function(data){
console.log("SUCCESS: " + data)
alert(data);
},
error: function(xhr,status,err){
console.log("ERROR: " + err);
alert("ERROR");
}
});
}
function startProgress(jobName, barName){
console.log("PG Process Started");
progressLoop(jobName, barName);
}
function progressLoop(jobName, barName){
console.log("Progress Called");
$.ajax({
url: "progress.php",
cache: false,
dataType: "JSON",
success: function(data){
console.log("pSUCCESS: " . data);
document.getElementById(barName).value = data.progress;
if (data.progress < 100 && !isNaN(data.progress)){
setTimeout(progressLoop(jobName, barName), (1000*2));
}
},
error: function(xhr,status,err){
console.log("pERROR: " + err);
alert("PROGRESS ERROR");
}
});
}
</script>
</body>
</html>
Debug: log.log output
PR: Request Made
Job Started
Progress now at 0
Progress now at 10
Progress now at 20
Progress now at 30
Progress now at 40
Progress now at 50
Progress now at 60
Progress now at 70
Progress now at 80
Progress now at 90
Progress now at 100
Job Finished
PR: Request Made
In similar cases, I usually do it this way:
Client sends AJAX request to Page B.
Important: On success, client sends the same request again.
On the initial request, Page B says: OK, THERE ARE 54555 RECORDS.. I use this count to initiate the progress bar.
On each of next requests, Page B returns a chunk of data. Client counts the size of chunk and updates progress bar. Also it collects chunks in one list.
On last request, when all data is sent, Page B says: THAT'S ALL and client renders the data.
I think, you've gotten the idea.
NOTE: you can request all chunks in parallel, but it is a complex way. Server (Page B) should also return a fixed chunksize in the initial response, then client sends TOTAL_COUNT / CHUNK_SIZE requests concurrently and combines the responses till the last request is completed. So it is much faster. You can use https://github.com/caolan/async in this case to do the code much more readable.
Related
I am new to this, so far i was just using html form, click the submit button, the page was refreshing and the data was sented to the server (mySQL). But i learned Ajax (AJAX is a developer's dream) they are saying cause you can:
Read data from a web server - after the page has loaded
Update a web page without reloading the page
Send data to a web server - in the background
So i did a simple example. Let's say that i have set the sqlConnection.php
let input = document.getElementById("inputField");
document.getElementById("submitBtn").addEventListener("click", function (){
if(input.value == ""){
alert("empty field");
}else {
$(document).ready(function (){
$.ajax({
url: 'insert.php',
method: 'POST',
dataType: 'text',
data: { comment: input.value },
success: function (){
input.value = "";
}
});
});
}
});
function selectQuestions(){
let data = "true";
$("#comments").load("select.php");
}
setInterval(selectQuestions, 3000);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ajax text</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-wEmeIV1mKuiNpC+IOBjI7aAzPcEZeedi5yW5f2yOq55WWLwNGmvvx4Um1vskeMj0" crossorigin="anonymous">
</head>
<body>
<div class="container py-3">
<input id="inputField" type="text" class="form-control text-left" aria-label="">
<div class="py-2 my-1">
<button id="submitBtn" value="addNew" class="btn btn-success">Submit</button>
</div>
</div>
<div class="container" id="comments">
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="main.js"></script>
</body>
</html>
select.php has this:
$sql = "SELECT * FROM data";
$result = $conn->query($sql);
if (mysqli_num_rows($result) > 0) {
while ($row = mysqli_fetch_assoc($result)) {
echo "<p>{$row['question']}</p>";
}
} else {
echo "No comments";
}
So my Question: Is this correct in order to see new results that came from the server ? I call the setInterval method every 3 seconds as you can see. Is this bad for the server ? For example if i upload this project to a server and 10 users are using it.. am i exhausting the server - consuming more space ?
Assuming your code is in main.js, you don't need the $(document).ready(), since at the bottom of the <body>, your code will only run after everything is ready anyway. Not to mention it's in the wrong place.
At first I thought you were using .load() wrong, since its a shorthand for the event handler .on('load'). But it turns out in jquery 3.0 they've added an ajax method also called .load(). This is dumb and going to cause alot of confusion, but I digress, use $.get() or $.getJson to get things from a server.
Hitting the server with an interval isn't necessarily bad, it's called polling and it's how the internet did full duplex communication for many years. The problem comes when you poll too often or want to update too much data or have too many users all polling at once. How much is too much all depends on the machine your server is running on. Websockets is definitely a better option, but quite a bit more complex to configure.
I took the liberty to re-write some things, since if you're using jquery, might as well use jquery.
let $input = $('#inputField');
$('#submitBtn').on('click', function(e) {
e.preventDefault(); //assuming this is in a <form>, default action is to reload the page
if ($input.val()) {
$.post('insert.php', { comment: $input.val() })
.done(function() {
$input.val('');
})
.fail(function(error) {
//error handling code
});
} else {
alert("empty field"); //alerts are annoying and thread blocking,
} //maybe use a different method to communicate with the user.
});
setInterval(function() {
$.get('select.php')
.done(function(select) {
//whatever you want to do with the response from this
})
.fail(function(error) {
//error handeling code
});
}, 3000);
On the php side, maybe just clean things up a bit so that it's more readable. You can use the ->fetch_all(MYSQLI_ASSOC) method instead of a while loop to get an associated array for the result. Then just array_map() and implode() that to build you html response.
<?php
$conn = new mysqli("configs and what not");
$statement = $conn->query("SELECT * FROM data");
$result = $statement->fetch_all(MYSQLI_ASSOC);
if (count($result) > 0) {
echo implode("", array_map(fn($row) => "<p>{$row["question"]}</p>", $result));
} else {
echo "No comments";
}
$conn->close();
I have two php pages. page.php and loader.php. Loader.php pulls data from mysql to fill a progress bar and page.php contains a function to refresh loader.php every second. It works but it's rather ugly because you can see the css animation resetting every second.
I would prefer having the loading bar html in page.php along with all the other html for my page but A) how do I get the vars from loader.php into page.php and B) how do I update the div (or any object) on page.php without refreshing the page?
I looked into AJAX which seems like it can do what I want but I'm new to AJAX and programming in general. I'm already proud it is (somewhat) working to begin with.
page.php
<script>
var myTimer = null;
//executes a script that fills mysql with data
function fileExec() {
$.ajax({
url:"fileexec.php",
type: "post"
});
startRefresh();
}
//Shows progress bar
function refreshData() {
$('#container').load('loader.php');
}
function stopRefresh() {
clearInterval(myTimer);
}
function startRefresh() {
myTimer = setInterval(refreshData, 1000);
}
</script>
loader.php
<?php
//Code not shown sets up connection to mysql to pull progress
$progress1 = $row['progress'];
$script1 = $row['script'];
//Stop refresh after shell script has finished
if ($script1 == "stop") {
echo "<script>";
echo "stopRefresh();";
echo "</script>";
}
?>
//Update progress bar with variable
<html>
<body>
<div class="progress-bar-wrapper">
<div class="progress-bar">
<div id="myBar" class="progress-bar-fill in-progress" style="height:10px;width:<?php echo $progress1; ?>%"></div>
</div>
</div>
</body>
</html>
Update it using js:
$.post("loader.php", {
function: "getProgress"
}, function(data) {
progress = JSON.parse(data);
//use progress to change your bar with js
});
And in the php:
switch ($_POST['function']) {
case 'getProgress':
getProgress();
break;
}
function getProgress() {
//get the progress state
echo json_encode($progress);
}
I have a dynamic web dashboard which displays data like temp, humidity, light, noise etc. I have multiple php files like temp.php, humidity.php, light.php and noise.php which take care of retrieving the data from db and then I have multiple js files too which basically use setTimeout and displays data from the corresponding php file to the html page every 3 seconds.
Each of the php file looks like this, example- humidity.php:
<?php
session_start();
if(isset($_SESSION["user_id"])){
include('db.php');
$unit = "820";
$stmt = $db->prepare("SELECT hv FROM humidity where
unitid=? order BY pk DESC LIMIT 1");
$stmt->execute([$unit]);
$humidity= $stmt->fetchColumn();
$humidity=round($humidity, 2, PHP_ROUND_HALF_ODD);
echo $humidity;
$stmt->closeCursor();
$db = null;
}
?>
And each js file looks like this, example- humidity.js:
$(document).ready(function() {
function foo() {
$('#showhumidity').load('humidity.php');
setTimeout(foo, 3000);
}
foo();
});
The process is working fine, but since there are multiple php requests, the overall processing time is little high (around 2 seconds). I would like to combine the phps into one php file and the js files into one too - thereby having just one php request to retrieve all the data.
What is the best way to do it?
Hope below approach will help you.
In your combined php file:
<?php
$humidity = getHumidity(<parameter>);
$temp = getTemp(<parameter>);
$light = getLight(<parameter>);
$retArr = array("humidity" => $humidity,"light" => $light, "temp" => $temp);
echo json_encode($retArr);
function getHumidity($param) {
// write your logic here to calculate the humidity
}
function getTemp($param) {
// write your logic here to calculate the temp
}
function getLight($param) {
// write your logic here to calculate the Light
}
?>
In your single .js file:
jQuery(document).ready(function() {
function foo() {
jQuery.ajax({
url : <path of your php file>,
type : <Method GET/POST as per your requirement >,
dataType : json,
async : false,
success : function(data, status) {
//update your html element with data
},
}
setInterval(foo, 3000);
});
I have a web page that allows users to complete quizzes. These quizzes use JavaScript to populate original questions each time it is run.
Disclaimer: JS Noob alert.
After the questions are completed, the user is given a final score via this function:
function CheckFinished(){
var FB = '';
var AllDone = true;
for (var QNum=0; QNum<State.length; QNum++){
if (State[QNum] != null){
if (State[QNum][0] < 0){
AllDone = false;
}
}
}
if (AllDone == true){
//Report final score and submit if necessary
NewScore();
CalculateOverallScore();
CalculateGrade();
FB = YourScoreIs + ' ' + RealScore + '%. (' + Grade + ')';
if (ShowCorrectFirstTime == true){
var CFT = 0;
for (QNum=0; QNum<State.length; QNum++){
if (State[QNum] != null){
if (State[QNum][0] >= 1){
CFT++;
}
}
}
FB += '<br />' + CorrectFirstTime + ' ' + CFT + '/' + QsToShow;
}
All the Javascript here is pre-coded so I am trying my best to hack it. I am however struggling to work out how to pass the variable RealScore to a MySql database via PHP.
There are similar questions here on stackoverflow but none seem to help me.
By the looks of it AJAX seems to hold the answer, but how do I implement this into my JS code?
RealScore is only given a value after the quiz is complete, so my question is how do I go about posting this value to php, and beyond to update a field for a particular user in my database on completion of the quiz?
Thank you in advance for any help, and if you require any more info just let me know!
Storing data using AJAX (without JQuery)
What you are trying to do can pose a series of security vulnerabilities, it is important that you research ways to control and catch these if you care about your web application's security. These security flaws are outside the scope of this tutorial.
Requirements:
You will need your MySQL database table to have the fields "username" and "score"
What we are doing is writing two scripts, one in PHP and one in JavaScript (JS). The JS script will define a function that you can use to call the PHP script dynamically, and then react according to it's response.
The PHP script simply attempts to insert data into the database via $_POST.
To send the data to the database via AJAX, you need to call the Ajax() function, and the following is the usage of the funciton:
// JavaScript variable declarations
myUsername = "ReeceComo123";
myScriptLocation = "scripts/ajax.php";
myOutputLocation = getElementById("htmlObject");
// Call the function
Ajax(myOutputLocation, myScriptLocation, myUsername, RealScore);
So, without further ado...
JavaScript file:
/**
* outputLocation - any HTML object that can hold innerHTML (span, div, p)
* PHPScript - the URL of the PHP Ajax script
* username & score - the respective variables
*/
function Ajax(outputLocation, PHPScript, username, score) {
// Define AJAX Request
var ajaxReq = new XMLHttpRequest();
// Define how AJAX handles the response
ajaxReq.onreadystatechange=function(){
if (ajaxReq.readyState==4 && xml.status==200) {
// Send the response to the object outputLocation
document.getElementById(outputLocation).innerHTML = ajaxReq.responseText;
}
};
// Send Data to PHP script
ajaxReq.open("POST",PHPScript,true);
ajaxReq.setRequestHeader("Content-type","application/x-www-form-urlencoded");
ajaxReq.send("username="username);
ajaxReq.send("score="score);
}
PHP file (you will need to fill in the MYSQL login data):
<?php
// MYSQL login data
DEFINE(MYSQL_host, 'localhost');
DEFINE(MYSQL_db, 'myDatabase');
DEFINE(MYSQL_user, 'mySQLuser');
DEFINE(MYSQL_pass, 'password123');
// If data in ajax request exists
if(isset($_POST["username"]) && isset($_POST["score"])) {
// Set data
$myUsername = $_POST["username"];
$myScore = intval($_POST["score"]);
} else
// Or else kill the script
die('Invalid AJAX request.');
// Set up the MySQL connection
$con = mysqli_connect(MYSQL_host,MYSQL_user,MYSQL_pass,MYSQL_db);
// Kill the page if no connection could be made
if (!$con) die('Could not connect: ' . mysqli_error($con));
// Prepare the SQL Query
$sql_query="INSERT INTO ".TABLE_NAME." (username, score)";
$sql_query.="VALUES ($myUsername, $myScore);";
// Run the Query
if(mysqli_query($con,$sql))
echo "Score Saved!"; // Return 0 if true
else
echo "Error Saving Score!"; // Return 1 if false
mysqli_close($con);
?>
I use these function for ajax without JQuery its just a javascript function doesnt work in IE6 or below. call this function with the right parameters and it should work.
//div = the div id where feedback will be displayed via echo.
//url = the location of your php script
//score = your score.
function Ajax(div, URL, score){
var xml = new XMLHttpRequest(); //sets xmlrequest
xml.onreadystatechange=function(){
if (xml.readyState==4 && xml.status==200){
document.getElementById(div).innerHTML=xml.responseText;//sets div
}
};
xml.open("POST",URL,true); //sets php url
xml.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xml.send("score="score); //sends data via post
}
//Your PHP-script needs this.
$score = $_POST["score"]; //obtains score from POST.
//save your score here
echo "score saved"; //this will be displayed in the div set for feedback.
so call the javascript function with the right inputs, a div id, the url to your php script and the score. Then it will send the data to the back end, and you can send back some feedback to the user via echo.
Call simple a Script with the parameter score.
"savescore.php?score=" + RealScore
in PHP Side you save it
$score = isset ($_GET['score']) ? (int)$_GET['score'] : 0;
$db->Query('INSERT INTO ... ' . $score . ' ...');
You could call the URL via Ajax or hidden Iframe.
Example for Ajax
var request = $.ajax({
url: "/savescore.php?score=" + RealScore,
type: "GET"
});
request.done(function(msg) {
alert("Save successfull");
});
request.fail(function(jqXHR, textStatus) {
alert("Error on Saving");
});
I'm using some jQuery to display tweets but once the Twitter API limit is reached, the request is sent but just keeps loading and loading. This doesn't look good. I want to be able to determine if the request is taking too long and then obviously do stuff, like cancel the request, change the styling, etc.
So this is the code that sends the request:
var fileref = document.createElement('script');
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src", "http://search.twitter.com/search.json?q="+buildString+"&callback=TweetTick&rpp=50");
document.getElementsByTagName("head")[0].appendChild(fileref);
And this is the TweetTick function:
function TweetTick(ob)
{
var container=$('#tweet-container');
container.html('');
$(ob.results).each(function(el){
/* in here, a div is built for each tweet and then appended to container */
});
container.jScrollPane(); /* just adds the scrollbar */
}
You need to cache twitter api response on your server side.
How do I keep from running into the rate limit?
I had a very similar problem lately. I use this script by Remy Sharp for most of my twitter requests: http://remysharp.com/2007/05/18/add-twitter-to-your-blog-step-by-step/
What you need to realise is that the api timeout is per IP address. So if the api has timed out for you based on your testing, it won't have timed out for someone else on a different IP address. Now, if someone accessing the site is doing so within a corporation or business, and others in the same place are doing the same, that timeout will occur almost instantaneously.
To get around this you need to cache your results. The way I did this was as follows.
I created a twitter caching system using the following code:
$twitter_username = "tadywankenobi"; //
$number_of_tweets = "10";
$options[CURLOPT_URL] = 'http://api.twitter.com/1/statuses/user_timeline.xml?screen_name='.$twitter_username.'&count='.$number_of_tweets.'&include_rts=1';
$options[CURLOPT_PORT] = 80;
$options[CURLOPT_FOLLOWLOCATION] = true;
$options[CURLOPT_RETURNTRANSFER] = true;
$options[CURLOPT_TIMEOUT] = 60;
$tweets = cache($options);
$twxml = new SimpleXMLElement($tweets);
echo "<ul>";
for($i=0;$i<=($number_of_tweets-1);$i++){
$text = $twxml->status[$i]->text;
echo "<li>".auto_link_twitter($text)."</li>";
}
echo "</ul>";
function cache($options) {
$cache_filename = "/var/cache/tweets.xml";
if(!file_exists($cache_filename)){
$handle = fopen($cache_filename, 'w') or die('Cannot open file: '.$my_file);
fclose($handle);
}// Check if cache file exists and if not, create it
$time_expire = filectime($cache_filename) + 60*60; // Expire Time (1 hour) // Comment for first run
// Set time to check file against
if(filectime($cache_filename) >= $time_expire || filesize($cache_filename) == 0) {
// File is too old or empty, refresh cache
$curl = curl_init();
curl_setopt_array($curl, $options);
$response = curl_exec($curl);
curl_close($curl);
if($response){
file_put_contents($cache_filename, $response);
}
else{
unlink($cache_filename);
}
}else{
$response = file_get_contents($cache_filename);
}
return $response;
}
What the cache function at the end does is create a file on the server and stores the twitter xml feedback in there. The system then checks to see the age of that file and if it's younger than an hour old, it takes its results from there. Otherwise, it re-accesses twitter. You need to have the file writable in the /var/cache folder (create it if it's not there).
I've kinda hacked this code together a bit, so let me know if you run into any issues with it. It also uses an auto_link_twitter() function, which creates the links required within the twitter text. I didn't write that, so I'll try and find you a link to it now.
Hope that all helps,
T
UPDATE: I can't remember where I got the auto_link_twitter() function, so here it is. If the person who wrote it reads this post, my apologies, I couldn't find the source again.
function auto_link_twitter($text) {
// properly formatted URLs
$urls = "/(((http[s]?:\/\/)|(www\.))?(([a-z][-a-z0-9]+\.)?[a-z][-a-z0-9]+\.[a-z]+(\.[a-z]{2,2})?)\/?[a-z0-9._\/~#&=;%+?-]+[a-z0-9\/#=?]{1,1})/is";
$text = preg_replace($urls, " <a href='$1'>$1</a>", $text);
// URLs without protocols
$text = preg_replace("/href=\"www/", "href=\"http://www", $text);
// Twitter usernames
$twitter = "/#([A-Za-z0-9_]+)/is";
$text = preg_replace ($twitter, " <a href='http://twitter.com/$1'>#$1</a>", $text);
// Twitter hashtags
$hashtag = "/#([A-Aa-z0-9_-]+)/is";
$text = preg_replace ($hashtag, " <a href='http://twitter.com/#!/search?q=%23$1'>#$1</a>", $text);
return $text;
}
You can use specific jQuery methods to make a JSONP request. There is basic $.ajax method and shorthand method $.getJSON which fits better for you. To control timeout of the request you can use timeout parameter. Request exceeded timeout can be processed using the error callback.
$.ajax(
dataType: 'jsonp',
url: 'http://search.twitter.com/search.json',
data: {
q: buildString,
rpp: 50
},
jsonpCallback: 'TweetTick',
timeout: 30000,
error: function(jqXHR, textStatus, errorThrown) {
if (textStatus == 'timeout') {
alert('timeout exceeded');
}
}
);