Almost done with File Library standard features. Still problem with Update.
authorChuck Scott <cscott@gaslightmedia.com>
Thu, 1 Feb 2018 20:26:41 +0000 (15:26 -0500)
committerChuck Scott <cscott@gaslightmedia.com>
Thu, 1 Feb 2018 20:26:41 +0000 (15:26 -0500)
js/fileLibraryUpload/fileLibraryUpload.js
models/admin/ajax/fileLibraryDelete.php [new file with mode: 0644]
models/admin/ajax/fileLibraryDownload.php [new file with mode: 0644]
models/admin/ajax/fileLibraryUpdate.php [new file with mode: 0644]
models/admin/ajax/fileLibraryUpload.php
models/admin/fileLibrary/index.php
setup/validActions.php
views/admin/fileLibrary/index.html

index bec4ed6..1436e1b 100644 (file)
@@ -314,16 +314,18 @@ jQuery(document).ready(function($) {
                     // Add files(s) to files display
                     for ( var i = 0; i < fileData.files.length; i++ ) {
                         // Using a copy of the supplied template, add file information
-                        fData = $('#glm-fileLibraryDataTemplate').html();
+                        fData = '<tbody id="fileContainer_{ id }">' + $('#glm-fileLibraryDataTemplate').html() + '</body>';      
                         fData = fData.replace(/{ id }/g, fileData.files[i].id);
-                        fData = fData.replace(/\{ filename \}/g, fileData.files[i].newFileName);
+                        fData = fData.replace(/\{ filename \}/g, fileData.files[i].name);
                         fData = fData.replace(/\{ fileurl \}/g, fileData.files[i].newFileUrl);
                         fData = fData.replace(/\{ newfilename \}/g, fileData.files[i].newFileName);
-                        $('#glm-newFileContainer').prepend(fData);
+                        $('#AfterNewFiles').before(fData);
+
+//                        $('#fileContainer_' + fileData.files[i].id).removeClass('glm-fileLibraryItemHidden');
                         $('.glm-NewFileHidden').removeClass('glm-fileLibraryItemHidden');
 
                         // Enable the fields that were just added
-                        $("#" + fileData.files[i].id + " input, #" + fileData.files[i].id + " textarea").removeAttr('disabled');
+//                        $("#" + fileData.files[i].id + " input, #" + fileData.files[i].id + " textarea").removeAttr('disabled');
 
                         // Prepend file ID to position order input field
                         $("#filePositionOrder").val(fileData.files[i].id + ',' + $("#filePositionOrder").val());
@@ -348,18 +350,5 @@ jQuery(document).ready(function($) {
 
     }
 
-    // Copy an element to the clipboard
-    function copyToClipboard(text) {
-        var $temp = $("<input>");
-        $("body").append($temp);
-        $temp.val(text).select();
-        document.execCommand("copy");
-        $temp.remove();
-    }
-
-    $('body').on('click', '.glm-file-library-copy', function(e) {
-        copyToClipboard($(this).attr('data-link'));
-    });
-    
     
 });
diff --git a/models/admin/ajax/fileLibraryDelete.php b/models/admin/ajax/fileLibraryDelete.php
new file mode 100644 (file)
index 0000000..8a7e3f6
--- /dev/null
@@ -0,0 +1,103 @@
+<?php
+
+/**
+ * Gaslight Media Members Database
+ * File Library - File Delete
+ *
+ * PHP version 5.5
+ *
+ * @category glmWordPressPlugin
+ * @package  glmMembersDatabase
+ * @author   Chuck Scott <cscott@gaslightmedia.com>
+ * @license  http://www.gaslightmedia.com Gaslightmedia
+ * @version  0.1
+ */
+
+/*
+ * This class performs the work of handling images passed to it via
+ * an AJAX call that goes through the WorPress AJAX Handler.
+ *
+ */
+class GlmMembersAdmin_ajax_fileLibraryDelete
+{
+
+    /**
+     * WordPress Database Object
+     *
+     * @var $wpdb
+     * @access public
+     */
+    public $wpdb;
+    /**
+     * Plugin Configuration Data
+     *
+     * @var $config
+     * @access public
+     */
+    public $config;
+
+    /*
+     * Constructor
+     *
+     * This contructor sets up this model. At this time that only includes
+     * storing away the WordPress data object.
+     *
+     * @return object Class object
+     *
+     */
+    public function __construct ($wpdb, $config)
+    {
+
+        // Save WordPress Database object
+        $this->wpdb = $wpdb;
+
+        // Save plugin configuration object
+        $this->config = $config;
+
+    }
+
+    /*
+     * Perform Model Action
+     *
+     * This modelAction takes an AJAX image upload and stores the image in the
+     * media/images directory of the plugin.
+     *
+     * This model action does not return, it simply does it's work then calls die();
+     *
+     * @param $_REQUEST['id']  File Library ID
+     */
+    public function modelAction ($actionData = false)
+    {
+
+        // Make sure the file ID is an integer
+        $fileId = filter_input(INPUT_GET, 'fileId', FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE );
+        if (!$fileId || $fileId < 0) {
+            die('Invalid File ID');
+        }
+
+        // Make sure there's a file
+        $file = $this->wpdb->get_col( "SELECT file_name FROM ".GLM_MEMBERS_PLUGIN_DB_PREFIX."file_library WHERE id = $fileId" );
+        if (!$file || !file_exists(GLM_MEMBERS_PLUGIN_FILE_LIBRARY_PATH.'/'.$file[0])) {
+            die('Not Found');
+        }
+
+        $filePath = GLM_MEMBERS_PLUGIN_FILE_LIBRARY_PATH.'/'.$file[0];
+        $fileSize = filesize($filePath);
+
+        // Delete the file and the file data
+        unlink($filePath);
+
+        $this->wpdb->query(
+            $this->wpdb->prepare("
+                DELETE FROM ".GLM_MEMBERS_PLUGIN_DB_PREFIX."file_library
+                        WHERE id = %d
+                       ",
+                $fileId
+            )
+        );
+
+        die('File Deleted');
+
+    }
+
+}
diff --git a/models/admin/ajax/fileLibraryDownload.php b/models/admin/ajax/fileLibraryDownload.php
new file mode 100644 (file)
index 0000000..c8f5e76
--- /dev/null
@@ -0,0 +1,97 @@
+<?php
+
+/**
+ * Gaslight Media Members Database
+ * File Library - File Download
+ *
+ * PHP version 5.5
+ *
+ * @category glmWordPressPlugin
+ * @package  glmMembersDatabase
+ * @author   Chuck Scott <cscott@gaslightmedia.com>
+ * @license  http://www.gaslightmedia.com Gaslightmedia
+ * @version  0.1
+ */
+
+/*
+ * This class performs the work of handling images passed to it via
+ * an AJAX call that goes through the WorPress AJAX Handler.
+ *
+ */
+class GlmMembersAdmin_ajax_fileLibraryDownload
+{
+
+    /**
+     * WordPress Database Object
+     *
+     * @var $wpdb
+     * @access public
+     */
+    public $wpdb;
+    /**
+     * Plugin Configuration Data
+     *
+     * @var $config
+     * @access public
+     */
+    public $config;
+
+    /*
+     * Constructor
+     *
+     * This contructor sets up this model. At this time that only includes
+     * storing away the WordPress data object.
+     *
+     * @return object Class object
+     *
+     */
+    public function __construct ($wpdb, $config)
+    {
+
+        // Save WordPress Database object
+        $this->wpdb = $wpdb;
+
+        // Save plugin configuration object
+        $this->config = $config;
+
+    }
+
+    /*
+     * Perform Model Action
+     *
+     * This modelAction takes an AJAX image upload and stores the image in the
+     * media/images directory of the plugin.
+     *
+     * This model action does not return, it simply does it's work then calls die();
+     *
+     * @param $_REQUEST['id']  File Library ID
+     */
+    public function modelAction ($actionData = false)
+    {
+
+        // Make sure the file ID is an integer
+        $fileId = filter_input(INPUT_GET, 'fileId', FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE );
+        if (!$fileId || $fileId < 0) {
+            die();
+        }
+
+        // Get the current file name
+        $file = $this->wpdb->get_row( "SELECT name, file_name FROM ".GLM_MEMBERS_PLUGIN_DB_PREFIX."file_library WHERE id = $fileId", ARRAY_A );
+        if (!$file || !file_exists(GLM_MEMBERS_PLUGIN_FILE_LIBRARY_PATH.'/'.$file['file_name'])) {
+            die();
+        }
+
+        $filePath = GLM_MEMBERS_PLUGIN_FILE_LIBRARY_PATH.'/'.$file['file_name'];
+        $fileSize = filesize($filePath);
+
+        // Send to browser
+        header('Content-Disposition: attachment; filename="'.$file['name'].'"');
+        header("Content-Length: $fileSize");
+        header("Content-Type: application/octet-stream;");
+        readfile($filePath);
+
+        die();
+
+    }
+
+}
diff --git a/models/admin/ajax/fileLibraryUpdate.php b/models/admin/ajax/fileLibraryUpdate.php
new file mode 100644 (file)
index 0000000..4b28ee7
--- /dev/null
@@ -0,0 +1,112 @@
+<?php
+
+/**
+ * Gaslight Media Members Database
+ * File Library - File Update
+ *
+ * PHP version 5.5
+ *
+ * @category glmWordPressPlugin
+ * @package  glmMembersDatabase
+ * @author   Chuck Scott <cscott@gaslightmedia.com>
+ * @license  http://www.gaslightmedia.com Gaslightmedia
+ * @version  0.1
+ */
+
+/*
+ * This class performs the work of handling images passed to it via
+ * an AJAX call that goes through the WorPress AJAX Handler.
+ *
+ */
+class GlmMembersAdmin_ajax_fileLibraryUpdate
+{
+
+    /**
+     * WordPress Database Object
+     *
+     * @var $wpdb
+     * @access public
+     */
+    public $wpdb;
+    /**
+     * Plugin Configuration Data
+     *
+     * @var $config
+     * @access public
+     */
+    public $config;
+
+    /*
+     * Constructor
+     *
+     * This contructor sets up this model. At this time that only includes
+     * storing away the WordPress data object.
+     *
+     * @return object Class object
+     *
+     */
+    public function __construct ($wpdb, $config)
+    {
+
+        // Save WordPress Database object
+        $this->wpdb = $wpdb;
+
+        // Save plugin configuration object
+        $this->config = $config;
+
+    }
+
+    /*
+     * Perform Model Action
+     *
+     * This modelAction takes an AJAX image upload and stores the image in the
+     * media/images directory of the plugin.
+     *
+     * This model action does not return, it simply does it's work then calls die();
+     *
+     * @param $_REQUEST['id']  File Library ID
+     */
+    public function modelAction ($actionData = false)
+    {
+
+        // Make sure the file ID is an integer
+        $fileId = filter_input(INPUT_POST, 'fileId', FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE );
+        if (!$fileId || $fileId < 0) {
+            die('Invalid File ID');
+        }
+
+        // Get input fields
+        $fileTitle = filter_input(INPUT_POST, 'title');
+        $fileDescr = filter_input(INPUT_POST, 'descr');
+
+        // Make sure there's a file
+        $file = $this->wpdb->get_col( "SELECT file_name FROM ".GLM_MEMBERS_PLUGIN_DB_PREFIX."file_library WHERE id = $fileId" );
+        if (!$file || !file_exists(GLM_MEMBERS_PLUGIN_FILE_LIBRARY_PATH.'/'.$file[0])) {
+            die('Not Found');
+        }
+
+        $filePath = GLM_MEMBERS_PLUGIN_FILE_LIBRARY_PATH.'/'.$file[0];
+        $fileSize = filesize($filePath);
+
+        // Delete the file and the file data
+
+        $this->wpdb->query(
+            $this->wpdb->prepare("
+                UPDATE ".GLM_MEMBERS_PLUGIN_DB_PREFIX."file_library
+                 SET descr = %s, title = %s, last_access_time = %s
+                        WHERE id = %d
+                       ",
+                array (
+                    $fileDescr,
+                    $fileTitle,
+                    date('Y-m-d H:i:s'),
+                    $fileId,
+                )
+            )
+        );
+
+        die('File updated');
+
+    }
+
+}
index 0281dde..5272977 100644 (file)
@@ -83,17 +83,6 @@ class GlmMembersAdmin_ajax_fileLibraryUpload extends GlmDataFileLibrary
             'message' => ''
         );
 
-/*
-        // Check for valid refType - See validActions in Admin Controller
-        if (!isset($_REQUEST['glm_refType']) || !isset($this->config['ref_type_table'][$_REQUEST['glm_refType']])) {
-            $return['message'] = 'Invalid target table does not exists!';
-            echo json_encode($return);
-            die();
-        }
-        $refType = $_REQUEST['glm_refType'];
-        $refTable = $this->config['ref_type_table'][$_REQUEST['glm_refType']];
-*/
-        
         // Check for uploaded files
         if (!isset($_FILES) || count($_FILES) == 0) {
             $return['message'] = 'No image file provided!';
@@ -101,26 +90,6 @@ class GlmMembersAdmin_ajax_fileLibraryUpload extends GlmDataFileLibrary
             die();
         }
 
-/*        
-        // Check for valid target record ID
-        if (!isset($_REQUEST['glm_refDest']) || ($_REQUEST['glm_refDest']-0) <= 0) {
-            $return['message'] = 'Invalid target ID!';
-            echo json_encode($return);
-            die();
-        }
-        $refDest = ($_REQUEST['glm_refDest']-0);
-
-        
-        // Make sure the record actually exists
-        $sql = "SELECT id FROM ".GLM_MEMBERS_PLUGIN_DB_PREFIX ."$refTable WHERE id = $refDest;";
-        $record = $this->wpdb->get_row($sql, ARRAY_A);
-        if (count($record['id']) != 1) {
-            $return['message'] = "Specified target record (".$record['id'].") does not exist in table (".$refTable.")!\n\n".$sql;
-            echo json_encode($return);
-            die();
-        }
-*/
-        
         // For each submitted file (usually only one)
         foreach( $_FILES as $file ) {
 
@@ -165,12 +134,12 @@ class GlmMembersAdmin_ajax_fileLibraryUpload extends GlmDataFileLibrary
      */
     public function storeFile ($file)
     {
-        
+
         // Check for fileLibrary media directory
         if (!file_exists(GLM_MEMBERS_PLUGIN_FILE_LIBRARY_PATH)) {
             mkdir(GLM_MEMBERS_PLUGIN_FILE_LIBRARY_PATH);
         }
-        
+
 
         // If $file is just a URL to an image, then simulate the file array from a form submission
         if (!is_array($file)) {
@@ -217,6 +186,9 @@ class GlmMembersAdmin_ajax_fileLibraryUpload extends GlmDataFileLibrary
             $file['newFileName'] = $newFilename;
             $file['newFileUrl'] = GLM_MEMBERS_WORDPRESS_FILE_LIBRARY_URL.$newFilename;
 
+
+            $lastAccessTime = date('Y-m-d H:i:s');
+
             // Store image name in images table
             $sql = "
                 INSERT INTO ".GLM_MEMBERS_PLUGIN_DB_PREFIX ."file_library
@@ -224,16 +196,18 @@ class GlmMembersAdmin_ajax_fileLibraryUpload extends GlmDataFileLibrary
                         name,
                         file_name,
                         descr,
-                        title
+                        title,
+                        last_access_time
                     )
                 VALUES
                     (
                         '".$file['name']."',
                         '".$file['newFileName']."',
                         '',
-                        ''
+                        '',
+                        '$lastAccessTime'
                     );
-            ";        
+            ";
             $this->wpdb->query($sql);
             $queryError = $this->wpdb->last_error;
 
index c6f85db..611b9da 100644 (file)
@@ -63,16 +63,16 @@ class GlmMembersAdmin_fileLibrary_index extends GlmDataFileLibrary
 
         // Save plugin configuration object
         $this->config = $config;
-        
+
         // Run constructor for members data class
         parent::__construct(false, false);
 
     }
 
     public function modelAction($actionData = false) {
-        
+
         $paging = false;
-        
+
         // File Library Upload scripts and css
         wp_register_script(
             'glm-members-admin-filelibrary-upload',
@@ -90,33 +90,33 @@ class GlmMembersAdmin_fileLibrary_index extends GlmDataFileLibrary
             GLM_MEMBERS_PLUGIN_VERSION
             );
         wp_enqueue_style('glm-members-admin-filelibrary-upload-css');
-        
+
         $haveFiles  = false;
 
-        $files = $this->getList();
+        $files = $this->getList(true, 'name');
         if ($files && count($files) > 0) {
             $haveFiles = true;
         }
-/*        
+/*
         // Update image gallery titles, descriptions, and image positions then return current image gallery
         $this->imageGallery = $Images->galleryImageDataUpdate($this->config['ref_type_numb']['MemberInfo'], $this->memberInfoID, 'galleryPositionOrder');
         $this->haveImageGallery = ($this->imageGallery != false);
-        
+
         // Update file captions, descriptions, and file positions then
         // return current files data.
         $this->files     = $Files->filesDataUpdate( $this->config['ref_type_numb']['MemberInfo'], $this->memberInfoID, 'filePositionOrder' );
         $this->haveFiles = ($this->files != false);
 */
-        
+
         // echo "<pre>".print_r($files,1)."</pre>";
-        
+
         // Compile template data
         $templateData = array(
             'haveFiles'     => $haveFiles,
             'files'         => $files,
             'paging'        => $paging
         );
-        
+
         // Return status, any suggested view, and any data to controller
         return array(
             'status'        => true,
index dbd1157..28f84bc 100644 (file)
 $glmMembersValidActions = array(
     'adminActions' => array(
         'ajax' => array(
-            'imageUpload'        => 'glm-member-db',
-            'fileUpload'         => 'glm-member-db',
-            'fileLibraryUpload'  => 'glm-member-db',
-            'newOldMemberIdsCsv' => 'glm-member-db',
-            'membersListExport'  => 'glm-member-db',
-            'memberClickThrough' => 'glm-member-db',
-            'memberDetailClick'  => 'glm-member-db',
-            'memberGraphs'       => 'glm-member-db',
+            'imageUpload'           => 'glm-member-db',
+            'fileUpload'            => 'glm-member-db',
+            'newOldMemberIdsCsv'    => 'glm-member-db',
+            'membersListExport'     => 'glm-member-db',
+            'memberClickThrough'    => 'glm-member-db',
+            'memberDetailClick'     => 'glm-member-db',
+            'memberGraphs'          => 'glm-member-db',
+            'fileLibraryUpload'     => 'glm-member-db',
+            'fileLibraryDownload'   => 'glm-member-db',
+            'fileLibraryDelete'     => 'glm-member-db',
+            'fileLibraryUpdate'     => 'glm-member-db'
         ),
         'dashboard' => array(
             'index'   => 'glm-member-db',
-            'members' => 'glm-member-db',
+            'members' => 'glm-member-db'
         ),
         'dashboardWidget' => array(
-            'index' => 'glm-member-db',
+            'index' => 'glm-member-db'
         ),
         'fileLibrary' => array(
-            'index' => 'glm-member-db',
+            'index' => 'glm-member-db'
         ),
         'members' => array(
             'index'   => 'glm-member-db',            // member list
             'list'    => 'glm-member-db',
             'reports' => 'glm-member-db',
-            'other'   => 'glm-member-db',
+            'other'   => 'glm-member-db'
         ),
         'member' => array(
             'index'      => 'glm-member-db',         // Member Dashboard
             'memberInfo' => 'glm-member-db',
             'memberEdit' => 'glm-member-db',
-            'locations'  => 'glm-member-db',
+            'locations'  => 'glm-member-db'
         ),
         'settings' => array(
             'index'      => 'glm-member-db',         // Member Types
@@ -70,7 +73,7 @@ $glmMembersValidActions = array(
             'cities'     => 'glm-member-db',
             'regions'    => 'glm-member-db',
             'counties'   => 'glm-member-db',
-            'amenities'  => 'glm-member-db',
+            'amenities'  => 'glm-member-db'
         ),
         'management' => array(
             'index'       => 'glm-member-db',        // General Options
@@ -80,21 +83,21 @@ $glmMembersValidActions = array(
             'theme'       => 'glm-member-db',
             'import'      => 'glm-member-db',
             'addons'      => 'glm-member-db',
-            'hooks'       => 'glm-member-db',
+            'hooks'       => 'glm-member-db'
         ),
         'shortcodes' => array(
-            'index' => 'glm-member-db',
+            'index' => 'glm-member-db'
         ),
         'error' => array(
             'index'     => 'glm-member-db',
-            'badAction' => 'glm-member-db',
+            'badAction' => 'glm-member-db'
         ),
         'pages' => array(
-            'shortcode' => 'glm-member-db',
+            'shortcode' => 'glm-member-db'
         ),
         'import' => array(
-            'index' => 'glm-member-db',
-        ),
+            'index' => 'glm-member-db'
+        )
     ),
     'frontActions' => array(
         'members' => array(
@@ -104,7 +107,7 @@ $glmMembersValidActions = array(
         ),
         'error' => array(
             'index'     => 'glm-member-db',
-            'badAction' => 'glm-member-db',
-        ),
+            'badAction' => 'glm-member-db'
+        )
     ),
 );
index 56a0c54..7268dfa 100644 (file)
@@ -1,5 +1,15 @@
 <div class="wrap glm-associate-admin-wrap">
 
+    <style type='text/css'>
+        .last-file-touched {
+            font-weight: bold;
+        }
+        .file-been-touched {
+            background-color: #f8ffff !important;
+        }
+    </style>
+    
+    
     <h2>Files Library</h2>
     <div id="glm-admin-content-container">
     
                             <table>
                                 <!-- Note that the template gets wrapped in a tbody and we copy it from there because the browser may create one after the table tag -->
                                 <tbody id="glm-fileLibraryDataTemplate" class="glm-fileLibraryItemHidden">
-                                <tr class="alternate">
-                                    <th class="glm-file-library-table-left">
-                                        <div class="glm-file-library-copy button button-secondary glm-button-small" style="margin: 0 .2em 0 .2em;" data-link="{ fileurl }">Copy Link URL</div>
-                                        { newfilename }
-                                    </th>
-                                    <td class="glm-file-library-table-left">
-                                        { filename }
-                                    </td>
-                                    <td class="glm-file-library-table-left">
-                                        &nbsp
-                                    </td>
-                                    <td class="glm-file-library-table-left">
-                                        &nbsp
-                                    </td>
-                                    <td class="glm-file-library-table-left">
-                                        <div class="button button-secondary glm-button-small glm-admin-edit-active-profile" style="margin: 0 .2em 0 .2em;">Edit</div>
-                                        <div class="button button-secondary glm-button-small glm-admin-edit-active-profile" style="margin: 0 .2em 0 .2em;">Delete</div>
-                                    </td>
-                                </tr>
+                                    <tr id="filenameLine_{ id }" class="glm-file-line glm-edit-form glm-file-{ id }" data-file="{ id }">
+                                        <td class="glm-file-library-table-left">
+                                            { filename }
+                                        </td>
+                                        <td class="glm-file-library-table-left">
+                                            { newfilename }
+                                        </td>
+                                        <td id="fileTitle_{ id }" class="glm-file-library-table-left">
+                                            &nbsp;
+                                        </td>
+                                        <td class="glm-file-library-table-left">
+                                            &nbsp
+                                        </td>
+                                    </tr>
+                                    <tr id="fileLinks_{ id }" class="glm-hidden glm-file-links"">
+                                        <td colspan="5" style="padding: .8rem; background-color: #fff;>
+                                            <span class="file-edit-link">
+                                                <a href="" class="glm-file-library-copy" data-file="{ id }" data-link="{ fileurl }">Copy File URL</a> |
+                                            </span>
+                                            <span class="file-edit-link">
+                                                <a class="glm-edit" href="#" data-file="{ id }">Edit File</a> |
+                                            </span>
+                                            <span>
+                                                 <a class="file-download-link" data-file="{ id }" href="{$ajaxUrl}?action=glm_members_admin_ajax&glm_action=fileLibraryDownload&fileId={ id }">Download File</a> |
+                                            </span>
+                                            <span>
+                                                <a class="delete-file" href="#" data-file="{ id }">Delete File</a> 
+                                            </span>
+                                            <span id="FileCopied_{ id }" class="glm-notice" style="display: none;">&nbsp;&nbsp;File URL copied to your clipboard.</span>
+                                            <span id="FileDeleted_{ id }" class="glm-notice" style="display: none;">&nbsp;&nbsp;File Deleted!</span>
+                                        </td>
+                                    </tr>
+                                    <tr class="glm-edit-form glm-edit-form-{ id }" style="display:none; background-color: #fff;">
+                                        <td colspan="5" style="border: 1px #ccc solid;">
+                                            <div class="glm-row" style="margin-bottom: 0px !important; margin-top: .5rem;">
+                                                <div class="glm-columns glm-small-6">
+                                                    <label>File Title: </label><BR>
+                                                    <input id="InputTitle_{ id }" class="glm-form-text-input-medium" type="text" name="title" value=""><br>
+                                                </div>
+                                                <div class="glm-columns glm-small-5">
+                                                    Description: 
+                                                    <textarea id="InputDescr_{ id }" class="glm-form-text-input-medium" name="descr"></textarea>
+                                                </div>
+                                            </div>
+                                            <div class="glm-row">
+                                                <div class="glm-columns glm-small-7">
+                                                    <button class="glm-cancel button button-secondary" data-file="{ id }">Cancel</button>
+                                                    <button class="glm-update button button-secondary" data-file="{ id }">Update</button>
+                                                </div>
+                                            </div>
+                                        </td>
+                                    </tr>
                                 <!-- End of template -->
                                 </tbody>
                             </table>
         <table class="wp-list-table striped glm-admin-table-single">
             <thead>
                 <tr>
-                    <th class="glm-file-library-table-left">File</th>
                     <th class="glm-file-library-table-left">Original Name</th>
+                    <th class="glm-file-library-table-left">Stored File Name</th>
                     <th class="glm-file-library-table-left">Title</th>
                     <th class="glm-file-library-table-left">Last Access</th>
-                    <th>&nbsp;</th>
                 </tr>
             </thead>
             <tbody>
                 <tr class="glm-NewFileHidden glm-fileLibraryItemHidden" style="background-color: #fff;"><th colspan="4" style="color: blue;">&nbsp;&nbsp;&nbsp;&nbsp;New Uploads</th></tr>
             </tbody>
-            <tbody id="glm-newFileContainer">
-            </tbody>
-            <tbody>
+            <tbody id="AfterNewFiles">
                 <tr class="glm-NewFileHidden glm-fileLibraryItemHidden" style="background-color: #fff;"><td colspan="4">&nbsp;</td></tr>
-                <tr class="glm-NewFileHidden glm-fileLibraryItemHidden" style="background-color: #fff;"><th colspan="4" style="color: blue;">&nbsp;&nbsp;&nbsp;&nbsp;Previous Uploads</th></tr>            
+                <tr class="glm-NewFileHidden glm-fileLibraryItemHidden" style="background-color: #fff;"><th colspan="4" style="color: blue;">&nbsp;&nbsp;&nbsp;&nbsp;Previous Uploads</th></tr>
+            </tbody>            
     {if $haveFiles}
         {assign var="i" value="0"}
         {foreach $files as $f}
-            {if $i++ is odd by 1}
-                <tr>
-            {else}
-                <tr class="alternate">
-            {/if}
-                    <td class="glm-file-library-table-left">
-                        <div class="glm-file-library-copy button button-secondary glm-button-small" style="margin: 0 .2em 0 .2em;" data-link="{$f.link_url}">Copy Link URL</div>
-                        {$f.file_name}
-                    </td>
+            <tbody id="fileContainer_{$f.id}">
+                <tr id="filenameLine_{$f.id}" class="glm-file-line glm-edit-form glm-file-{$f.id}{if $i++ is odd by 1} {/if}" data-file="{$f.id}">
                     <td class="glm-file-library-table-left">
                         {$f.name}
                     </td>
                     <td class="glm-file-library-table-left">
+                        {$f.file_name}
+                    </td>
+                    <td id="fileTitle_{$f.id}" class="glm-file-library-table-left">
                         {$f.title}
                     </td>
                     <td class="glm-file-library-table-left">
                         {$f.last_access_time.datetime}
                     </td>
-                    <td class="glm-file-library-table-left">
-                        <div class="button button-secondary glm-button-small glm-admin-edit-active-profile" style="margin: 0 .2em 0 .2em;">Edit</div>
-                        <div class="button button-secondary glm-button-small glm-admin-edit-active-profile" style="margin: 0 .2em 0 .2em;">Delete</div>
+                </tr>
+                <tr id="fileLinks_{$f.id}" class="glm-hidden glm-file-links"">
+                    <td colspan="5" style="padding: .8rem; background-color: #fff;>
+                        <span class="file-edit-link">
+                            <a href="" class="glm-file-library-copy" data-file="{$f.id}" data-link="{$f.link_url}">Copy File URL</a> |
+                        </span>
+                        <span class="file-edit-link">
+                            <a class="glm-edit" href="#" data-file="{$f.id}">Edit File</a> |
+                        </span>
+                        <span>
+                            <a class="file-download-link" data-file="{$f.id}" href="{$ajaxUrl}?action=glm_members_admin_ajax&glm_action=fileLibraryDownload&fileId={$f.id}">Download File</a> |
+                        </span>
+                        <span>
+                            <a class="delete-file" href="#" data-file="{$f.id}">Delete File</a> 
+                        </span>
+                        <span id="FileCopied_{$f.id}" class="glm-notice" style="display: none;">&nbsp;&nbsp;File URL copied to your clipboard.</span>
+                        <span id="FileDeleted_{$f.id}" class="glm-notice" style="display: none;">&nbsp;&nbsp;File Deleted!</span>
+                    </td>
+                </tr>
+                <tr class="glm-edit-form glm-edit-form-{$f.id}{if $f@iteration is div by 2} alternate{/if}" style="display:none; background-color: #fff;">
+                    <td colspan="5" style="border: 1px #ccc solid;">
+                        <div class="glm-row" style="margin-bottom: 0px !important; margin-top: .5rem;">
+                            <div class="glm-columns glm-small-6">
+                                <label>File Title: </label><BR>
+                                <input id="InputTitle_{$f.id}" class="glm-form-text-input-medium" type="text" name="title" value="{$f.title}"><br>
+                            </div>
+                            <div class="glm-columns glm-small-5">
+                                Description: 
+                                <textarea id="InputDescr_{$f.id}" class="glm-form-text-input-medium" name="descr">{$f.descr}</textarea>
+                            </div>
+                        </div>
+                        <div class="glm-row">
+                            <div class="glm-columns glm-small-7">
+                                <button class="glm-cancel button button-secondary" data-file="{$f.id}">Cancel</button>
+                                <button class="glm-update button button-secondary" data-file="{$f.id}">Update</button>
+                            </div>
+                        </div>
                     </td>
                 </tr>
+            </tbody>
         {/foreach}
     {else}
                 <tr class="alternate"><td colspan="4">(no files listed)</td></tr>
    </div>
    </div>
 
+
+
+<script>
+jQuery(document).ready(function($){
+
+
+    // Copy an element to the clipboard
+    function copyToClipboard(text) {
+        var $temp = $("<input>");
+        $("body").append($temp);
+        $temp.val(text).select();
+        document.execCommand("copy");
+        $temp.remove();
+    }
+
+    $('body').on('click', '.glm-file-library-copy', function(e) {
+        e.preventDefault();
+        copyToClipboard($(this).attr('data-link'));
+        var fileId = $(this).attr('data-file');
+        lastFileTouched(fileId);
+        flashNotice($('#FileCopied_' + fileId));
+        return false;
+    });
+    
+    $('.glm-edit').live('click', function(e){
+        e.preventDefault();
+        fileLinksEditSelected();
+        $('.glm-edit-form-' + $(this).data('file')).show();
+        var fileId = $(this).data('file');
+        lastFileTouched(fileId);
+    });
+
+    $('.glm-cancel').live('click', function(e){
+        e.preventDefault();
+        clearFileLinks();
+        $('.glm-edit-form-' + $(this).data('file')).hide();
+        $('.glm-file-' + $(this).data('file')).show();
+    });
+
+    $('.file-download-link').live('click', function(e) {
+        var fileId = $(this).data('file');
+        lastFileTouched(fileId);
+    });
+    
+    // File Line Hover Action
+    var fileEditFlag = false;
+    var fileHoverId = false;    
+    $('.glm-file-line').live( 'mouseenter', function() {
+        if (fileEditFlag) {
+            return;
+        }
+        fileHoverId = $(this).attr('data-file');
+        $('.glm-file-links').addClass('glm-hidden');
+        $('#fileLinks_' + fileHoverId).removeClass('glm-hidden');
+    });
+    function fileLinksEditSelected() {
+        $('#fileLinks_' + fileHoverId).addClass('glm-hidden');
+        fileEditFlag = true;
+    }
+    function clearFileLinks() {
+        fileLinksEditSelected();
+        fileEditFlag = false;
+        fileHoverId = false;
+    }
+    $('.glm-admin-table-inner').mouseleave( function() {
+        $('#fileLinks_' + fileHoverId).addClass('glm-hidden');
+    })
+    
+    // Delete file
+    $('.delete-file').live('click', function(e){
+        
+        e.preventDefault();
+        var fileId = $(this).data('file');
+
+        if (confirm('Are you sure you want to delete this file?')) {
+            $.ajax({
+                context: this,
+                url: '{$ajaxUrl}?action=glm_members_admin_ajax',
+                data: {
+                    glm_action: 'fileLibraryDelete',
+                    fileId: fileId
+                }
+            }).done(function(msg){
+                if (msg == 'File Deleted') {
+                    $('#fileContainer_' + fileId).fadeOut(1000, function() {
+                        $('#fileContainer_' + fileId).remove();
+                    });
+                } else {
+                    alert('Unable to delete: ' + msg);
+                }
+            }).fail(function(msg){
+                alert('Unable to delete this file at this time.');
+            });
+        }
+
+    });
+
+    function flashNotice(notice) {
+        notice.fadeOut(500).fadeIn(500).fadeOut(500).fadeIn(500).fadeOut(500).fadeIn(500).fadeOut(500).fadeIn(500).fadeOut(500).fadeIn(500).fadeOut(500);
+    }
+    
+    $('.glm-update').live('click', function(e){
+        e.preventDefault();
+        var fileId = $(this).data('file');
+        
+        // Get possible custom field data
+        var fileFormData = $('#glm-file-form-' + fileId).serialize();
+        console.log(fileFormData);
+
+        var fileTitle = $('#InputTitle_' + fileId).val().trim();
+        var fileDescr = $('#InputDescr_' + fileId).val().trim();
+
+        $.ajax({
+            context: this,
+            type: 'POST',
+            url: '{$ajaxUrl}?action=glm_members_admin_ajax',
+            dataType: 'text',
+            data: {
+                glm_action: 'fileLibraryUpdate',
+                fileId: fileId,
+                title: fileTitle,
+                descr: fileDescr
+            }
+        }).done(function(){
+            $('.glm-edit-form-' + $(this).data('file')).hide();
+            $('.glm-file-' + $(this).data('file')).show();
+            $('#fileTitle_' + fileId).text(fileTitle);
+            clearFileLinks();
+        }).fail(function(msg){
+            alert('Unable to update file: ' + msg);            
+        });
+    });
+
+    // highlight last file touched
+    function lastFileTouched(fileId) {
+        $('.glm-file-line').removeClass('last-file-touched');
+        $('#filenameLine_' + fileId).addClass('last-file-touched file-been-touched');
+    }
+
+});
+</script>
+
             
 {include file='admin/footer.html'}