2
votes

Today I ran into a seemingly simple styling task when using the Select2 plugin, but it seems that the thing I want to achieve is more difficult than I thought. Here's what I want to do:

The user should be able to choose a contact from a dropdown menu. Each contact entry should be displayed as the contact's profile picture and some data next to it. When collapsed, the dropdown should display the selected contact (i.e. the selected contact's profile picture and some data next to it) with a "dropdown triangle" next to it. In the expanded state, the dropdown should additionally display the other contacts, each with profile pic and data. Put simply, I want to do templating as described in the "Templating" example on the select2 example page, just with a more complex layout (profile picture on the left plus three stacked lines of text right next to the picture).

I managed to apply the desired style to the results by using the formatResult select2 option, using a format function which wraps the image and data in styled div elements (note that I use Twitter Bootstrap's 'media' css class for styling):

function formatContactResult(item) {
 if(!item.id)
    return "No contact selected";

 var contact = JSON.parse(item.text);
 return "<div class='media'><a class='pull-left' href='#'><img style='margin-top: 5px;' class='media-object' data-src='holder.js/64x64' src='" + contact.thumbUrl + "' /></a><div class='media-body' style='font-size: 11px;'><strong>" + contact.displayName + "</strong><br />" + contact.jobTitle + "</div></div>"
};

My problem: I can't figure out how to apply a complex layout like this to the selection. I'm aware of the formatSelection option, but the return value of the formatSelection function is wrapped in a span element which is not an appropriate wrapper for complex layouts. Although I know it's not valid, I tried to apply the same layout function I mentioned above, but that expectedly led to weird results (the desired layout being pushed far to the right).

Does anyone have an clue on how I can achieve the described layout with select2?

If it's of any interest, I'm using the Select2 plugin with Knockout.js and Twitter Bootstrap.

1

1 Answers

2
votes

I figured it out - the problem was that all div elements contained in the select2-choice component are absolutely positioned and styled in select2.css:

.select2-container .select2-choice div {
    display: block;
    width: 18px;
    height: 100%;
    position: absolute;
    right: 0;
    top: 0;
    [...]
}

This style is used to render the "dropdown triangle" of the dropdown box, which happens to be a div element. Unfortunately, the triangle div doesn't have an own CSS class name which should be used to style it.

So as a workaround, I created a new CSS class and applied it to the div elements I wanted to render inside of the select2-choice component. The idea is to override the position and width attributes:

.innerDiv {
    position: relative !important; 
    width: auto !important;
}