vendredi 18 novembre 2016

Dropdown with checkbox hack - how to make first tap open menu without selecting option?

I want to make something that is like a dropdown menu in a form, but I want to be able to show images or other content in each option. A bit like msdropdown but with the ability to put any content in the dropdown, not just images. For instance, I might want coloured rectangles that are inline-block elements styled with css.

The way I'm approaching it at the moment is by building on this checkbox hack

Here's what I've got so far, which works well in the desktop browsers that I've tested: jsfiddle

The trouble is that on iOS and Android, when you click on the dropdown to expand it, it selects the first option in the list. I want that first click to expand the dropdown, but not to click any options yet. Is there a way to do this, e.g. by adding a simple bit of javascript?

Or, alternatively, is there a more elegant way to go about solving the whole problem of putting arbitrary content in a dropdown instead of using the checkbox hack?

Full code from JSfiddle below:

HTML

<p>Show what's currently selected, using javascript:</p>

<input type="text" value="" id="trace"/>

<p>Dropdown with custom styling, using the checkbox hack, along the lines of <a href="http://ift.tt/2g3qMnt">this</a>, using the variant suggested by "namehere" in the comments.</p>

<form class="my-image-dropdown">
    <label>
        <input type="radio" name="line-style" value="1"  />
        <div class="dropdown-label">
            <span class="color-swatch vmiddle">
                <span style="background-color:red;">&nbsp;</span><span style="background-color:green;">&nbsp;</span><span style="background-color:blue;">&nbsp;</span>    
            </span>
            <span class="collapsedonly vmiddle">&#9662;</span>
            <span class="checkedonly vmiddle">&#x2713;</span>
        </div>
    </label>
    <label>
        <input type="radio" name="line-style" value="2" checked="checked"/>
        <div class="dropdown-label">
            <span class="color-swatch vmiddle">
                <span style="background-color:purple;">&nbsp;</span><span style="background-color:green;">&nbsp;</span><span style="background-color:pink;">&nbsp;</span>    
            </span>
            <span class="collapsedonly vmiddle">&#9662;</span>
            <span class="checkedonly vmiddle">&#x2713;</span>
        </div>
    </label>
    <label>
        <input type="radio" name="line-style" value="3" />
        <div class="dropdown-label">
            <span class="color-swatch vmiddle">
                <span style="background-color:grey;">&nbsp;</span><span style="background-color:darkblue;">&nbsp;</span><span style="background-color:black;">&nbsp;</span>    
            </span>
            <span class="collapsedonly vmiddle">&#9662;</span>
            <span class="checkedonly vmiddle">&#x2713;</span>
        </div>
    </label>
    <label>
        <input type="radio" name="line-style" value="4" />
        <div class="dropdown-label">
            <span class="color-swatch vmiddle">
                <span style="background-color:yellow;">&nbsp;</span><span style="background-color:orange;">&nbsp;</span><span style="background-color:green;">&nbsp;</span>    
            </span>
            <span class="collapsedonly vmiddle">&#9662;</span>
            <span class="checkedonly vmiddle">&#x2713;</span>
        </div>
    </label>
</form>

JAVASCRIPT

/* Update the trace showing currently selected option */
$( document ).ready(function() {
    var i = setInterval(function(){$("#trace").val($("input:checked").val());},100);
});

/* Fix the sticky hover bug on iOS - see http://ift.tt/2g3tVUr    entry.php?335-iOS-Sticky-Hover-Fix-Unhovering-dropdown-CSS-menus */
(function(l){var i,s={touchend:function(){}};for(i in s)l.addEventListener(i,s)})(document);

CSS

/* Hide the radio buttons */
.my-image-dropdown input {
    /*height: 0; width: 0; opacity:0;*/ /* This was in original code, seems unnecessary */
    display:none; /* Using display:none seems easier than setting height, width, opacity */
}


/* Style the container for both minimized and maximised state*/
.my-image-dropdown {
    width: auto; 
    height: auto; 
    background: #DDDDDD;
    border: 1px solid #999999;
    display: table;
    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
    border-radius: 5px;
    padding: 5px;
}


/* Collapse the dropdown when no hover, by hiding the contents of the label elements */
.my-image-dropdown label input ~ * {
    display:none;  
}


/* Expand the dropdown on hover (mouse) or tap (touch-screen) */
.my-image-dropdown:hover {
    height: auto;  /* Use fixed height or else auto to fit all color swatches */
    overflow-y: scroll;  /* If fixed height, use native scrolling */
}
.my-image-dropdown:hover label input ~ * {
    /* Use display:inline-block for tiling           */                             
    /*   or display:block;       for full-width vertical stacking */
    /*   or display:table;       for vertical stacking and fit to width of contents */
    display: table;  /* Vertical stacking and fit to width of contents */
}

/* Add some space between rows when expanded */
/* This uses the :not() selector which has pretty solid browser support */
/* http://ift.tt/TVDvKN */
.my-image-dropdown:hover label:not(:first-child) input ~ * {
    margin-top: 10px;
}

/* Display the checked option even when the dropdown is collapsed */
.my-image-dropdown label input:checked ~ * {
    display:table;
    /* Optional: apply styling to the chosen option */
}

/* Apply effect when hovering over a particular label */
.my-image-dropdown label:hover input ~ * {
    opacity:0.5;
}

/* Show the down arrow only when collapsed and only for the checked option */
.my-image-dropdown label .collapsedonly {
    display:none;
}
.my-image-dropdown label input:checked ~ .dropdown-label .collapsedonly {
    display:inline;
}
.my-image-dropdown:hover label input:checked ~ .dropdown-label .collapsedonly {
    display:none;
}


/* Show a tick next to the checked option but only when expanded */
.my-image-dropdown label .checkedonly {
    display:none;
}
.my-image-dropdown:hover label input:checked ~ .dropdown-label .checkedonly {
    display:inline;
}


/* Style the tick and the down arrow */
.dropdown-label .checkedonly, .dropdown-label .collapsedonly {
    font-size: 120%;
    margin-left: 15px;
    margin-right: 5px;
}


/* Style the colored squares */
.color-swatch{
    display: inline-block;
}
.color-swatch > span {
    display: inline-block;
    width:50px;
    height:50px; /* If you change this then also change line-height of dropdown-label */
    margin:2px;
}

/* Vertically center an element within its neighbour */
.vmiddle {
    display: inline-block;
    vertical-align: middle;
}




Aucun commentaire:

Enregistrer un commentaire