3

Scenario:

  1. User enters text "thisisabutton" for ButtonA

  2. User enters text "thisisalongerbutton" for ButtonB

  3. Both buttons dynamically adapt in size to fit text length, thus making them 2 different sizes

  4. I want ButtonA to be the same size as ButtonB (which will determine the size since it's longer than ButtonA).

What is the best approach to do this in Javascript?

bensiu
  • 24,660
  • 56
  • 77
  • 117
  • First they should be dynamically and then you want them to have the same size? – dan-lee Dec 04 '12 at 20:49
  • I've provided an answer under the assumption you already have a function to change the button content. Please clarify in your question if this is true. – Randy Hall Dec 04 '12 at 21:20

3 Answers3

1
<button id="ButtonA" onChange="ResizeButtons();">Hello</button>
<button id="ButtonB" onChange="ResizeButtons();">Worlddddddddddddddd</button>
<script type="text/javascript">
    function getWidth(element) {
        return parseInt(window.getComputedStyle ? window.getComputedStyle(element,null).getPropertyValue("width")  : element.currentStyle.width );
    }
    function ResizeButtons() {
        var buttonA = document.getElementById("ButtonA");
        var buttonB = document.getElementById("ButtonB");
        buttonA.style.width = "auto";
        buttonB.style.width = "auto";
        var buttonAWidth = getWidth(buttonA);
        var buttonBWidth = getWidth(buttonB);
        var maxWidth = (buttonAWidth > buttonBWidth ? buttonAWidth: buttonBWidth) + "px";
        buttonA.style.width = maxWidth;
        buttonB.style.width = maxWidth;
    }
</script>

1) Cross Browser.

2) Resets elements to "auto" before computing, or else they'll never resize after the first character is entered.

3) Avoids re-accessing DOM after getting buttonA and buttonB.

4) Checks while each button is being modified.

EDIT

You may have to put the ResizeButtons(); event on the inputs you're using to change the button content, or better yet, simply run the function ResizeButtons() inside your current script that changes the button content, immediately after the content is changed.

Randy Hall
  • 7,716
  • 16
  • 73
  • 151
  • Is untested, but should work. Let me know if you have problems, and I'll set up a fiddle. – Randy Hall Dec 04 '12 at 21:17
  • This works, but as far as I can see the onChange action on the buttons never gets called, which isn't surprising because onChange is meant for changes in an input field. As you suggest, the ResizeButtons() function has to be called explicitly. http://jsfiddle.net/pBhuk/2/ – Stuart Dec 04 '12 at 22:11
  • @Stuart Yeah I was wondering how they were changing the buttons in the first place... I guess they're leaving something to the imagination. – Randy Hall Dec 07 '12 at 21:04
0
    <button id="ButtonA">Hello</button>
    <button id="ButtonB" onChange="ResizeButtons();">Worlddddddddddddddd</button>
    <script type="text/javascript">
        function ResizeButtons()
        {
            var buttonAWidth = document.getElementById("ButtonA").style.width;
            var buttonBWidth = document.getElementById("ButtonB").style.width;
            var maxWidth = 0;
            if (buttonAWidth >= buttonBWidth){
                maxWidth = buttonAWidth;
            }
            else{
                maxWidth = buttonBWidth;
            }
            document.getElementById("ButtonA").style.width = maxWidth;
            document.getElementById("ButtonB").style.width = maxWidth;
        }
    </script>
tuck
  • 452
  • 5
  • 15
  • This won't work because (i) style.width will only contain the width explicitly set in the HTML and (ii) when you set a width using `...style.width =` you need to add 'px' so that it knows the width you are giving it is in pixels. – Stuart Dec 04 '12 at 22:01
  • and also javascript gets widths as a string, e.g. "10px" or "100px", but when it compares strings it will not do it in the way you expect: `"10px" > "100px"` returns `true`. So the line comparing the widths will not always work. – Stuart Dec 04 '12 at 22:17
0

While this answer utilizes jQuery the principles are the same as the above answers without a lot of the extra hassle of handling getting a true element width. I by no means am advocating that you should necessarily use jQuery, but I think it illustrates the solution in a more concise fashion.

  1. The user adds a new button by providing a new name.
  2. Calculate the longest button and reset the widths of smaller buttons

The code:

<label for="buttonName">Enter Button Name:</label><input id="buttonName">
<button id="createButton">Create Button</button>
<div id="buttons"></div>

<script type="text/javascript">
$('#createButton').button().click(function(){
    var buttonName = $('#buttonName').val();
    $('#buttonName').val("");
    $('#buttons').append($('<button>'+buttonName+'</button>').button());

    var widestButton = 0;
    $('#buttons button').each(function(){
        widestButton = Math.max($(this).width(), widestButton);
    });
    $('#buttons button').width(function(){
        if ($(this).width() < widestButton)
            $(this).width(widestButton);                        
    });
});
</script>

http://jsfiddle.net/PwNUA

purgatory101
  • 6,494
  • 1
  • 20
  • 21