Jump to:

23459 Posts in 18906 Topics by 2877 members

General Questions

SilverStripe Forums » General Questions » How to populate a <select> from a DataObjectSet without the duplicates

General questions about getting started with SilverStripe that don't fit in any of the categories above.

Moderators: martimiz, Sean, biapar, Willr, Ingo, swaiba, simon_w

Page: 1
Go to End
Author Topic: 1480 Views
  • lise
    Avatar
    Community Member
    47 Posts

    How to populate a <select> from a DataObjectSet without the duplicates Link to this post

    This is a very simplified/childish version of my data structure and code so I can better explain the problem.

    Let's assume a a Dataobject

    class Customers extends DataObject {
    static $db = array(
    'Name' => 'Text',
    'Country' => 'Text'
    );

    In a template reports.ss , I would like to have a dropdown field (<select>) populated with all the "Country" existing
    in the "Customers" dataObject. The trick is that I would like to ignore/delete the duplicates and ,if possible, to have
    the list sorted.

    My idea was to create a function (get_unique_country() )which returns a ObjectDataSet which I can use in a control block :

    <% control get_unique_country %>
    <option value=$Country>$country</option>
    <% end_control %>

    The problem is that I can't find a way to create a DataObject with no duplicate . However I found in the book (page 205-206) a
    way to create an array containing unique values of countries :

    I would have a function

    function get_unique_country(){
    $myentries = DataObject::get('Customers');
    if(!$myentries) return array();
    $countryList = array_unique($myentries->column('country'));
    sort($countryList);
    return $countryList;
    }

    The problem is that it returns an array not a DataObject . How can I use an array into a <% control %> block?

    What is the best SS-way to achieve what I want?

    Any hints would be very appreciated.
    Thanks!

    Lise

  • Willr
    Avatar
    Forum Moderator
    5497 Posts

    Re: How to populate a <select> from a DataObjectSet without the duplicates Link to this post

    You can use the sort parameter on the dataobject get all and the removeDuplicates() functions which you can call on a DataObjectSet.

    Sadly to use the removeDuplicates() function like removeDuplicates('Country') you have to be using branches/2.4 and a relatively recent checkout of that too. Before you could only removeDuplicates() on ID. But if your running 2.4 then its a piece of cake

    function getUniqueCountries() {

    $countries = DataObject::get('Country', '', 'Country ASC');
    if(!$countries) return false;

    $countries->removeDuplicates('Country');

    return $countries;
    }

    However if your running 2.3 a number of ways you could get round that. Having a quick look - there is a function GroupedBy() which you can group a set by any column so perhaps try this if your on 2.3

    function getUniqueCountries() {

    $countries = DataObject::get('Country', '', 'Country ASC');
    if(!$countries) return false;

    $countryArray = $countries->groupBy('Country');

    return new ArrayData($countryArray);
    }

  • lise
    Avatar
    Community Member
    47 Posts

    Re: How to populate a <select> from a DataObjectSet without the duplicates Link to this post

    Thank you very much Willr.
    I didn't know about the "GroupedBy" function. This is exactly what I needed.

    However I want to mention for those who read this thread that the code you sent didn't exactly work :
    Instead of using 'groupBy' , I had to use 'GroupedBy' which returns an DataObjectSet so it is even easier.
    You mentioned correctly "GroupedBy" in your response but used "groupBy" in your example. Actually I don't quite understand why
    "groupBy" doesn't work ...

    Also thank you very much for the info about 2.4. I will keep it in mind. It looks pretty cool.
    Below is the code which works for me on 2.3 .

    Thanks - Lise
    -------------------------------------------------------------------------------------------------
    function getUniqueCountries() {

    $countries = DataObject::get('Country', '', 'Country ASC');
    if(!$countries) return false;

    $countrySet = $countries->GroupedBy('Country');

    return $countrySet;
    }
    --------------------------------------------------------------------------------------------------------

  • Sean
    Avatar
    Forum Moderator
    921 Posts

    Re: How to populate a <select> from a DataObjectSet without the duplicates Link to this post

    I believe the following code may be more efficient, as you don't have to do any post-processing of the result in PHP. It's all done in the database using "SELECT DISTINCT".

    If you need more columns to be selected, just add them in the select clause. At the moment, I have only selected the bare minimum, which is the ClassName enumeration column, and the Country column.

    function getUniqueCountries() {
       $result = DB::query('SELECT DISTINCT ClassName, Country FROM Country ORDER BY Country ASC');
       return singleton('Country')->buildDataObjectSet($result);
    }

    Sean

  • lise
    Avatar
    Community Member
    47 Posts

    Re: How to populate a <select> from a DataObjectSet without the duplicates Link to this post

    Thank you Sean. This works also very well for me.

    And for those who (like me) are not too familiar with raw sql, I suggest to look at the tutorial:
    http://doc.silverstripe.org/doku.php?id=SQLquery

    1480 Views
Page: 1
Go to Top

Want to know more about the company that brought you SilverStripe? Then check out SilverStripe.com

Comments on this website? Please give feedback.