How to transform a JQuery button into a dropdown menu

For inspiration, consider this JQuery UI Button example: http://jqueryui.com/demos/button/#splitbutton

Now, how can you create a dropdown menu when the small button is clicked? My main concern is the way .button() alters the button's actual appearance, causing issues with the positioning.

In essence, I am seeking insights on the proper way to implement a dropdown functionality for a JQuery button that fits seamlessly with the current theme.

Appreciate the input! Alex

Answer №1

After reaching my goal, the outcome resembled the image displayed above.
For more detailed information, I have documented the process in my blog post here and included all the code below.
Please refer to the blog for a comprehensive explanation.

CSS

<style type="text/css>

    .ItemActionButtons{}
    .ItemActionButtons .SaveExtraOptions
    {
        display: none; list-style-type: none; padding: 5px; margin: 0; border: 1px solid #DCDCDC; background-color: #fff; z-index: 999; position: absolute;
    }
    .ItemActionButtons .SaveExtraOptions li
    {
        padding: 5px 3px 5px 3px; margin: 0; width: 150px; border: 1px solid #fff;
    }
    .ItemActionButtons .SaveExtraOptions li:hover
    {
        cursor: pointer;
        background-color: #DCDCDC;
    }
    .ItemActionButtons .SaveExtraOptions li a
    {
        text-transform: none;
    }
</style>

HTML

<div class="ItemActionButtons">
    <div class="buttonset" style="float: right;">
        <input id="btnDelete" type="button" value="Delete" class="button" onclick="ItemActionButtons.onDeleteClick.apply(this)" />
        <input id="btnCancel" type="button" value="Cancel" class="button"onclick="ItemActionButtons.onCancelClick.apply(this)" />
    </div>  
    <div id="divSaveButton" class="buttonset" style="float: right;">
        <input id="btnSave" type="button" value="Save" class="button" onclick="ItemActionButtons.onSaveClick.apply(this)" />
        <input id="btnSaveExtra" type="button" class="button" value="+" onclick="ItemActionButtons.onSaveExtraClick.apply(this)" />

        <ul class="SaveExtraOptions ui-corner-bottom" id="btnSaveExtraOptions">
            <li onclick="$('#btnSaveExtraOptions').toggle(); ItemActionButtons.SaveAndNewClick.apply(this)">Save and New</li>
            <li onclick="$('#btnSaveExtraOptions').toggle(); ItemActionButtons.SaveAndCopyClick.apply(this)">Save and Copy</li>
        </ul>
    </div>
</div>

JavaScript

<script type="text/javascript">

    $(document).delegate('#btnSaveExtra', 'mouseleave', function () { setTimeout(function(){ if (!ItemActionButtons.isHoverMenu) { $('#btnSaveExtraOptions').hide(); }}, 100, 1) });
    $(document).delegate('#btnSaveExtraOptions', 'mouseenter', function () { ItemActionButtons.isHoverMenu = true; });
    $(document).delegate('#btnSaveExtraOptions', 'mouseleave', function () { $('#btnSaveExtraOptions').hide(); ItemActionButtons.isHoverMenu = false; });

    var $IsHoverExtraOptionsFlag = 0;
    $(document).ready(function () {
        $(".button").button();
        $(".buttonset").buttonset();
        $('#btnSaveExtra').button({ icons: { primary: "ui-icon-plusthick" } });
        $('#btnSaveExtraOptions li').addClass('ui-corner-all ui-widget');
        $('#btnSaveExtraOptions li').hover(
            function () { $(this).addClass('ui-state-default'); },
            function () { $(this).removeClass('ui-state-default'); }
        );
        $('#btnSaveExtraOptions li').mousedown(function () { $(this).addClass('ui-state-active'); });
        $('#btnSaveExtraOptions li').mouseup(function () { $(this).removeClass('ui-state-active'); });
    });

    var ItemActionButtons = {
        isHoverMenu: false,

        AllowDelete: function (value) { value ? $("#btnDelete").show() : $("#btnDelete").hide() },
        AllowCancel: function (value) { value ? $("#btnCancel").show() : $("#btnCancel").hide(); },
        AllowSave: function (value) { value ? $("#btnSave").show() : $("#btnSave").hide() },
        AllowSaveExtra: function (value) { value ? $("#btnSaveExtra").show() : $("#btnSaveExtra").hide() },

        onDeleteClick: function () { },
        onCancelClick: function () { },
        onSaveClick: function () { },
        onSaveExtraClick: function () {
            $('#btnSaveExtraOptions').toggle();

            var btnLeft = $('#divSaveButton').offset().left;
            var btnTop = $('#divSaveButton').offset().top + $('#divSaveButton').outerHeight(); // +$('#divSaveButton').css('padding');
            var btnWidth = $('#divSaveButton').outerWidth();
            $('#btnSaveExtraOptions').css('left', btnLeft).css('top', btnTop);
        },
        SaveAndNewClick: function () { },
        SaveAndCopyClick: function () { }
    }

