SilverStripe Template - how to access keyless values - silverstripe

How can I show a 2 dimensional array as html table per SS template? Since there are just values and no keys for the Child/Row DO I'm struggling to show theme per template. How do I call theme in template or how would you do?
array showItems
0 =
0 = Title
1 = Text
...
1 =
0 = Title
1 = Text
...
...
PHP
public function showItems() {
$result = ArrayList::create();
$table = $this->getItems();
foreach ($table as $row) {
$r = DataObject::create($row);
$result->push($r);
}
return $result;
}
Template:
<% if $showItems %>
<table>
<% loop $showItems %> // loop for rows
<tr>
<% loop $Children %> // loop for cells
<td>$Me</td>
<% end_loop %>
</tr>
<% end_loop %>
</table>
<% end_if %>

Use ArrayData for each row, but as you know what each column is standing for I'd add keys to it, e.g. using array_combine()
Untested:
public function showItems() {
$result = ArrayList::create();
$table = $this->getItems();
$keys = array('ID', 'Foo', 'Bar');
foreach ($table as $row) {
$r = ArrayData::create(array_combine($keys, $row));
$result->push($r);
}
return $result;
}
Another possibility:
public function showItems() {
$result = ArrayList::create();
$table = $this->getItems();
foreach ($table as $row) {
$r = ArrayList::create($row)); //you can oop over an ArrayList
$result->push($r);
}
return $result;
}
In your template you might do:
<% if $showItems %>
<table>
<% loop $showItems %> // loop for rows
<tr>
<td>$ID - $Foo</td>
<td>$Bar</td>
</tr>
<% end_loop %>
</table>
<% end_if %>
Another possibility:
public function showItems() {
$result = ArrayList::create();
$table = $this->getItems();
foreach ($table as $row) {
$r = ArrayData::create(array('Row' => ArrayList::create($row)))); //you can oop over an ArrayList
$result->push($r);
}
return $result;
}
<% if $showItems %>
<table>
<% loop $showItems %> // loop for rows
<tr>
<% loop $Row %>
<td>$Me</td> //dunno if that really works...
<% end_loop %>
</tr>
<% end_loop %>
</table>
<% end_if %>

Related

How to add paging in Doctrine Zend Framework 3

I've already added paginator.phtml file and I have added some code in controller
$adapter = new DoctrineAdapter(new ORMPaginator( $logList , false));
$paginator = new Paginator($adapter);
$paginator->setDefaultItemCountPerPage(10);
$paginator->setCurrentPageNumber(1);
return new ViewModel(['logList'=>$logList ,'form'=>$form,'posts' => $paginator]);
On the view page I'm using this code:
$this->paginationControl($posts,
'Sliding',
'ripple-site/partial/paginator',
['route' => 'ripplesite']
);
This code produces error:
Argument 1 passed to Doctrine\ORM\Tools\Pagination\Paginator::cloneQuery() must be an instance of Doctrine\ORM\Query, array given, called in C:\zend\vendor\doctrine\orm\lib\Doctrine\ORM\Tools\Pagination\Paginator.php on line 244
Done this a few times now, so I'll provide you with a basic indexAction. (Note the difference in what's loaded into the OrmPaginator, which is probably your issue)
use Doctrine\Common\Collections\Criteria;
use Doctrine\ORM\QueryBuilder;
use Doctrine\ORM\Tools\Pagination\Paginator as OrmPaginator;
use DoctrineORMModule\Paginator\Adapter\DoctrinePaginator as OrmAdapter;
// class
public function indexAction()
{
$page = $this->params()->fromQuery('page', 1); // default page
$pageSize = $this->params()->fromQuery('pageSize', 10); // default page size
$orderBy = $this->params()->fromQuery('orderBy', 'createdAt'); // default order by (replace with your own property name!)
$orderDirection = $this->params()->fromQuery('orderDirection') === Criteria::ASC // default order direction (desc to display newest first - replace with your own)
? Criteria::ASC
: Criteria::DESC;
$criteria = (new Criteria())
->setFirstResult($page * $pageSize)
->setMaxResults($pageSize)
->orderBy([$orderBy => $orderDirection]);
/** #var QueryBuilder $qb */
$qb = $this->getObjectManager()->createQueryBuilder();
$qb->select('a') // replace with your own alias key
->from(Article::class, 'a') // replace with your own class and alias
->addCriteria($criteria);
$paginator = new Paginator(new OrmAdapter(new OrmPaginator($qb)));
$paginator->setCurrentPageNumber($page);
$paginator->setItemCountPerPage($pageSize);
return [
'paginator' => $paginator,
'queryParams' => $this->params()->fromQuery(),
];
}
Requirements are that the class has the an instance of ObjectManager. If you use $entityManager, that's fine, just replace $this->getObjectManager() with $this->getEntityManager() or $this->entityManager.
The rest should work out of the box.
Display like so in index.phtml for this controller->action
<?php
/** #var \Article\Entity\Article[] $paginator */
$pagination = $this->paginationControl(
$paginator,
'sliding',
'theme/partials/pagination', // This here assumes you have a partial setup for pagination. If not, leave a comment and I can add a default Bootstrap 4 compatible one.
[
'route' => 'admin/articles',
'queryParams' => $queryParams,
]
);
<?php if (isset($paginator) && $paginator->count() > 0) : ?>
<table class="table table-striped">
<thead>
<tr>
<th><?= $this->translate('Title') ?></th>
<!-- more columns -->
</tr>
</thead>
<tbody>
<?php foreach ($paginator as $article): ?>
<tr>
<td>
<?= $this->escapeHtml($article->getTitle()) ?>
</td>
<!-- more columns -->
</tr>
<?php endforeach ?>
</tbody>
</table>
<?php if ($paginator->count() > 1) : ?>
<?= $pagination ?>
<?php endif ?>
<?php else : ?>
<p><?= $this->translate('No records found. Try again later or report an issue.') ?></p>
<?php endif ?>

symfony crawler access nested div

I'm desperately trying to access content in a nested div :
<tr>
<th class="monthCellContent" style="vertical-align : top">
<div class="monthEventWrapper">
<div class="monthEvent">
<a class="event"
href="/event/1"
title="test title updated - test place - 09:00-10:00">
09:00
<span class="showForMediumInline">
test title updated test place
</span>
</a>
</div>
</div>
</th>
</tr>
I'm trying to access "09:00" and "test title updated test place" in the link.
I'm somehow stuck at
<div class="monthEventWrapper">
which I can access with
$items = $crawler->filter('div[class="monthEventWrapper"]');
print "\n found " . count($items) . " monthEventWrapper divs\n";
found 35 monthEventWrapper divs
but I cannot access
<div class="monthEvent">
with
$items = $crawler->filter('div[class="monthEvent"]');
print "\n found " . count($items) . " monthEvent divs\n";
found 0 monthEvent divs
I tried all variations around
foreach ($items as $item) {
foreach ($item->childNodes as $child) {
$value .= $paragraph->ownerDocument->saveHTML($child);
}
}
and
$crawler->filterXPath('//div[#class="monthEvent"]')
with no luck.
The html passes validations and there's no js.
Thanks !
This a workaround type of code:
<?php
use Symfony\Component\DomCrawler\Crawler;
require_once(__DIR__ . '/../vendor/autoload.php');
$html = <<<'HTML'
<!DOCTYPE html>
<html>
<body>
<tr>
<th class="monthCellContent" style="vertical-align : top">
<div class="monthEventWrapper">
<div class="monthEvent">
<a class="event"
href="/event/1"
title="test title updated - test place - 09:00-10:00">
09:00
<span class="showForMediumInline">
test title updated test place
</span>
</a>
</div>
</div>
</th>
</tr>
</body>
</html>
HTML;
$crawler = new Crawler($html);
$crawlerFiltered = $crawler->filter('div[class="monthEventWrapper"] a');
$results = [];
$childResults = [];
for ($i=0; $i<count($crawlerFiltered); $i++) {
$results[] = removeLeadingAndTrailingWhiteCharsAndNewLine($crawlerFiltered->eq($i)->text());
$children = $crawlerFiltered->eq($i)->children();
if (count($children)) {
for ($j=0; $j<count($children); $j++) {
$childResults[] = removeLeadingAndTrailingWhiteCharsAndNewLine($children->eq($j)->text());
}
}
}
$results[0] = substractSpan($results[0], $childResults[0]);
function removeLeadingAndTrailingWhiteCharsAndNewLine(string $text) : string
{
$pattern = '/(?:\r\n[\s]+|\n[\s]+)/s';
return preg_replace($pattern, '', $text);
}
function substractSpan($text, $textToSubstract) : string
{
$length = strlen($text) - strlen($textToSubstract);
return substr($text, 0, $length);
}
echo 'Parent Nodes:' . PHP_EOL;
var_export($results);
echo PHP_EOL;
echo 'Child Nodes:' . PHP_EOL;
var_export($childResults);
echo PHP_EOL;
echo 'Time: ';
echo $results[0];
echo PHP_EOL;
echo 'Text: ';
echo $childResults[0];
but gives this result:
Parent Nodes:
array (
0 => '09:00',
)
Child Nodes:
array (
0 => 'test title updated test place',
)
Time: 09:00
Text: test title updated test placee
Note I used for loop with ->eq(<node-number>) that gives Crawler instance instead of DOMNode that you get by using foreach
Note the code assumes the wanted text part 9:00 is at the beginning.

Get featured image of post once gravity forms selects that post

I'm creating a form using Gravity Forms where users will be able to select type of aircrafts, add different flight hours, perks, and other add-ons to their flight. I'm populating the checkbox fields in Gravity Forms with a custom post type I created.
Once a user selects the flight and other perks available, to the left of their selections, I'm populating an HTML Field from GF to display {all_fields}. Since the aircrafts checkboxes are being populated by a custom post type, I want to be able to grab that featured image of that post type and then display it above the location of the HTML Field.
The code listed here is the function I'm using to populate those checkboxes with the custom post type:
add_filter( 'gform_pre_render_6', 'ldm_do_bac_aircraft_large' );
add_filter( 'gform_pre_validation_6', 'ldm_do_bac_aircraft_large' );
add_filter( 'gform_pre_submission_filter_6', 'ldm_do_bac_aircraft_large' );
add_filter( 'gform_admin_pre_render_6', 'ldm_do_bac_aircraft_large' );
function ldm_do_bac_aircraft_large( $form ) {
foreach ( $form['fields'] as &$field ) {
if ( strpos( $field->cssClass, 'bac-aircraft-large' ) === false ) {
continue;
}
$posts = get_posts( array(
'numberposts' => -1,
'post_status' => 'publish',
'post_type' => 'ldm_build_card',
'order' => 'ASC',
'tax_query' => array(
array(
'taxonomy' => 'ldm_build_card_categories',
'field' => 'slug',
'terms' => array( 'large' ),
),
),
) );
$choices = array();
foreach ( $posts as $post ) {
$choices[] = array( 'text' => $post->post_title, 'value' => $post->post_title );
}
$field->choices = $choices;
}
return $form;
}
So my goal is for when the user selects either a Large, Super-Mid, Mid, or Small aircraft (and those are the categories) the next page of the multi-page GF will not only display that plane the user selected, which is does, but I want it to display that post/Aircrafts featured image above it. So the image will change depending on the aircraft selected.
Does anyone have an idea how I can get the featured image of that post ID depending on what the user selects in GF?
UPDATE 6/24
Ok so to be more clear to what I'm doing. Im using gravity forms Multi-page to create a form to get aircrafts, perks, hours, add-ons, etc. I needed to populate the Aircrafts 'page' of the form with the custom post type. I have these populated but I needed to display the post information such as a Featured Image, Aircraft Name, Range, etc.. above the actual input. I have done that and satisfied but I needed to pull the image of the post so when the form then is submitted and navigates to the next page of the form, it would display that Post Featured Image along with all the other fields I selected.
In this case I selected an aircraft which it displays the title and I needed the Featured Image to go with it. Originally this needed to be an AJAX Gravity Form. The image would not display and would display as undefined when I checked the console log because I'm also moving things around with jQuery.
You may say why am I doing it this way, well it's just what I decided to do because this is my first crack at a multi-page GF where I needed to display a custom post type as selections.
Ok so since the image was not displaying, I decided to turn off AJAX on the Form because I had this idea that the script that is spitting out the filterable categories of the aircrafts was being removed. I was correct so I turned off AJAX and the image now displays. So my Question now is how can I include this script to be included in the AJAX request for this particular Form.
Below I have my jQuery to display the post image in a specific area once that aircraft has been selected.
var checkboxValue = $('#gform_page_6_1 input[type=checkbox]:checked').val();
var aircraftSelect = $('#membershipAircrafts').find('[data-aircraft-title="'+checkboxValue+'"]');
var aircraftImage = $(aircraftSelect).find( '.membership-aircraft-image' );
console.log( aircraftImage );
$('.summary-image').html( aircraftImage );
Now here is the script that I thought was being removed:
function ldm_add_membership_aircrafts() {
?>
<script type="text/template" id="single-membership-listings">
<% _.each( membershipAircrafts, function( membershipAircraft ) { %>
<div id="aircraft<%= membershipAircraft.id %>" class="single-membership-inner clearfix col-sm-4" data-aircraft-title="<%= membershipAircraft.title %>">
<% if( membershipAircraft.imageURL ) { %>
<img class="membership-aircraft-image" src="<%= membershipAircraft.imageURL %>" alt="<%= membershipAircraft.title %>" />
<div class="single-membership-content-container">
<% } else { %>
<div class="single-membership-content-container">
<% } %>
<div class="single-membership-title"><%= membershipAircraft.title %></div>
<div class="single-membership-range">
<p id="membership-label">Range:</p>
<p id="membership-range-content"><%= membershipAircraft.range %></p>
</div>
<div class="single-membership-passengers">
<p id="membership-label">Passengers:</p>
<p id="membership-passengers-content"><%= membershipAircraft.passengers %></p>
</div>
<div class="single-membership-baggage">
<p id="membership-label">Luggage Capacity:</p>
<p id="membership-baggage-content"><%= membershipAircraft.baggage %></p>
</div>
<div class="single-membership-cabinDimensions">
<p id="membership-label">Cabin Dimensions:</p>
<p id="membership-cabinDimensions-content"><%= membershipAircraft.cabinDimensions %></p>
</div>
</div>
</div>
<% }); %>
</script>
<script type="text/template" id="single-categories-listings">
<% var categoryName; %>
<% var count = 0; %>
<div class="membership-categories-inner">
<% _.each( membershipCategories, function( membershipCategory ) { %>
<% if( count !== 0 && categoryName !== membershipCategory.taxonomy ) { %>
</div>
<% } %>
<div data-term-id="<%= membershipCategory.id %>" class="single-membership-category <%= membershipCategory.termName %><% if( count === 0 ){ %> category-active <% } %>"><%= membershipCategory.termName %></div>
<% categoryName = membershipCategory.taxonomy; %>
<% count++; %>
<% }); %>
</div>
</div>
</script>
<?php
}
Thinking about it I'm not sure the script is being removed but AJAX is actually removing the custom fields that I am placing as a partial and using jQuery to add them above the actual inputs
echo '<li id="aircraft-tax" class="gfield">';
echo '<div class="row">';
echo '<div class="col-sm-12">';
echo '<div id="membershipCategories" class="membership-categories"></div>';
echo '</div>';
echo '</div>';
echo '</li>';
echo '<li id="aircraft-content" class="gfield">';
echo '<div class="row">';
echo '<div class="col-sm-10 col-sm-offset-1">';
echo '<div id="membershipAircrafts" class="membership-aircrafts"></div>';
echo '</div>';
echo '</div>';
echo '</li>';
Here is the jQuery that i'm using to place above the inputs:
$('#field_6_2').after( $('#aircraft-tax') );
$('#aircraft-tax').after( $('#aircraft-content') );
What Can I do to prevent AJAX from removing this information. If I can include this into the AJAX request then I feel the images will display just like they do if I turn AJAX off on the GF.
**
UPDATE 3
**
I found my issue. Turns out that when I enable ajax on Gravity Forms, it is not adding a template that I originally load on the page. For example I have a partial that I'm including on my page:
get_template_part( 'partials/membership-template', 'aircraft' );
This is being added originally but once I navigate to the next form page (because it is a multi-page form) this template that is being called on the page gets removed.
So how can I keep this template or partial from being removed after the form navigates to the next form page?
Since your form is having users select a category of plane (from you custom taxonomy) you need to get an actual post in order to display a featured image. Add this where you are rendering your form page.
$args = array(
'posts_per_page' => 1,
'post_type' => 'ldm_build_card',
'ldm_build_card_categories' => 'large',//or selected type
'post_status' => 'publish'
);
$show_image = get_posts( $args );
if( $show_image ) {
get_the_post_thumbnail( $show_image[0]->ID, 'image-size');
}
UPDATE: In case I misunderstood your question:
The post ID should also be in your form input so get_the_post_thumbnail( $entry[id-of-selection-field], 'image-size');would also output your image.
UPDATE 2:
To get data from one page to another add an html field to the second page, use a pre_render filter:
add_filter( 'gform_pre_render_{form_id}', 'populate_html' );
Then use GFFormDisplay to get the page. Loop through form fields to get your post id and get the image from there.
function populate_html( $form ) {
//this is a 2-page form with the data from page one being displayed in an html field on page 2
$current_page = GFFormDisplay::get_current_page( $form['id'] );
$html_content = "The information you have submitted is as follows:<br/><ul>";
if ( $current_page == 2 ) {
foreach ( $form['fields'] as &$field ) {
//gather form data to save into html field (id 3 on my form), exclude page break
foreach ( $field->inputs as $input ) {
if ($input['id'] == {selected-plane-input}) {
$input_name = 'input_' . str_replace( '.', '_', $input['id'] );
$value = rgpost( $input_name );
$html_content .= '<p>' . wp_get_attachment_url( get_post_thumbnail_id($value)). '</li>';
}
}
}
}
foreach ( $form['fields'] as &$field ) {
if ( $field->id == {your-html-field-id} ) {
//set the field content to the html
$field->content = $html_content;
}
}
return $form;
}

How to remove inserted digit at the end of a metabox in WordPress?

I created a custom metabox in Wordpress but in rendering there is a "1" at the end of my content. I can't figure out how to remove it.
With this call...
add_meta_box(2, 'Calendrier de la formation', 'render_formations_calendrier_meta_box', null, 'side');
I get this metabox.
What is this "1" ? And can I remove it ? (it didn't come from my template)
edit
function render_formations_calendrier_meta_box($post) {
echo require('templates/partials/admin/formations/calendrier_metabox.php');
}
templates/partials/admin/formations/calendrier_metabox.php :
<table id="new_date_area">
<?php $dates = get_post_meta($post->ID, 'next_date') ?>
<?php foreach($dates as $key => $date) : ?>
<?php foreach($date as $event) : ?>
<tr>
<td style="padding:10px 0 0 0">
<input type="text" name="next_date[]" class="datepicker" value="<?= date('d-m-Y', $event) ?>"><span class="dashicons dashicons-trash"></span>
</td>
</tr>
<?php endforeach; ?>
<?php endforeach; ?>
</table>
<button id="new_date_button">nouvelle date</button>
<script>
$(document).ready(function(){
// datepicker
var format = 'dd-mm-yy'
$('.datepicker').datepicker({
dateFormat : format
})
// new date
$('#new_date_button').on('click', (click_event) => {
click_event.preventDefault()
var row = '<tr><td><input type="text" name="next_date[]" class="datepicker"><span class="dashicons dashicons-trash"></span></td></tr>'
$('#new_date_area').append(row)
$('.datepicker').datepicker({
dateFormat : format
})
})
// delete date
$(document).on('click', '.dashicons-trash', function(e) {
$(e.target).closest('tr').remove()
})
})
</script>
I solved it, the "1" was the return of the function require(). I was making echo require() but I only have to do a require without the echo.

Datatable server side wordpress integration

So, I am inheriting an intranet site that was built on datatables. Basically it is made in Wordpress and then displays custom fields that the users have filled out in the datatable. But it was querying 40 columns per post over 2k entries so is now grinding to a standstill when the users try and view the data in the table.
I'm attempting to utilize the server-side aspect of Datatables for this, but running into a little trouble because of how the sql data is formatted.
Can anyone offer any assistance in how to set up the server_processing.php file (i'm using this one: http://datatables.net/development/server-side/php_mysql) to:
Display rows based on the wp_posts.ID index
Display columns in this row based on a different table (wp_postmeta) wherein each column value is indexed separately in the wp_postmeta table by the ID found in 1
Link entire row to a url found in the wp_posts table
If anyone has any ideas I would really appreciate it...
Definitely a plugin for WordPress is most efficient. AJAX can conflict/cause problems with the JQuery that is core to using WordPress edit functions etc. I'd go to WordPress.org and look under plugins for help there. There are also paid/premium intranet plugins such as Simple Intranet. :)
Chris
Probably you might be interested in this plugin - looks like it does exactly what you're looking for: http://wpdatatables.com
An example with server-side processing: http://wpdatatables.com/display-mysql-table-in-wordpress/
You will definitely need a Wordpress table plugin that wraps DataTables functionality. You may consider Tabulizer for Wordpress (http://www.tabulizer.com) that supports server side processing and loads table data via Ajax calls only when needed. There is also a data source cache for improved performance.
Ajax dataTable or server-side processing dataTable in WordPress or Core PHP.
HTML Code
<table id="student_table" width="100%">
<thead>
<tr>
<th>Roll No.</th>
<th>Full Name</th>
<th>Phone</th>
<th>Action</th>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr>
<th>Roll No.</th>
<th>Full Name</th>
<th>Phone</th>
<th>Action</th>
</tr>
</tfoot>
</table>
jQuery code
jQuery('#student_table').DataTable({
"bProcessing": true,
"serverSide": true,
"ajax":{
"url": FrontendConfig.ajaxurl+'?action=getStudentsFromExamIdAjax&exam_nounce=exam_nounce_data&exam_id=1',
type: "post",
}
});
WordPress or PHP code
add_action('wp_ajax_getStudentsFromExamIdAjax', 'getStudentsFromExamIdAjax' );
add_action('wp_ajax_nopriv_getStudentsFromExamIdAjax', 'getStudentsFromExamIdAjax' );
function getStudentsFromExamIdAjax(){
if(empty($_GET['action']) || empty($_GET['exam_id'])){
wp_send_json_error( new \WP_Error( 'Bad Request' ) );
}
if(isset($_GET['exam_id']) && $_SERVER['REQUEST_METHOD'] === 'POST' && wp_verify_nonce( $_GET['exam_nounce'], 'exam_nounce_data' )):
$exam_id = (isset($_GET['exam_id'])) ? absint($_GET['exam_id']) : '';
/*# You can create a function to get the data here */
$students = getStudentsFromExamId($exam_id);
$tdata = [];
foreach ($students as $key => $value):
$tdata[$key][] = $value->roll_no;
$tdata[$key][] = $value->name;
$tdata[$key][] = $value->phone;
$tdata[$key][] = 'action here';
endforeach;
$total_records = count($tdata);
$json_data = array(
/* $_REQUEST['draw'] comes from the datatable, you can print to ensure that */
"draw" => intval( $_REQUEST['draw'] ),
"recordsTotal" => intval( $total_records ),
"recordsFiltered" => intval( $total_records ),
"data" => $tdata
);
echo json_encode($json_data);
endif;
wp_die();
}
Custom.js
jQuery( document ).ready(function() {
alert('test');
jQuery('#employee_grid').DataTable({
"bProcessing": true,
"serverSide": true,
"ajax":{
url :ajax_url_object.ajax_url+'?action=getStudentsFromExamIdAjax&exam_nounce=exam_nounce_data&exam_id=1', // json datasource
type: "POST", // type of method ,GET/POST/DELETE
error: function(){
jQuery("#employee_grid_processing").css("display","none");
}
}
}); });
WordPress or PHP code
function theme_styles1()
{
$template_dir_uri =content_url();
$pluginurl =plugins_url();
//====================js
wp_enqueue_style( 'vpn-custom-style1','https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.2/css/bootstrap.css', true );
wp_enqueue_style( 'vpn-custom-boostrap1','https://cdn.datatables.net/1.11.3/css/dataTables.bootstrap4.min.css', true );
wp_enqueue_script( 'vpn-script11','https://cdn.datatables.net/1.11.3/js/jquery.dataTables.min.js', true );
wp_enqueue_script( 'vpn-script21','https://cdn.datatables.net/1.11.3/js/dataTables.bootstrap4.min.js', true );
wp_enqueue_script( 'vpn_script31', plugin_dir_url( __FILE__ ).'js/custom.js', true );
//============ ajax url
$urls= array('ajax_url'=> admin_url( 'admin-ajax.php' ),
'site_url' => site_url()
);
wp_localize_script( 'vpn_script31', 'ajax_url_object',$urls);
}
add_action( 'wp_enqueue_scripts', 'theme_styles1',99 );
div class="wrap">
<h1>Service List</h1>
<div class="container">
<table id="employee_grid" class="display" width="100%" cellspacing="0">
<thead>
<tr>
<th>Empid</th>
<th>Name</th>
<th>Salary</th>
<th>Age</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Empid</th>
<th>Name</th>
<th>Salary</th>
<th>Age</th>
</tr>
</tfoot>
</table>
</div>
add_action('wp_ajax_getStudentsFromExamIdAjax', 'getStudentsFromExamIdAjax' );
add_action('wp_ajax_nopriv_getStudentsFromExamIdAjax', 'getStudentsFromExamIdAjax' );
function getStudentsFromExamIdAjax(){
global $wp;
$servername = "localhost:3308";
$username = "root";
$password = "";
$dbname = "demo";
$conn = mysqli_connect($servername, $username, $password, $dbname) or die("Connection failed: " . mysqli_connect_error());
$params = $columns = $totalRecords = $data = array();
$params = $_REQUEST;
// echo "<pre>";
// print_r($params);
// die;
//define index of column
$columns = array(
0 =>'id',
1 =>'employee_name',
2 => 'employee_salary',
3 => 'employee_age'
);
$where = $sqlTot = $sqlRec = "";
// check search value exist
if( !empty($params['search']['value']) ) {
$where .=" WHERE ";
$where .=" ( employee_name LIKE '".$params['search']['value']."%' ";
$where .=" OR employee_salary LIKE '".$params['search']['value']."%' ";
$where .=" OR employee_age LIKE '".$params['search']['value']."%' )";
}
// getting total number records without any search
$sql = "SELECT * FROM `employee` ";
$sqlTot .= $sql;
$sqlRec .= $sql;
//concatenate search sql if value exist
if(isset($where) && $where != '') {
$sqlTot .= $where;
$sqlRec .= $where;
}
$sqlRec .= " ORDER BY ". $columns[$params['order'][0]['column']]." ".$params['order'][0]['dir']." LIMIT ".$params['start']." ,".$params['length']." ";
$queryTot = mysqli_query($conn, $sqlTot) or die("database error:". mysqli_error($conn));
$totalRecords = mysqli_num_rows($queryTot);
$queryRecords = mysqli_query($conn, $sqlRec) or die("error to fetch employees data");
//iterate on results row and create new index array of data
while( $row = mysqli_fetch_row($queryRecords) ) {
$data[] = $row;
}
// echo "<pre>";
// print_r($data);
// die;
$json_data = array(
"draw" => intval( $params['draw'] ),
"recordsTotal" => intval( $totalRecords ),
"recordsFiltered" => intval($totalRecords),
"data" => $data // total data array
);
echo json_encode($json_data); // send data as json format
}

Resources