10/10/2018, 09:44

[ASK] Datagrid nào Xịn nhất trong PHP

Dear All

Mình đang tìm một class chuyên trị datagrid (hiển thi records) trong PHP.
Chức năng tối thiểu như sau:
- Khai báo đơn giản (ví dụ chỉ cần gọi một Class, truyền mảng record, và xuất)
- Hỗ trợ phân trang, chọn số record trên một bảng (20/30/50...)
- Sort (càng tốt)
- Filter (càng tốt)

- ko bắt buộc hỗ trợ AJAX

- Kinh nghiệm các Pro thì datagrid nào dễ dùng? Minh thích loại chỉ cần một class. (nhiều module phức tạp lắm). Hoặc các Pro có link nào hay hay nhớ chi sẽ nhe.



[=========> Bổ sung bài viết <=========]

Đây là một Class mình đang dùng. Nhưng hiện tại mình cảm muốn mở rộng nên đã bỏ:

PHP Code:
<?php
class datagrid
{
var 
$sCssHeader "GridHeader";
var 
$sCssItem   "GridItem";
var 
$sCssTable  "GridTable"
var 
$sCssTaskBg ="TaskBg";
var 
$sCssTitleBg="gridtitle";
var 
$sGridWidth "100%";
var 
$iPageSize 20;
var 
$sFormName   ="frmList";
var 
$sPageLink   ""
var 
$***traActionLink  "";
var 
$***traActionName  "";
var 
$sDataKey;
var 
$sItemNameList;
var 
$aItemNameList;
var 
$sSQL;
var 
$sStatusName="Status";
var 
$sStatusKey="iStatus";
var 
$aStatus = array("Disable","Enable");
var 
$sQrstr="?";        


function 
datagrid($sSQL,$sItemNameList,$sPageLink,$iPageSize=20,$***traActionLink="",$***traActionName="")
   {                    
        
$this->sSQL $sSQL;
        
$this->sItemNameList $sItemNameList;
        
$this->sPageLink $sPageLink;
        
$this->iPageSize=$iPageSize;
        
$this->***traActionLink $***traActionLink;
        
$this->***traActionName $***traActionName;
        
$this->aItemNameList explode(",",$this->sItemNameList);
        
$this->sDataKey=strtolower($this->aItemNameList***91;0***93;);
        if(
strpos($this->sPageLink,"?")>0$this->sQrstr="&";
        
   }
function  
fShowGrid($iPage,$sTitle="")
   {                   
       global 
$objData;
       
$Result $objData->fExecQuery($this->sSQL);
       
$objPager = new pager($Result,$iPage,$this->iPageSize);
       
$sGridTitle="";
       if(
strlen($sTitle)>0)
       
$sGridTitle="
            <table width='
$this->sGridWidth' class=$this->sCssTable cellpadding=0 cellspacing=0>
            <tr>
            <td width=100% class='
$this->sCssTitleBg' align=center height=30>
            <strong>
$sTitle</strong>
            </td>
            </tr>
            </table>"
;

       
$sReturn=$sGridTitle.$this->fMakeButtonPager($objPager->fShowPager($this->sPageLink,"frmPager1"));
       
       
$sReturn.="
       <table border=0 width=
$this->sGridWidth class=$this->sCssTable cellpadding=0 cellspacing=1>
       <form name='
$this->sFormName' method=post>
       "
.$this->fMakeHeader();  
       
       
$i=0;
       while((
$aRow=mysql_fetch_array($Result))and($i<$this->iPageSize))
            {
                
$sReturn .= $this->fMakeItem($aRow);
                
$i++;
            }
        
$sReturn.="</form></table>".$this->fMakeButtonPager($objPager->fShowPager($this->sPageLink)).$this->fCreateJSFunction();    

        return 
$sReturn;
   }
   
function 
fMakeItem($aData)
   {
        
$sReturn="<tr class=GridItem><td>&nbsp;&nbsp;<input type=checkbox name='chkSelect***91;***93;' value=$aData***91;0***93;></td>";
        
$iLen=count($this->aItemNameList);
        for(
$i=1$i<=$iLen$i++)
            {
               
$sReturn.="<td>&nbsp;&nbsp;$aData***91;$i***93;</td>";
            }
        
$***traAction "";    
        if(
strlen($this->***traActionLink)>0)
        
$***traAction ="&nbsp;&nbsp; | &nbsp;&nbsp;<a href='$this->***traActionLink$aData***91;0***93;'>$this->***traActionName</a>";    
        
$sReturn.="<td>&nbsp;&nbsp;".$this->aStatus***91;$aData***91;$this->sStatusKey***93;***93;."</td><td>&nbsp;&nbsp;<a href='$this->sPageLink".$this->sQrstr."action=edit&ID=$aData***91;0***93;'>Edit</a>$***traAction</td></tr>";
        return 
$sReturn;    
   }    
   
function 
fMakeHeader()
   {
        
$aData=explode(",",$this->sItemNameList);
        
$sReturn="<tr class=GridHeader><td>&nbsp;&nbsp;<input type=checkbox name='chkSelectAll' onclick='checkme()'></td>";
        for(
$i=0$i<count($aData); $i++)
            {
               
$sReturn.="<td>&nbsp;&nbsp;".$aData***91;$i***93;."</td>";
            }
        
$sReturn.="<td>$this->sStatusName</td><td>&nbsp;&nbsp;Action</td></tr>";
        return 
$sReturn;    
   }     
   
 function 
fMakeButtonPager($sPager="",$iShowOrderButton=0)
   {
      global 
$aLang;
      
$sOrderButton="";
      if(
$iShowOrderButton)
         
$sOrderButton="<input type='button' value='$aLang***91;Form_UpdateOrder***93;' onclick='submit_form(5)'>";
      
$sReturn.="              
      <table width='
$this->sGridWidth' class=$this->sCssTable cellpadding=0 cellspacing=1>
      <tr>
         <td width=100% class='
$this->sCssTaskBg'>
            <table width=98% >
                <tr>
                    <td width=50%>
                        &nbsp;&nbsp;
                        <input type='button' value='
$aLang***91;Form_Add***93;' onclick='submit_form(1)'>
                        <input type='button' value='
$aLang***91;Form_Delete***93;' onclick='submit_form(2)'>
                        <input type='button' value='
$aLang***91;Form_Enable***93;' onclick='submit_form(3)'>
                        <input type='button' value='
$aLang***91;Form_Disable***93;' onclick='submit_form(4)'>
        
                    </td>
                    <td width=50% align=right>"
.$sPager."</td>
                </tr>
            </table>
         </td>
      </tr>  
      </table>"
;
      return 
$sReturn;
     
   }  
   
 function 
fCreateJSFunction()
    {
       global 
$aLang;
       
$sDeleteAlert=str_replace("{0}",$this->sDataKey,$aLang***91;'Form_DeleteAlert'***93;);
       
$sEnableAlert=str_replace("{0}",$this->sDataKey,$aLang***91;'Form_EnableAlert'***93;);
       
$sDisableAlert=str_replace("{0}",$this->sDataKey,$aLang***91;'Form_DisableAlert'***93;);
       
       
$sReturn "<script language='Javascript'>
     function checkme()
       {
          isCheck=document.
$this->sFormName.chkSelectAll.checked;
          elts=document.
$this->sFormName.elements***91;'chkSelect***91;***93;'***93;;
          //alert(isCheck);
          if(isCheck)
             {
                for(i=0;i<elts.length;i++)
                   elts***91;i***93;.checked=true;
             }
          else
             {
                for(i=0;i<elts.length;i++)
                   elts***91;i***93;.checked=false;
             }
       }
     function submit_form(kind)

       {
           if(kind==1)
              {
                       document.
$this->sFormName.action="$this->sPageLink".$this->sQrstr."action=add";
                       document.
$this->sFormName.submit();
                    
              }
            else if(kind==5)
              {
                       document.
$this->sFormName.action="$this->sPageLink".$this->sQrstr."action=order";
                       document.
$this->sFormName.submit();
                    
              }
            else if(!isSelected())
              {
                 alert("
$aLang***91;Form_PleaseSelect***93; $this->sDataKey!");
              }
           else if(kind==2)
              {
                 if(confirm("
$sDeleteAlert"))
                    {
                       document.
$this->sFormName.action="$this->sPageLink".$this->sQrstr."action=delete";
                       document.
$this->sFormName.submit();
                    }
              }
           else if(kind==3)
              {
                 if(confirm("
$sEnableAlert"))
                    {
                       document.
$this->sFormName.action="$this->sPageLink".$this->sQrstr."action=enable";
                       document.
$this->sFormName.submit();
                    }
              }
           else if(kind==4)
              {
                 if(confirm("
$sDisableAlert"))
                    {
                       document.
$this->sFormName.action="$this->sPageLink".$this->sQrstr."action=disable";
                       document.
$this->sFormName.submit();
                    }
              }
       }
     function isSelected()
     {
         t=false;
         elts=document.
$this->sFormName.elements***91;'chkSelect***91;***93;'***93;;
         if(elts.length==null)
             {
               t=elts.checked;
             }
         i=0;
         while((!t)&&(i<elts.length))
           {
              t=elts***91;i***93;.checked;
              i++;
           }
         return t;
     }
     </script>"
;
     return 
$sReturn;
    }       
function  
fShowGridCat()
   {
    global 
$objData;
    
$sReturn="".$this->fMakeButtonPager("",1);
    
$sReturn.="<table border=0 width=$this->sGridWidth class=$this->sCssTable cellpadding=0 cellspacing=1>
    <form name='
$this->sFormName' method=post>
    "
.$this->fMakeCatHeader();  
    
$this->fMakeListCatItem(0,$sReturn);
    
$sReturn.=$this->fMakeButtonPager("",1).$this->fCreateJSFunction();    
    return 
$sReturn;
   }
   
    
function 
fMakeListCatItem($iParentID,&$sReturn)
    {
    global 
$objData;
    
$sSQL "Select * from product_category where iParentID=$iParentID order by iOrder";
    
$Result $objData->fExecQuery($sSQL);
    if(
$Result)
    {
    while(
$aRow=mysql_fetch_array($Result))
        {
        
$sIndent str_repeat('--',$aRow***91;'iLevel'***93;*2);
        
$sReturn .= $this->fMakeCatItem($aRow***91;'iCatgoryID'***93;,$aRow***91;'sCategory'***93;,$aRow***91;'iOrder'***93;,$aRow***91;'iStatus'***93;,$sIndent);
        
$this->fMakeListCatItem($aRow***91;'iParentID'***93;, $sReturn);
        }
    }
}
    
    
function 
fMakeCatItem($iCategoryID,$sCategory,$iOrder,$iStatus,$sIndent)
{
    
$sReturn="<tr class=GridItem><td>&nbsp;&nbsp;<input type=checkbox name='chkSelect***91;***93;' value=$iCategoryID></td>
    <td>&nbsp;&nbsp;
$sIndent$sCategory</td>
    <td>&nbsp;&nbsp;<input type=textbox name='txtOrder***91;***93;' value=
$iOrder size=2></td>
    <td>&nbsp;&nbsp;"
.$this->aStatus***91;$iStatus***93;."</td><td>&nbsp;&nbsp;<a href='$this->sPageLink?action=edit&ID=$iCategoryID'>Edit</a></td></tr>";
    return 
$sReturn;
}    
   
function 
fMakeCatHeader()
   {
    
$sReturn="
        <tr class=GridHeader><td>&nbsp;&nbsp;<input type=checkbox name='chkSelectAll' onclick='checkme()'></td>
        <td>&nbsp;&nbsp;Category</td>
        <td>&nbsp;&nbsp;Order</td>
        <td>&nbsp;&nbsp;Status</td>
        <td>&nbsp;&nbsp;Action</td></tr>
        "
;
    return 
$sReturn;
   }        

}
?>


Gọi:
PHP Code:
<?PHP
$sSQL
="select iAboutID,sAboutName,iStatus 
from about"
;

$objGrid=new DataGrid($sSQL,"Hello, I'am datagird","about.php",15);
echo 
$objGrid->fShowGrid($page);
}
?>
Kết quả tương tự như sau:
[IMG]
3do viết 11:49 ngày 10/10/2018
nếu bạn dùng symfony thì tôi có thể giới thiệu cho bạn sfDoctrinePager và sfPropelPager
vuatintac viết 12:01 ngày 10/10/2018
nhưng ko sao cả Hai bác ơi!
sao cũng được cả. Nếu có sẵn, hay, thì mình dùng (Đỡ tốn time).
Nếu có rồi nhưng chưa phù hợp thì edit lại.
Miễn là hoàn tất công việc thôi

thank hai bác.



[=========> Bổ sung bài viết <=========]

Được gửi bởi 3do
nếu bạn dùng symfony thì tôi có thể giới thiệu cho bạn sfDoctrinePager và sfPropelPager
Tiếc là mình ko dùng symfony Framework.
vuatintac viết 11:57 ngày 10/10/2018
Các bác pó tay hết rồi sao
LTQ viết 12:00 ngày 10/10/2018
Mình có viết 1 cái tương tự như bạn, nhưng không tìm ngay cho bạn được . Mình cũng thích tự viết . Mình góp ý với bạn chút về cái DG của bạn :

Về tiêu chí :
- Giảm tối đa số lượng tham số , hàm
- Tăng tối đa khả năng linh động của DG
Vì thế :
- Bạn bên bỏ hết CSS ở trên đi . Chỉ cần 1 cái CSS chung cho toàn bộ DG thôi, khi nào dùng ta muốn xây dựng CSS mới thì người dùng phải xây dựng theo cấu trúc như css của mình (bao hồm CSS cho header, cho các ITem ...)

- Không nên truyền vào một chuỗi SQL như trên . Thay vào đó là truyền vào dữ liệu dạng resourrce . Mình chạy câu truy vấn ở ngoài rồi gán kết quả vào như vậy hay hơn. Nó giống như gán DataSet cho thuộc tính DataSource trong .Net

- Mình có thể tùy biến trật tự các cột khi hiển thị bằng 1 thuộc tính , thuộc tính đó là 1 mảng các tên cột được xắp theo thứ tự mình muốn
- Cái DataGrid này bị cứng nhắc trong vấn đề xử lý . Mình chưa mô tả ra đây được, hôm khác mình sẽ up cái của mình lên
Bài liên quan
0