</script>

Answer №2

You can easily accomplish this using a plugin.

Check out the jQuery DropDown Button plugin!

Answer №3

In my opinion, dropdowns should always be displayed above other content instead of pushing it down. This is why using absolute positioning is ideal. Simply create a wrapper div with position: relative around the button and dropdown menu (which will have

position: absolute; display: none
), and then toggle the visibility of the dropdown on click. The absolute positioning ensures that the dropdown's placement is not affected by other elements within the wrapper div, such as the button, allowing it to appear exactly where specified in the CSS.

Answer №4

HTML:

<div id="container"> 
    <span class="arrow">&or;</span> <span class="default">Choose your preferred option...</span>
    <input type="hidden" value="" class="mehidden"/>
    <ul class="selectBox">
        <li>Option One</li>
        <li>Option Two</li>
        <li>Option Three</li>
    </ul>
</div>

CSS:

.arrow
{
    background: none repeat scroll 0 0 #FFFFFF;
    border: 1px solid #CCCCCC;
    font-size: 0.8em;
    font-weight: bold;
    height: 26px;
    left: 208px;
    line-height: 26px;
    position: absolute;
    text-align: center;
    vertical-align: middle;
    width: 26px;
    z-index: 100;
}

.selectBox
{
    border: 1px solid #1F1F1F;
    list-style-type: none;
    margin: 0;
    padding: 3px;
    position: absolute;
    width: 200px;
    display:none;
    top: 25px;
}

#container
{
    position:relative
}

.toggler
{
    overflow:visible;
}

.default
{
    border: 1px solid #1f1f1f;
    width:200px;
    height:20px;
    padding:3px;
    position:absolute
}

.selectBox li:hover
{
    background:#ddd
}

JQUERY:

$('.arrow').click(function() {
    $('.selectBox').slideToggle(200).css('borderTop', 'none');
    $('.selectBox li').click(function() {
        $('.mehidden').val($(this).text());
        $('.default').text($(this).text());
        $('.selectBox').slideUp(200);
    });
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is the absolute positioned element on the left or right based on its current location?

Is there a way to assign absolute positioning with left at 0px or right at 0px depending on whether the positioned div will go outside of its container? For example, when you right click in a browser and see the menu appear to the right of where you click ...

Tips for selecting a secondary or even tertiary ancestor in a Sass project

Check out this piece of HTML code: <body> <div> <li class="more">hello <ul class="hello"> <li>hello</li> <li>hello</li> ...

I am attempting to retrieve the value of a 'td' element using jQuery, but it consistently returns 'null'

My task involves extracting the value of a specific cell within a table to filter out unwanted rows. However, every time I attempt to retrieve the value of that cell, it consistently returns null or nothing at all. Despite referencing various sources and s ...

How to position an absolute element beneath a fixed element

My website is experiencing a problem where the fixed header is overlapping an absolute paragraph on this page. Does anyone know how to resolve this issue? ...

the counterpart of jQuery.active in vanilla JavaScript

Is there a way to monitor the active Ajax requests on a non-jQuery site? I'm looking for an equivalent to jQuery.active. I am interested in checking if all the ajax requests have been completed after loading a page. I came across the window.XMLHttpR ...

Web browser displaying vertical scroll bars centered on the page

I'm new to HTML and have been experimenting with this CSS file to center my form. I've managed to get it working, but the issue now is that it's causing scroll bars to appear on the web browser. How can I resolve this without them? @import ...

Swapping stylesheets using a hyperlink - a simple guide

Currently, I am creating a website that utilizes PHP, XHTML strict, and jQuery. The main goal is to ensure the site is adaptable for mobile and desktop devices by implementing the principles of Responsive Web Design. This involves serving different stylesh ...

Error: Phonegap displaying incomplete or corrupted image

Currently, my Android application is being developed with Phonegap. Users have the ability to take photos that are then stored in a mysql database (medium-blob column) using a simple INSERT INTO query without altering the data. These images are then sent s ...

Retrieve the identifier of the higher-order block when it is clicked

When I have a parent block with a nested child block inside of it, I expect to retrieve the id of the parent when clicked. However, the event target seems to be the child element instead. Is there a way for JavaScript to recognize the parent as the event ...

Looking to set up a layout with two columns in the first row and one column in the second row, then combine the two columns using HTML and CSS

My goal is to set up a layout with two columns in the first row, one at 70% width and the other at 30%, and a single column in the second row. However, when I add text and images, the content doesn't position as expected: body { background-image: ...

Check out how to utilize the jQuery .ajax Post method in a function

Can an AJAX POST be directed to a specific function in a PHP file? $.ajax({ type: "POST", url: "functions.php", //is there a way to specify a function here? data: "some data...", success: function(){ alert('Succ ...

To handle async actions in Typescript with React and Redux, ensure that all actions passed to axios are plain objects. If you need to perform

Looking for assistance with Typescript, React, and Redux. export function fetchAllMeals (subject: string){ axios .get(`https://www.themealdb.com/api/json/v1/1/search.php?s=${subject}`) .then((response: any) => { console.log(response.data) ...

What is the best way to clear cookies when making external API calls in Next.js?

Despite my efforts, I have been unable to successfully remove cookies from my API calls in NextJS using Axios as the httpClient. The accumulation of cookies in users' browsers is causing issues and bloating, but I can't seem to find a solution. ...

Guide to embed a Google Sheets chart into a WordPress website

I'm looking to include a chart in a wordpress post, using the script generated from google sheets' publish function. When I add the script to a generic HTML page, the chart displays properly. However, when I insert it into a wordpress post, I en ...

When you click, transfer a single item from one array to another and modify the text according to the items in the array

How can I dynamically update a shopping cart feature on my website when a user clicks on the "addtocart" button? I want to create functionality where clicking on the button adds the corresponding product to the cart array, and updates the cart amount displ ...

XPages component retrieval function is malfunctioning

Utilizing an XPage with JQuery dialog and client-side validation adds efficiency to the user input process. However, there seems to be a disconnect between the client-side validation and server-side properties. Although the client-side validation functions ...

Tips for saving an image that has been dragged onto the browser locally

I recently started working with Angular and decided to use the angular-file-upload project from GitHub here. I'm currently in the process of setting up the backend for my application, but I'd like to be able to display dropped files locally in th ...

React revolutionizes the way we handle line breaks in

Just starting out in the world of coding and feeling a bit overwhelmed. I have checked out MDN, WJ3 but I'm still struggling with inserting line breaks into my code. return market.outcomes.map( ({ name, price ...

Solved the issue of inconsistent element height and jumping on mobile devices during scrolling

Problem persists with the fixed element at the bottom of my mobile device when I scroll. It seems that the height is recalculated each time due to an increase in document height on mobile devices. The issue appears to be related to the address bar fading ...

Error: The parent container element cannot be edited until the child element has been properly closed

I received a Script Error stating that I am unable to modify the parent container element before the child element is closed. In response, I clicked Yes but my web page isn't being displayed. In the code for my Product page, I start with: http://past ...