Etable/formType/file:修訂版本之間的差異
出自六年制學程
(→修改 etable.php 中的 javascript 函式) |
(→(三)新增 login.php 中可以後送檔案的 javascript 函式 postFormData(…)) |
||
(未顯示同用戶所作出之30次版本) | |||
第 1 行: | 第 1 行: | ||
[[分類:Etable]] | [[分類:Etable]] | ||
− | + | 托盤有兩元素: | |
+ | #f[表名][欄名][path]:是一選單 | ||
+ | #f[表名][欄名][fileName]:是一上傳按鈕 | ||
− | |||
− | |||
− | |||
− | + | 上傳檔真正移往的位置,與要塞入資料表的欄值是:<pre>$this->formType[$lc_name][1]['docsPath'].$value['path'].'/'.$_FILES['f']['name'][$as_name][$key]['fileName']</pre> | |
+ | #formType該欄指示的第0個元素是表單類別:file,第1個元素是陣列,其'docsPath'索引到的值 | ||
+ | #托盤傳回的使用者選用路徑 | ||
+ | #托盤傳回的使用者上傳檔檔名 | ||
− | |||
− | + | 圖片在 HTML 中的顯示位置是:substr($value,strlen($this->formType[$lc_name][1]['docsPath'])) | |
− | === | + | 即欄值取文件根目錄之後的值 |
+ | ====(一)製作表單元素類別==== | ||
+ | formsome.php 中 | ||
+ | <pre>class XoopsFormUploadFile extends XoopsFormElement{ // 上傳按鈕 | ||
+ | function XoopsFormUploadFile($caption, $name){ // 提示、後傳變數名 | ||
+ | $this->setCaption($caption); | ||
+ | $this->setName($name); | ||
+ | } | ||
+ | function render(){ | ||
+ | return "<input type='file' name='".$this->getName()."' id='".$this->getName()."'".$this->getExtra()." />".$this->getExtra('2'); | ||
+ | } | ||
+ | } | ||
+ | class XoopsFormFile extends XoopsFormElementTray{ // 上傳托盤:前為路徑選單,後為上傳按鈕 | ||
+ | function XoopsFormFile($caption, $name, $value='', $paths=array('.'=>'當前路徑')){ | ||
+ | $this->XoopsFormElementTray($caption,' '); | ||
+ | $pathSelect=new XoopsFormSelect('路徑:',$name.'[path]',$value='');// 產生路徑選單物件,並指定預選值為空字串 | ||
+ | $pathSelect->addOptionArray($paths); // 將傳入之 $paths 轉成選項 | ||
+ | $this->addElement($pathSelect); // 將選單物件放入表單 | ||
+ | $fileUpload=new XoopsFormUploadFile('請選檔:', $name.'[fileName]');// 加上上傳按鈕 | ||
+ | $this->addElement($fileUpload); // 將選單物件放入表單 | ||
+ | } | ||
+ | }</pre> | ||
− | ==== | + | ====(二)addElements($i,$value)==== |
+ | 加表單元素類型為 file 則<pre>$j=new XoopsFormFile($this->fields[$i]['colalias'],'f['.$this->fields[$i]['as_name'].']['.$this->fields[$i]['colname'].']',str_replace("'",'&#39;',str_replace("&",'&#38;',$value)),$this->formType["$lc_name"][1]['paths']); | ||
+ | $this->form->addElement($j,(($this->fields[$i]['formValidate']==0)?'0':'1')); | ||
+ | $this->form->addElement(new XoopsFormHidden('uploadFileField',$lc_name,0)); | ||
+ | $this->form->addElement(new XoopsFormHidden('uploadFilePath',$value,0));</pre> | ||
− | ==== | + | ====(三)新增 login.php 中可以後送檔案的 javascript 函式 postFormData(…)==== |
+ | 可參考[[Ajax#檔案上傳程式範例|檔案上傳程式範例]]。 | ||
+ | <pre>function postFormData(formID,dataSource,divID){ // 以 fetch 發POST請求,可以上傳檔案,等於原來的 sendFormData+postData | ||
+ | var formData = new FormData(); | ||
+ | for(var i=0;i<document.getElementById(formID).elements.length;i++){ | ||
+ | if(document.getElementById(formID).elements[i].type=='checkbox' || document.getElementById(formID).elements[i].type=='radio'){ | ||
+ | if(document.getElementById(formID).elements[i].type=='checkbox'){ // 處理核取方塊,checked回傳值,沒checked回傳空字串 | ||
+ | if(document.getElementById(formID).elements[i].checked==true){formData.append(document.getElementById(formID).elements[i].name,document.getElementById(formID).elements[i].value);} | ||
+ | else{formData.append(document.getElementById(formID).elements[i].name,'');} | ||
+ | }else{ // 處理按鈕,checked回傳值,否則跳過 | ||
+ | if(document.getElementById(formID).elements[i].checked==true){formData.append(document.getElementById(formID).elements[i].name,document.getElementById(formID).elements[i].value);} | ||
+ | } | ||
+ | } | ||
+ | else if(document.getElementById(formID).elements[i].type=='hidden'){formData.append(document.getElementById(formID).elements[i].name,document.getElementById(formID).elements[i].value);} | ||
+ | //新增檔案資料 | ||
+ | else if(document.getElementById(formID).elements[i].type=='file'){formData.append(document.getElementById(formID).elements[i].name,document.getElementById(formID).elements[i].files[0]);} | ||
+ | else{formData.append(document.getElementById(formID).elements[i].name,document.getElementById(formID).elements[i].value);} | ||
+ | } | ||
+ | fetch(dataSource,{method:'POST',body:formData}).then((response)=>{return response.text();}).then((responseText)=>{document.getElementById(divID).innerHTML=responseText;onAjax(a);}); | ||
+ | }</pre> | ||
− | ====「$action=='edited'」==== | + | ====(四)修改 etable.php 中的 javascript 函式 checkFormlist(…)==== |
+ | <pre>if($field['formType'][0]=='file'){$str.="\t\telse if(document.getElementsByName('f[".$field['as_name']."][".$field['colname']."][path]')[0].value!='notToChangeFile' && !(/".$field['formValidate'][0]."/.test(document.getElementsByName('f[".$field['as_name']."][".$field['colname']."][path]')[0].value) && (/".$field['formValidate'][0]."/.test(document.getElementsByName('f[".$field['as_name']."][".$field['colname']."][fileName]')[0].value)))){alert(\"".$field['formValidate'][1]."\");}\n";} | ||
+ | </pre> | ||
+ | 說明: | ||
+ | #第一層測試是「條件A && 條件B」必須兩個都 true 才合條件出警示。有一個為 false 另一個不用測。 | ||
+ | #先測 path 是不是選「notToChangeFile」,若是 && 前半已為 false ,直接跳出不必再測。 | ||
+ | #path 若未選「notToChangeFile」,則 條件A 合,開始測 條件B 。 | ||
+ | # 條件B 為 !(path不空白 && fileName不空白) | ||
+ | |||
+ | ====(五)修改 etable.php 中的 fieldValue2sqlStr 函式==== | ||
+ | <pre>if(is_array($value)){ | ||
+ | … | ||
+ | elseif(isset($value['path']) && $value['path']!='notToChangeFile'){ | ||
+ | if(isset($value['path']) && isset($_FILES['f']['name'][$as_name][$key]['fileName'])){ // file | ||
+ | if(move_uploaded_file($_FILES['f']['tmp_name'][$as_name][$key]['fileName'],$this->formType[$lc_name][1]['docsPath'].$value['path'].'/'.$_FILES['f']['name'][$as_name][$key]['fileName'])){ | ||
+ | if(!$isIns){unlink($_POST['uploadFilePath']);} // 若非插入而是編畢,且上傳新檔成功,先刪舊檔;下行準備以新檔路徑插入欄值 | ||
+ | $value=$this->formType[$lc_name][1]['docsPath'].$value['path'].'/'.$_FILES['f']['name'][$as_name][$key]['fileName']; | ||
+ | } | ||
+ | else{$value=$_POST['uploadFilePath'];} | ||
+ | } | ||
+ | } | ||
+ | elseif(isset($value['path']) && $value['path']=='notToChangeFile'){$value=$_POST['uploadFilePath'];} | ||
+ | … | ||
+ | }</pre> | ||
+ | |||
+ | ====(六)修改 etable.php 中的 main() / 單筆資料前置處理 / 編畢、刪一筆==== | ||
+ | |||
+ | '''「$action=='ins_ed'」或「$action=='inss'」''':已透過 fieldValue2sqlStr 函式處理 | ||
+ | |||
+ | '''「$action=='erase'」''' | ||
+ | <pre>if($action=='erase'){ | ||
+ | foreach($this->editables['erase'] as $as_name){ | ||
+ | foreach($this->formType as $k=>$v){ | ||
+ | if($v[0]=='file'){ | ||
+ | unlink(mysqli_result(DB::queryF("select `$k` from ".$this->tables["$as_name"]['t_name']." where 1 ".$this->decode($this->rid["$as_name"])." limit 1"),0,0)); | ||
+ | } | ||
+ | } | ||
+ | DB::queryF("delete from ".$this->tables["$as_name"]['t_name']." where 1 ".$this->decode($this->rid["$as_name"])." limit 1"); // by jj now | ||
+ | } | ||
+ | }</pre> | ||
+ | |||
+ | '''「$action=='edited'」''':已透過 fieldValue2sqlStr 函式處理 | ||
+ | |||
+ | ====(七)修改 etable.php 中的 colValue()==== | ||
+ | <pre>elseif($this->tran){ | ||
+ | … | ||
+ | elseif($this->formType["$lc_name"][0]=='file'){ | ||
+ | if($value){$value="<img src='".substr($value,strlen($this->formType[$lc_name][1]['docsPath']))."' width=100 height=* />";} | ||
+ | else{$value="";} | ||
+ | } | ||
+ | … | ||
+ | }</pre> |
2023年3月23日 (四) 17:09的最新修訂版本
托盤有兩元素:
- f[表名][欄名][path]:是一選單
- f[表名][欄名][fileName]:是一上傳按鈕
$this->formType[$lc_name][1]['docsPath'].$value['path'].'/'.$_FILES['f']['name'][$as_name][$key]['fileName']
- formType該欄指示的第0個元素是表單類別:file,第1個元素是陣列,其'docsPath'索引到的值
- 托盤傳回的使用者選用路徑
- 托盤傳回的使用者上傳檔檔名
圖片在 HTML 中的顯示位置是:substr($value,strlen($this->formType[$lc_name][1]['docsPath']))
即欄值取文件根目錄之後的值
目錄
(一)製作表單元素類別
formsome.php 中
class XoopsFormUploadFile extends XoopsFormElement{ // 上傳按鈕 function XoopsFormUploadFile($caption, $name){ // 提示、後傳變數名 $this->setCaption($caption); $this->setName($name); } function render(){ return "<input type='file' name='".$this->getName()."' id='".$this->getName()."'".$this->getExtra()." />".$this->getExtra('2'); } } class XoopsFormFile extends XoopsFormElementTray{ // 上傳托盤:前為路徑選單,後為上傳按鈕 function XoopsFormFile($caption, $name, $value='', $paths=array('.'=>'當前路徑')){ $this->XoopsFormElementTray($caption,' '); $pathSelect=new XoopsFormSelect('路徑:',$name.'[path]',$value='');// 產生路徑選單物件,並指定預選值為空字串 $pathSelect->addOptionArray($paths); // 將傳入之 $paths 轉成選項 $this->addElement($pathSelect); // 將選單物件放入表單 $fileUpload=new XoopsFormUploadFile('請選檔:', $name.'[fileName]');// 加上上傳按鈕 $this->addElement($fileUpload); // 將選單物件放入表單 } }
(二)addElements($i,$value)
加表單元素類型為 file 則$j=new XoopsFormFile($this->fields[$i]['colalias'],'f['.$this->fields[$i]['as_name'].']['.$this->fields[$i]['colname'].']',str_replace("'",'&#39;',str_replace("&",'&#38;',$value)),$this->formType["$lc_name"][1]['paths']); $this->form->addElement($j,(($this->fields[$i]['formValidate']==0)?'0':'1')); $this->form->addElement(new XoopsFormHidden('uploadFileField',$lc_name,0)); $this->form->addElement(new XoopsFormHidden('uploadFilePath',$value,0));
(三)新增 login.php 中可以後送檔案的 javascript 函式 postFormData(…)
可參考檔案上傳程式範例。
function postFormData(formID,dataSource,divID){ // 以 fetch 發POST請求,可以上傳檔案,等於原來的 sendFormData+postData var formData = new FormData(); for(var i=0;i<document.getElementById(formID).elements.length;i++){ if(document.getElementById(formID).elements[i].type=='checkbox' || document.getElementById(formID).elements[i].type=='radio'){ if(document.getElementById(formID).elements[i].type=='checkbox'){ // 處理核取方塊,checked回傳值,沒checked回傳空字串 if(document.getElementById(formID).elements[i].checked==true){formData.append(document.getElementById(formID).elements[i].name,document.getElementById(formID).elements[i].value);} else{formData.append(document.getElementById(formID).elements[i].name,'');} }else{ // 處理按鈕,checked回傳值,否則跳過 if(document.getElementById(formID).elements[i].checked==true){formData.append(document.getElementById(formID).elements[i].name,document.getElementById(formID).elements[i].value);} } } else if(document.getElementById(formID).elements[i].type=='hidden'){formData.append(document.getElementById(formID).elements[i].name,document.getElementById(formID).elements[i].value);} //新增檔案資料 else if(document.getElementById(formID).elements[i].type=='file'){formData.append(document.getElementById(formID).elements[i].name,document.getElementById(formID).elements[i].files[0]);} else{formData.append(document.getElementById(formID).elements[i].name,document.getElementById(formID).elements[i].value);} } fetch(dataSource,{method:'POST',body:formData}).then((response)=>{return response.text();}).then((responseText)=>{document.getElementById(divID).innerHTML=responseText;onAjax(a);}); }
(四)修改 etable.php 中的 javascript 函式 checkFormlist(…)
if($field['formType'][0]=='file'){$str.="\t\telse if(document.getElementsByName('f[".$field['as_name']."][".$field['colname']."][path]')[0].value!='notToChangeFile' && !(/".$field['formValidate'][0]."/.test(document.getElementsByName('f[".$field['as_name']."][".$field['colname']."][path]')[0].value) && (/".$field['formValidate'][0]."/.test(document.getElementsByName('f[".$field['as_name']."][".$field['colname']."][fileName]')[0].value)))){alert(\"".$field['formValidate'][1]."\");}\n";}
說明:
- 第一層測試是「條件A && 條件B」必須兩個都 true 才合條件出警示。有一個為 false 另一個不用測。
- 先測 path 是不是選「notToChangeFile」,若是 && 前半已為 false ,直接跳出不必再測。
- path 若未選「notToChangeFile」,則 條件A 合,開始測 條件B 。
- 條件B 為 !(path不空白 && fileName不空白)
(五)修改 etable.php 中的 fieldValue2sqlStr 函式
if(is_array($value)){ … elseif(isset($value['path']) && $value['path']!='notToChangeFile'){ if(isset($value['path']) && isset($_FILES['f']['name'][$as_name][$key]['fileName'])){ // file if(move_uploaded_file($_FILES['f']['tmp_name'][$as_name][$key]['fileName'],$this->formType[$lc_name][1]['docsPath'].$value['path'].'/'.$_FILES['f']['name'][$as_name][$key]['fileName'])){ if(!$isIns){unlink($_POST['uploadFilePath']);} // 若非插入而是編畢,且上傳新檔成功,先刪舊檔;下行準備以新檔路徑插入欄值 $value=$this->formType[$lc_name][1]['docsPath'].$value['path'].'/'.$_FILES['f']['name'][$as_name][$key]['fileName']; } else{$value=$_POST['uploadFilePath'];} } } elseif(isset($value['path']) && $value['path']=='notToChangeFile'){$value=$_POST['uploadFilePath'];} … }
(六)修改 etable.php 中的 main() / 單筆資料前置處理 / 編畢、刪一筆
「$action=='ins_ed'」或「$action=='inss'」:已透過 fieldValue2sqlStr 函式處理
「$action=='erase'」
if($action=='erase'){ foreach($this->editables['erase'] as $as_name){ foreach($this->formType as $k=>$v){ if($v[0]=='file'){ unlink(mysqli_result(DB::queryF("select `$k` from ".$this->tables["$as_name"]['t_name']." where 1 ".$this->decode($this->rid["$as_name"])." limit 1"),0,0)); } } DB::queryF("delete from ".$this->tables["$as_name"]['t_name']." where 1 ".$this->decode($this->rid["$as_name"])." limit 1"); // by jj now } }
「$action=='edited'」:已透過 fieldValue2sqlStr 函式處理
(七)修改 etable.php 中的 colValue()
elseif($this->tran){ … elseif($this->formType["$lc_name"][0]=='file'){ if($value){$value="<img src='".substr($value,strlen($this->formType[$lc_name][1]['docsPath']))."' width=100 height=* />";} else{$value="";} } … }