Convert Upload to UploadMany
Convert Upload to UploadMany
joseoliveiraborlas
Posts: 80Questions: 8Answers: 3
Hello,
I can't figure out how to get the upload to work with multiple files. I've tried several methods here on the forum, but it always gives me errors or "Uncaught Error: Upload collections must have an array as a value", if I use the name with array it gives me the error: "Uncaught Error: Call to undefined method DataTables\Editor \Field::db() in ...".
Can anyone help me with this example?
.js
{
label: "Imagen:",
name: "imagem",
type: "upload",
display: (fileId, counter) => '<img src="'+table.file( 'files', file_id ).web_path+'"/>',
clearText: "Clear",
ajax: {
url: "includes/table.sells.php",
type: "POST",
enctype: 'multipart/form-data',
processData: false,
contentType: false,
},
noImageText: 'No image',
noFileText: 'No images',
},
Then in .php:
Field::inst( 'imagem' )
->setFormatter( 'Format::nullEmpty' )
>upload(
Upload::inst( function ( $file, $id ) use ( $varArray, $db ) {
move_uploaded_file( $file['tmp_name'] , $varArray["sysPath"] .$id. '.jpg' );
make_thumb($varArray["sysPath"] .$id. '.jpg', $varArray["sysPathThumbs1"].$id. '.thumb.jpg', 480);
$db->update(
'files', // Database table to update
[
"web_path" => $varArray["webPath"] .$id. '.jpg',
"system_path" => $varArray["sysPath"] .$id. '.jpg',
"web_path_thumb1" => $varArray["webPathTumbs1"] .$id. '.thumb.jpg',
"system_path_thumb1" => $varArray["sysPathThumbs1"] .$id. '.thumb.jpg',
],
[ "id" => $id ]
);
return $id;
} )
->db( 'files', 'id', array(
'site' =>'',
'filename' => Upload::DB_FILE_NAME,
'filesize' => Upload::DB_FILE_SIZE,
'web_path' => '',
'system_path' => '',
'web_path_thumb1' => '',
'system_path_thumb1' => '',
) )
->validator( function ( $file ) {
return$file['size'] >= 3000000 ?
"Files must be smaller than 3000K o 3,0 Mb" :
null;
} )
->dbClean( function ( $data ) {
// Remove the files from the file system
for ( $i=0, $ien=count($data) ; $i<$ien ; $i++ ) {
unlink( $data[$i]['system_path'] ); // upload file folder
unlink( $data[$i]['system_path_thumb1'] ); //my thumbnails file folder #1
}
// Have Editor remove the rows from the database
return true;
} )
->allowedExtensions( array( 'jpg' ), "Please upload an image file, ONLY .jpg " )
),
This question has accepted answers - jump to:
Answers
Your Javascript is only for single uploads. You would need something like this:
Read the docs please:
https://editor.datatables.net/reference/field/uploadMany
https://editor.datatables.net/examples/advanced/upload-many
Hello rf1234, thank you. I've already tried this way, the problem is that I get an error saying that this name image[] does not exist. Regarding the docs, I have already analyzed them, I have even tried the examples described there. Can you review the php code, please? About db, it's all the same when using only one file, right? When I using your code in the db de value is "array" and give error. When using one image, appear the value corrected ("4" for example).
And please, help me understand how different is the 2 manners, what's changes about single and multiple... To learn and then to know how to optimize the project. Thank you a lot!
I never use single upload, only multiple upload on very many occasions. It is rather straightforward I would say. If the examples aren't instructive enough here is one from my own coding:
the most important line is
This is the array of files the user can upload. It can be empty or contain multiple values.
In your PHP code I do not see a join! Without a join this is never going to work. The join must be between the files table and the contract table in my example. Don't know what the tables are called in your example. You will need a link table as well to do that join. In my example the link table is called "contract_has_file".
So this is my PHP:
And a screenshot from my data model:
You can see multiple "..._has_file" tables. Those are the link tables used in the Mjoin.
Good luck.
I just wanted to add that if you are still having problems with this, could you show me the JSON that is being returned by the server when the table is initially loaded please? Showing the Javascript you are using for the
uploadMany
would be useful as well.Thanks,
Allan
To my shame, I haven't managed to get there yet...
I have a database table named "sells" with a customer sells list that contains columns:
id | date | contact_id | imagem
where the "imagem" column indicates whether that row has files or not.
I also have another table named "files123" where the locations of the images will be stored. It contains the columns:
id | filename | filesize | web_path | system_path
I took these column names from a forum example. (I renamed them for better understanding, avoiding conflicts with 'file' and similar words.)
I might be confusing "file" and "files," and I'm unsure about the use of "_id" and ".id."
Do I need to perform a join between the two tables? Initially, I thought I would just retrieve the "imagem" column from the "sells" table and get this value from the "files123" table. Although, as I write this sentence, it makes sense to have a function for this
I apologize for asking, but could you modify your example to use the information I provided above? I know it might seem odd and ugly to ask someone to "write my code," but I'll understand it better with the logic, just as I've learned from examples in the forum and documentation (except for this and select2, which are giving me a headache)
No, you can't do it that way. You must use a link table for "uploadMany" because otherwise you cannot use the Mjoin which is required. Take a look at the picture from my data model above.
You have three tables.
a) contract
b) contract_has_file
c) file
b) is just the link between "contract" and "file" to allow one contract to have many files. Yes you could also resolve this with a 1:N relationship with "file" containing the foreign key from "contract". But that doesn't work with an Mjoin!
Whether you call your file table "file" or "files" doesn't matter. I always use singular. But you can do what you like.
You would need a table "sale" or "sales", a table "file" or "files" and a table "sale_has_file". The column "imagem" to indicate whether a record has a file or not is not needed. For that you have the Mjoin which will return nothing if there is no file for the sale.
Thank very much!! I think I understood.
I thought it was only necessary to reference 1 column as it works in single file upload. Apparently everything is working, or it should be, but this time there are errors in the Javascript:
Uncaught Error: No Ajax option specified for upload plugin
at Kb.b.ajax.h.onload
I need to add a new ajax inside that code again? I have the same in top
I have the same in top of script when start editor:
maybe @allan can help you with that issue?!
Thank you rf1234 for all your help!
Already solved, whit the ajax marked as "this one"... i just want to learn why i need another ajax info in uploadMany type.
Ok, now I am getting it! I think you don't need an additional ajax specification for uploadMany. I don't use one either.
This is a simple example from my own coding allowing users to safely upload documentation instead of sending it by email.
I have this one:
if i dont put ajax again, give the error:
Uncaught Error: No Ajax option specified for upload plugin at Kb.b.ajax.h.onload
After rereading both, I understood that I am using an additional function... this is probably what interrupts the editor's defaults, right?
ajax:function(method, url, data, success, error) {
Probably yes, but I am not an expert on this. I use the "ajax" method in a simple version only ...
I also use it to post variables to the server like this, but that is as complex as it gets in my code ...
This passes the selected "contract_id" to the server so that it can be used as $_POST['contract_id'] in PHP.
It does - the upload request would go through your custom function, which is probably causing the issue since it isn't handling file upload.
What you can do is specify an
ajax
property on the object for theuploadMany
object with just a string if you want the field's default handling Ajax to handle it (and keep your custom function at the top level).Allan