簡體   English   中英

創建DataObject以在SilverStripe中構建表行和列

[英]Create a DataObject to build table rows and columns in SilverStripe

我正在嘗試為SilverStripe站點做一些非常不同的事情:在幾個子頁面上是數據表,這些表每個都有自己的列標題集,有些表的列比其他表多。 我想避免在富文本編輯器中構建表格,因為這容易出現很多錯誤,並且隨着時間的推移維護是一件麻煩事。

我想要做的是創建一個DataObject,它允許第n個列和第n個相應的行。 這樣我可以在模板中調用一個循環(或可能是兩個),我已經有了HTML表結構。 內容管理員可以完全控制任何給定子頁面的表格中的哪些列,並且他們不必擔心維護HTML表格設置。

我有一些想法沒有產生我想要的結果,沒有a)使內容管理器的UI體驗過於復雜,b)無法正確地將列與行鏈接。

我曾想過為Table Headers創建一個DataObject,為Table Rows創建一個DataObject,但后來我很難理解如何以一種有意義的方式組合它們,特別是因為可能有任意數量的列。

有人會有任何建議來接近這個嗎?

更新:好的,我有一些可用的TableRowItem數據對象,並且接近工作。 但是,現在的問題是:當我基本上即時創建它們時,如何將字段值保存到數據庫? 就像現在一樣,保存到數據庫的唯一字段是PDF文件上載字段,其他所有內容在點擊“創建”時都會被刪除。

<?php

class TruckBodyPdfTableRowItem extends DataObject {

    private static $db = array(
    );

    // One-to-one relationship with gallery page
    private static $has_one = array(
        'TablePage'=> 'Page',
        'TableColumnSet' => 'TableColumnSet',
        'PDF' => 'File',
    );


    // tidy up the CMS by not showing these fields
    public function getCMSFields() {
        $fields = parent::getCMSFields();
        $fields->removeFieldFromTab("Root.Main","TablePageID");
        $fields->removeFieldFromTab("Root.Main","TableColumnSetID");
        $fields->removeFieldFromTab("Root.Main","SortOrder");
        $fields->addFieldsToTab("Root.Main", $this->getMyColumnOptions());

        return $fields;
    }
    public function getMyColumnOptions()
    {
        $columnArray = [];
        $Columns = DataObject::get('TableColumnSet');

        foreach($Columns as $Column){
          $columnArray[] = TextField::create($Column->TableColumnHeader);
        }

        return $columnArray;
    }

    // Tell the datagrid what fields to show in the table
    private static $summary_fields = array(
    );

    public function canEdit() {
        return true;
    }

    public function canDelete() {
        return true;
    }

    public function canCreate(){
        return true;
    }

    public function canPublish(){
        return true;
    }

    public function canView(){
        return true;
    }
}

但這些是棘手的部分:弄清楚如何將值從一個DataObject映射到另一個DataObject的標簽,然后根據已創建的列數自動生成第n行。

<?php

class TablePage extends Page
{
    private static $db = array(
        'H1' => 'varchar(250)',
    );

    private static $has_many = array(
        'TableRowItems' => 'TableRowItem',
        'TableColumnSets' => 'TableColumnSet'
    );

    private static $has_one = array(

    );

    public function getCMSFields()
    {
        $fields = parent::getCMSFields();

        $fields->addFieldToTab("Root.Main", new TextField("H1"), "Content");

        $gridFieldConfig = GridFieldConfig_RecordEditor::create();

        $gridFieldConfig->getComponentByType('GridFieldDataColumns')->setDisplayFields(array(
            // field from drawer class => label in UI
            'TableColumnHeader' => 'Table Column Header'
        ));

        $gridfield = new GridField(
            "TableColumnSets",
            "Table Column Sets",
            $this->TableColumnSets(),
            $gridFieldConfig
        );

        $fields->addFieldToTab('Root.Specs Table', $gridfield);




        $gridFieldConfig2 = GridFieldConfig_RecordEditor::create();

        $gridFieldConfig2->getComponentByType('GridFieldDataColumns')->setDisplayFields(array(
            // field from drawer class => label in UI
            'TableRowValue' => 'Table Row Value'
        ));

        $gridfield2 = new GridField(
            "TableRowItems",
            "Table Row Items",
            $this->TableRowItems(),
            $gridFieldConfig2
        );
        $fields->addFieldToTab('Root.Specs Table', $gridfield2);



        return $fields;
    }
}

class TablePage_Controller extends Page_Controller
{
    private static $allowed_actions = array(

    );

    public function init()
    {
        parent::init();
        // You can include any CSS or JS required by your project here.
        // See: http://doc.silverstripe.org/framework/en/reference/requirements
    }
}

這是TableColumnSet和TableRowValue類。 我想,會有一組列標題與第n行相關聯,所以我認為兩個類之間會有一個$has_many關系,因為TableColumnSet可能有很多TableRowValues,但只有一個TableColumnSet對於所有TableRowValues。 我希望使用帶有所有列標題的下拉列表將TableRowValues與TableColumnSet值相關聯,但這聽起來不錯。 必須手動將一行中的每個字段與列標題相關聯,這似乎是單調且可能很困難的內容管理器。

<?php

class TableColumnSet extends DataObject {

    private static $db = array(
        'SortOrder' => 'Int',
        'TableColumnHeader'=>'varchar(250)'
    );

    // One-to-one relationship with gallery page
    private static $has_one = array(
        'TablePage'=> 'Page'
    );

    private static $has_many = array(
        'TableRowItems' => 'TableRowItem'
    );

    // tidy up the CMS by not showing these fields
    public function getCMSFields() {
        $fields = parent::getCMSFields();
        $fields->removeFieldFromTab("Root.Main","TablePageID");

        $fields->removeFieldFromTab("Root.Main","SortOrder");

        return $fields;
    }

    // Tell the datagrid what fields to show in the table
    private static $summary_fields = array(
        'TableColumnHeader' => 'Table Column Header',
    );

    public function canEdit() {
        return true;
    }

    public function canDelete() {
        return true;
    }

    public function canCreate(){
        return true;
    }

    public function canPublish(){
        return true;
    }

    public function canView(){
        return true;
    }
}

我覺得可能會在這里做點什么,至少在列標題和行之間的關系方面? 不過我不確定。

我可能不在這里,因為我沒有使用SilverStripe的經驗。 但是......我的PHP / HTML表解決方案可能適用於此:

<?php

// parse your table data into this structure
$tableData = array(
    "rowOne" => array(
        "columnName" => "columnValue1",
        "colName" => "colValue1"
        // .....
    ),
    "rowTwo" => array(
        "columnName" => "columnValue2",
        "colName" => "colValue2"
        // .....
    )
);

// now loop through the array with a printHeader parameter
$tableHTML = array(
    "<table>"
);
$tableHead = array(
    "<thead>"
);
$tableBody = array(
    "<tbody>"
);
$printHeader = true;

foreach ($tableData as $row) {
    foreach ($row as $column => $value) {
        $tableRow = "<tr>";
        if ($printHeader) {
            $tableHead[] = "<th>".$column."</th>";
        }
        $tableRow .= "<td>".$value."</td>";
    }
    $tableBody[] = $tableRow."</tr>";
    // after the first row, set printHeader to false and close the <thead>
    $printHeader = false;
    $tableHead[] = "</thead>";
}

 // implode table header to string with linebreaks
$tableHead = implode(PHP_EOL, $tableHead);

// close table <tbody> & implode to string with linebreaks
$tableBody[] = "</tbody>";
$tableBody = implode(PHP_EOL, $tableBody);

// add all table elements together
$tableHTML[] = $tableHead;
$tableHTML[] = $tableBody;
$tableHTML[] = "</table>";
// implode table array to string
$tableHTML = implode(PHP_EOL, $tableHTML);

// print or write anywhere
echo($tableHTML);

?>

循環中所有步驟的數組結構是使默認服務器內存更清晰,以刪除舊數據。 如果你將所有引用連接起來( $var .= "string"; )作為字符串,所有引用將保留在內存中,並在顯示大表時陷入服務器。 我希望這有一些幫助

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM