From: Polin Wei
XOOPS源碼分析之--表單組件淺析(一)
表單是幾乎所有WEB開發中都會用到的,生成表單的方法有很多,我先後用過的方法就很雜,有直接echo表單的html代碼 XOOPS居然有一套非常完善的form類,相比較而言XOOPS的表單類更容易使用,完全是面向對象的模式,而且代碼更為簡潔,控制更為靈活。這些表單類都保存在XOOPS_ROOT/class/xoopsform目錄下,有時間大家可以好好研習一下。從我目前理解的狀況來說,其中有2個是基類,一個是XoopsForm,一個是XoopsElement,其他都是對這2個基類的繼承和擴展。下面我們開始簡單的剖析其中幾個比較常用的類:
[一]表單的form類--form.php
文件定義了XoopsForm基類,XoopsSimpleForm、XoopsTableForm、XoopsThemeForm都是對這個對象的擴展。
1、XoopsForm對象的私有變量
    * $_action :對應form中的action,即處理表單提交的操作; 
    * $_method :對應form中的method,即POST或是GET; 
    * $_name :對應form中name,即表單名; 
    * $_title :表單的標題; 
    * $_elements :表單成員數組,即form所包含的checkbox,text等元素; 
    * $_extra :這個變量會保存一些額外的信息,如class=「formclass」; 
    * $_required :這是個數組變量,保存著form中有哪些成員是必添項,結合Xoops自帶的腳本可以方便地在提交前實現必添字段的檢查 
2、XoopsForm對象的成員函數
    * function XoopsForm($title, $name, $action, $method="post", $addtoken=false) 
XoopsForm對象的構造函數,前4個參數對照私有變量的命名很容易理解,其中默認的提交方法是"post",$addtoken這個布爾參數,控制是否要添加一個加密的令牌到form中,我理解是類似於給form增加一個sessionID,防止來自網站之外的惡意提交,默認情況是不添加這個令牌的。
    * function getTitle() | function setTitle() 
    * function getName() | function setName() 
    * function getAction()| function setAction() 
    * function getMethod()| function setMethod() 
這四組函數很容易理解,分別完成對title,Name,Action,Method的讀取(get)和設置(set).
    * function addElement(&$formElement, $required=false) 
這個函數是比較重要的,它完成form中元素的添加,$formElement是元素對象,$required設置是否這個元素為必添字段,即是否加入校驗隊列。
    * function &getElements($recurse = false) 
這個函數返回form中元素數組,$recurse根據源碼註釋是控制是否採取遞歸循環方式生成元素數組,因為這個函數一般比較少用,我沒仔細去理解它的源碼,不知道解釋得對不對。
    * function getElementNames() 
函數返回所有元素的名稱,返回值為數組
    * function &getElementByName($name) 
根據名稱返回相應的元素對象,找不到則返回false;我個人認為這個函數是非常有意義的,可以在已經添加元素後,對它進行修改,當然修改還要用到Element對象的函數。
    * function setElementValue($name, $value) 
此函數可以設置form名為$name元素的值,沒有返回值
    * function setElementValues($values) 
此函數實際上是上一函數的批處理,一次對form多個元素進行賦值,$values是$name/$value對的數組
    * function &getElementValue($name) 
獲得名為$name的form元素值,如果沒有設置則返回NULL。
    * function &getElementValues() 
是上一函數的批處理,返回$name/$value對數組。
    * function setExtra($extra, $replace = false) 
這個函數也是比較有用的,用於設置form中除name,method,action之外其他的標記,$replace控制是否覆蓋原有$_extra,默認為將$extra添加到原有$_extra後面,返回新的$_extra內容
    * function &getExtra() 
此函數讀取form的$_Extra內容。
    * function setRequired(&$formElement) 
此函數將&$formElement指向的元素添加到form對象的必添數組$_required中.
    * function &getRequired() 
此函數返回form對象的必添元素數組$_required
    * function insertBreak($extra = null) 
這是個抽像函數,需要在子類定義中覆蓋
    * function display() 
