PHP datatables / ajax : <td> in data - php

I need to update an old project - it has its own backend and does deliver row data as an array which gets displayed as a standard html table.
The last attribute in the row array has an "editing column" by default, which means, it contains markup for an edit-icon like this:
$aData = array(
"first_name" => "John",
"last_name" => "Connor",
"edit_columns" => "<a href='#' class='edit'>Edit</a>"
);
The problem - there are also tables in my backend which will deliver several table cells (which works so far as it used to be a html table) with array data like this:
$aData = array(
"first_name" => "John",
"last_name" => "Connor",
"edit_columns" => "<a href='#' class='edit'>Edit</a> </td><td> <a href='#' class='delete'>Delete</a>"
);
The problem: the datatables plugin will treat edit_columns as a single cell and filter the </td><td> markup which results in 2 hyperlinks within one cell.
I know i would need to refactor my data but my customer wants to keep the backend data untouched. So - is there a way to "shift" the cell data as required?

Depending on the version of datatables you are using you could listen to the xhr.dt-event with javascript and then modify/split the data before it gets rendered in your table.
myTable.on('xhr.dt', function (e, settings, json, xhr) {
let data = json.data;
for ( let i=0, dataLength=data.length; i<dataLength; i++ ) {
let edit_columns = data[i].edit_columns.split("</td><td>");
data[i].edit_column = edit_columns[0];
data[i].delete_column = edit_columns[1];
}
});
Now you can use the created data-columns (edit_column and delete_column) in your table like they are regular columns without modifying the code on the backend/serverside.

Related

jquery - How to add image to the Select2 dropdown list with data retreived from MySQL and PHP through AJAX?

I want to add an image in front of the options in the searchable dropdown list I made. The list is populated with data from MySQL database retrieved via PHP and AJAX. I am using the Select2 plugin for this problem, and I succeeded in making it work with simple data from the database, but I don't know how to add an image (link to the image is stored in the database) to the option. I read this article, but I don't know how to implement that information into my code.
This is what I made so far:
HTML
<select id="js-hieroglyph-code-select" name="hieroglyph-code-input" data-width="100%">
<option value="" selected disabled>Select hieroglyph code</option>
</select>
JS/Jquery
$("#js-hieroglyph-code-select").select2({
ajax : {
url : "./includes/individual_retrieve_scripts/retrieve_hieroglyph_undefined.script.php",
type : "POST",
dataType : "json",
delay : 250,
data : function(params){
return {
hieroglyphCodeValue : params.term
};
},
processResults : function(response){
return {
results : response
};
},
cache : true
}
});
PHP
$data = array(["id" => "0", "text" => "Hieroglyph without code"]);
while ($row = mysqli_fetch_array($fetchData)) {
$data[] = array(
"id" => $row["undefined_hieroglyph_code"],
"text" => $row["undefined_hieroglyph_code"]
);
}
echo json_encode($data);
exit();
I purposely left out the database query part of the PHP code for the sake of convenience, but I think it is not important for the problem here.
I thought about concatenating image link data and text data in PHP and then separate it in Javascript, but this is only an idea, and I don't know how to use that separated data further. Something like this:
while ($row = mysqli_fetch_array($fetchData)) {
$data[] = array(
"id" => $row["undefined_hieroglyph_code"],
"text" => $row["undefined_hieroglyph_code"]."/".$row["image_link"]
);
}
Is there a solution to this problem?
I recommend you take a look at select2 templateResult option here
You should first add the URL of the image as a separate key in your results and then use it in the function that templates your select2
while ($row = mysqli_fetch_array($fetchData)) {
$data[] = array(
"id" => $row["undefined_hieroglyph_code"],
"text" => $row["undefined_hieroglyph_code"],
"imageUrl" => $row["image_link"]
);}

Want to have checkbox already checked when data is loaded

I am using bootstrap-table (https://bootstrap-table.com/) and loading data via json. All data is currently loading correctly - an id field, checkbox field, and name. I load the data into an array, then into the table. However, I want certain records to have the checkbox already selected, depending on certain things. How do I pass this via the array below?
The scenario below does not work.
Here is how I am preparing my array in php:
$user_accounts[] = array(
'id' => $i,
'selected' => 'true', -- this is the checkbox
'name' => $name
);
My table is set up with these columns:
{ field: 'id', colspan: 1 },
{ field: 'bs-checkbox' },
{ field: 'name', align: center }
I get my data from an ajax call:
$.ajax
.....
success: function(data);
var opts = $.parseJSON(data);
$('.userTable').bootstrapTable(load,opts);
I thought sending 'true' to the checkbox would cause the checkbox to be checked, but that does not seem to be the case.
My HTML is set up as follows:
<th data-field="id"></th>
<th data-field="state" data-checkbox=true"></th>
<th data-field="cn">Name</th>
<th data-field="selected">Selected</th>
You can use the built-in bootstrap-table check method as:
$('.userTable').bootstrapTable('check', 1);
Where 1 is the row index that of the row that you want to be checked.
In your case you should place this code after table has loaded.

PHP table + pdfMake + AngularJS

I'm a noobie of PHP and AngularJS.
I have a webpage that communicates to a web serves with PHP - AJAX. It queries a database, and echoes the result (a big table) in an html placeholder.
I want to print the content of that table in a downloadable PDF file when the user pushes a button.
I want to use PDFmake and now it works well for test purpose, but how can I pass that content of my table to AngularJS' app?
Maybe should I pass table's id to docDefinition content? In that case I don't know how to do that.
Note: Maybe my approach is uncorrent cause I have to relegate PHP to different tasks and use AngularJS to query the Database, but for now I want to mantain this approach.
Thank You
I suggest you use an angular service (as explained in the docs
)
var bigTableApp = angular.module('bigTable',[])
bigTableApp.factory('BigTableSrv', ['$resource',
function($resource) {
return $resource('URL_to_php_backend', {}, {
query: {
method: 'GET',
params: {param1: 'value 1', param2: 'value 2'},
isArray: true
}
});
}
]);
Then, you can use it in a controller to fetch data from the back-end and build a table structure in PDFmake's table format:
bigTableApp.controller('BigTableController', ['$scope', 'BigTableSrv',
function BigTableController($scope, BigTableSrv) {
$scope.bigTable = BigTableSrv.query();
$scope.pdfMakeTable = {
// array of column widths, expand as needed
widths: [10, *, 130],
body: []
};
$scope.printTable = function() {
pdfMakeTable.body = $scope.bigTable.map(el => {
// process each element of your "big table" to one line of the
// pdfMake table, size of return array must match that of the widths array
return [el.prop1, el.prop2, el.prop3]
});
// create the pdfMake document
let docDefinition = {
content: [ pdfMakeTable ]
}
// print your pdf
pdfMake.creatPdf(docDefinition).print()
}
}
]);

CakePHP 2.4: Getting large, extensible forms past SecurityComponent?

What is the most secure way to submit large, extensible forms with CakePHP (2.4) and SecurityComponent?
I have a form on my app which creates new fields to store new subrecords (and sub-subrecords) using jQuery. This clashes with Cake's SecurityComponent, which expects all fields on a submitted form to have been created server-side by FormHelper.
In the past, when I've been only saving records across one association, I've been able to limit fields user-side to a high but workable number like 100, and explicitly unlock each and every possible field the form could generate:
while($i < 100){
$this->Form->unlockField('ChildModel.' . $i . '.value'); $i++;
// unlock other fields for that possible record
}
However, with this new form I have to save data across not one but two relationships. Users can potentially create a lot of sub-records or sub-sub-records, so the namespace ChildModel.[1-100].field, ChildModel.[1-100].GrandchildModel.[1-100].field starts to get huge. Unlocking a namespace of tens of thousands of possible fields, very few of which are going to be used but all of which are potentially going to be needed, starts to sound really crazy.
What solutions have other CakePHP devs found to get around this issue? I presume this is something that other people have encountered, where disabling Security for the entire action is simply not an option.
Personally I'm doing it this way:
Use AJAX to send the information of the dynamic fields to create back to the server
Genereate a form with the new inputs
Extract the token values from the generated form HTML and pass them back together with the generated HTML of the new fields
Inject the generated HTML and token values into the existing form
???
Profit!
Here's a very basic stripped example from an older project, it is used to add additional inputs for a single association.
Server side:
App::uses('Xml', 'Utility');
$formHtml = $this->Form->create('Model');
$this->Form->input('some_field');
$this->Form->input('also_a_field');
$dynamicInputs = array();
for($i = 0; $i < $numberOfEntries; $i ++)
{
$dynamicInputs[] = $this->Form->input('AssociatedModel.' . $i . '.field');
}
$formHtml .= $this->Form->end();
$xml = Xml::build($formHtml);
$formData = Xml::toArray($xml);
$data = array
(
'token' => array
(
'key' => array
(
'id' => $formData['form']['div'][0]['input'][1]['#id'],
'value' => $formData['form']['div'][0]['input'][1]['#value']
),
'fields' => array
(
'id' => $formData['form']['div'][2]['input'][0]['#id'],
'value' => $formData['form']['div'][2]['input'][0]['#value']
),
'unlocked' => array
(
'id' => $formData['form']['div'][2]['input'][1]['#id'],
'value' => $formData['form']['div'][2]['input'][1]['#value']
)
),
'dynamicInputs' => $dynamicInputs
);
echo json_encode($data);
Frontend (using jQuery):
var form = $('#my-form');
function addEntry()
{
var inputs = form.find('.associated-model .input');
var numberOfEntries = inputs.length + 1;
$.ajax({
url: '/controller/action/whatever',
type: 'POST',
data: 'numberOfEntries=' + numberOfEntries + '&' + form.serialize(),
dataType: 'json',
success: function(data)
{
updateForm(data);
}
});
}
function updateForm(data)
{
var tokenKey = form.find('input[name=\'data[_Token][key]\']');
tokenKey.attr('id', data.token.key.id);
tokenKey.attr('value', data.token.key.value);
var tokenFields = form.find('input[name=\'data[_Token][fields]\']');
tokenFields.attr('id', data.token.fields.id);
tokenFields.attr('value', data.token.fields.value);
var tokenUnlocked = form.find('input[name=\'data[_Token][unlocked]\']');
tokenUnlocked.attr('id', data.token.unlocked.id);
tokenUnlocked.attr('value', data.token.unlocked.value);
form.find('.associated-model').empty().append(data.dynamicInputs.join('\n'));
}

Autopopulate textarea from database based on dropdown selection

I am trying to autopopulate a textarea with values from a (wordpress) database based on the value selected in a select menu. Basically the select menu contains a list of teams and I wish to populate my textarea with names of the players from the selected team.
The problem is that I need to convert the selected text to a php variable in order to use it to query the database. Like so:
PHP
$usergroups = $mingleforum->get_usergroups();
$team_title = $_GET['usergroup'];
$team_id = get_page_by_title( $team_title );
$players = get_users( array (
'meta_key' => 'team-meta',
'meta_value' => $team_id
));
JS
jQuery(function(jQuery){
jQuery('#usergroup').change(function() {
jQuery.ajax({
type: "GET",
url: "http://localhost:8888/dev_wordpress/wp-admin/admin.php?page=mfgroups&mingleforum_action=usergroups&do=add_user_togroup",
data: { usergroup: jQuery(this).find(':selected').text() }
}).done(function( msg ) {
alert( "Data Saved: " + msg );
});
});
});
UPDATE: corrected the url (based on #jterry 's comment) and no longer getting error (although it still isn't working)
I am getting the following error:
GET http://localhost:8888/dev_wordpress/wp-admin/wpf-addusers.php?usergroup=Coq+and+Bulldog 404 (Not Found)
For the points! :D
wpf-addusers.php doesn't exist at that path. Specify the absolute URI and you'll at least make it past the 404 error. Also, it looks like your url parameter has "" on both sides of the variable - you just need one on each side.
EDIT
To access the variable you're looking for (usergroup) to use in your PHP script, you can use $_GET['usergroup']. From there, you can use it as you see fit or insert it as the value of an input element.
If you use the value in an input element, be sure to use htmlentities to properly escape the value.

Categories