Upload file: How to reference (view) individual items when I use standalone?

Upload file: How to reference (view) individual items when I use standalone?

aneto2400aneto2400 Posts: 58Questions: 8Answers: 1

Hi Allan,
I´m using your standalone example (collection.html) with upload file feature (datatable editor 1.5.1) , I don’t get to view (show) the individual items that are inside of object {files:} , on JSON output.
My focus are to show the image (picture) , but also I want to know how to show rest of items, such as filename, etc.
Second question: the jSON output give me all files, when I´ve a where condition in server-side, what am I doing wrong?
My current code is showed below. Can you help me?
My best regards,
Eduardo

var editor; // use a global for the submit and return data rendering in the examples

function createPanel ( data )
{
    var id = data.DT_RowId;
    $(
        '<div class="panel" data-editor-id="'+id+'">'+
            '<i class="edit fa fa-pencil" data-id="'+id+'"/>'+
            '<i class="remove fa fa-times" data-id="'+id+'"/>'+
            '<dl>'+
                '<dt>Producto:</dt>'+
                '<dd>'+
                    '<span data-editor-field="prod_estr">'+data.prod_estr+'</span> '+
                '</dd>'+
                '<dt>Establec:</dt>'+
                '<dd>'+
                    '<span data-editor-field="nom_estbl">'+data.nom_estbl+'</span>'+
                '</dd>'+
                '<dt>Imagen:</dt>'+
                '<dd>'+
                    '<span data-editor-field="image">'+data.image+'</span>'+
                '</dd>'+
                '<dt>Nombre Fichero:</dt>'+
                '<dd>'+
                    '<span data-editor-field="filename">'+data.filename+'</span>'+
                '</dd>'+

            '</dl>'+
        '</div>'
    ).appendTo( '#panels' );
}
$(document).ready(function() {
    // form:
    editor = new $.fn.dataTable.Editor( {
        ajax: "../php/collection.php",
        fields: [ 
            {
                label: "Producto estrella:",
                name: "prod_estr"
            },
 
            {
                label: "Nombre establec:",
                name: "nom_estbl"
            },
            
            {
                label: "Nombre Fich:",
                name: "files.filename"
            },
            {
                label: "Destacado:",
                name: "image",
                //status: "This field is required", //add, foto lo usa scan and get  app
                type: "upload",
                display: function ( file_id ) {
                    return '<img src="'+( 'files', file_id ).web_path+'"/>'; //ori
                },
                clearText: "Clear",
                noImageText: 'No image'
            }
        ]
    } );

    // Create record - on create we insert a new panel
    editor.on( 'postCreate', function (e, json) {
        createPanel( json.data[0] );
    } );

    $('button.create').on( 'click', function () {
        editor
            .title('Create new record')
            .buttons('Create')
            .create();
    } );

    // Edit
    $('#panels').on( 'click', 'i.edit', function () {
        editor
            .title('Edit record')
            .buttons('Save changes')
            .edit( $(this).data('id') );
    } );

    // Remove
    $('#panels').on( 'click', 'i.remove', function () {
        editor
            .title('Delete record')
            .buttons('Delete')
            .message('Are you sure you wish to delete this record?')
            .remove( $(this).data('id') );
    } );

    // Load the initial data and display in panels
    $.ajax( {
        url: '../php/collection.php',
        dataType: 'json',
        success: function ( json ) {
            for ( var i=0, ien=json.data.length ; i<ien ; i++ ) {
                createPanel( json.data[i] );
            }
        }
    } );
} );
</head>
<body class="dt-example">
    <div class="container">
        <h1>Editor example <span>Standalone collection editor</span></h1>
                       <div id="panels">
                <button class="create">New</button>
            </div>

    </div>

</body>
</html>

Server side:

$site="342800010";
// Build our Editor instance and process the data coming from _POST
Editor::inst( $db, 'r_clientes' )
    ->fields(
        Field::inst( 'prod_estr' )->validator( 'Validate::notEmpty' ),
        Field::inst( 'nom_estbl' )->validator( 'Validate::notEmpty' ),
        Field::inst( 'image' )
            ->validator( 'Validate::notEmpty' ) // obligado , foto usara scan and get app
            ->setFormatter( 'Format::nullEmpty' )
            ->upload( Upload::inst( $_SERVER['DOCUMENT_ROOT'].'/upload/__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
                ) )

            )

    )
            ->where( 'site', $site) //añado para seleccionar solo el site

    ->process( $_POST )
    ->json();

jSON output:

{"data":[{"DT_RowId":"row_93","prod_estr":"cocteles sin alcohol","nom_estbl":"La demo","image":"123"}],"options":[],"files":{"files":{"123":{"id":"123","filename":"coctel.frutas.jpg","filesize":"9140","web_path":"\/upload\/123.jpg","system_path":"\/home\/tripntry\/www\/upload\/123.jpg"},"133":{"id":"133","filename":"tapas.jpg","filesize":"15489","web_path":"\/upload\/133.jpg","system_path":"\/home\/tripntry\/www\/upload\/133.jpg"},"131":{"id":"131","filename":"tapas.jpg","filesize":"15489","web_path":"\/upload\/131.jpg","system_path":"\/home\/tripntry\/www\/upload\/131.jpg"}}}}

Answers

  • allanallan Posts: 61,744Questions: 1Answers: 10,111 Site admin

    I don’t get to view (show) the individual items that are inside of object {files:} , on JSON output. My focus are to show the image (picture) , but also I want to know how to show rest of items, such as filename, etc.

    If you are using Editor as standalone you don't have access to the file() method that Editor adds to the DataTable. Unfortunately, that makes getting the information about the file a bit more tricky - to the point that you will actually need to make an Ajax request to the server to get the information based on the id value given, since the JSON is not directly available at that point.

    Let me have a bit of a think about this, for how it can be improved, and get back to you.

    Second question: the jSON output give me all files, when I´ve a where condition in server-side, what am I doing wrong?

    You aren't doing anything wrong here - that is just how the file information currently operates. Ultimately it should do a join so it only gets the file information that is actually required, although I was concerned about that adding too many constraints on the system.

    Regards,
    Allan

  • VitalizVitaliz Posts: 71Questions: 7Answers: 1

    I´m using your standalone example (collection.html) with upload file feature (datatable editor 1.5.1)

    And I have such problem too.
    Thank you for any helpful advice, Allan.

  • aneto2400aneto2400 Posts: 58Questions: 8Answers: 1

    I will await your reply, thank you Allan.

  • VitalizVitaliz Posts: 71Questions: 7Answers: 1

    Hi, Eduardo.
    Were you able to make any progress in solving your problem?

  • aneto2400aneto2400 Posts: 58Questions: 8Answers: 1

    Hi, nothing. I'm waiting next comments of Allan. Regards

  • allanallan Posts: 61,744Questions: 1Answers: 10,111 Site admin

    I've just been looking into this - what you can do is get the file information from $.fn.dataTable.Editor.files.files. That is an object that contains the information about the uploaded files, after a file has been uploaded. The object key is the primary key value for the file (i.e. the id that is passed into the rendering function) so you could do:

    $.fn.dataTable.Editor.files.files[ id ]
    

    to get the object for that file.

    One important note is that since you are using a standalone Editor, this object will not be automatically populated on page load. You would need to assign the files to it if you wanted to have that information on load.

    Allan

  • aneto2400aneto2400 Posts: 58Questions: 8Answers: 1

    Thanks Allan, I'm going to work with your help and in shortly i will post my work about it. Thank you!

  • VitalizVitaliz Posts: 71Questions: 7Answers: 1
    edited November 2015

    Hi,
    I have tested standalone example (collection.html) with UploadMany option. I use upload-many.html example as a guide for this case.
    This is js file part:

    function createPanel ( data )
    {
        var id = data.DT_RowId;
          file_mess=data.files.length ? data.files.length+' files' :
                            'No attached files';
        $(
            '<div class="panel" data-editor-id="'+id+'">'+
                '<i class="edit fa fa-pencil" data-id="'+id+'"/>'+
                '<i class="remove fa fa-times" data-id="'+id+'"/>'+
                '<dl>'+
                    '<dt>Name:</dt>'+
                    '<dd>'+
                        '<span data-editor-field="first_name">'+data.first_name+'</span> '+
                        '<span data-editor-field="last_name">'+data.last_name+'</span>'+
                    '</dd>'+
                    '<dt>Position:</dt>'+
                    '<dd data-editor-field="position">'+data.position+'</dd>'+
                    '<dt>Office:</dt>'+
                    '<dd data-editor-field="office">'+data.office+'</dd>'+
                    '<dd data-editor-field="files[].id">'+file_mess+'</dd>'+
                '</dl>'+
            '</div>'
        ).appendTo( '#panels' );
    }
    
    $(document).ready(function() {
        editor = new $.fn.dataTable.Editor( {
            ajax: "../php/staff.php",
            fields: [ {
                    label: "First name:",
                    name: "first_name"
                }, {
                    label: "Last name:",
                    name: "last_name"
                }, {
                    label: "Position:",
                    name: "position"
                }, {
                    label: "Office:",
                    name: "office"
                },
          {
                    label: "Images:",
                    name: "files[].id",
                    type: "uploadMany",
             display: function ( fileId, counter) {
              return $.fn.dataTable.Editor.files.files[fileId].fileName; 
          },  
          dragDrop: false,
            noImageText: 'No images'
                }
            ]
        } );
    *** code for work with Panels was there ***
    $.ajax( {
            url: '../php/staff.php',
            dataType: 'json',
            success: function ( json ) {
                for ( var i=0, ien=json.data.length ; i<ien ; i++ ) {
                    createPanel( json.data[i] );
                }
          all_data=json.data;
          all_files=json.files;
          console.log(all_data,all_files);
            }
        } );
    } );
    

    and this is PHP file:

    Editor::inst( $db, 'datatables_demo' )
        ->fields(
            Field::inst( 'first_name' )->validator( 'Validate::notEmpty' ),
            Field::inst( 'last_name' )->validator( 'Validate::notEmpty' ),
            Field::inst( 'position' ),
            Field::inst( 'email' ),
            Field::inst( 'office' ),
            Field::inst( 'extn' )->validator( 'Validate::numeric' ),
            Field::inst( 'age' )->validator( 'Validate::numeric' ),
            Field::inst( 'salary' )->validator( 'Validate::numeric' ),
            Field::inst( 'start_date' )
                ->validator( 'Validate::dateFormat', array(
                    "format"  => Format::DATE_ISO_8601,
                    "message" => "Please enter a date in the format yyyy-mm-dd"
                ) )
                ->getFormatter( 'Format::date_sql_to_format', Format::DATE_ISO_8601 )
                ->setFormatter( 'Format::date_format_to_sql', Format::DATE_ISO_8601 ),
            Field::inst( 'in_out' )
        )
         ->join(
            Mjoin::inst( 'files' )
                ->link( 'datatables_demo.id', 'mess_files.mess_id' )
                ->link( 'files.id', 'mess_files.file_id' )
                ->fields(
                    Field::inst( 'id' )
                        ->upload( Upload::inst( $_SERVER['DOCUMENT_ROOT'].'/upload/__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( function ( $file ) {
                                return$file['size'] >= 50000 ?
                                    "Files must be smaller than 50K" :
                                    null;
                            } )
                            ->allowedExtensions( [ 'png', 'jpg','gif' ], "Please upload an image" )
                        )
                )
        )
        ->process( $_POST )
        ->json();
    
    

    the fist problem is that in this case $.fn.dataTable.Editor.files.files is not defined.
    I'd try to use arrays from JSON data instead, but arrays not updated in moment of file uploading, so I can't write apropriate display function for editor's fields declaration. Files are uploaded, but I can't display them in Editor's window.
    I only see "undefined" instead of a file name and button for file deletion.

    The next bug in my case is that information about previously uploaded files is lost (deleted from mjoin link table) while panel is edited and new files are added.

  • allanallan Posts: 61,744Questions: 1Answers: 10,111 Site admin

    $.fn.dataTable.Editor.files.files it won't be on initial load, but it should be once a file has been uploaded. If is still isn't can you please give me a link to your page so I can take a look and see what is going wrong.

    Allan

  • VitalizVitaliz Posts: 71Questions: 7Answers: 1
    edited November 2015

    $.fn.dataTable.Editor.files.files it won't be on initial load, but it should be once a file has been uploaded

    Yes, Allan, it is.
    But it means that I can use $.fn.dataTable.Editor.files.files in panel creation process(.

    And that about other problems: apropriate display function for editor's fields declaration and broken information about previously uploaded files?

    I will shortly upload this example to web and post the link.

    UPD: the link is: http://uchet.nuzenavtor.ru/dte/examples/standalone/collection-mod.html

    But it unfortunately don`t work on server yet.(
    Than I test staff.php standalone, it's show these errors:

    Warning: require(/home/k/konsta6g/uchet.nuzenavtor.ru/public_html/dte/php/Editor/MJoin.php): failed to open stream: No such file or directory in /home/k/konsta6g/uchet.nuzenavtor.ru/public_html/dte/php/Bootstrap.php on line 52
    Fatal error: require(): Failed opening required '/home/k/konsta6g/uchet.nuzenavtor.ru/public_html/dte/php/Editor/MJoin.php' (include_path='.:/usr/share/php') in /home/k/konsta6g/uchet.nuzenavtor.ru/public_html/dte/php/Bootstrap.php on line 52

  • allanallan Posts: 61,744Questions: 1Answers: 10,111 Site admin

    But it means that I can use $.fn.dataTable.Editor.files.files in panel creation process(.

    That is correct - as I noted in my post above:

    One important note is that since you are using a standalone Editor, this object will not be automatically populated on page load. You would need to assign the files to it if you wanted to have that information on load.

    This is because the standalone Editor does not require an Ajax load of data - it can just use the data from the document. How the data gets into the document is up to yourself, which is why you would also need to handle the file information on load. I realise this is a bit of a pain, but for the standalone Editor to be flexible, it can't make an assumption about an Ajax load of data like the DataTable can.

    require(/home/k/konsta6g/uchet.nuzenavtor.ru/public_html/dte/php/Editor/MJoin.php): failed to open stream: No such file or directory

    The class should be called Mjoin not MJoin. That is probably what the issue is and causing the autoloader some issues.

    Allan

  • VitalizVitaliz Posts: 71Questions: 7Answers: 1
    edited November 2015

    The class should be called Mjoin not MJoin.

    Yes, it is precisely this reason. Locally on XAMPP for Win work normally, but don't work on Linux server.
    Thanks for your correction, Allan.

  • VitalizVitaliz Posts: 71Questions: 7Answers: 1

    Hi, Eduardo.
    Нave you achieved success in your work?

    and in shortly i will post my work about it.

    Are you ready to publish your code?

    I have some problems yet and don't ready post any solution(.

  • aneto2400aneto2400 Posts: 58Questions: 8Answers: 1

    Hi!, my apologies... I've had to stop the investigations about it. At the moment I have not any idea about how to resolve the issue, I'm sorry. Good luck!

  • VitalizVitaliz Posts: 71Questions: 7Answers: 1

    Ok, Eduardo. I will fight alone))). Good luck!

This discussion has been closed.