Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Display multiple columns in Select2

I'm using select2 and I'd like to show a multicolum table as a drop down, so I need the width of the drop down container to have a different (larger) width than the input itself

Is it possible to do that?

moreover I'd like to show a table with several columns. From the movies example, I saw that in the formatResult function you create a new table for each row.

Would it be possible to include every row in the same table, so that every cells has the same width? I would need to set some template to contain the rows or something like that.

What I want to achieve is a small input to show the code of an entity, and a large dropdown to show several more columns

--

here's a related issue on github: https://github.com/ivaynberg/select2/issues/1314

like image 891
opensas Avatar asked May 15 '13 03:05

opensas


2 Answers

formatresult didn't work for me ! But templateResult works fine like this with data form PHP in HTML generated (not ajax content).

Here is woorking code for me, I seperate my columns by a pipe char (we could have more than 2 columns) :

html (from PHP) :

<option value="...">
    column 1 text | column 2 text
</option>

javascript (jQuery) :

$('#selectSubstance').select2({
    templateResult: function(data) {
        var r = data.text.split('|');
        var $result = $(
            '<div class="row">' +
                '<div class="col-md-3">' + r[0] + '</div>' +
                '<div class="col-md-9">' + r[1] + '</div>' +
            '</div>'
        );
        return $result;
    }
}); 

EDIT 2021-06-28

If you want the same visual for selected item (closed select), use the same syntax with templateSelection:

For example :

$('#selectProduct').select2({            
    placeholder: 'Choose a product.',
    templateResult: function(data) {
        var r = data.text.split('| ');
        var result = jQuery(
            '<div class="row">' +
                '<div class="col-md-3">' + r[0] + '</div>' +
                '<div class="col-md-9">' + r[1] + '</div>' +
            '</div>'
        );
        return result;
    },
    templateSelection: function(data) {
        var r = data.text.split('| ');
        var result = jQuery(
            '<div class="row">' +
                '<div class="col-md-3">' + r[0] + '</div>' +
                '<div class="col-md-9">' + r[1] + '</div>' +
            '</div>'
        );
        return result;
    }
});
like image 185
Meloman Avatar answered Sep 18 '22 07:09

Meloman


I wanted to give my solution which will hopefully help others.

Using Select2 v4 tableish styling and multicolumn search. This uses local JSON data.

Quick overview of how this works:

There are 2 functions. The matcher function and the formatSelect.

The matcher function is used for the query. It will check each word of the query to see if there is a match in any of the rows. Currently set to return any row that matches atleaast 1 word.

The formatSelect function is then run once the matcher has returned all matching rows (all rows if no query). formatSelect adds header columns on the first row of data if its the first row being rendered.

The table in this case uses bootstrap column widths for structure.

The code:

var firstEmptySelect = true;

function formatSelect(result) {
    if (!result.id) {
        if (firstEmptySelect) {
            console.log('showing row');
            firstEmptySelect = false;
            return '<div class="row">' +
                    '<div class="col-xs-3"><b>Client</b></div>' +
                    '<div class="col-xs-3"><b>Account</b></div>' +
                    '<div class="col-xs-3"><b>Deal</b></div>' +
                    '</div>';
        } else {
            console.log('skipping row');
            return false;
        }
        console.log('result');
        console.log(result);
    }
    return '<div class="row">' +
                 '<div class="col-xs-3">' + result.client_name + '</div>' +
                 '<div class="col-xs-3">' + result.account_name + '</div>' +
                 '<div class="col-xs-3">' + result.deal_name + '</div>' +
                 '</div>';      
}

function matcher(query, option) {
    firstEmptySelect = true;
    if (!query.term) {
        return option;
    }
    var has = true;
    var words = query.term.toUpperCase().split(" ");
    for (var i =0; i < words.length; i++){
        var word = words[i];
        has = has && (option.text.toUpperCase().indexOf(word) >= 0); 
    }
    if (has) return option;
    return false;
}

$('#selectAccountDeal').select2({
    data: {!! $deals !!},
    width: '100%',
    templateResult: formatSelect,
    templateSelection: formatSelect,
    escapeMarkup: function(m) { return m; },
    matcher: matcher
})

My example JSON data

[{
    "text": "JL - o yea - Testing this deal",
    "id": 4,
    "client_name": "JL",
    "account_name": "o yea",
    "deal_name": "Testing this deal"
}, {
    "text": "JL - test - fj;askld fj",
    "id": 3,
    "client_name": "JL",
    "account_name": "test",
    "deal_name": "fj;askld fj"
}]

HTML for select element

<select id="selectAccountDeal" name="account_deal_id" placeholder="Select your Deal" required>
  <option></option>
</select>

Example of the select2 dropdown

select2 table view

like image 33
BrinkDaDrink Avatar answered Sep 17 '22 07:09

BrinkDaDrink