openskill / datatable Goto Github PK
View Code? Open in Web Editor NEWModular server side Datatable package for Laravel 5 for various client side table plugins
Home Page: http://openskill.github.io/Datatable/
License: MIT License
Modular server side Datatable package for Laravel 5 for various client side table plugins
Home Page: http://openskill.github.io/Datatable/
License: MIT License
@Chumper what do you say to me finishing up some documentation on the QBProvider in the documentation
class, and then you removing the scary warning on the master
README.md
?
To me, it seems that QBProvider
, Datatable19QueryParser
and Datatable19Version
has at least the core functionality to replace general usages from Chumper/Datatable
.
The only things that would be blocking this (AFAIK) is:
With the current separation i try to achieve in the code we could also support http://www.dynatable.com/.
We just need a new DTQueryParser
, DTViewCreator
and DTResponseCreator
DTQueryParser
DTViewCreator
DTResponseCreator
ServiceProvider
I know progress can be a bit slow sometimes, but the expected timeline stated in the docs and the current commit history don't match.
I think this project is great, but installing a potentially abandoned unfinished repository seems a bit risky to me.
Would you mind commenting on the current status in the docs? Postponed, migrated, abandoned, "as-is", etc... Thanks!
It would be very helpful if support for pagination could be added.
https://laravel.com/docs/5.2/pagination
We'd like to be able to use Eloquent models without needing to load the full dataset from the table.
VersionEngine
is awesome. Sadly, it's a little bit too optimistic for me.
I have a lot of legacy code that runs on Datatables 1.9, and I am not really prepared to start moving all of that to Datatables 1.10. It would be awesome if there was a configuration file (something like app/config/app.php) where it could be specified in an array what providers you want to use.
For example, datatable.php
:
<?php
return [
'providers' => [
OpenSkill\Datatable\Versions\Datatable110Version::class,
OpenSkill\Datatable\Versions\Datatable19Version::class
];
];
Laravel 5.2 requires "symfony/http-foundation": "2.8.*|3.0.*"
and another package I am using requires ~2.1
which means it tries to install 2.8
but that won't work with openskill/datatable
because it doesn't allow 2.8.*
The Datatable then holds a configuration of all columns and accepts the incoming request parameters. It will then delegate the data processing to the Provider and will provide a ColumnConfiguration object and a PresenterDetail or similar which will include information on what the frontend requested.
While doing a new PR for supporting an older version of symfony/http-foundation
, I found that illuminate/support=4.2.1
does not support reject()
.
We should either update the CollectionProvider to not require reject, or up the minimum version required.
$ phpunit --coverage-clover build/logs/clover.xml
PHPUnit 4.8.0 by Sebastian Bergmann and contributors.
Warning: No whitelist configured for code coverage
.............................PHP Fatal error: Call to undefined method Illuminate\Support\Collection::reject() in /home/travis/build/OpenSkill/Datatable/src/OpenSkill/Datatable/Providers/CollectionProvider.php on line 187
PHP Stack trace:
PHP 1. {main}() /home/travis/.phpenv/versions/5.5.9/bin/phpunit:0
PHP 2. PHPUnit_TextUI_Command::main() /home/travis/.phpenv/versions/5.5.9/bin/phpunit:722
PHP 3. PHPUnit_TextUI_Command->run() phar:///home/travis/.phpenv/versions/5.5.9/bin/phpunit/phpunit/TextUI/Command.php:104
PHP 4. PHPUnit_TextUI_TestRunner->doRun() phar:///home/travis/.phpenv/versions/5.5.9/bin/phpunit/phpunit/TextUI/Command.php:152
PHP 5. PHPUnit_Framework_TestSuite->run() /home/travis/build/OpenSkill/Datatable/vendor/phpunit/phpunit/src/TextUI/TestRunner.php:432
PHP 6. PHPUnit_Framework_TestSuite->run() /home/travis/build/OpenSkill/Datatable/vendor/phpunit/phpunit/src/Framework/TestSuite.php:735
PHP 7. PHPUnit_Framework_TestCase->run() /home/travis/build/OpenSkill/Datatable/vendor/phpunit/phpunit/src/Framework/TestSuite.php:735
PHP 8. PHPUnit_Framework_TestResult->run() /home/travis/build/OpenSkill/Datatable/vendor/phpunit/phpunit/src/Framework/TestCase.php:702
PHP 9. PHPUnit_Framework_TestCase->runBare() /home/travis/build/OpenSkill/Datatable/vendor/phpunit/phpunit/src/Framework/TestResult.php:601
PHP 10. PHPUnit_Framework_TestCase->runTest() /home/travis/build/OpenSkill/Datatable/vendor/phpunit/phpunit/src/Framework/TestCase.php:746
PHP 11. ReflectionMethod->invokeArgs() /home/travis/build/OpenSkill/Datatable/vendor/phpunit/phpunit/src/Framework/TestCase.php:881
PHP 12. packages\OpenSkill\Datatable\tests\OpenSkill\Datatable\Providers\CollectionProviderTest->testProcess() /home/travis/build/OpenSkill/Datatable/vendor/phpunit/phpunit/src/Framework/TestCase.php:881
PHP 13. OpenSkill\Datatable\Providers\CollectionProvider->process() /home/travis/build/OpenSkill/Datatable/tests/OpenSkill/Datatable/Providers/CollectionProviderTest.php:48
PHP 14. OpenSkill\Datatable\Providers\CollectionProvider->compileCollection() /home/travis/build/OpenSkill/Datatable/src/OpenSkill/Datatable/Providers/CollectionProvider.php:112
PHP 15. OpenSkill\Datatable\Providers\CollectionProvider->removeEmptyRowsFromCollection() /home/travis/build/OpenSkill/Datatable/src/OpenSkill/Datatable/Providers/CollectionProvider.php:141
Fatal error: Call to undefined method Illuminate\Support\Collection::reject() in /home/travis/build/OpenSkill/Datatable/src/OpenSkill/Datatable/Providers/CollectionProvider.php on line 187
Is working with Datatable::query too?
In the documentation says: Support Collections
is only for collections?
Implement basic usage for EloquentModelProvider
$datatable = Datatable::make(new EloquentModelProvider(User::class))
return view("template", $datatable)
Laravel version 5.2
Guys, I don't know if this is related to /Chumper/Datatable/pull/375 or /Chumper/Datatable/pull/372
(and /ladybirdweb/faveo-helpdesk/issues/85)
but I'm having troubles with the table() function with openskill datatables.
This code in my view:
{!! Datatable::table()
->addColumn($columns)
->setUrl(url('api/products/'))
->setOptions('sPaginationType', 'bootstrap')
->setOptions('bFilter', false)
->setOptions('bAutoWidth', false)
//->setOptions('aoColumns', [[ "sWidth"=> "15%" ], [ "sWidth"=> "35%" ]])
->setOptions('aoColumnDefs', [['bSortable'=>false, 'aTargets'=>[3]]])
->render('datatable') !!}
(and that's straight from invoiceninja application)
gives the error in the title.
"chumper/datatable": "dev-develop#04ef2bf" is working properly, so probably not merged yet into openskill datatables.
This is a meta bug to show the current state of work (TODO List) for the future version of Datatable.
If you have any questions or comments, please, make sure that you go to the particular issue/topic in question.
The default global search for the CollectionProvider
does ignore the Searchable
property of the columns when a global search is being performed.
The CollectionProvider
should respect individual column settings even on a global search.
I have looked over openskill datatables and it seems the syntax used is very different from Chumper datatables. Is this the case and if so how easy is it to convert old syntax to new. For instance how difficult would it be to change something like the following:
Controller:-
` return Datatable::collection(new Collection($leads))
->addColumn('created_at', function ($Lead) {
return date('Y-m-d H:i', strtotime($Lead['created_at']));
})
->showColumns('reference')
->addColumn('bdm', function ($Lead) {
if ($Lead['bdm_allocated'] == 0) {
return 'None allocated';
} else {
$bdm = User::find($Lead['bdm_allocated']);
$firstname = $bdm['firstname'];
return '<a href="/leads/' . $Lead['bdm_allocated'] . '/user" >' . $firstname . '</a>';
}
})
->showColumns('lead_title')
->addColumn('address', function ($Lead) {
if ($Lead['street_number'] != NULL) {
$address = $Lead['street_number'];
} else {
$address = '';
}
if ($Lead['street_name'] != NULL) {
$address .= ' ' . $Lead['street_name'];
} else {
$address .= '';
}
if ($Lead['suburb_town_city'] != NULL) {
$address .= ' ' . $Lead['suburb_town_city'];
} else {
$address .= '';
}
if ($address == '') {
return 'No Address';
} else {
return $address;
}
})
->addColumn('transaction_type', function ($Lead) {
$type = DB::table('lead_prop_trans_types')->select('type')->whereId($Lead['lead_prop_trans_type'])
->first();
if (!empty($type)) {
if ($type->type == 'Other') {
if ($Lead['lead_prop_trans_type_other'] == '') {
return 'Other';
}
return $Lead['lead_prop_trans_type_other'];
} else {
return $type->type;
}
} else {
return 'Not Selected';
}
})
->addColumn('contact_firstname', function ($Lead) {
$query = 'SELECT u.firstname, u.lastname
FROM users u
INNER JOIN lead_user lu ON u.id = lu.user_id
WHERE CONCAT(u.firstname, " ",u.lastname) IS NOT NULL
AND CONCAT(u.firstname, " ",u.lastname) <> " "
AND lu.lead_id = ' . $Lead['id'] . '
UNION ALL
SELECT lc.firstname, lc.lastname
FROM lead_contacts lc
INNER JOIN leads l ON l.id = lc.lead_id
WHERE CONCAT(lc.firstname, " ",lc.lastname) IS NOT NULL
AND CONCAT(lc.firstname, " ",lc.lastname) <> " "
AND l.id = ' . $Lead['id'] . '
LIMIT 1';
$contact = DB::select($query);
if (empty($contact)) {
return 'No Contacts';
}
return $contact[0]->firstname . ' ' . $contact[0]->lastname;
})
->addColumn('contact_email', function ($Lead) {
$query = 'SELECT u.email, u.cellnumber AS tel
FROM users u
INNER JOIN lead_user lu ON u.id = lu.user_id
WHERE CONCAT(u.firstname, " ",u.lastname) IS NOT NULL
AND CONCAT(u.firstname, " ",u.lastname) <> " "
AND lu.lead_id = ' . $Lead['id'] . '
UNION ALL
SELECT lc.email, lc.tel
FROM lead_contacts lc
INNER JOIN leads l ON l.id = lc.lead_id
WHERE CONCAT(lc.firstname, " ",lc.lastname) IS NOT NULL
AND CONCAT(lc.firstname, " ",lc.lastname) <> " "
AND l.id = ' . $Lead['id'] . '
LIMIT 1';
$contact = DB::select($query);
if (empty($contact)) {
return 'No Contacts';
}
$email = '';
if ($contact[0]->email != '') {
$email = '<strong>Email:</strong> ' . $contact[0]->email . '<br>';
}
$tel = '';
if ($contact[0]->tel != '') {
$tel = '<strong>Tel: </strong>' . $contact[0]->tel;
}
return $email . $tel;
})
->addColumn('note', function ($Lead) {
$query = "SELECT p.note, p.created_at AS date FROM prop_notes p
INNER JOIN users u ON u.id = p.users_id
WHERE p.lead_id = " . $Lead['id'] . "
ORDER BY p.created_at DESC
LIMIT 1";
$last_note = DB::select($query);
if (empty($last_note)) {
return 'No Notes';
}
return $last_note[0]->note . ' <i>...' . $last_note[0]->date . '</i>';
})
->addColumn('actions', function ($Lead) use ($user_id, $lead_id_array) {
if (in_array($Lead['id'], $lead_id_array)) {
$editing_user_id = array_search($Lead['id'], $lead_id_array);
$session = DB::select('SELECT * FROM lead_session WHERE user_id =' . $editing_user_id);
if (($editing_user_id == Auth::user()->id) || (strtotime($session[0]->created_at) <= strtotime('-1 hours'))) {
return '<a href="/leads/' . $Lead['id'] . '/edit" title="Edit" ><i class="i-circled i-light i-alt i-small icon-edit"></i></a>
<a href="/leads/' . $Lead['id'] . '/delete" title="Delete" ><i class="i-circled i-light i-alt i-small icon-remove"></i></a>';
}
$editing_user = DB::table('users')->whereId($editing_user_id)->first();
return $editing_user->firstname . ' is busy with lead';
} else {
if ($user_id == 'Archived') {
return '<a href="/leads/' . $Lead['id'] . '/edit" title="Edit" ><i class="i-circled i-light i-alt i-small icon-edit"></i></a>
<a href="/leads/' . $Lead['id'] . '/restore" title="Restore" ><i class="i-circled i-light i-alt i-small icon-check"></i></a>';
} else {
$query = "SELECT p.note, p.created_at AS date FROM prop_notes p
INNER JOIN users u ON u.id = p.users_id
WHERE p.lead_id = " . $Lead['id'];
$last_note = DB::select($query);
if (sizeof($last_note) > 1) {
$Lead['check_lead'] = 1;
}
if ((Auth::user()->id == $Lead['bdm_allocated'] && $Lead['check_lead'] == null) || (Auth::user()->hasRole('Admin') && $Lead['check_lead'] == null)) {
return '<a href="/leads/' . $Lead['id'] . '/edit" title="Edit" ><i class="i-circled i-light i-alt i-small icon-edit"></i></a>
<a href="/leads/' . $Lead['id'] . '/delete" title="Delete" ><i class="i-circled i-light i-alt i-small icon-remove"></i></a>
<a href="/leads/' . $Lead['id'] . '/check_lead" title="Mark as Viewed" ><i class="i-circled i-light i-alt i-small icon-check" style="color:#FF3100"></i></a>';
} elseif (Auth::user()->hasRole('Admin') && $Lead['check_lead'] == 1) {
return '<a href="/leads/' . $Lead['id'] . '/edit" title="Edit" ><i class="i-circled i-light i-alt i-small icon-edit"></i></a>
<a href="/leads/' . $Lead['id'] . '/delete" title="Delete" ><i class="i-circled i-light i-alt i-small icon-remove"></i></a>
<a href="/leads/' . $Lead['id'] . '/check_lead" title="Mark as Viewed" ><i class="i-circled i-light i-alt i-small icon-check" style="color:#00FF48"></i></a>';
} else {
return '<a href="/leads/' . $Lead['id'] . '/edit" title="Edit" ><i class="i-circled i-light i-alt i-small icon-edit"></i></a>
<a href="/leads/' . $Lead['id'] . '/delete" title="Delete" ><i class="i-circled i-light i-alt i-small icon-remove"></i></a>';
}
}
}
})
->searchColumns('lead_ref', 'created_at', 'reference', 'bdm', 'lead_title', 'address', 'transaction_type', 'contact_firstname', 'contact_email', 'note')
->orderColumns('lead_ref', 'created_at', 'reference', 'bdm', 'lead_title', 'address', 'transaction_type', 'contact_firstname', 'contact_email', 'note')
->make();`
view-
`@if($archived == 'Archived')
<h4>Archived Leads List</h4>
<div id='follow_datatable'>
{{ Datatable::table()
// these are the column headings to be shown
->addColumn('Date', 'Reference', 'BDM', 'Title', 'Address', 'Listing Type', 'Contact Name', 'Contact Details', 'Notes', 'Actions')
// this is the route where data will be retrieved
->setUrl(route('api.leads.followup', ['user_id' => 'Archived']))
->setId('followupDatatable')
->setOptions(["order" => [[ 0, "desc" ]], "bStateSave" => true])
->render() }}
</div>
@elseif($user->hasRole('LeadReviewer'))
<h4>Lead Follow Up List</h4>
<div id='follow_datatable'>
{{ Datatable::table()
// these are the column headings to be shown
->addColumn('Date', 'Reference', 'BDM', 'Title', 'Address', 'Listing Type', 'Contact Name', 'Contact Details', 'Notes', 'Actions')
// this is the route where data will be retrieved
->setUrl(route('api.leads.followup', ['user_id' => $user->id]))
->setId('followupDatatable')
->setOptions(["order" => [[ 0, "desc" ]], "bStateSave" => true])
->render() }}
</div>
@else
<h4>Lead Follow Up List for {{$user->firstname}} {{$user->lastname}}</h4>
<div id='follow_datatable'>
{{ Datatable::table()
// these are the column headings to be shown
->addColumn('Date', 'Reference', 'BDM', 'Title', 'Address', 'Listing Type', 'Contact Name', 'Contact Details', 'Notes', 'Actions')
// this is the route where data will be retrieved
->setUrl(route('api.leads.followup', ['user_id' => $user->id]))
->setId('followupDatatable')
->setOptions(["order" => [[ 0, "desc" ]], "bStateSave" => true])
->render() }}
</div>
@endif`
I dont think these tables are overly complex but I am a bit lost as to how your new system works
I used chumper/datatable in my project but after upgrading my Laravel version to 5.2 I started facing issues in sorting in collection. So now I am trying to use Openskill Datatable in laravel 5.2. I tried to implement basic datatable by following the exact steps described in documentation.
I am getting an error saying that Class CollectionProvider not found.
My controller function looks like
I am not sure, am I doing something wrong?
Please help me out.
I am using d765c9f
Here is my controller code:
class DatatableTestController extends Controller
{
public function test() {
$t = Datatable::make(new CollectionProvider(Categories::all()))
->column('id') // show the id column of the user model
->column('name', null, Searchable::NONE(), Orderable::NONE()) // also show the full name of the user, but do not allow searching or ordering of the column
->build();
if ($t->shouldHandle()) {
return $t->handleRequest();
}
return view('admin.test.categories', array(
'datatable' => $t->view()
));
}
}
admin/test/categories.blade.php
has the following code:
<h1>Testing Datatable 0.2.1</h1>
{!!
$datatable
->headers() // tell the table to render the header in the table
->columns('id', 'id') // show # in the header instead of 'id'
->columns('name', 'name') // show 'Full name' in the header instead of 'name'
->endpoint(route('admin.datatabletest'))
// render just the table
->table()
!!}
{!!
$datatable
// now render the script
->script()
!!}
The endpoint works perfectly ๐
The AJAX request that is sent contains the following request parameters:
sEcho:1
iColumns:2
sColumns:
iDisplayStart:0
iDisplayLength:10
mDataProp_0:id
mDataProp_1:name
sSearch:
bRegex:false
sSearch_0:
bRegex_0:false
bSearchable_0:true
sSearch_1:
bRegex_1:false
bSearchable_1:true
iSortCol_0:0
sSortDir_0:asc
iSortingCols:1
bSortable_0:true
bSortable_1:true
and the response is:
{
"sEcho": "1",
"iTotalRecords": 5,
"iTotalDisplayRecords": 5,
"aaData": [{
"id": "",
"name": ""
}, {
"id": "",
"name": ""
}, {
"id": "",
"name": ""
}, {
"id": "",
"name": ""
}, {
"id": "",
"name": ""
}]
}
Note the empty id
, and name
for each column, even though running dd(Categories::all())
shows that there is infact data inside the Collection
.
(Note that my register
function inside DatatableServiceProvider
has been edited to force VersionEngine
to only use Datatable19Version
(I could not find a way to nicely have ->view
render with the datatable19.blade.php
Datatable javascript, but that's a story for another feature request).
To support laravel 4 we need a ServiceProvider
for it.
I used the tagging feature to provide an array of parsers to the QueryEngine
in laravel5. We need to find a way to make this possible in laravel4.
Maybe we need to hardcode the implementations in the service provider.
Sorting columns does not work.
I am trying to install datatable package to my laravel 5.2 project and composer gives dependency error:
$ composer require OpenSkill/Datatable
Using version ^0.2.0 for OpenSkill/Datatable
./composer.json has been updated
> php artisan clear-compiled
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.
Problem 1
- Installation request for openskill/datatable ^0.2.0 -> satisfiable by openskill/datatable[0.2.0].
- Conclusion: remove symfony/http-foundation v3.0.1
- Conclusion: don't install symfony/http-foundation v3.0.1
- openskill/datatable 0.2.0 requires symfony/http-foundation 2.7.* -> satisfiable by symfony/http-foundation[v2.7.0, v2.7.1, v2.7.2, v2.7.3, v2.7.4, v2.7.5, v2.7.6, v2.7.7, v2.7.8, v2.7.9].
- Can only install one of: symfony/http-foundation[v2.7.0, v3.0.1].
- Can only install one of: symfony/http-foundation[v2.7.1, v3.0.1].
- Can only install one of: symfony/http-foundation[v2.7.2, v3.0.1].
- Can only install one of: symfony/http-foundation[v2.7.3, v3.0.1].
- Can only install one of: symfony/http-foundation[v2.7.4, v3.0.1].
- Can only install one of: symfony/http-foundation[v2.7.5, v3.0.1].
- Can only install one of: symfony/http-foundation[v2.7.6, v3.0.1].
- Can only install one of: symfony/http-foundation[v2.7.7, v3.0.1].
- Can only install one of: symfony/http-foundation[v2.7.8, v3.0.1].
- Can only install one of: symfony/http-foundation[v2.7.9, v3.0.1].
- Installation request for symfony/http-foundation == 3.0.1.0 -> satisfiable by symfony/http-foundation[v3.0.1].
Installation failed, reverting ./composer.json to its original content.
We should have a replacement ready for the old QueryEngine
, so a user can pass a query builder or similar to the datatable.
What i found was really 'annoying' was the small little details i had to put into the old QueryEngine
to make the search work across different databases.
So i would like to include search functionality behaviour as method on this provider so the user can implement it as needed.
I also see a problem if the user pre selected any data and then passes it to the EloquentQueryProvider
.
E.g. if a user passes all users sorted by name to the datatable but skips the first 10 we have a problem, because the initial dataset can change.
So when a user orders by id (and the user skips the first 10 and passes it to the provider) then there is a changed dataset where different 10 users are missing.
Also should we override the skip
and take
parameter of the user?
In the current implementation the CollectionProvider
can be provided with custom column search functions as well as a custom global search function.
It would also make sense to be able to pass a custom sorting function to the CollectionProvider
Currently the searchfunction will only receive the evaluated entries that will be returned to the User.
It would be nice to have access to the raw model to provide yet more flexibility.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.