Diving into a new project and trying to teach myself JSON,PHP,MySQL and Morris.js.
Some background into what I am trying to achieve.
I have a PHP file that goes out to a webpage and grabs JSON data. (Right now I just have it set to grab everything). Then with the data that it grabs it puts it into a mysql database. I have set a Cron job up right now to run this file every 1 minute, so that I can get some data flowing into this database.
<?php
//connect to mysql db
$con = mysql_connect('localhost','user','password',"") or die('Could not connect: ' . mysql_error());
//connect to the database
mysql_select_db('database', $con);
//read the json file contents
$jsondata = file_get_contents('http://192.168.10.243/j');
//convert json object to php associative array
$data = json_decode($jsondata, true);
//get the device details
$id = $data['data']['id'];
$type = $data['data']['type'];
$detector = $data['data']['detector'];
$cpm = $data['data']['cpm'];
$temperature = $data['data']['temperature'];
$uptime = $data['data']['uptime'];
//insert into mysql table
$sql = "INSERT INTO database_table_1(id, type, detector, cpm, temperature, uptime)
VALUES('$id', '$type', '$detector', '$cpm', '$temperature', '$uptime')";
if(!mysql_query($sql,$con))
{
die('Error : ' . mysql_error());
}
?>
After this, I then use PHP again to parse the information out of MySQL into a JSON array. Right now it will parse all the MySQL data it has (which I'm not sure if this is a good thing right now or if I should figure out a way to just parse the most recent data from MySQL.) Let me know what you think.
<?php
//open connection to mysql db
$connection = mysqli_connect('localhost','user','password','database_table_1') or die("Error " . mysqli_error($connection));
//fetch table rows from mysql db
$sql = "select * from database_table_1";
$result = mysqli_query($connection, $sql) or die("Error in Selecting " . mysqli_error($connection));
//create an array
$emparray[] = array();
while($row =mysqli_fetch_assoc($result))
{
array_push(
$emparray,
array(
'a' => $row['timestamp'],
'w' => $row['id'],
'x' => $row['cpm'],
'y' => $row['temperature'],
'Z' => $row['uptime']
)
);
}
// $emparray[] = $row;
echo json_encode($emparray);
//close the db connection
mysqli_close($connection);
?>
Now if I was to run this PHP file by itself manually I would receive a lot of JSON data formatted just like this.
[{"a":"2015-08-17 21:34:01","w":"110000","x":"16","y":"28","Z":"112094"}]
Now my plan is to have this information update a chart or charts on a webpage using the morris.js charts. Here is my current index.html page with the PHP script and morris.js sections being near the bottom.
<!DOCTYPE html>
<html lang="en">
<!-- morris.js dependencies -->
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/morris.js/0.5.1/morris.css">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/morris.js/0.5.1/morris.min.js"></script>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<title>Chart V0.1</title>
<!-- Bootstrap Core CSS -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- Custom CSS -->
<link href="css/simple-sidebar.css" rel="stylesheet">
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div id="wrapper">
<!-- Sidebar -->
<div id="sidebar-wrapper">
<ul class="sidebar-nav">
<li class="sidebar-brand">
<a href="#">
Start Bootstrap
</a>
</li>
<li>
Dashboard
</li>
</ul>
</div>
<!-- /#sidebar-wrapper -->
<!-- Page Content -->
<div id="page-content-wrapper">
<div id="myfirstchart" style="height: 300px;"></div>
<div class="container-fluid">
<div class="row">
<div class="col-lg-12">
<h1>Simple Sidebar</h1>
<p> This template has a responsive menu toggling system.</p>
Toggle Menu
</div>
</div>
</div>
</div>
<!-- /#page-content-wrapper -->
</div>
<!-- /#wrapper -->
<!-- PHP from Mysql to Json array -->
<?php
//open connection to mysql db
$connection = mysqli_connect('localhost','user','password','database_table_1') or die("Error " . mysqli_error($connection));
//fetch table rows from mysql db
$sql = "select * from database_table_1";
$result = mysqli_query($connection, $sql) or die("Error in Selecting " . mysqli_error($connection));
//create an array
$emparray[] = array();
while($row =mysqli_fetch_assoc($result))
{
array_push(
$emparray,
array(
'a' => $row['timestamp'],
'w' => $row['id'],
'x' => $row['cpm'],
'y' => $row['temperature'],
'Z' => $row['uptime']
)
);
}
// $emparray[] = $row;
echo json_encode($emparray);
//close the db connection
mysqli_close($connection);
?>
<!-- Json Pull -->
<script>
Morris.Area({
// ID of the element in which to draw the chart.
element: 'myfirstchart',
// Chart data records -- each entry in this array corresponds to a point on the chart.
data: <?php echo json_encode($emparray);?>,
// The name of the data record attribute that contains x-values.
xkey: 'a',
// A list of names of data record attributes that contain y-values.
ykeys: ['x'],
// Labels for the ykeys -- will be displayed when you hover over the chart.
labels: ['x-test']
});
</script>
<!-- jQuery -->
<script src="js/jquery.js"></script>
<!-- Bootstrap Core JavaScript -->
<script src="js/bootstrap.min.js"></script>
<!-- Menu Toggle Script -->
<script>
$("#menu-toggle").click(function(e) {
e.preventDefault();
$("#wrapper").toggleClass("toggled");
});
</script>
So far I have figure most of this new project, though I am currently stumped on how to take the data that I can parse from my PHP script and feed it to a morris.js chart or charts. I would like to have it so the chart or charts will update themselves every 1 minute for now and that the morris.js charts will get their data from my PHP script.
Any help, ideas, links, or best practices would help out a lot. My coding experience is little to none so I do apologize in advance.
Thank you
UPDATE:
I migrated the PHP script out of the HTML page and tried calling the PHP results via $.getJSON in the HTML page. Though I still am not able to get morris.js to use the parsed data. I dont even get a chart Any ideas?
<!-- Ajax -->
<script>
$.getJSON('export_php_test_1.php', function( data ){
Morris.Area({
// ID of the element in which to draw the chart.
element: 'myfirstchart',
// Chart data records -- each entry in this array corresponds to a point on the chart.
data: data,
// The name of the data record attribute that contains x-values.
xkey: 'a',
// A list of names of data record attributes that contain y-values.
ykeys: 'x',
// Labels for the ykeys -- will be displayed when you hover over the chart.
labels: 'x-test'
});
});
</script>
You can use meta refresh. Following code will refresh the full html page automatically after 60 seconds.
<meta http-equiv="refresh" content="60">
If you want to refresh only the chart section, then you have to remove the inline php codes to a separate source, and use Ajax to fetch the data for morris. If you do so, then you can use JS function setInterval to run the Ajax in regular interval.
Related
I am trying to make a table that will display information on a page. I DO NOT want the text to wrap. I've done so much searching and I can't seem to fix it! I'm using bootstrap and I have no idea how to override whatever type of limit is happening here. Please help!
Image of webpage
HTML/PHP for webpage
<?php
function createTable(){
$maxDays=date('t'); //gets the number of days in a month
$currentDayOfMonth=date('j'); //gets the current day
$rows = 14; // define number of rows
$cols = $maxDays;// define number of columns
// loops through and creates the table
for($tr=1;$tr<=$rows;$tr++){
echo "<tr>";
for($td=1;$td<=$cols;$td++){
echo "<td class='tableCells'>654 kwh</td>";
}
echo "</tr>";
}
}
function writeDays(){
$lastDayUTS = mktime (0, 0, 0, date("m"), date('t'), date("Y"));
$lastDay = date("d", $lastDayUTS);
$monthName = date("M", $lastDayUTS);
//writes the days above the table
for($n=1;$n <= $lastDay;$n++){
echo "<th>$monthName $n</th>";
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BmbxuPwQa2lc/FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH/Ev+nYRRuWlolflfl" crossorigin="anonymous">
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-lg-9">
<table class='table table-hover'>
<thead>
<!-- writes the days above the table -->
<?php writeDays(); ?>
</thead>
<tbody>
<?php
// loops through and puts values into the table
createTable();
?>
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>
The end goal is to have this embedded in a page and overflow the x axis so you can scroll horizontally. I want the text to all be on one line (not wrapped). Any help is greatly appreciated!!!
I have been searching around for a solution to this problem for a few days and finally decided to ask you lovely people as there seem to be multiple ways to skin this proverbial cat.
I have a php page (index.php) that currently displays results from a SQL select query using the following external php script (script.php):
<?php
{
include('database.php');
// Microsoft SQL Server using the SQL Native Client 11.0 ODBC Driver
$conn = odbc_connect($server,$Username,$Password);
// Query
$qry = $Query; <-- this var is set in the included database.php above
$nextbreach = odbc_exec($conn,$qry);
odbc_close();
}
$nextbreachvalue = odbc_result($nextbreach,"Breached Time");
$nextbreachref = odbc_result($nextbreach,"Reference");
?>
$nextbreachvalue and $nextbreachref are then echo'd in my index.php using
<?php echo ($nextbreachref); ?>
<?php echo ($nextbreachvalue); ?>
I'm able to do this as i have used {include('script.php');}
Whilst this works on loading index.php in the browser I would like to update the variables $nextbreachref and $nextbreachvalue every second without having to refresh the page.
I have seen many articles suggesting ajax, json and js can achieve this however i'm somewhat confused on how this is achieved in my circumstance especially as many of the online examples use mysql and not mssql.
Index.php below:
<!DOCTYPE HTML>
<html>
<head>
<link rel="stylesheet" href="assets/css/style.css">
<?php
{include('script.php');}
?>
</head>
<body>
<div id="container">
<div id="countdowncontainer">
<div id="countdownclock">
<p id="ref" ><?php echo ($nextbreachref); ?></p>
</div>
</div>
</div>
A basic structure for what you are trying to do is:
<!DOCTYPE HTML>
<html>
<head>
<link rel="stylesheet" href="assets/css/style.css">
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
<script>
$(function() {
setInterval(function(){
$.get("data.php", function( data ) { //receiving the echo from the php data file
$("#ref").html(data); //putting the echoed value directly into the p tag
});
}, 1000); //setting the requests to 1 second each
);
</script>
</head>
<body>
<div id="container">
<div id="countdowncontainer">
<div id="countdownclock">
<p id="ref" ></p>
</div>
</div>
</div>
And your data.php would be similar to the code you have that fecthes data from the database. The difference is that it now echoes the result you want to retrieve in the main page, and does not include any html:
<?php
{
include('database.php');
// Microsoft SQL Server using the SQL Native Client 11.0 ODBC Driver
$conn = odbc_connect($server,$Username,$Password);
// Query
$qry = $Query; <-- this var is set in the included database.php above
$nextbreach = odbc_exec($conn,$qry);
odbc_close();
}
$nextbreachvalue = odbc_result($nextbreach,"Breached Time");
$nextbreachref = odbc_result($nextbreach,"Reference");
echo($nextbreachref);
?>
I have a working autocomplete script that links to my database but I'm sure how to sort the results.
My table has 4 columns: ID, location, slug, population. The table itself has about 1,000 entries.
Currently, my autocomplete takes in user search for slug, and it will search for slugs but I would like the autocomplete list results to be sorted by population order, the higher population being highest on list.
Index.php:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Autocomplete using PHP/MySQL and jQuery</title>
<link rel="stylesheet" href="css/style.css" />
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/script.js"></script>
</head>
<body>
<div class="container">
<div class="header">
</div><!-- header -->
<h1 class="main_title">Autocomplete using PHP/MySQL and jQuery</h1>
<div class="content">
<form>
<div class="label_div">Type a keyword : </div>
<div class="input_container">
<input type="text" id="slug" onkeyup="autocomplet2()">
<ul id="list_id"></ul>
</div>
</form>
</div><!-- content -->
<div class="footer">
Powered by Jason's Fingers</a>
</div><!-- footer -->
</div><!-- container -->
</body>
</html>
script.js:
// autocomplete : this function will be executed every time we change the text
function autocomplet2() {
var min_length = 3; // min caracters to display the autocomplete
var keyword = $('#slug').val();
if (keyword.length >= min_length) {
$.ajax({
url: 'ajax_refresh.php',
type: 'POST',
data: {keyword:keyword},
success:function(data){
$('#list_id').show();
$('#list_id').html(data);
}
});
} else {
$('#list_id').hide();
}
}
// set_item : this function will be executed when we select an item
function set_item(item) {
// Changes input to the full name on selecting
$('#slug').val(item);
// Hides list after selection from list
$('#list_id').hide();
}
ajax_refresh.php:
<?php
// PDO connect *********
function connect() {
return new PDO('mysql:host=localhost;dbname=wallettest', 'root', 'butthead', array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
}
$pdo = connect();
$keyword = '%'.$_POST['keyword'].'%';
$sql = "SELECT * FROM population WHERE slug LIKE (:keyword) ORDER BY id ASC LIMIT 0, 10";
$query = $pdo->prepare($sql);
$query->bindParam(':keyword', $keyword, PDO::PARAM_STR);
$query->execute();
$list = $query->fetchAll();
foreach ($list as $rs) {
// put in bold the written text
$slug = str_replace($_POST['keyword'], '<b>'.$_POST['keyword'].'</b>', $rs['slug']);
// add new option
echo '<li onclick="set_item(\''.str_replace("'", "\'", $rs['slug']).'\')">'.$slug.'</li>';
}
?>
You could set the "ORDER BY" part of $sql to be:
...ORDER BY population DESC LIMIT 0, 10"
Figured it out, in this line:
$sql = "SELECT * FROM country WHERE country_name LIKE (:keyword) ORDER BY country_id ASC LIMIT 0, 10";
Change Order by country_id to population
I have an Autocomplete that works perfectly but I'm having trouble figuring out how to re-direct the user to a separate web page containing info about his selection upon pressing ENTER on keyboard. The website itself doesn't have to exist, I just want to know the code for it assuming the website already exists.
index.php:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Autocomplete using PHP/MySQL and jQuery</title>
<link rel="stylesheet" href="css/style.css" />
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/script.js"></script>
</head>
<body>
<div class="container">
<div class="header">
</div><!-- header -->
<h1 class="main_title">Autocomplete using PHP/MySQL and jQuery</h1>
<div class="content">
<form>
<p>Table consists of : ID, Location, Slug, Population </p>
<br><br>
<div class="label_div">Search for a Slug : </div>
<div class="input_container">
<input type="text" id="slug" onkeyup="autocomplet2()">
<ul id="list_id"></ul>
</div>
</form>
<br><br><br><br>
<p>List will be ordered from Highest population to lowest population (Top to bottom)</p>
<br><br>
</div><!-- content -->
<div class="footer">
Powered by Jason's Fingers</a>
</div><!-- footer -->
</div><!-- container -->
</body>
</html>
script.js:
// autocomplete : this function will be executed every time we change the text
function autocomplet2() {
var min_length = 3; // min caracters to display the autocomplete
var keyword = $('#slug').val();
if (keyword.length >= min_length) {
$.ajax({
url: 'ajax_refresh.php',
type: 'POST',
data: {keyword:keyword},
success:function(data){
$('#list_id').show();
$('#list_id').html(data);
}
});
} else {
$('#list_id').hide();
}
}
// set_item : this function will be executed when we select an item
function set_item(item) {
// Changes input to the full name on selecting
$('#slug').val(item);
// Hides list after selection from list
$('#list_id').hide();
}
function change()
ajax_refresh.php:
<?php
// PDO connect *********
function connect() {
return new PDO('mysql:host=localhost;dbname=wallettest', 'root', 'butthead', array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
}
$pdo = connect();
$keyword = '%'.$_POST['keyword'].'%';
$sql = "SELECT * FROM population WHERE slug LIKE (:keyword) ORDER BY population DESC LIMIT 0, 10";
$query = $pdo->prepare($sql);
$query->bindParam(':keyword', $keyword, PDO::PARAM_STR);
$query->execute();
$list = $query->fetchAll();
foreach ($list as $rs) {
// put in bold the written text
$slug = str_replace($_POST['keyword'], '<b>'.$_POST['keyword'].'</b>', $rs['slug']);
// add new option
echo '<li onclick="set_item(\''.str_replace("'", "\'", $rs['slug']).'\')">'.$slug.'</li>';
}
?>
Listen for the keydown event, and check if the key pressed was the enter key, by checking the keycode.
input.on('keydown', function (ev) {
if (ev.keyCode === 13) { //enter's keycode is 13
//redirect code
}
});
You might also have to do ev.preventDefault() if the enter key would normally do something unwanted.
I am working on an autocomplete script where i first read files from a local directory using php as shown below:
<?php
$file = glob('pages/*');
//var_dump($file);
foreach($file as $value)
{
$output = substr($value, 6, strlen($value) - 6);
//echo($output)."<br>";
}
?>
the above script displays all the files in the 'pages' folder i.e pageone.html,pagetwo.html....
i then use a javascript file to dispaly a text field that when entered for example 'page', should show aome autocomplete options say 'pageone.html' or 'pagetwo.html' e.t.c
<html lang="en">
<head>
<meta charset="utf-8">
<title>jQuery UI Autocomplete - Default functionality</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.9.1.js"></script>
<script src="//code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css">
<script>
$(function() {
var availableTags = ["
<?php echo $output; ?>"
];
$( "#tags" ).autocomplete({
source: availableTags
});
});
</script>
</head>
<body>
<div class="ui-widget">
<label for="tags">Tags: </label>
<input id="tags">
</div>
</body>
</html>
i combine the above php code with this js to a single php file
as shown, i try embedding the '$output' into the js 'availableTags' variable but when i type something on the text field, nothing happens..i'm sure it has to do with the php code embedded in the js so any help would be appreciated
Your $output contains only a single value (last file in your list). You can create an array of files like:
$res = array();
foreach($file as $value)
{
$res[] = substr($value, 6, strlen($value) - 6);
}
and pass it to javascript as: a javascript array (with json_encode function)
<script>
$(function() {
var availableTags = <?=json_encode($res)?>
...
You can use autocomplete.js. It's more lite and easy to use that jQuery UI.