Modifying the "File upload (many)" example to accept PDFs and other file types
Modifying the "File upload (many)" example to accept PDFs and other file types
Hi All, me again:)
I have been able to get the File upload (many) example to work as presented, but I would like to be able to change the functionality of the example in 2 ways:
1) I have been able to upload PDFs with a couple of tweaks to the example code, but when I thereafter attempt to view the PDF (or, other file types) by clicking on the uploaded file in Editor, it just leaves the computer spinning; nor does the thumbnail show visually except as a common 'dead link' icon. Is it possible to tweak the example in such a way as to have it work as an "Upload Attachments (many)" code block?
2) I'd like to be able see the uploaded images in an "Images" table column by clicking "View" in the Images column of the current record. Currently, the only way to see the images I have uploaded is by clicking on the edit icon for a particular record, wherein I see all of the Editor fields expecting an update as well as a thumbnail of the associated images. As I have no mind for coding (HTML and CSS aside) I have no idea where to even start to accomplish this, if I may ask, please, for some guidance?
For reference, here is my modified table.products.js code, taken from the example linked above. JavaScript:
$(document).ready(function() {
var editor = new $.fn.dataTable.Editor( {
ajax: 'php/table.products.php',
table: '#products',
fields: [
etc...
{
"label": "Description:",
"name": "products.description",
"type": "textarea"
},
{
"label": "ResTit1:",
"name": "products.restit1"
},
{
"label": "ResLink1:",
"name": "products.reslnk1",
"def": "#"
},
{
"label": "ResTit2:",
"name": "products.restit2"
},
{
"label": "ResLink2:",
"name": "products.reslnk2",
"def": "#"
},
{
"label": "ResTit3:",
"name": "products.restit3"
},
{
"label": "ResLink3:",
"name": "products.reslnk3",
"def": "#"
},
{
"label": "ResTit4:",
"name": "products.restit4"
},
{
"label": "ResLink4:",
"name": "products.reslink4",
"def": "#"
},
{
"label": "Comment:",
"name": "products.comment",
"type": "textarea"
},
{
"label": "Keywords:",
"name": "products.keywords"
},
{
"label": "Metacat:",
"name": "products.metacat",
"type": "select",
"placeholder": "Select MetaCategory"
},
{
"label": "Category:",
"name": "products.category"
},
{
"label": "Form:",
"name": "products.catform"
},
{
"label": "Manufacturer:",
"name": "products.manufacturer"
},
{
"label": "MFRPN:",
"name": "products.mfrpn"
},
{
"label": "ProdID:",
"name": "products.prodid"
},
{
"label": "Images:",
"name": "files[].id",
"type": "uploadMany",
"display": function ( fileId, counter ) {
return '<div class="image-set"><a class="example-image-link" rel="nofollow" href="'+editor.file( 'files', fileId ).web_path+'" data-lightbox="example-set" data-title="Product"><img class="example-image" width="75" src="'+editor.file( 'files', fileId ).web_path+'" alt="Product" /></a></div>';
},
noFileText: 'No images'
},
{
"label": "Universe:",
"name": "products.universe",
"type": "select",
"placeholder": "Select Universe"
}
]
} );
etc...
var table = $('#products').DataTable( {
ajax: 'php/table.products.php',
columns: [
etc...
// {
// "data": "products.description"
// },
// {
// "data": "products.restit1"
// },
// {
// "data": "products.reslnk1"
// },
// {
// "data": "products.restit2"
// },
// {
// "data": "products.reslnk2"
// },
// {
// "data": "products.restit3"
// },
// {
// "data": "products.reslnk3"
// },
// {
// "data": "products.restit4"
// },
// {
// "data": "products.reslnk4"
// },
// {
// "data": "products. Comment"
// },
{
"data": "products.keywords"
},
{
"data": "metacats.metacat"
},
{
"data": "products.category"
},
{
"data": "products.catform"
},
{
"data": "products.manufacturer"
},
{
"data": "products.mfrpn"
},
{
"data": "products.prodid"
},
{
data: "files",
render: function ( d ) {
return d.length ?
d.length+' image(s)' :
'No image';
},
title: "Image"
},
{
"data": "universes. Universe"
}
],
And this is the table.products.php file:
<?php
/*
* Editor server script for DB table products
* Created by http://editor.datatables.net/generator
*/
// DataTables PHP library and database connection
include( "lib/DataTables.php" );
// Alias Editor classes so they are easy to use
use
DataTables\Editor,
DataTables\Editor\Field,
DataTables\Editor\Format,
DataTables\Editor\Mjoin,
DataTables\Editor\Options,
DataTables\Editor\Upload,
DataTables\Editor\Validate,
DataTables\Editor\ValidateOptions;
// Build our Editor instance and process the data coming from _POST
Editor::inst( $db, 'products', 'id' )
->fields(
Field::inst( 'products.product' )
->validator( Validate::notEmpty() ),
Field::inst( 'products.prodshot' ),
Field::inst( 'products.description' ),
Field::inst( 'products.restit1' ),
Field::inst( 'products.reslnk1' )
->validator( Validate::url() ),
Field::inst( 'products.restit2' ),
Field::inst( 'products.reslnk2' )
->validator( Validate::url() ),
Field::inst( 'products.restit3' ),
Field::inst( 'products.reslnk3' )
->validator( Validate::url() ),
Field::inst( 'products.restit4' ),
Field::inst( 'products.reslnk4' )
->validator( Validate::url() ),
Field::inst( 'products.comment' ),
Field::inst( 'products.keywords' ),
Field::inst( 'products.category' ),
Field::inst( 'products.catform' ),
Field::inst( 'products.manufacturer' ),
Field::inst( 'products.mfrpn' ),
Field::inst( 'products.prodid' ),
Field::inst( 'products.universe' )
->options( Options::inst()
->table( 'universes' )
->value( 'id' )
->label( 'universe' )
)
->validator( Validate::dbValues() ),
Field::inst( 'universes.universe' ),
Field::inst( 'products.metacat' )
->options( Options::inst()
->table( 'metacats' )
->value( 'id' )
->label( 'metacat' )
)
->validator( Validate::dbValues() ),
Field::inst( 'metacats.metacat' )
)
->join(
Mjoin::inst( 'files' )
->link( 'products.id', 'products_files.product_id' )
->link( 'files.id', 'products_files.file_id' )
->fields(
Field::inst( 'id' )
->upload( Upload::inst( $_SERVER['DOCUMENT_ROOT'].'/uploads/__ID__.__EXTN__' )
->db( 'files', 'id', array(
'filename' => Upload::DB_FILE_NAME,
'filesize' => Upload::DB_FILE_SIZE,
'web_path' => Upload::DB_WEB_PATH,
'system_path' => Upload::DB_SYSTEM_PATH
) )
->validator( Validate::fileSize( 50000000, 'Files must be smaller that 50M' ) )
->validator( Validate::fileExtensions( array( 'png', 'jpg', 'jpeg', 'gif', 'webp' ), "Please upload an image" ) )
)
)
)
->leftJoin( 'universes', 'universes.id', '=', 'products.universe' )
->leftJoin( 'metacats', 'metacats.id', '=', 'products.metacat' )
->leftJoin( 'files', 'files.id', '=', 'products.id' )
->process( $_POST )
->json();
As you may glean, my way of working is always to modify the files created using the Generator.
To avoid confusion, hopefully, I'm asking for help with just 2 things:
How can I modify the example code to show the uploaded images by clicking on a link in an Images column?
Can the example code be easily modified to properly accept file uploads that are not images but instead PDFs and hopefully documents/other filetypes?
p.s. I would like very much to renew my annual subscription in order to ensure the DataTables people are being properly compensated for their time and intellectual property (given how absolutely critical DataTables/Editor are to my coding pleasure), but I am currently unemployed since being laid off (thanks Covid lol!) so all I can offer for now is my heartfelt thank you. Once employed, I promise that will change:)
Merci:)
Shawn
Answers
Hi Shawn,
That is expected. A pdf is not an image and browsers won't natively show it as such. If a thumbnail of the file is something you want, then you'd need to use a process on the server that would generate an image from the uploaded file. Perfectly possible with extra software that can do that, but typically I've seen authors just using a pdf file icon instead.
That would be done in your rendering function which is currently just;
i.e. it is showing the number of images. If you want to show
img
tags, then you'd need to loop over thed
array and generate thaimg
for each one (similar to what you are doing in thedisplay
function for Editor) and return that.Allan
p.s. Sorry to hear you were laid off. That really sucks
Thanks Allan, you are quick:) I will study your response and see how far I can get using your excellent and encyclopedic documentation:) . I'd be perfectly happy with a PDF icon, or even a generic file icon for any upload which is not an image. Ultimately, I hope to strip out the example into separate Image Upload and Attachments Upload blocks.
Yes, being laid off after 19.5 years with the same company is a bit of a drag. The entire landscape has changed...a bit overwhelming, but I will succeed, with enough effort:)
Merci,
Shawn
Well fire away with any questions you have. I'm a full time JavaScript developer (DataTables, Editor and CloudTables) and I find it overwhelming at times as well!
Allan