2017-04-03 28 views
2

我想與SilverStripe中的DataLists不同。目標是以這種格式返回按狀態排序的商店列表。SilverStripe - 過濾DataList結果,以刪除重複項和值組

有已經創建了管理員模式叫StoreLocation.php其中包含了存儲數據:

class StoreLocation extends DataObject { 

    private static $db = array(
     'Address' => 'Varchar(250)', 
     'City'  => 'varchar(100)', 
     'State'  => 'varchar(2)', 
     'Zip'  => 'varchar(10)' 
    ); 

    private static $has_one = array(
     'Store' => 'Store' 
    ); 

    private static $summary_fields = array(
     'getStoreSummaryLabel' => 'Store Info' 
    ); 

    private static $field_labels = array(
     'Address', 
     'City', 
     'State', 
     'Zip' 
    ); 

    public function getStoreSummaryLabel() { 
     $storeName = $this->Store()->Name; 
     return sprintf("%s (%s)", $storeName, $this->addressPretty()); 
    } 

    // tidy up the CMS by not showing these fields 
    public function getCMSFields() { 
     $fields = parent::getCMSFields(); 

     $siteConfig = SiteConfig::current_site_config(); 

     $statesDropdown = DropdownField::create("State", "State", $siteConfig->stateList()) 
      ->setEmptyString('Select State'); 

     if ($siteConfig->GoogleAPIKey == "") { 
      $fields->addFieldToTab("Root.Main", new HeaderField("error","Error: No Google API Key Defined!",2)); 
     } 

     $fields->removeFieldsFromTab('Root.Main', [ 
      'State', 
     ]); 

     return $fields; 
    } 

    public function addressPretty() { 
     return sprintf("%s %s, %s %s", $this->data()->Address, $this->data()->City, $this->data()->State, $this->data()->Zip); 
    } 
} 

StoreDataObject這是由StoreLocation引用:

class Store extends DataObject { 
    private static $db = array(
     'Name' => 'Varchar(100)' 
    ); 

    private static $has_one = array(
     'Logo' => 'Image' 
    ); 

    private static $has_many = array(
     'Locations' => 'StoreLocation' 
    ); 

    private static $summary_fields = array(
     'Name' => 'Name' 
    ); 

    private static $field_labels = array(
     'Name', 
     'Logo' 
    ); 

    // tidy up the CMS by not showing these fields 
    public function getCMSFields() { 
     $fields = parent::getCMSFields(); 
     return $fields; 
    } 

    static $default_sort = "Name ASC"; 
} 

的問題是我需要按狀態返回商店列表,但由於我沒有顯示商店地址,因此刪除了任何重複的商店名稱。我只需要顯示名字(我不知道爲什麼,這就是它的樣子)。因此,例如,阿拉巴馬州的商店ABC可能有5個結果,因爲它有5個位置,但我只想爲阿拉巴馬州返回商店ABC一次。

簡單地返回StoreLocation數據的格式列表返回正確的結果,但與噸重複的和國家的名稱即各店重複上面:

更新:我發現了一個可能的解決方案發現此鏈接包含後自定義嵌套分組列表類文件:https://www.silverstripe.org/community/forums/general-questions/show/24195

通過使用這個類的,我能夠做出GroupedList中,我可以通過一個數據對象的2個不同的方面進行排序:

public function GroupedEntries() { 
    return NestedGroupedList::create(
     StoreLocation::get()->sort('State ASC, StoreID ASC') 
    ); 
} 

然後,在模板中,我成立了這一點:

<div class="col-md-12" style="padding-bottom:40px;"> 
    <div class="retailer-listing" style="text-align: left;"> 
     <% loop $GroupedEntries.GroupedBy('State,StoreID') %> 
      <strong>$State</strong><br /> 
       <% loop $Children %> 
         <% loop $Children.First %> 
          $Store.Name<br /> 
         <% end_loop %> 
       <% end_loop %> 
     <% end_loop %> 
    </div> 
</div> 

這似乎是返回結果的正確的組織,由國家按字母順序排序各商店名稱的第一個實例。它花了一些猜測和檢查測試,直到我得到正確的循環。

+1

請分享'getAllRetailersByState'函數的內容 –

+0

目前,這是我在我的帖子的底部:$ counter = GroupedList :: created(StoreLocation :: get()) - > GroupedBy('State') –

回答

1

我找到了解決辦法發現這個鏈接,包含自定義嵌套分組列表類文件後:https://www.silverstripe.org/community/forums/general-questions/show/24195

通過使用這個類的,我能夠做出GroupedList中,我可以通過2個不同的方面進行排序一個數據對象:

public function GroupedEntries() { 
    return NestedGroupedList::create(
     StoreLocation::get()->sort('State ASC, StoreID ASC') 
    ); 
} 

然後,在模板中,我成立了這一點:

<div class="col-md-12" style="padding-bottom:40px;"> 
     <div class="retailer-listing" style="text-align: left;"> 
      <% loop $GroupedEntries.GroupedBy('State,StoreID') %> 
       <strong>$State</strong><br /> 
        <% loop $Children %> 
          <% loop $Children.First %> 
           $Store.Name<br /> 
          <% end_loop %> 
        <% end_loop %> 
      <% end_loop %> 
     </div> 
    </div> 

這似乎是回到了正確的organiz結果,按狀態按字母順序排列每個商店名稱的第一個實例。它花了一些猜測和檢查測試,直到我得到正確的循環。

1

首先,我們創建一個函數來在我們的頁面控制器返回StoreLocationGroupedList一個項目:

public function getGroupedStoreLocations() { 
    return GroupedList::create(StoreLocation::get()->sort('State')); 
} 

在我們的頁面模板中,我們再對我們的GroupedStoreLocations功能列表中通過調用GroupedBy(State)到組。這會返回包含索引(階段名稱)的組項的ArrayList以及屬於該組的子項列表。我們的內部循環GroupedStoreLocations我們可以遍歷$Children要經過的每個項目在GroupedList:在GroupedList Documentation

<% loop $GroupedStoreLocations.GroupedBy(State) %> 
    <h4>$State</h4> 
    <ul> 
    <% loop $Children %> 
     <li>$Store.Name</li> 
    <% end_loop %> 
    </ul> 
<% end_loop %> 

查看更多信息。

+0

這與我所需要的非常接近,但一個問題是$ Children循環返回與某個狀態關聯的每個商店的名稱 - 這意味着會發生重複,因爲在一個狀態中可能存在多個商店位置(即在俄亥俄州可能有一噸沃爾格林和一堆Walmarts)。 –

+0

我會研究它,看看我們能做些什麼。 – 3dgoo

+0

我想我可能有一些東西。我希望明天在這裏發佈。這不是有史以來最偉大的事情,但它似乎工作。 –