此函數用於表單最後的渲染輸出。
    * function renderValidationJS( $withtags = true ) 
此函數用於Xoops表單內置校驗腳本的輸出,基本上不會用到。
    * function assign(&$tpl) 
此函數讓表單使用$tpl指向的smarty模板對象,來替代直接顯示輸出,或者說把現有的form對像傳遞到smarty模板中,由smarty完成最好的顯示輸出。
下面我們舉個簡單的例子來看看XoopsForm的基本使用流程
//第一步:包含XoopsForm的調用文件
include_once XOOPS_ROOT_PATH."/class/xoopsformloader.php";
//第二步:添加一個表單實例,這裡用的是比較常用的XoopsThemeForm,它採用一個table來安排表單佈局,如果我沒記錯,這個table的class=outer,也就是說你可以在css中更改outer的定義,美好表單的顯示。
$form = new XoopsThemeForm('標題', '名稱', 'action.php');
//第三步:加入文本元素,注意最後的true表示提交時檢查是否填寫了內容
$form->addElement(new XoopsFormText("姓名", 'name', 30, 70, $xoopsUser->name()), true);
//第四步:加入表單的提交按鈕
$form->addElement(new XoopsFormButton("", 'submit', "提交", 'submit'),0);
//第五步:加入驗證表單用的JavaScript腳本
$form->renderValidationJS();
//第六步:輸出表單
$form->display();
XOOPS源碼分析之--表單組件淺析(二)
也就是XoopsFormElement進行簡單分析,form中的checkbox,radio,等等組件都是對這個類的延展,所以弄清XoopsFormElement是如何定義的,將是又一個良好的開端。
表單元素的基類:XoopsFormElement (XOOPS_ROOT/class/xoopsform目錄下formelement.php)
1、XoopsElement對象的私有變量
    * $_name:元素名稱;
    * $_id :ID號;
    * $_caption:顯示標題;
    * $_accesskey:訪問此元素的快捷鍵;
    * $_class :元素的樣式 classl;
    * $_hidden:布爾值,定義是否為隱藏字段,默認為false;
    * $_extra :元素額外的定義;
    * $_required :布爾值,定義是否為必添字段,默認為false ;
    * $_description :元素描述。 
2、XoopsFormElement對象的成員函數
    * function XoopsFormElement() 
XoopsFormElemen對象的構造函數,其實什麼都沒定義,每種元素都有各自的定義。
    * function getCaption() | function setCaption()
    * function getName() | function setName()
    * function getID()| function setID()
    * function getAccessKey()| function setAccessKey()
    * function getDescription() | function setDescription()
    * function isHidden | function setHidden()
    * function getExtra() | function setExtra()
    * function getClass() | function setClass() 
這八組函數很容易理解,分別完成對caption,Name,id,AccessKey,Description等屬性的讀取(get)和設置(set).
    * function isContainer() 
這個函數非常簡單,就是返回false,告訴你這個元素不是一個容器。
    * function getAccessString( $str ) 
這個函數是會在$str字符串中尋找你定義的AccessKey,如果找到,就會將第一個找到的AccessKey字符底下畫線,說起來比較亂,大家打開軟件的文件菜單,你可以看到'新建(N)',對,就是這個意思。假定你設『N』是你的AccessKey,$str為'新建(N)',這個函數就負責返回給你'新建(N)',不知道我講明白了沒,呵呵。
    * function render() 
這個函數這裡講沒什麼意義,因為一行代碼都沒寫,
到這兒,XoopsFormElement對像講解就結束了,你肯定覺得這什麼都沒說啊,沒錯,我前面講了,這是個基類,也就搭個架子,具體的元素有各自的定義,基本上也就是在construct函數以及render函數上做文章,但也都是大同小異。
用法:(假定$form = new XoopsThemeForm('標題', '名稱', 'action.php');)
1. 直接引用form對像添加: $form->addElement(new 元素的構造函數, true/false); 2. 先定義元素,後添加到form對像中 $element=new 元素的構造函數; . -添加其他定義 . $form->addElement($element, true/false);
下面我們來看幾個常用的form元素的構造函數:
    * 單行文本字段: function XoopsFormText($caption, $name, $size, $maxlength, $value="", $id = "") 
參數含義依次為:標題,form中名稱,顯示寬度(單位為字符數),最大字符數,文本值,ID號。
    * 多行文本字段: function XoopsFormTextArea($caption, $name, $value="", $rows=5, $cols=50, $id = "") 
參數含義依次為:標題,form中名稱,文本值,顯示行數,顯示列數,ID號。
    * 文本標籤:function XoopsFormLabel($caption="", $value="") 
參數含義依次為:標題,值。
    * 選擇列表:function XoopsFormSelect($caption, $name, $value=null, $size=1, $multiple=false, $id="") 
參數含義依次為:標題,名稱,默認被選擇的值,顯示大小(如果為1,則顯示為下拉框,其他為N行的列表框),是否為多選,ID; XoopsFormSelect對像還有幾個非常重要的私有屬性,$_options和$_disabled(xoops2.2開始變為數組),其中$ _options是選項value->name對值數組,而$_disabled則定義有哪些不可以選,就是value數組, XoopsFormSelect對象可以參照用法2,使用函數addOptionArray($options, $disabled = array())來添加選項數組和非可選數組的2個定義。
    * 多選框:function XoopsFormCheckBox($caption, $name, $value = null, $id = "") 
參數含義依次為:標題,名稱,默認被選中的值數組,ID;同樣XoopsFormCheckBox也有$_options 屬性,為value->name 數組,也需要用addOptionArray($options)函數添加選項數組或是addOption($value, $name="")來添加一個選項。
    * 單選框:function XoopsFormRadio($caption, $name, $value = null, $id = "") 
XoopsFormRadio與XoopsFormCheckBox極為相似,所不同的是XoopsFormCheckBox的$value是數組,而XoopsFormRadio的則是一個值,添加選項的函數是完全一樣的。
    * 隱藏字段:function XoopsFormHidden($name, $value, $id="") 
參數含義依次為:名稱,默認值,ID,比較簡單
    * 密碼字段:function XoopsFormPassword($caption, $name, $size, $maxlength, $value="") 
參數含義依次為:標題,form中名稱,顯示寬度(單位為字符數),最大字符數,文本值;與單行文本字段在操作上沒有任何區別;
    * 安全令牌: function XoopsFormHiddenToken($name = 'XOOPS_TOKEN_REQUEST', $timeout = 0) 
這個字段應該不需要用到,如果你在創建form對像時,定義$addtoken=true,form對像會自己調用這個函數添加一個$name = 'XOOPS_TOKEN_REQUEST'的隱含字段。
    * 按鈕:function XoopsFormButton($caption, $name, $value="", $type="button", $id="") 
構造按鈕的5個參數含義依次是:顯示文字,form中的名字,按鈕的值,按鈕類型(buttion/submit/reset 3個值,默認為button),ID號;默認情況下按鈕的css 設定為「formButton」。
OK,到這兒,XoopsForm對象的常用元素就描述完了。
XoopsForm的這些元素如何使用
//第一步:包含XoopsForm的調用文件 include_once XOOPS_ROOT_PATH."/class/xoopsformloader.php";
//第二步:添加一個表單實例,這裡用的是比較常用的XoopsThemeForm,它採用一個table來安排表單佈局,如果我沒記錯,這個table的class=outer,也就是說你可以在css中更改outer的定義,美好表單的顯示。 $form = new XoopsThemeForm('更改用戶資料', 'changeUserInfo', 'action.php');
//3.1 加入標籤元素 $form->addElement(new XoopsFormLable("ID", "1033"), false);
//3.2 加入文本元素,注意最後的true表示提交時檢查是否填寫了內容 $form->addElement(new XoopsFormText("用戶名", 'username', 30, 70, $xoopsUser->name()), true);
//3.3 加入密碼元素,注意最後的true表示提交時檢查是否填寫了內容 $form->addElement(new XoopsFormPassword("更改密碼", 'newpassword', 30, 70, ""), true);
//3.4 加入多行文本元素,注意最後的true表示提交時檢查是否填寫了內容 $form->addElement(new XoopsFormTextArea("簽名", 'name', 30, 70, ""), true);
//3.5 加入多選字段元素,注意最後的true表示提交時檢查是否填寫了內容 $checkbox=new XoopsFormCheckBox("興趣", "intresting", null, $id = ""); $checkbox->addOption('0','讀書'); $checkbox->addOptions(array('1'->'繪畫','2'->'書法','3'->'音樂'); $checkbox->setValue(array('1','2')); //set 默認選中選項 $form->addElement($checkbox, true);
//3.6 加入單選字段元素,注意最後的true表示提交時檢查是否填寫了內容 $radio=new XoopsFormRadio("是否願意接收網站郵件", "receiveMail", 'y', $id = ""); $radio->addOptions(array('y'->'是','n'->'否'); $form->addElement($checkbox, true);
//3.7 加入select元素,注意最後的true表示提交時檢查是否填寫了內容 $countryOptions=array('0'->'請選擇您的國家','1'->'china','2'->'USA','3'->'France',4->'Other'); $disabled=array(1->'0'); $defaultCounty=; $countrySelect= new XoopsFormSelect('國家', 'CountryID',$defaultCounty, $size=1, $multiple=false); $countrySelect->addOptionArray($countryOptions,$disabled); $form->addElement($countrySelect, true);
//3.8 加入隱含字段 $form->addElement(new XoopsFormHidden("action", "modify"),false);
//第四步:加入表單的提交按鈕 $form->addElement(new XoopsFormButton(, 'submit', "提交", 'submit'),false);
//第五步:加入驗證表單用的JavaScript腳本 $form->renderValidationJS();
//第六步:輸出表單 $form->display();
表單物件列表
    * 引入表單物件會用到的檔案 
include_once XOOPS_ROOT_PATH."/class/xoopsformloader.php";
    * 新增一個表單物件實例,第一個參數是標題名稱,第二個參數是表單名稱,第三個參數是表單送出後執行的程式,第四個參數表單傳送方式。 
$form = new XoopsThemeForm("表單標題", 'form', "action.php", 'post', true);
//XoopsThemeForm( string $title, string $name, string $action, string $method = "post" ); 
    * 加入一個欄位 
$form->addElement(新增的實體欄位new XoopsFormXXX , 是否必填true or false );
    * 加入標籤 
$form->addElement(new XoopsFormLabel("標籤標題", "標籤值"));
//XoopsFormLabel($caption="", $value="");
    * 加入文字欄位 
$form->addElement(new XoopsFormText("文字欄位標題", "text_name", 35, 255, "預設值"));
//XoopsFormText( string $caption, string $name, int $size, int $maxlength, string $value = "" )
    * 加入隱藏欄位 
$form->addElement(new XoopsFormHidden('op', 'save'));
//XoopsFormHidden($name, $value);
    * 加入TOKEN REQUEST 
$form->addElement(new XoopsFormHiddenToken('XOOPS_TOKEN_REQUEST',360));
//XoopsFormHiddenToken($name = 'XOOPS_TOKEN_REQUEST', $timeout = 360);
    * 加入上傳欄位 
$form->setExtra("enctype='multipart/form-data'");
$form->addElement(new XoopsFormFile('上傳欄位標題', 'File_name', "2048")); 
    * 加入密碼欄位 
$form->addElement(new XoopsFormPassword('密碼欄位標題', 'Password_name', 20, 255, "1234"));
//XoopsFormPassword($caption, $name, $size, $maxlength, $value="");
    * 加入文字方塊 
$form->addElement(new XoopsFormTextArea("文字方塊標題", 'field_description', "預設值",5,50,));
//XoopsFormTextArea($caption, $name, $value="", $rows=5, $cols=50, $id = "");
    * 加入Dhtml編輯框 
$form->addElement(new XoopsFormDhtmlTextArea("編輯框標題", 'DhtmlTextArea_name', , 5, 50, "xoopsHiddenText"));
//XoopsFormDhtmlTextArea($caption, $name, $value, $rows=5, $cols=50, $hiddentext="xoopsHiddenText"); 
若想改成 TinyMCE
//$textarea = new XoopsFormDhtmlTextArea(_AM_CONTENT, 'bcontent', $block['content'], 15, 70);
if ( is_readable(XOOPS_ROOT_PATH . "/class/xoopseditor/tinymce/formtinymce.php")) {
    include_once(XOOPS_ROOT_PATH . "/class/xoopseditor/tinymce/formtinymce.php");
    $textarea = new XoopsFormTinymce(array('caption'=>_AM_CONTENT, 'name'=>'bcontent', 'value'=>$block['content'], 'width'=>'100%', 'height'=>'400px',  'xEditor'=>'1'));
}else{
    $textarea = new XoopsFormDhtmlTextArea(_AM_CONTENT, 'bcontent', $block['content'], 15, 70);
}
若想改成 FCKeditor
//$textarea = new XoopsFormDhtmlTextArea(_AM_CONTENT, 'bcontent', $block['content'], 15, 70);
if ( is_readable(XOOPS_ROOT_PATH . "/class/xoopseditor/fckeditor/formfckeditor.php")) {
    include_once(XOOPS_ROOT_PATH . "/class/xoopseditor/fckeditor/formfckeditor.php");
    $textarea = new XoopsFormFckeditor(array('caption'=>_AM_CONTENT, 'name'=>'bcontent', 'value'=>$block['content'], 'width'=>'100%', 'height'=>'400px',  'xEditor'=>'1'));
}else{
    $textarea = new XoopsFormDhtmlTextArea(_AM_CONTENT, 'bcontent', $block['content'], 15, 70);
}
若想改成 Koivi
//$textarea = new XoopsFormDhtmlTextArea(_AM_CONTENT, 'bcontent', $block['content'], 15, 70);
if ( is_readable(XOOPS_ROOT_PATH . "/class/xoopseditor/koivi/formwysiwygtextarea.php")) {
    include_once(XOOPS_ROOT_PATH . "/class/xoopseditor/koivi/formwysiwygtextarea.php");
    $textarea = new XoopsFormWysiwygTextArea(array('caption'=>_AM_CONTENT, 'name'=>'bcontent', 'value'=>$block['content'], 'width'=>'100%', 'height'=>'400px',  'xEditor'=>'1'));
}else{
    $textarea = new XoopsFormDhtmlTextArea(_AM_CONTENT, 'bcontent', $block['content'], 15, 70);
}
    * 加入送出與清除按鈕與同一欄 
$Tray1=new XoopsFormElementTray("按鈕標題", " ", "name", true);
$Tray1->addElement(new XoopsFormButton(, 'submit_name', "送出", 'submit'));
$Tray1->addElement(new XoopsFormButton(, 'reset_name', "清除", 'reset'));
$form->addElement($Tray1);
//XoopsFormButton(str $caption, str $name, bool $value="", button|submit|reset $type="button") 
    * 加入核取方塊 
//第一個參數為標題,第二個參數為表單欄位名稱,第三個參數可設定選取單一選項
$checkbox = new XoopsFormCheckBox('複選方塊標題', 'box_name', "k1","");
//XoopsFormCheckBox($caption, $name, $value = null, $id = "")
$checkbox->addOption("a1", "顯示值1");
//多重預設值設定
$def_arr=array("k1","k4");
$checkbox->setValue($def_arr);
$options["k2"]="顯示值2";
$options["k3"]="顯示值3";
$options["k4"]="顯示值4";
$checkbox->addOptionArray($options);
$form->addElement($checkbox); 
    * 加入單選鈕 
