前面几节所做的操作都是对服务器内容的读取,下面开始探讨若干会牵扯到修改服务器的操作。
首先是在当前文件夹下新建文件,对应着文件夹上方的New File菜单项。
<li><a href="#" title="new file" onClick="onNewFile()"><img src="images/newfile48.png" class="topmenu" alt=""/></a></li>
其响应的onNewFile函数,如果在C/S程序中,可以弹出一个对话框,使用户输入新建文件的文件名,然后将请求发送给服务器端。然而,如何在B/S程序中实现这个对话框呢?幸好有jQueryUI。
通过以下代码引入在线CDN的jQueryUI,也可以考虑保存到服务器上后引用,本文的方法可以节省服务器的资源。
<link rel="stylesheet" href="http://cdn.bootcss.com/jqueryui/1.11.2/jquery-ui.min.css"> <link rel="stylesheet" href="http://cdn.bootcss.com/jqueryui/1.11.2/jquery-ui.theme.min.css"> <script type="text/javascript" src="http://cdn.bootcss.com/jqueryui/1.11.2/jquery-ui.min.js"></script>
jQueryUI可以通过简单调用.dialog函数实现对话框的弹出。具体到响应onNewFile函数中:
function onNewFile() { $('#dialogNewFile').dialog({ height:'auto', width:'auto', position:{my:'center',at:'center',collision:'fit'}, modal:false, draggable:true, resizable:true, title:"New File", show:'slide', hide:'explode', buttons:{ OK: function() { strNewFileName = $('#textNewFileName').val(); if (strNewFileName == "") return; $.post("query.php", {act:"newFile", file:strNewFileName}, function (data) { $('#spanDirTable').html(data); $( '#dialogNewFile' ).dialog( "close" ); }); }, Cancel: function() { $( this ).dialog( "close" ); } } }); }
注意到dialog后面提供了若干参数,这里不做详细解释,感兴趣的读者可以去查阅相关的官方介绍。
同时,在dialog中提供了两个按钮,并绑定了点击时触发的处理流程,最关键的是对OK按钮的处理:
OK: function() { strNewFileName = $('#textNewFileName').val(); if (strNewFileName == "") return; $.post("query.php", {act:"newFile", file:strNewFileName}, function (data) { $('#spanDirTable').html(data); $( '#dialogNewFile' ).dialog( "close" ); }); }
其从输入框textNewFileName中取出了新建文件的名称,并向query.php发送请求。接收到信息后,填充网页内容,并关闭对话框。
当然,只有这个函数并不能实现对话框功能,还需要在网页中加入“原材料”:
<div id="dialogNewFile" style="display:none"> <strong>Create File Under Folder:<br/></strong> Please input File Name:<input type="text" id="textNewFileName"/> </div>
点击效果如下:
服务端接收该命令后,尝试新建对应的文件,并通过alert向用户返回提示信息。
PHP中,通过fileexists判断文件是否存在,通过fopen可以新建或打开文件。
case "newFile": $isDirContentView = true; if (isset($_SESSION["currDir"])) { $strDirName = $_SESSION["currDir"]; } else $strDirName = "/home"; if (isset($_POST["file"])) { $strFileName = $_POST["file"]; $strFilePath = $strDirName."/".$strFileName; $fileNew = fopen($strFilePath, "w"); if ($fileNew === false) { echo "<script>alert('Create New File \"$strFilePath\" Failed!')</script>"; } else { fclose($fileNew); echo "<script>alert('Create New File \"$strFilePath\" Succeed!')</script>"; } } break;
注意,这里的$isDirContentView = true会导致触发前文提到的获取文件夹内容列表的操作。
实现效果:
点击alert的按钮,dialog也会关闭。
新建文件夹也可以用类似的方法解决。
图片链接:
<li><a href="#" title="new folder" onClick="onNewFolder()"><img src="images/newfolder48.png" class="topmenu" alt=""/></a></li>
“原材料”:
<div id="dialogNewFolder" style="display:none"> <strong>Create Sub-Folder Under Folder:<br/></strong> Please input Folder Name:<input type="text" id="textNewFolderName"/> </div>
onNewFolder函数:
function onNewFolder() { $('#dialogNewFolder').dialog({ height:'auto', width:'auto', position:{my:'center',at:'center',collision:'fit'}, modal:false, draggable:true, resizable:true, title:"New File", show:'slide', hide:'explode', buttons:{ OK: function() { strNewFolderName = $('#textNewFolderName').val(); if (strNewFolderName == "") return; $.post("query.php", {act:"newFolder", file:strNewFolderName}, function (data) { $('#spanDirTable').html(data); $( '#dialogNewFolder' ).dialog( "close" ); }); }, Cancel: function() { $( this ).dialog( "close" ); } } }); }
PHP中通过mkdir来创建文件夹,对应的响应:
case "newFolder": $isDirContentView = true; if (isset($_SESSION["currDir"])) { $strDirName = $_SESSION["currDir"]; } else $strDirName = "/home"; if (isset($_POST["file"])) { $strSubDirName = $_POST["file"]; $strSubDirPath = $strDirName."/".$strSubDirName; if (mkdir($strSubDirPath) === false) { echo "<script>alert('Create New Folder \"$strSubDirPath\" Failed!')</script>"; } else { echo "<script>alert('Create New Folder \"$strSubDirPath\" Succeed!')</script>"; } } break;
实现效果:
查看文件属于文件操作的一部分,需要文件可读。下面的代码段在操作栏中添加查看图标:
$viewMode= "content"; $encodedFilePath = urlencode($filePath); $info.= "<td><ul class=\"operations\">"; if (is_readable($filePath)) $info.= "<li><a href=\"#\" title=\"view\" onClick=\"onElemAct('$viewMode','$encodedFilePath')\"><img src=\"images/view32.png\" alt=\"\" class=\"tabmenu\"/></a></li>";
注意,实际响应按钮事件为onElemAct('content','urlencode($filePath)')。
这里通过onElemAct,在客户端JS中对针对文件夹下项目的操作统一起来。
下面是对查看内容的响应:
function onElemAct(strViewMode, strViewPath) { switch (strViewMode) { case "content": $.post("query.php", {act:"content", file:strViewPath}, function (data){ $('#textContent').text(""+data); $('#dialogContent').dialog({ height:'auto', width:'auto', position:{my:'center',at:'center',collision:'fit'}, modal:false, draggable:true, resizable:true, title:'View Content', show:'slide', hide:'explode' }); }); break;
同新建文件不同的是,这里首先POST请求文件内容,然后将文件内容填入textContent区域中,再显示dialogContent来弹出对话框。对应的“原材料”为:
<div id="dialogContent" style="display:none"> <textarea class="text-dialog" id="textContent"></textarea> </div>
服务端通过file_get_content可以获取文件的内容。这里JS端使用text而不是html装入内容可以有效避免触发服务端文件的html标记。
case "content": $isDirContentView = false; if (isset($_POST["file"])) { $strFileName = urldecode($_POST["file"]); echo file_get_contents($strFileName); } break;
这里$isDirContentView = false;可以避免刷新文件夹内容,因为不需要返回该内容。
具体效果:
编辑文档需要结合新建文档和查看文档中的技术:首先请求获取文档内容,在编辑后通过按钮事件将编辑后的内容发送到服务器,并返回修改结果。
首先是按钮图标,接在查看按钮后面,注意可编辑的文件必须可写:
if (is_writable($filePath)) $info.= "<li><a href=\"#\" title=\"edit\" onClick=\"onElemAct('edit','$encodedFilePath')\"><img src=\"images/edit32.png\" alt=\"\" class=\"tabmenu\"/></a></li>";
在onElemAct中响应该事件:
case "edit": $.post("query.php", {act:"content", file:strViewPath}, function (data){ $('#textEdit').text(""+data); $('#dialogEdit').dialog({ height:'auto', width:'auto', position:{my:'center',at:'center',collision:'fit'}, modal:false, draggable:true, resizable:true, title:'Edit Content', show:'slide', hide:'explode', buttons:{ OK: function() { strEditContent = $('#textEdit').val(); $.post("query.php", {act:"editFile", file:strViewPath, content:strEditContent}, function (data) { $('#spanDirTable').html(data); $( '#dialogEdit' ).dialog( "close" ); }); }, Cancel: function() { $( this ).dialog( "close" ); } } }); }); break;
对应的原材料:
<div id="dialogEdit" style="display:none"> <textarea class="text-dialog" id="textEdit"></textarea> </div>
在服务器中,通过file_get_content获取内容,通过file_put_content修改内容:
case "editFile": $isDirContentView = true; if (isset($_SESSION["currDir"])) { $strDirName = $_SESSION["currDir"]; } else $strDirName = "/home"; if (isset($_POST["file"]) && isset($_POST["content"])) { $strFilePath = urldecode($_POST["file"]); if (file_put_contents($strFilePath, $_POST["content"])) { echo "<script>alert('File \"$strFilePath\" Edit Succeed!')</script>"; } else { echo "<script>alert('File \"$strFilePath\" Edit Failed!')</script>"; } } break;
实现效果: