var table = $('#accessRequest').DataTable({
"dom": 'Blfrtip',
"ajax": "Editor-PHP-1.5.1/php/editor-serverside.php",
"columns": [
{ //special column for detail view
"className": 'details-control',
"orderable": false,
"data": null,
"defaultContent": ''
},
{ data: "DT_RowId",
render: function ( data ) {
return data.replace( 'row_', '' );
}
},
{ data: null,
render: function ( data, type, row ) {
// Combine the first and last names into a single table field
return data.first+' '+data.last;
}
},
{ "data": "phone" },
{ "data": "responsibleParty" },
{ "data": "email" },
{ "data": "building" },
{ "data": "typeOfWork" },
{ "data": "startTime" },
{ "data": "endTime" },
{ "data": "description" },
{ "data": "dockNeeded" },
{ "data": "numPeople" },
{ "data": "numTrucks" },
{ "data": "requestPlaced" },
{ "data": "updatedAt" },
{ "data": "approved" },
{ "data": "approvedBy" },
{ "data": "approvedAt" },
{ "data": null }
],
"aoColumnDefs": [
{
"aTargets": [-1],
"mData": null,
"mRender": function (data, type, full) {
return '<button id="ApprovalButton" onclick="$.post(\'extra.php\', \'approve_request\')" action="extra.php" method="post"> Process </button>';
//Send post request
}
}
],
"order": [[1, 'asc']],
select: true,
buttons: [
{ extend: "create", editor: editor },
{ extend: "edit", editor: editor },
{ extend: "remove", editor: editor }
]
});
I have a string of code (above) in which I am creating a table to contain information. On the line that says "//send post request" I'm trying to make it so the button directly above it sends a post request to a separate file called "extra.php", and despite what I've done I haven't been able to that.
I've tried using a submit button in an input form, but that didn't work. I've tried a lot of different things, but I can't seem to get it to work. Any help would be appreciated.
There is already a file (extra.php) that is capable of receiving a post request and acting on it once it has received it. I'm attempting to create a button in HTML on a page, that when clicked posts 'approve_request' to the file "extra.php"
Sorry, I'm new to both coding and this website, there's probably something simple that I'm not doing.
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<?php
header('Access-Control-Allow-Origin: *');
$id = intval($_POST['id']);
$con = mysql_connect("RequestAccess.db.10160035.hostedresource.com","RequestAccess","br#6HeCher");
if (!$con){
die('Could not connect: ' . mysql_error());
}
mysql_select_db("RequestAccess", $con);
//if action sent is approve set request as apporved
if(isset($_POST['approve_request'])){
$sql = "UPDATE AccessRequests
SET approved='1', approvedAt=current_timestamp
WHERE AccessID='" . $_POST['approve_request']."'";
$results = mysql_query($sql);
}
//else action sent must be for child rows so populate child row
else {
}
This is the section responsible for handling the post request, if that helps.
I think you are missing this:
"processing": true,
"serverSide": true,
DataTabele needs these directives to know that you want perform the request to the php script.
And maybe also this:
"ajax": "your php.php"
Remove your database credentials from this post immediately.
Your backend script shouldn't have any HTML associated with it. You can't return headers if you've already output to the DOM.
Documentation: http://php.net/manual/en/function.header.php
For data-tables you will need to return json from the backend script. It should look something like this. Assuming your SQL and Schema is correct.
<?php
//Use PDO this is deprecated.
$con = mysql_connect("stuff","things","password");
if (!$con){
die('Could not connect: ' . mysql_error());
}
mysql_select_db("RequestAccess", $con);
$id = (int) $_POST['id'];
if(isset($_POST['approve_request'])){
$sql = "
UPDATE AccessRequests
SET approved='1', approvedAt=current_timestamp -- this may need to be in quotes.
WHERE AccessID='{$_POST['approve_request']}'
";
$results = mysql_query($sql);
} else {
$results = null;
}
//Set headers
header('Access-Control-Allow-Origin: *');
header('Content-Type: application/json');
//Output data.
echo json_encode($results);
I use a program to debug my ajax requests. Firebug is a good option.
I would highly suggest learning a framework first (guard rails are nice).
http://www.sitepoint.com/best-php-framework-2015-sitepoint-survey-results/
Related
In a backend panel, in order to populate a datatable, I echo the records in a php page in format JSON, then I parse, format and populate the datatable with JS.
The issue is, how do I prevent peoples from accessing that php page and leaking all the informations?
This is what my code look like:
var options = {
data: {
type: 'remote',
source: {
read: {
url: 'http://127.0.0.1/inc/phpscripts/printinfo.php',
},
},
pageSize: 10,
serverPaging: false,
serverFiltering: false,
serverSorting: false,
},
layout: {
scroll: false,
footer: false
},
sortable: true,
pagination: true,
columns: [{
field: 'id',
title: '#',
sortable: false,
width: 20,
selector: {
class: ''
},
textAlign: 'center',
}, {
field: 'name',
title: 'name',
}, {
field: 'surname',
title: 'surname',
}, {
field: 'address',
title: 'address',
}, {
field: 'phone',
title: 'phone',
},
}],
};
This is the code of the printinfo.php
function datatable($userid){
global $conn;
$total = totalrows($userid);
$pagination = ceil($total/10);
echo '{
"meta": {
"page": 1,
"pages": '.$pagination.',
"perpage": 10,
"total": '.$total.',
"sort": "desc",
"field": "name"
},
"data":';
$rows = array();
$query = $conn->prepare('SELECT * FROM table WHERE id = ? ORDER BY name DESC');
$query->bind_param('i', $userid);
if (!$query->execute());
$res = $query->get_result();
$counter = 0;
//$rows = array();
while ($data = $res->fetch_assoc()) {
$rows[] = $data;
}
print json_encode($rows);
echo '}';
}
datatable(SESSION['id']);
While this is the display content of printinfo.php
{ "meta": { "page": 1, "pages": 1, "perpage": 10, "total": 4, "sort": "desc", "field": "level" }, "data":
[{"id":1,"name":"frank","surname":"blank","address":"st andrew","phone":"+1555484845"},
{"id":1,"name":"andrew","surname":"blank","address":"st paroli","phone":"+1555895685"}]}
It works fine, but I don't think this is secure at all.
So, how would you approach it in order to secure the datas?
You should build some authentication scheme, in order to validate the identity of user that fetches your data.
A simple example (not secure at all, but shows the goal) - send some identification code as post request to that php script and validate it there.
Better security can be achieved by creating a database with hashed or encrypted passwords and validating the user at sign in stage. After that validation, you can store some credentials on the server and check in your php script the identity.
Again, this is not so simple as described and should be done carefully.
I am trying something really complex here, and I have not worked out a way to implement a solution yet. The part I work on looks like this:
1. simple page A that dynamically loads datatable from db.Last col is a button.
2. an html page B that loads different things according to 2 values stored at at local storage. these are available in the aforementioned table.
Now the part I cannot figure out:
3. Into the simple page A, there is a modal div. I want to load the B page into this modal on button click, and load different data, according to the values stored at local storage.
Here is my code so far:
function getadminprojects(){ //function that dynamically loads datatable
$.ajax({
url: "http://....../CustomServices/DBDistApps",
type: "GET",
dataType: 'json',
async: false,
success: function(data) {
$('#projectsdt').show();
projectsTable = $('#projectsdt').DataTable({
"pageLength": 10,
"data": data,
"scrollX": true,
"order": [[ 4, "desc" ]],
//"aaSorting": [],
"columns": [
{ "data": "code" },
{ "data": "descr" },
{ "data": "manager" },
{ "data": "customer" },
{ "data": "link_date" },
{ "data": "delink_date"},
{ "data": "type"},
{
"data": null,
"defaultContent": "<button class='btn btn-warning' onclick='openmodal2();'>button1</button>"
},
{
"data": null,
"defaultContent": "<button class='btn btn-success' onclick='localStorage.setItem('username',"+row.customer+");localStorage.setItem('projectid',"+row.code+"); projectpopmodal(); '>button2</button>"
},
] ,
});
$('#projectsdt thead').on('click', 'tr', function () {
var data2 = table.row( this ).data();
alert( 'You clicked on '+data2[0]+'\'s row' );
} );
$('#projectsdt').show();
$('#projectsdt').draw();
}
});
}
function projectpopmodal(){
$('#showfreakinmap').load('newprojects.html');
$('#fsModal').modal('show');
}//function to load page B into modal of page A
Thank you in advance!
I understand that this question has been asked before, but my variation does not match the other answers.
I have a json data source in this form :
{
"columns":[
{"title":"Store Number","data":"StoreNbr"},
{"title":"Store Name","data":"StoreName"},
{"title":"2016-01-01","data":"2016-01-01"},
{"title":"2016-01-02","data":"2016-01-02"}
],
"data":[
{"2016-01-01":"51","StoreNbr":"1","StoreName":"Store 1","2016-01-02":"52"}
]
}
I am loading the data like this :
$("#datatable").DataTable({
"ajax": {
"url": "http://myjsonurl-that-produces-above-response",
"dataSrc": "data"
},
"columns": [
{"title":"Store Number","data":"StoreNbr"},
{"title":"Store Name","data":"StoreName"},
{"title":"2016-01-01","data":"2016-01-01"},
{"title":"2016-01-02","data":"2016-01-02"},
],
dom: "Bfrtip",
"bProcessing": true,
"bServerSide" : true
});
The above works flawlessly. What I need, is to load the columns dynamically, like this :
"columns": $.getJSON($('#datatable').DataTable().ajax.url(),
function(json){
return (JSON.stringify(json.columns));
});
All I get is a aDataSource error.
If I run the .getJSON thing anywhere else in the code I get the expected response, the one I need. Any ideas?
I would like to make this to work as it is preferably as my datasource keeps changing based on filters I apply that affect the json source, dataset etc.
Update :
The way the table is initialized :
<script type="text/javascript">
TableManageButtons.init();
TableManageButtons = function () {"use strict"; return { init: function () { handleDataTableButtons() } }}();
var handleDataTableButtons = function () {
"use strict";
0 !== $("#datatable-buttons").length && $("#datatable-buttons").DataTable({
"ajax": {
"url": "http://myjsonurl.php",
.......
Try to get the columns first and then proceed with datatables initialization:
$.getJSON('url/for/colums', function(columnsData) {
$("#datatable").DataTable({
...
"columns": columnsData
});
});
EDIT
If I understand correctly, you want to do this:
$("#datatable").DataTable({
"ajax": {
"url": "http://myjsonurl-that-produces-above-response",
"dataSrc": "data"
},
"columns": getColumns(), //Execute $.getJSON --> asynchronous (the code continous executing without the columns result)
dom: "Bfrtip",
"bProcessing": true,
"bServerSide" : true
});
In this way, when you call getColumns() the execution is asynchronous, so the columns are going to be undefined.
That's why you have to call the DataTable initializer in the getJSON callback function.
Another way might be to get the columns in a not asynchronous function setting async: false (Check this question)
You can form a custom js function to put your headers in place once you get the response from server. Have a look into below code:
JSON response from server:
{
"columns": [
[ "Name" ],
[ "Position" ],
[ "Office" ],
[ "Extn." ],
[ "Start date" ],
[ "Salary" ]
],
"data": [
[
"Tiger Nixon",
"System Architect",
"Edinburgh",
"5421",
"2011/04/25",
"$320,800"
],....
}
And js method to process it to put headers on place:
$( document ).ready( function( $ ) {
$.ajax({
"url": 'arrays_short.txt',
"success": function(json) {
var tableHeaders;
$.each(json.columns, function(i, val){
tableHeaders += "<th>" + val + "</th>";
});
$("#tableDiv").empty();
$("#tableDiv").append('<table id="displayTable" class="display" cellspacing="0" width="100%"><thead><tr>' + tableHeaders + '</tr></thead></table>');
//$("#tableDiv").find("table thead tr").append(tableHeaders);
$('#displayTable').dataTable(json);
},
"dataType": "json"
});
});
Check this url for more clarification.
Hope this helps!!
I'm using jquery data table to display large amounts of data inside grid. I implemented server side pagination but I'm struggling with sorting data server side.
Below is my datatable initialization, answer with query for sorting is not the subject here, I just need a way to pass information of which column is clicked to the controller, the one upon I will do the sorting.
('#myTable').dataTable({
"processing": true,
"serverSide": true,
"info": false,
"pageLength": 10,
"lengthChange": false,
"stateSave": false,
"bPaginate": true,
"bFilter": false,
"sPaginationType": "full_numbers",
"info": "Page _PAGE_ from _PAGES_",
"infoEmpty": "No data",
"oPaginate": {
"sFirst": "First",
"sPrevious": "Previous",
"sNext": "Next",
"sLast": "Last"
},
"ajax": {
"url": "#string.Format("{0}://{1}{2}", Request.Url.Scheme, Request.Url.Authority, Url.Content("~"))/MyController/GetData",
"type": "GET",
"data": function (d) {
.....
},
},
preDrawCallback: function (settings) {
...
},
drawCallback: function (settings) {
...
},
"columns": [
{ "data": "Id" },
{ "data": "FirstName" },
{ "data": "LastName" },
{ "data": "Age" }
],
"columnDefs": [
{
targets: [0],
orderable: false
},
{
render: function (data, type, row) {
...
}
],
"order": [[0, "desc"]]
});
public ActionResult GetData(){
var sortColumn = ...
...
}
You can bind the 'order' event like this:
$('#myTable').on( 'order.dt', function () {
var order = table.order();
var column_selected = order[0][0];
var order_way= order[0][1];
doStuff(column_selected ,order_way);
});
See it in plugin reference
By specifying "serverSide": true,, datatables will by default add information to the request which you need to use in your server-side code. If you look in the Firebug Network panel, you will be able to see the request with the querystring parameters. See here for the full list of parameters. Note that the link is to the v1.9 documentation, because that's what it looks like you're using.
So for sorting, you'd be interested in iSortCol_0 and sSortDir_0 which relate to the clicked column and the sort direction respectively.
In your controller method, you would access the parameters like this:
var sortColumnIndex = Convert.ToInt32(Request["iSortCol_0"]);
var sortColumnDir = Request["sSortDir_0"];
You then need to incorporate this, and the other parameters into your query.
Here is an article on using server-side datatables with MVC
I'm trying to use a select with inline editing. I have gotten this to display properly using the popup for editing, but I want it all to be inline and submit on blur. My data includes both an ID and a name for each dropdown item, which I have in an object that looks like { label: "blah", value: "blah" } etc.
However, in the DataTable the dropdowns are all being displayed with the ID instead of the label as the default value. I don't want users to see the id. I tried setting the editor field name to be the label and the DataTable column to be the value, which seemed to work for the popup but for inline editing I get the error "Uncaught Unable to automatically determine field from source. Please specify the field name".
My initializations look like this:
editor = new $.fn.dataTable.Editor({
ajax: 'url',
table: '#table',
idSrc: 'id',
fields: [{
label: "Location",
name: "location_name", //this is where the problem is, I think
type: "select",
ipOpts: locationList
}]})
$('#table').dataTable({
dom: "Tfrtip",
"searching": false,
"ajax": {
"url": "url",
"type": "GET"
},
"columnDefs": [
{ "visible": false, "targets": [8] }
],
"columns": [
{ "data": "location_id" }
])}
If I change the DataTable to use the name, the display is correct, but I get the name submitted to the database instead of the ID, and I need the ID.
What should I do?
I did it like this, it's messy but works:
Each editable object has it's own span class. An ID that relates to the parent object. A key that relates to the object that is being updated. And then of course the data.
<td><span class="dcmeta" data-value="'.$row['DATACENTER'].'" data-type="select" id="'.$row['CLUSTERNAME'].'" key="DATACENTER">'.$row['DATACENTER'].'</span></td>
<td><span class="tiermeta" data-value="'.$row['TIER'].'" data-type="select" id="'.$row['CLUSTERNAME'].'" key="TIER">'.$row['TIER'].'</span></td>
Javascript:
<script type="text/javascript">
jQuery(document).ready(function() {
$.fn.editable.defaults.mode = 'popup';
$('.xedit').editable();
$('.tiermeta').editable({
title: 'Test title',
source: [
{value: 'Tier 1', text: 'Tier 1'},
{value: 'Tier 2', text: 'Tier 2'},
]
});
$('.dcmeta').editable({
title: 'Test title',
source: [
{value: 'DC1', text: 'DC1'},
{value: 'DC2', text: 'DC2'},
]
});
$(document).on('click','.editable-submit',function(){
var key = $(this).closest('.editable-container').prev().attr('key');
var x = $(this).closest('.editable-container').prev().attr('id');
var y = $('.input-metadata').val();
var z = $(this).closest('.editable-container').prev().text(y);
$.ajax({
url: "process.php?id="+x+"&data="+y+"&key="+key,
type: 'GET',
success: function(s){
if(s == 'status'){
$(z).html(y);}
if(s == 'error') {
alert('Error Processing your Request! ');}
},
error: function(e){
alert('Error Processing your Request!! ');
}
});
});
});
</script>
PHP:
<?php
$conn = sqlsrv_connect( $serverName, $connectionInfo );
if( $conn === false ) {
die( print_r( sqlsrv_errors(), true));
}
if($_GET['id'] and $_GET['data'] and $_GET['key'])
{
$id = $_GET['id'];
$data = $_GET['data'];
$key = $_GET['key'];
$sql = "update CLUSTER set $key='$data' where CLUSTERNAME='$id'";
echo 'success';
$stmt = sqlsrv_query( $conn, $sql );
if( $stmt === false) {
die( print_r( sqlsrv_errors(), true) );
}
}
?>