0
votes

I use jquery UI - Select Menu to build a List with picture. I follow this link and it's good. But When you select an item, just the text is copying, not the picture. I explain why I want picture. I've a List with no text, just picture, then When you choose an item, you see an empty span ... Someone have an idea?

Here My code

<script type="text/javascript">
    $(function () {
        $.widget("custom.iconselectmenu", $.ui.selectmenu, {
            _renderItem: function (ul, item) {
                var li = $("<li>", { html: item.element.html() });
                var attr = item.element.attr("data-style");
                if (typeof attr !== typeof undefined && attr !== false) {
                    $("<span>", {
                        style: item.element.attr("data-style"),
                        "class": "ui-icon TFOOptlstFiltreImg"
                    }).appendTo(li);
                }
                return li.appendTo(ul);
            }
        });

        $("#people")
          .iconselectmenu().iconselectmenu("menuWidget").addClass("ui-menu-icons");
    });
</script>
<style type="text/css">
    select
    {
        width: 200px;
    }
</style>
<select name="people" id="people">
    <option value="1" data-style="background-image: url(&apos;http://www.gravatar.com/avatar/b3e04a46e85ad3e165d66f5d927eb609?d=monsterid&amp;r=g&amp;s=16&apos;);">John Resig</option>
    <option value="2" data-style="background-image: url(&apos;http://www.gravatar.com/avatar/e42b1e5c7cfd2be0933e696e292a4d5f?d=monsterid&amp;r=g&amp;s=16&apos;);">Tauren Mills</option>
    <option value="3" data-style="background-image: url(&apos;http://www.gravatar.com/avatar/bdeaec11dd663f26fa58ced0eb7facc8?d=monsterid&amp;r=g&amp;s=16&apos;);">Jane Doe</option>
</select>

fiddle demo here

4
Did you remember to change this $( "<li>", { text: item.label } ) to $( "<li>", { html: item.element.html() } )? - blgt
Yes. I Update my question - YannickIngenierie
Actually with your setup you don't need my previous comment at all. Your span should have a background-image, but most likely the browser sees it has no content and renders it with width and height 0, so you should also manually resize it appropriately. I can't give more details without a working example (fiddle?) - blgt

4 Answers

2
votes

Using JQuery UI selectmenu examples i came up with the following solution:

$(function () {
    $.widget("custom.iconselectmenu", $.ui.selectmenu, {
        _renderItem: function (ul, item) {
            var li = $("<li>"),
                wrapper = $("<div>", { html: item.element.html() });

            if (item.disabled) {
                li.addClass("ui-state-disabled");
            }

            $("<span>", {
                style: item.element.attr("data-style"),
                "class": "ui-icon " + item.element.attr("data-class")
            })
                .appendTo(wrapper);

            return li.append(wrapper).appendTo(ul);
        }
    });

    $("#people")
        .iconselectmenu({
            create: function (event, ui) {
                var widget = $(this).iconselectmenu("widget");
                $span = $('<span id="' + this.id + 'selected" class="avatar-selected"> ').html("&nbsp;").appendTo(widget);
                $span.attr("style", $(this).children(":first").data("style"));
            },
            change: function (event, ui) {
                $("#" + this.id + 'selected').attr("style", ui.item.element.data("style"));
            }
        })
        .iconselectmenu("menuWidget")
        .addClass("ui-menu-icons avatar");
});

and corresponding CSS:

    .ui-selectmenu-menu .ui-menu.avatar .ui-menu-item-wrapper {
        padding: 2px 10px 0 30px;
    }

    .ui-selectmenu-menu .ui-menu.avatar .ui-menu-item .ui-icon {
        height: 24px;
        width: 24px;
        top: 0.1em;
    }

    .ui-selectmenu-text {
        padding-left: 2em;
    }

    .avatar-selected {
        position:absolute;
        height: 24px;
        width: 24px;
        right:auto;
        margin-top:-12px;
        top:50%;
        background-repeat:no-repeat;
    }
2
votes

I added few updates for keep Icon when selected the item. Working Perfect.

$(function () {
                $.widget("custom.iconselectmenu", $.ui.selectmenu, {
                    _renderItem: function (ul, item) {
                        var li = $("<li>"),
                            wrapper = $("<div>", { text: item.label });

                        if (item.disabled) {
                            li.addClass("ui-state-disabled");
                        }
                        $("<i>", {
                            style: item.element.attr("data-style"),
                            "class": "bl-icon " + item.element.attr("data-class")
                        })
                            .appendTo(wrapper);
                        return li.append(wrapper).appendTo(ul);
                    }
                });

                $("#IconDropdown").iconselectmenu({
                    create: function (event, ui) {
                        var widget = $(this).iconselectmenu("widget");
                        $span = $('<i id="' + this.id + 'selected" class="avatar-selected"> ').html("&nbsp;").appendTo(widget);
                        $("#" + this.id + 'selected').attr("class", $("#IconDropdown option:selected")[0].getAttribute('data-class'));
                    },
                    change: function (event, ui) {
                        $("#" + this.id + 'selected').attr("class", ui.item.element[0].getAttribute('data-class'));
                    }
                }).iconselectmenu("menuWidget").addClass("ui-menu-icons");
            });
0
votes

This solution run ok Here I've in item only text or only picture. Never both in same time.

<script type="text/javascript">
    $(function () {
        $.widget("custom.TFOiconSelectImg", $.ui.selectmenu, {
            _renderItem: function (ul, item) {
                var li = $("<li>", { html: item.element.html() });
                var attr = item.element.attr("data-style");
                if (typeof attr !== typeof undefined && attr !== false) {
                    $("<span>", {
                        style: item.element.attr("data-style"),
                        "class": "ui-icon TFOOptlstFiltreImg"
                    }).appendTo(li);
                }
                return li.appendTo(ul);
            }
        });

        $("#people")
          .TFOiconSelectImg({
              create: function (event, ui) {
                  var widget = $(this).TFOiconSelectImg("widget");
                  widget.attr("style", $(this).children(":first").data("style")).addClass("TFOOptlstFiltreImg");
              },
              change: function (event, ui) {
                  $(this).TFOiconSelectImg("widget").attr("style", ui.item.element.data("style")).addClass("TFOOptlstFiltreImg")
                  //$("span.ui-selectmenu-text").append($("span", event.currentTarget).clone());
                  //alert($(this).val());
              }
          }).TFOiconSelectImg("menuWidget").addClass("ui-menu-icons customicons");
    });
</script>

In each option, it's important have empty picture and text OR picture and " "

 <select name="people" id="people" class="TFOlstFiltreImg TFOfilter lstfilter">
    <option value="" data-style="background-image: url(&apos;/Images/vide.png&apos;);" selected="selected">TOUS</option>
    <option value="" data-style="background-image: url(&apos;/Images/vide.png&apos;);">SANS</option>
    <option value="/Images/imgres.jpg" data-style="background-image: url(&apos;/Images/imgres.jpg&apos;);">&nbsp;</option>
    <option value="/Images/imgres.png" data-style="background-image: url(&apos;/Images/imgres.png&apos;);">&nbsp;</option>
</select>

.TFOOptlstFiltreImg
{
background-repeat:no-repeat;
background-size: 24px 24px;
width:100px;
}
.ui-widget
{
font-size: 1em;
}
.ui-selectmenu-menu .ui-menu.customicons .ui-menu-item
{
padding: 0.5em 0 0.5em 2.1em;
background-repeat: no-repeat;
}

/*Agrandir sinin 16px par defaut*/
.ui-selectmenu-menu .ui-menu.customicons .ui-menu-item .ui-icon
{
    height: 24px;
    width: 24px;
    top: 0.1em;
}

Problem with this solution it's sometimes css of your span menu-button can be modify. Then better use method in other post , and add an object

0
votes

And here another solution:

<script type="text/javascript">
    $(function () {
        $.widget("custom.TFOiconSelectImg", $.ui.selectmenu, {
            _renderItem: function (ul, item) {
                var li = $("<li>", { html: item.element.html() });
                var attr = item.element.attr("data-style");
                if (typeof attr !== typeof undefined && attr !== false) {
                    $("<span>", {
                        style: item.element.attr("data-style"),
                        "class": "ui-icon TFOOptlstFiltreImg"
                    }).appendTo(li);
                }
                return li.appendTo(ul);
            }
        });

        $("#people")
          .TFOiconSelectImg({
              create: function (event, ui) {
                  var widget = $(this).TFOiconSelectImg("widget");
                  $span = $('<span id="' + this.id + 'ImgSelected" class="TFOSizeImgSelected"> ').html("&nbsp;").appendTo(widget);
                  $span.attr("style", $(this).children(":first").data("style"));
              },
              change: function (event, ui) {
                  $("#" + this.id + 'ImgSelected').attr("style", ui.item.element.data("style"));
              }
          }).TFOiconSelectImg("menuWidget").addClass("ui-menu-icons customicons");
    });
</script>


<select name="people" id="people" class="TFOlstFiltreImg">
    <option value="" data-style="background-image: url(&apos;/Images/vide.png&apos;);" selected="selected">TOUS</option>
    <option value="" data-style="background-image: url(&apos;/Images/vide.png&apos;);">SANS</option>
    <option value="/Images/imgres.jpg" data-style="background-image: url(&apos;/Images/imgres.jpg&apos;);">&nbsp;</option>
    <option value="/Images/imgres.png" data-style="background-image: url(&apos;/Images/imgres.png&apos;);">&nbsp;</option>
</select>

And the associated CSS

.ui-widget
{
font-size: 1em;
}

.ui-widget-content
{
border-style: none;
}

/*Affichage des options*/
.ui-selectmenu-menu .ui-menu.customicons .ui-menu-item
{
padding: 0.5em 0 0.5em 2.1em;
background-repeat: no-repeat;
}

/*Agrandir sinon 16px par defaut*/
.ui-selectmenu-menu .ui-menu.customicons .ui-menu-item .ui-icon
{
    height: 24px;
    width: 24px;
    top: 0.1em;
}

.TFOlstFiltreImg
{
width: 100px;
}

.TFOSizeImgSelected
{
position:absolute;
height: 24px;
width: 24px;
left:35%;
right:auto;
margin-top:-12px; /* 24/2*/
top:50%;
background-size:24px 24px;
background-repeat:no-repeat;
}

.TFOOptlstFiltreImg
{
background-size:24px 24px;
background-repeat:no-repeat;
}

And here another sample. Instead of add a span, just add a picture

$("#people")
          .TFOiconSelectImg({
              create: function (event, ui) {
                  var widget = $(this).TFOiconSelectImg("widget"); var $SpanTxt = widget.children(":last");
                  $span = $('<img class="TFOSizeImgSelected TFOOptlstFiltreImg"> ').appendTo($SpanTxt);
                  $span.attr("style", $(this).children(":first").data("style"));
              },
              change: function (event, ui) {
                  var widget = $(this).TFOiconSelectImg("widget"); var $SpanTxt = widget.children(":last");
                  $span = $('<img class="TFOSizeImgSelected TFOOptlstFiltreImg"> ').appendTo($SpanTxt);
                  $span.attr("style", ui.item.element.data("style"));
                  //$("#" + this.id + 'ImgSelected').attr("style", ui.item.element.data("style"));
              }
          }).TFOiconSelectImg("menuWidget").addClass("ui-menu-icons customicons");

modify css with

.TFOSizeImgSelected
{
position:absolute;
height: 24px;
width: 24px;
left:2em;
}

.TFOOptlstFiltreImg
{
background-size:24px 24px;
background-repeat:no-repeat;
}