I have this row in a database
and I want to be able to change the values in each block (e.g. [license_civ_driver,1]) through a page on a website. The full cell in the database can be seen here.
"[[`license_civ_driver`,1],[`license_civ_boat`,0],[`license_civ_pilot`,1],[`license_civ_advpilot`,1],[`license_civ_trucking`,1],[`license_civ_gun`,1],[`license_civ_hunting`,0],[`license_civ_dive`,0],[`license_civ_home`,0],[`license_civ_platinum`,1],[`license_civ_oil`,1],[`license_civ_diamond`,0],[`license_civ_salt`,0],[`license_civ_sand`,0],[`license_civ_iron`,0],[`license_civ_copper`,1],[`license_civ_cement`,0],[`license_civ_rubber`,0],[`license_civ_meth`,0],[`license_civ_cocaine`,0],[`license_civ_heroin`,0],[`license_civ_marijuana`,0],[`license_civ_rebel`,0],[`license_civ_advrebel`,0]]"
(I already have all the database connections set up, I just need the query and PhP code to do as I mention).
I also want to make each block translate into text (e.g. license_civ_driver will be Driver License).
As well as that, I want to display each block as a div and have the background change colour based on the number within the block.
I know this is probably a huge ask but I have tried everything to my knowledge including using sites to help me do it myself (this is my attempt). If anyone can help me do it then I would be extremely grateful. If someone wants to make it for me then I would greatly appreciate that but obviously I want to learn so I'd rather be helped.
Thanks in advance!
I notice in your code that you are including many files inside a loop - some inside other loops... this is NOT the way to do it I would say. Also I believe it is something of a mistake to say "I'll sort that ( sql injection ) out later" considering "...obviously I want to learn so I'd rather be helped."
It would be better to adopt the good practises early, do it right and then not have to go back.
That said perhaps the following might be of use based upon the comments in the question rather than in-depth studying of the php.
update:
After reading your comment I added some hastily written javascript code ( and made a minor change to the php generated html ) - it's not tested mor ethan a simple click but should give the mechanism by which you can accomplish the stated goal. Use the request to trigger some PHP code ( same page or other script... ) - validate parameters/data sent, construct sql prepared statement and execute.
/* some rudimentary styles for demo purposes */
echo "
<style>
.class_low{padding:1rem;width:100%;background:rgba(255,0,0,0.25);}
.class_medium{padding:1rem;width:100%;background:rgba(0,0,255,0.25);}
.class_high{padding:1rem;width:100%;background:rgba(0,255,0,0.25);}
.unknown{padding:1rem;width:100%;background:yellow}}
</style>
<script>
const buildparams=function(p){
if( p && typeof( p )==='object' ){
p=Object.keys( p ).map(function( k ){
return typeof( p[ k ] )=='object' ? buildparams( p[ k ] ) : [ encodeURIComponent( k ), encodeURIComponent( p[ k ] ) ].join('=')
}).join('&');
}
return p;
};
const ajax=function(url,params,callback){
let xhr=new XMLHttpRequest();
xhr.onload=function(){
if( this.status==200 && this.readyState==4 )callback.call( this, this.response )
};
xhr.onerror=function(e){
alert(e)
};
xhr.open( 'POST', url, true );
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xhr.setRequestHeader('X-Requested-With','XMLHttpRequest');
xhr.send( buildparams( params ) );
};
const evtcallback=function(r){
alert(r);
};
const evtbindclicks=function(div){
div.addEventListener( 'click', evtclickhandler, false );
};
const evtclickhandler=function(e){
let url=document.location.href;
let params={ licence:this.innerHTML, value:this.dataset.value };
ajax.call( this, url, params, evtcallback );
};
document.addEventListener('DOMContentLoaded',function(){
Array.prototype.slice.call( document.querySelectorAll('.class_low, .class_medium, .class_high, .unknown') ).forEach( evtbindclicks );
},false );
</script>";
/* a lookup object to choose correct style based upon integer value */
$matrix=array(
0 => 'class_low',
1 => 'class_medium',
2 => 'class_high'
);
/* fudge around with the database column data. It would be so much easier if the data were originally json in the db! */
function makejson( $colval, $arr ){
$colval=str_replace( array( '"', '`','_' ),array('',"#",' ' ), $colval );
return json_decode( str_replace( $arr,'', str_replace( '#', '"', $colval ) ) );
}
/* words to replace in data */
$arrchrs=array('civ','license');
/* source data - ie: column data from db */
$colval="[[`license_civ_driver`,1],[`license_civ_boat`,2],[`license_civ_pilot`,15],[`license_civ_advpilot`,0],[`license_civ_trucking`,1],[`license_civ_gun`,1],[`license_civ_hunting`,0],[`license_civ_dive`,0],[`license_civ_home`,0],[`license_civ_platinum`,1],[`license_civ_oil`,1],[`license_civ_diamond`,0],[`license_civ_salt`,0],[`license_civ_sand`,0],[`license_civ_iron`,0],[`license_civ_copper`,1],[`license_civ_cement`,0],[`license_civ_rubber`,0],[`license_civ_meth`,0],[`license_civ_cocaine`,0],[`license_civ_heroin`,0],[`license_civ_marijuana`,0],[`license_civ_rebel`,0],[`license_civ_advrebel`,0]]";
/* attempt to make the above usable */
$json=makejson( $colval, $arrchrs );
/* process the data, create a new div per item and assign class using matrix */
foreach( $json as $arr ){
$class = isset( $matrix[ $arr[1] ] ) ? $matrix[ $arr[1] ] : 'unknown';
$name = $arr[0];
printf( '<div class="%s" data-value="%d">%s Licence</div>', $class, $arr[1], ucwords( $name ) );
}
This will yield something like this:
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()
}
}
]);
Im trying to update the mini-cart (cart_fragments) after/on an ajax event. It works like this.
HTML Trigger:
<a id="woomps-button-\'.$nr.\'" class="woomps-button" '.$ajax_url.' data-button-nr="'.$nr.'">
jQuery request:
jQuery( document ).on('click', '.woomps-button', function() {
var nr= jQuery(this).data('button-nr');
jQuery.ajax({
url : subpost.ajax_url,
type : 'post',
data : {
action : 'woomps_update_nr',
security : subpost.security,
nr: nr
},
success : function( response ) {
window.alert(nr);
//MAYBE_code to refresh_fragments here
}
});
return false;
});
PHP responder:
function woomps_update_choosen_person () {
$p = $_POST['nr'];
if ($p == 1) {$x= "This must show in cart";}
WC()->session->set( 'woomps_limit_by_persons' , $x );
//MAYBE code to refresh_fragments here
}
And in the mini-cart.php template i have a calculation based on this field.
$items_left_start = WC()->session->get( 'woomps_limit_by_persons' )?: 3 ;
//Do something something here
So this works, except I need to refresh the cart like when an item is added to cart. My assumption is that is should be an ajax request from jQuery that i can put in the success block?
The class i (think) I want to fire is this WC_AJAX::get_refreshed_fragments(); But this is fired from an an add_action, so i tried this add_action( 'wp_ajax_nopriv_woocommerce_get_refreshed_fragments', array( 'WC_AJAX', 'get_refreshed_fragments' ) );. But it did not work either.
I also try to create an jQuery ajax call like it does in the add_to_cart button, but it neither worked.
//MAYBE_code to refresh_fragments here
var data = {};
jQuery.post(
wc_get_refreshed_fragments_params.wc_ajax_url.toString().
replace( '%%endpoint%%', 'get_refreshed_fragments' ), data,
function( response ){
})
}
I do not completely understand how this works, if anyone have some pointers or a snippet i would so much appriciate it. Been struggeling with this for some time now.
After much struggeling this topic on stack helped create the correct code to update mini cart fragments. It was both PHP and jQuery neeeded.
So basically you can call the WC_AJAX::get_refreshed_fragments() at the end of your PHP coode responder; if it comes from an AJAX call. It will not return to your PHP responder code so put it at the end. The PHP respons will end/sent back to jQuery inside the WC_AJAX::get_refreshed_fragments(); so you also need to create some jQuery that responds to this. This i got from the topic:
var fragments = response.fragments;
if ( fragments ) {
jQuery.each(fragments, function(key, value) {
jQuery(key).replaceWith(value);
});
}
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'));
}
i have made this example work on my page http://datatables.net/examples/server_side/server_side.html, (using php5, jquery+ui and dataTables.net)
i would like to be able to add a Modify and Delete link on each row, how can i do that without sending two extra columns with the links from the server?
also how can i substitute the ids the rows have in the database and that are sent by the server with nice number starting from 1 till iTotalDisplayRecords...
thank you
found how
var controller_name = '<?php echo Zend_Controller_Front::getInstance()->getRequest()->getControllerName();?>';
"fnDrawCallback": function ( oSettings ) {
/* Need to redo the counters if filtered or sorted */
for ( var i=0, iLen=oSettings.aiDisplay.length ; i<iLen ; i++ )
{
var link = $(' Modifica Cancella');
$('td:eq(0)', oSettings.aoData[ oSettings.aiDisplay[i] ].nTr ).html( i+1 );
$('td:eq(0)', oSettings.aoData[ oSettings.aiDisplay[i] ].nTr ).append(link);
}
},