//第一個參數為標題,第二個參數為表單欄位名稱,第三個參數可設定預設選取選項
$Radio = new XoopsFormRadio('單選鈕標題', 'radio_name', "w1","");
$Radio->addOption("w1", "顯示值1");
$Roptions["w2"]="顯示值2";
$Roptions["w3"]="顯示值3";
$Roptions["w4"]="顯示值4";
$Radio->addOptionArray($Roptions);
$form->addElement($Radio);
    * 加入是否單選鈕 
第三個參數為預選值, "0" (No) 或 "1" (Yes)
$form->addElement(new XoopsFormRadioYN('是否單選鈕標題', 'radioYN_name', 1)); 
    * 加入下拉選單 
//參數一:標題、參數二:選單欄位名稱、參三:單一預設值,參四:選單長度,參五:是否多重
$select=new XoopsFormSelect("下拉選單標題", "select_name", "s2", 2, true);
//XoopsFormSelect($caption, $name, $value=null, $size=1, $multiple=false);
$select->addOption("s1", "顯示值1", true);
//addOption($value, $name="", $disabled = false) ;
$Soptions["s2"]="顯示值2";
$Soptions["s3"]="顯示值3";
$Soptions["s4"]="顯示值4";
$Soptions["s5"]="顯示值5";
$Soptions["s6"]="顯示值6";
$Soptions["s7"]="顯示值7";
$select->addOptionArray($Soptions);
//addOptionArray($options, $disabled=array());
//多重預選陣列
$sdef_arr=array("s6","s4");
$select->setValue($sdef_arr);
$form->addElement($select);
    * 加入文字日期欄位 
$form->addElement(new XoopsFormTextDateSelect('文字日期欄位標題', 'textDateSelect_name', 15, 0));
//XoopsFormTextDateSelect($caption, $name, $size = 15, $value= 0);
    * 加入日期時間 
$form->addElement(new XoopsFormDateTime("日期時間框標題", 'DateTime_name', 15, 0));
//XoopsFormDateTime( mixed $caption, mixed $name, mixed $size = 15, mixed $value = 0 );
範例
if ($_POST['op']=='save') {
  echo 'Will SAVE:
';
  echo "姓名:".$_POST['name'].'
';
  echo "電子郵件:".$_POST['email'].'
';
  $html=1;
  $smiley=1;
  $xcodes = 1;
  $myts =&MyTextSanitizer::getInstance();
  $message = $myts->displayTarea($_POST['message'],$html,$smiley,$xcodes);
  echo "訊息:".$message.'
';
} else {
  $contact_form=creat_form();
  echo $contact_form;
}
function  creat_form()  {
  //引入表單物件會用到的檔案
   include_once  XOOPS_ROOT_PATH."/class/xoopsformloader.php";
 //新增一個表單物件實例,第一個參數是標題名稱,第二個參數是表單名稱,第三個參數是表單送出後執行的程式
  $form  =  new  XoopsThemeForm('留下消息',  'contactform',  $_SERVER['PHP_SELF']);
  //加入一個文字列
  $form->addElement(new  XoopsFormText("姓名",  'name',  30,  70,  'test'),  true);
  //加入一個文字列
  $form->addElement(new  XoopsFormText("電子郵件",  'email',  40,  90,  'test@edu.tw'),  false);
  //加入一個文字方塊,第一個參數是標題名稱,第二個參數是表單名稱
  $form->addElement(new  XoopsFormDhtmlTextArea("訊息",  'message',  ,  12,  35),  true);
  //TOKEN
  $form->addElement(new XoopsFormHiddenToken('XOOPS_TOKEN_REQUEST',2));
  //Hidden
  $form->addElement(new XoopsFormHidden('op', 'save'));
  //加入送出表單的按鈕
  $form->addElement(new  XoopsFormButton('操作',  'submit',  "送出",  'submit'),0);
 //加入驗證表單用的JavaScript程式
  $form->renderValidationJS();
  return $form->render();
}
參考:http://163.30.191.22/wiki/index.php/XOOPS的表單設計
 
 
沒有留言:
張貼留言