diff options
author | Alexander Schmitz <arschmitz@gmail.com> | 2014-08-22 23:39:35 -0400 |
---|---|---|
committer | Alexander Schmitz <arschmitz@gmail.com> | 2015-10-07 10:57:59 -0400 |
commit | 40a9d1dfdb6a341904ae7bcd4600b0ef201d14df (patch) | |
tree | b4eaf29211bd94d9f947e8f0613f7798efe98126 | |
parent | 6e2bbcaa5e19bb933d8024ff5d6fcff34f91e034 (diff) | |
download | jquery-ui-40a9d1dfdb6a341904ae7bcd4600b0ef201d14df.tar.gz jquery-ui-40a9d1dfdb6a341904ae7bcd4600b0ef201d14df.zip |
Controlgroup: Inital commit of new widget
This widget replaces the buttonset widget
-rw-r--r-- | demos/button/icons.html | 1 | ||||
-rw-r--r-- | demos/controlgroup/default.html | 23 | ||||
-rw-r--r-- | demos/controlgroup/index.html | 2 | ||||
-rw-r--r-- | demos/controlgroup/splitbutton.html | 23 | ||||
-rw-r--r-- | demos/controlgroup/toolbar.html | 140 | ||||
-rw-r--r-- | demos/index.html | 1 | ||||
-rw-r--r-- | demos/tooltip/video-player.html | 8 | ||||
-rw-r--r-- | tests/unit/controlgroup/common.js | 26 | ||||
-rw-r--r-- | tests/unit/controlgroup/controlgroup.html | 39 | ||||
-rw-r--r-- | tests/unit/controlgroup/controlgroup_core.js | 77 | ||||
-rw-r--r-- | tests/unit/controlgroup/core.js | 69 | ||||
-rw-r--r-- | tests/unit/controlgroup/methods.js | 150 | ||||
-rw-r--r-- | tests/unit/controlgroup/options.js | 108 | ||||
-rw-r--r-- | tests/unit/index.html | 1 | ||||
-rw-r--r-- | themes/base/base.css | 1 | ||||
-rw-r--r-- | themes/base/button.css | 17 | ||||
-rw-r--r-- | themes/base/controlgroup.css | 30 | ||||
-rw-r--r-- | ui/.DS_Store | bin | 0 -> 10244 bytes | |||
-rw-r--r-- | ui/controlgroup.js | 205 |
19 files changed, 820 insertions, 101 deletions
diff --git a/demos/button/icons.html b/demos/button/icons.html index f0b0f90fb..a8deca9cd 100644 --- a/demos/button/icons.html +++ b/demos/button/icons.html @@ -41,6 +41,7 @@ <button>Button with icon on the right</button> <button>Button with icon on the top</button> <button>Button with icon on the bottom</button> + <button>Button with icon on the top</button> </div> <div class="css"> <h1>CSS</h1> diff --git a/demos/controlgroup/default.html b/demos/controlgroup/default.html index 9e4bcdd80..0fc963537 100644 --- a/demos/controlgroup/default.html +++ b/demos/controlgroup/default.html @@ -16,18 +16,15 @@ <link rel="stylesheet" href="../demos.css"> <script> $(function() { - $( ".controlgroup" ).eq( 0 ).controlgroup() - .end().eq( 1 ).controlgroup({ - "direction": "vertical" - }); + $( ".controlgroup" ).controlgroup() + $( ".controlgroup-vertical" ).controlgroup({ + "direction": "vertical" + }); }); </script> <style> .ui-controlgroup-vertical { - width: 300px; - } - .ui-controlgroup-vertical select { - width: 100%; + width: 150px; } .ui-controlgroup.ui-controlgroup-vertical > button.ui-button { text-align: center; @@ -35,9 +32,6 @@ </style> </head> <body> -<div class="demo-description"> -<p>A Controlgroup featuring various form controls</p> -</div> <div class="widget"> <h1>Controlgroup</h1> <fieldset> @@ -64,7 +58,7 @@ <br/> <fieldset> <legend>Rental Car</legend> - <div class="controlgroup-horizontal"> + <div class="controlgroup-vertical"> <select> <option>Compact car</option> <option>Midsize car</option> @@ -83,8 +77,9 @@ <button>Book Now!</button> </div> </fieldset> ->>>>>>> 423b976... Checkboxradio: Fixed demos and tests </div> - +<div class="demo-description"> +<p>A controlgroup featuring various form controls. The first features a horizontal toolbar like orientation, the second is in a space saving vertical orientation for usages like mobile devices and panels.</p> +</div> </body> </html> diff --git a/demos/controlgroup/index.html b/demos/controlgroup/index.html index 58e2f7eda..5aa4f5fd6 100644 --- a/demos/controlgroup/index.html +++ b/demos/controlgroup/index.html @@ -3,7 +3,7 @@ <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> - <title>jQuery UI Checkboxradio Demos</title> + <title>jQuery UI Controlgroup Demos</title> </head> <body> diff --git a/demos/controlgroup/splitbutton.html b/demos/controlgroup/splitbutton.html index 5d4c7b3ce..a72cefd96 100644 --- a/demos/controlgroup/splitbutton.html +++ b/demos/controlgroup/splitbutton.html @@ -19,27 +19,19 @@ $( "select" ).selectmenu({ classes: { "ui-selectmenu-button": "ui-button-icon-only" + }, + change: function(){ + $( ".output" ).append( "<li>" + this.value + "</li>" ); } - }).selectmenu( "widget" ).removeClass( "ui-icon-end" ); - $( ".controlgroup" ).controlgroup(); - $( "select" ).on( "selectmenuchange", function(){ - alert( this.value ); }); + $( ".controlgroup" ).controlgroup(); $( "button" ).click(function() { - alert( "Running the last action" ); + $( ".output" ).append( "<li>Running Last Action...</li>" ); }); }); </script> - <style> - select { - width: 2em; - } - </style> </head> <body> -<div class="demo-description"> -<p>A Controlgroup creating a split button</p> -</div> <div class="widget"> <h1>Split button</h1> <div class="controlgroup"> @@ -50,9 +42,12 @@ <option>Delete</option> </select> </div> + <br/> + <h3>Output:</h3> + <ul class="output"></ul> </div> <div class="demo-description"> - <p>A Controlgroup creating a split button</p> + <p>A controlgroup creating a split button, by combining a button and a selectmenu. We adjust the classes option on the selectmenu to show only the icon</p> </div> </body> </html> diff --git a/demos/controlgroup/toolbar.html b/demos/controlgroup/toolbar.html index f90fb3040..fb3172418 100644 --- a/demos/controlgroup/toolbar.html +++ b/demos/controlgroup/toolbar.html @@ -19,10 +19,11 @@ var iframe = $( "<iframe id='display' contenteditable='true'>" ), contents = iframe.appendTo( "body" ); - // Firefox and IE require us to wait for next tick before interacting with the iframe + // Support: Firefox <= 36, IE <= 11 + // These browsers require us to wait for next tick before interacting with the iframe setTimeout(function(){ - contents = contents.contents() + contents = contents.contents(); contents[ 0 ].designMode = "On"; contents[ 0 ].contenteditable = true; contents.find( "body" ).append( $( "#input" ).clone().attr( "id", "output" ) ); @@ -43,7 +44,7 @@ contents[ 0 ].execCommand( this.id ); }); $( "#fontsize, #forecolor, #hilitecolor, #backcolor, #fontname" ).on( "change selectmenuchange", function() { - contents[ 0 ].execCommand( this.id ,false, $( this ).val() ); + contents[ 0 ].execCommand( this.id, false, $( this ).val() ); }); $( ".toolbar" ).controlgroup(); $( "#zoom" ).on( "selectmenuchange", function() { @@ -57,7 +58,7 @@ </script> <style> #zoom, #fontsize { - min-width:75px; + min-width: 75px; } #input { display: none; @@ -74,75 +75,72 @@ </style> </head> <body> -<div class="demo-description"> -<p>A sample editor toolbar</p> -<p>Highlight text and edit it using the buttons and dropdowns in the toolbar</p> -</div> - <div class="toolbar"> - <button id="print">Print</button> - <button id="undo">Undo</button> - <button id="redo">Redo</button> - <select id="zoom"> - <option>50%</option> - <option>75%</option> - <option>90%</option> - <option selected>100%</option> - <option>125%</option> - <option>150%</option> - <option>200%</option> - </select> - <select id="fontname"> - <option>Arial</option> - <option>Comic Sans MS</option> - <option>Courier New</option> - <option>Georgia</option> - <option>Impact</option> - <option selected>Lucida Grande</option> - <option>Times New Roman</option> - <option>Verdana</option> - </select> - <select id="fontsize"> - <option value="1">8px</option> - <option value="2">9px</option> - <option value="3" selected>10px</option> - <option value="4">11px</option> - <option value="5">12px</option> - <option value="6">14px</option> - <option value="7">18px</option> - <option value="8">24px</option> - <option value="9">30px</option> - <option value="10">36px</option> - </select> - <select id="hilitecolor"> - <option value="white">Highlight: None</option> - <option value="red">Highlight: Red</option> - <option value="yellow">Highlight: Yellow</option> - <option value="green">Highlight: Green</option> - <option value="blue">Highlight: Blue</option> - <option value="grey">Highlight: Grey</option> - <option value="purple">Highlight: Purple</option> - <option value="orange">Highlight: Orange</option> - </select> - <select id="forecolor"> - <option value="white">Font: None</option> - <option value="red">Font: Red</option> - <option value="yellow">Font: Yellow</option> - <option value="green">Font: Green</option> - <option value="blue">Font: Blue</option> - <option value="#ccc">Font: Grey</option> - <option value="purple">Font: Purple</option> - <option value="orange">Font: Orange</option> - </select> - <button id="bold">B</button> - <button id="italic">I</button> - <button id="underline">U</button> +<div class="toolbar"> + <button id="print">Print</button> + <button id="undo">Undo</button> + <button id="redo">Redo</button> + <select id="zoom"> + <option>50%</option> + <option>75%</option> + <option>90%</option> + <option selected>100%</option> + <option>125%</option> + <option>150%</option> + <option>200%</option> + </select> + <select id="fontname"> + <option>Arial</option> + <option>Comic Sans MS</option> + <option>Courier New</option> + <option>Georgia</option> + <option>Impact</option> + <option selected>Lucida Grande</option> + <option>Times New Roman</option> + <option>Verdana</option> + </select> + <select id="fontsize"> + <option value="1">8px</option> + <option value="2">9px</option> + <option value="3" selected>10px</option> + <option value="4">11px</option> + <option value="5">12px</option> + <option value="6">14px</option> + <option value="7">18px</option> + <option value="8">24px</option> + <option value="9">30px</option> + <option value="10">36px</option> + </select> + <select id="hilitecolor" title="Background color"> + <option value="white">Highlight: None</option> + <option value="red">Highlight: Red</option> + <option value="yellow">Highlight: Yellow</option> + <option value="green">Highlight: Green</option> + <option value="blue">Highlight: Blue</option> + <option value="grey">Highlight: Grey</option> + <option value="purple">Highlight: Purple</option> + <option value="orange">Highlight: Orange</option> + </select> + <select id="forecolor"> + <option value="black" selected>Font: Black</option> + <option value="white">Font: White</option> + <option value="red">Font: Red</option> + <option value="yellow">Font: Yellow</option> + <option value="green">Font: Green</option> + <option value="blue">Font: Blue</option> + <option value="#ccc">Font: Grey</option> + <option value="purple">Font: Purple</option> + <option value="orange">Font: Orange</option> + </select> + <button id="bold">B</button> + <button id="italic">I</button> + <button id="underline">U</button> - </div> - <br/><br/> +</div> +<br/><br/> <pre id="input"> The Rime of the Ancient Mariner (text of 1834) BY SAMUEL TAYLOR COLERIDGE -Argument +Argument How a Ship having passed the Line was driven by storms to the cold Country towards the South Pole; and how from thence she made her course to the tropical Latitude of the Great Pacific Ocean; and @@ -252,5 +250,9 @@ From the fiends, that plague thee thus!— Why look'st thou so?'—With my cross-bow I shot the ALBATROSS. </pre> +<div class="demo-description"> + <p>A sample editor toolbar</p> + <p>Highlight text and edit it using the buttons and dropdowns in the toolbar</p> +</div> </body> </html> diff --git a/demos/index.html b/demos/index.html index 4b4d04e06..89375dde7 100644 --- a/demos/index.html +++ b/demos/index.html @@ -12,6 +12,7 @@ <li><a href="autocomplete/">autocomplete</a></li> <li><a href="button/">button</a></li> <li><a href="checkboxradio/">checkboxradio</a></li> + <li><a href="controlgroup/">controlgroup</a></li> <li><a href="datepicker/">datepicker</a></li> <li><a href="dialog/">dialog</a></li> <li><a href="draggable/">draggable</a></li> diff --git a/demos/tooltip/video-player.html b/demos/tooltip/video-player.html index cbcce3db0..e1ebac24f 100644 --- a/demos/tooltip/video-player.html +++ b/demos/tooltip/video-player.html @@ -35,7 +35,7 @@ } </style> <script src="../../external/requirejs/require.js"></script> - <script src="../bootstrap.js" data-modules="button menu effect effect-blind"> + <script src="../bootstrap.js" data-modules="button controlgroup menu effect effect-blind"> function notify( input ) { var msg = "Selected " + $.trim( input.data( "tooltip-title" ) || input.text() ); $( "<div>" ) @@ -70,8 +70,10 @@ notify( button ); }); }); - $( ".set" ).buttonset({ - items: "button" + $( ".set" ).controlgroup({ + items: { + "button" : "button" + } }); $( "button.menu" ) diff --git a/tests/unit/controlgroup/common.js b/tests/unit/controlgroup/common.js new file mode 100644 index 000000000..421e92e71 --- /dev/null +++ b/tests/unit/controlgroup/common.js @@ -0,0 +1,26 @@ +define( [ + "lib/common", + "ui/controlgroup", + "ui/checkboxradio", + "ui/selectmenu", + "ui/button" +], function( common ) { + +common.testWidget( "controlgroup", { + defaults: { + disabled: null, + items: { + "button": "input[type=button], input[type=submit], input[type=reset], button, a", + "checkboxradio": "input[type='checkbox'], input[type='radio']", + "selectmenu": "select" + }, + direction: "horizontal", + excludeInvisible: true, + classes: {}, + + // Callbacks + create: null + } +}); + +} ); diff --git a/tests/unit/controlgroup/controlgroup.html b/tests/unit/controlgroup/controlgroup.html new file mode 100644 index 000000000..df77ed64d --- /dev/null +++ b/tests/unit/controlgroup/controlgroup.html @@ -0,0 +1,39 @@ +<!doctype html> +<html lang="en"> +<head> + <meta charset="utf-8"> + <title>jQuery UI Controlgroup Test Suite</title> + + <script src="../../../external/requirejs/require.js"></script> + <script src="../../lib/css.js" data-modules="core button checboxradio selectmenu controlgroup"></script> + <script src="../../lib/bootstrap.js" data-modules="common core methods options"></script> +</head> +<body> + +<div id="qunit"></div> +<div id="qunit-fixture"> + <div class="controlgroup"> + <button style="display:none">Button with icon only</button> + <select> + <option>Fast</option> + <option>Medium</option> + <option>Slow</option> + </select> + <label for="checkbox">Checkbox</label> + <input type="checkbox" value="checkbox" id="checkbox" /> + <select> + <option>Fast</option> + <option>Medium</option> + <option>Slow</option> + </select> + <div class="test"></div> + <button>Button with icon on the bottom</button> + <select> + <option>Fast</option> + <option>Medium</option> + <option>Slow</option> + </select> + </div> +</div> +</body> +</html> diff --git a/tests/unit/controlgroup/controlgroup_core.js b/tests/unit/controlgroup/controlgroup_core.js index e69de29bb..2177c767b 100644 --- a/tests/unit/controlgroup/controlgroup_core.js +++ b/tests/unit/controlgroup/controlgroup_core.js @@ -0,0 +1,77 @@ +module( "Controlgroup: Core" ); + +function hasCornerClass( element ) { + return !!element.attr( "class" ).match( /ui-corner/g ); +} + +test( "selectmenu: open/close corners", function( assert ) { + expect( 1 ); + var element = $( ".controlgroup" ).controlgroup(), + selects = element.find( "select" ), + selectButton = selects.eq( 0 ).selectmenu( "widget" ); + + expect( 12 ); + + selects.eq( 0 ).selectmenu( "open" ); + assert.hasClasses( selectButton, "ui-corner-tl", + "Horizontal: First selectmenu gets ui-corner-tl when opened" ); + + selects.eq( 0 ).selectmenu( "close" ); + assert.hasClasses( selectButton, "ui-corner-left", + "Horizontal: First selectmenu gets ui-corner-left when closed" ); + + selectButton = selects.eq( 1 ).selectmenu( "widget" ); + selects.eq( 1 ).selectmenu( "open" ); + strictEqual( hasCornerClass( selectButton ), false, + "Horizontal: Middle selectmenu does not get corner class when opened" ); + + selects.eq( 1 ).selectmenu( "close" ); + strictEqual( hasCornerClass( selectButton ), false, + "Horizontal: Middle selectmenu does not get corner class when closed" ); + + selectButton = selects.eq( 2 ).selectmenu( "widget" ); + selects.eq( 2 ).selectmenu( "open" ); + assert.hasClasses( selectButton, "ui-corner-tr", + "Horizontal: Last selectmenu gets ui-corner-tr when opened" ); + + selects.eq( 2 ).selectmenu( "close" ); + assert.hasClasses( selectButton, "ui-corner-right", + "Horizontal: Last selectmenu gets ui-corner-right when closed" ); + + element.controlgroup( "option", "direction", "vertical" ); + selectButton = selects.eq( 0 ).selectmenu( "widget" ); + selects.eq( 0 ).selectmenu( "open" ); + assert.hasClasses( selectButton, "ui-corner-top", + "vertical: First selectmenu gets ui-corner-top when opened" ); + + selects.eq( 0 ).selectmenu( "close" ); + assert.hasClasses( selectButton, "ui-corner-top", + "vertical: First selectmenu gets ui-corner-top when closed" ); + + selectButton = selects.eq( 1 ).selectmenu( "widget" ); + selects.eq( 1 ).selectmenu( "open" ); + strictEqual( hasCornerClass( selectButton ), false, + "vertical: Middle selectmenu does not get corner class when opened" ); + + selects.eq( 1 ).selectmenu( "close" ); + strictEqual( hasCornerClass( selectButton ), false, + "vertical: Middle selectmenu does not get corner class when closed" ); + + selectButton = selects.eq( 2 ).selectmenu( "widget" ); + selects.eq( 2 ).selectmenu( "open" ); + strictEqual( hasCornerClass( selectButton ), false, + "vertical: Last selectmenu does not get corner class when opened" ); + + selects.eq( 2 ).selectmenu( "close" ); + assert.hasClasses( selectButton, "ui-corner-bottom", + "vertical: Last selectmenu gets ui-corner-bottom when closed" ); +}); +test( "invisibles excluded from corner classes", function( assert ) { + expect( 2 ); + var element = $( ".controlgroup" ).controlgroup(), + buttons = element.children( ".ui-button" ); + strictEqual( hasCornerClass( buttons.eq( 0 ) ), false, + "ExcludeInvisible: true: Hidden first element does not get a corner class" ); + assert.hasClasses( buttons.eq( 1 ), "ui-corner-left", + "ExcludeInvisible: true: First button is hidden second button get corner class" ); +});
\ No newline at end of file diff --git a/tests/unit/controlgroup/core.js b/tests/unit/controlgroup/core.js new file mode 100644 index 000000000..f84136b2f --- /dev/null +++ b/tests/unit/controlgroup/core.js @@ -0,0 +1,69 @@ +define( [ + "jquery", + "ui/controlgroup", + "ui/checkboxradio", + "ui/selectmenu", + "ui/button" +], function( $ ) { + +module( "Controlgroup: Core" ); + +test( "selectmenu: open/close corners", function( assert ) { + expect( 1 ); + var element = $( ".controlgroup" ).controlgroup(), + selects = element.find( "select" ), + selectButton = selects.eq( 0 ).selectmenu( "widget" ); + + expect( 12 ); + + selects.eq( 0 ).selectmenu( "open" ); + assert.hasClasses( selectButton, "ui-corner-tl", + "Horizontal: First selectmenu gets ui-corner-tl when opened" ); + + selects.eq( 0 ).selectmenu( "close" ); + assert.hasClasses( selectButton, "ui-corner-left", + "Horizontal: First selectmenu gets ui-corner-left when closed" ); + + selectButton = selects.eq( 1 ).selectmenu( "widget" ); + selects.eq( 1 ).selectmenu( "open" ); + assert.lacksClassStart( selectButton, "ui-corner" ); + + selects.eq( 1 ).selectmenu( "close" ); + assert.lacksClassStart( selectButton, "ui-corner" ); + + selectButton = selects.eq( 2 ).selectmenu( "widget" ); + selects.eq( 2 ).selectmenu( "open" ); + assert.hasClasses( selectButton, "ui-corner-tr", + "Horizontal: Last selectmenu gets ui-corner-tr when opened" ); + + selects.eq( 2 ).selectmenu( "close" ); + assert.hasClasses( selectButton, "ui-corner-right", + "Horizontal: Last selectmenu gets ui-corner-right when closed" ); + + element.controlgroup( "option", "direction", "vertical" ); + selectButton = selects.eq( 0 ).selectmenu( "widget" ); + selects.eq( 0 ).selectmenu( "open" ); + assert.hasClasses( selectButton, "ui-corner-top", + "vertical: First selectmenu gets ui-corner-top when opened" ); + + selects.eq( 0 ).selectmenu( "close" ); + assert.hasClasses( selectButton, "ui-corner-top", + "vertical: First selectmenu gets ui-corner-top when closed" ); + + selectButton = selects.eq( 1 ).selectmenu( "widget" ); + selects.eq( 1 ).selectmenu( "open" ); + assert.lacksClassStart( selectButton, "ui-corner" ); + + selects.eq( 1 ).selectmenu( "close" ); + assert.lacksClassStart( selectButton, "ui-corner" ); + + selectButton = selects.eq( 2 ).selectmenu( "widget" ); + selects.eq( 2 ).selectmenu( "open" ); + assert.lacksClassStart( selectButton, "ui-corner" ); + + selects.eq( 2 ).selectmenu( "close" ); + assert.hasClasses( selectButton, "ui-corner-bottom", + "vertical: Last selectmenu gets ui-corner-bottom when closed" ); +}); + +} ); diff --git a/tests/unit/controlgroup/methods.js b/tests/unit/controlgroup/methods.js new file mode 100644 index 000000000..c691e4c46 --- /dev/null +++ b/tests/unit/controlgroup/methods.js @@ -0,0 +1,150 @@ +define( [ + "jquery", + "ui/controlgroup", + "ui/checkboxradio", + "ui/selectmenu", + "ui/button" +], function( $ ) { + +module( "Controlgroup: methods" ); + +test( "destroy", function( assert ) { + expect( 1 ); + assert.domEqual( ".controlgroup", function() { + $( ".controlgroup" ).controlgroup().controlgroup( "destroy" ); + }); +}); +test( "disable", function( assert ) { + expect( 2 ); + var element = $( ".controlgroup" ).controlgroup().controlgroup( "disable" ); + assert.lacksClasses( element, "ui-state-disabled", + "The widget does not get the disabled class, because we disable each child widget" ); + strictEqual( element.find( ".ui-state-disabled" ).length, 6, + "Child widgets are disabled" ); +}); + +test( "enable", function( assert ) { + expect( 2 ); + var element = $( ".controlgroup" ).controlgroup().controlgroup( "enable" ); + assert.lacksClasses( element, "ui-state-disabled", + "ui-state-disabled is not present on widget after enabling" ); + strictEqual( element.find( "ui-state-disabled" ).length, 0, + "Child widgets are disabled" ); +}); + +var tests = { + "checkboxradio": "<input type='checkbox'>", + "selectmenu": "<select><option>foo</option></select>", + "button": "<button>" + }, + orientations = { + "horizontal": [ + "ui-corner-left", + false, + false, + "ui-corner-right" + ], + "vertical": [ + "ui-corner-top", + false, + false, + "ui-corner-bottom" + ] + }; + +// Iterate through supported element markup +$.each( tests, function( widget, html ) { + + // Check in both horizontal and vertical orientations + $.each( orientations, function( name, classes ) { + + test( "refresh: " + widget + ": " + name, function( assert ) { + expect( 41 ); + + var i, control, currentClasses, + controls = [], + element = $( "<div>" ).controlgroup({ + direction: name + }).appendTo( "body" ); + + // checks the elements with in the controlgroup against the expected class list + function checkCornerClasses( classList ) { + for ( var j = 0; j < 4; j++ ) { + if ( classList[ j ] ) { + assert.hasClasses( controls[ j ][ widget ]( "widget" ), classList[ j ] ); + } else { + assert.lacksClassStart( controls[ j ][ widget ]( "widget" ), "ui-corner" ); + } + } + } + + function showElements( index, value ) { + $( value )[ widget ]( "widget" ).show(); + } + + // Hide each element and check the corner classes + function iterateHidden( excludeInvisible ) { + for ( i = 0; i < 4; i++ ) { + + $( controls ).each( showElements ); + + controls[ i ][ widget ]( "widget" ).hide(); + + currentClasses = classes.slice( 0 ); + if ( excludeInvisible ) { + if ( i === 0 ) { + currentClasses[ i + 1 ] = classes[ i ]; + currentClasses[ i ] = false; + } else if ( i === 3 ) { + currentClasses[ i - 1 ] = classes[ i ]; + currentClasses[ i ] = false; + } + } + element.controlgroup( "refresh" ); + checkCornerClasses( currentClasses ); + } + } + + // Add a label for each element and then append the element to the control group + for ( i = 0; i < 4; i++ ) { + control = $( html ).attr( "id", "id" + i ) + .add( $( "<label>" ).clone().attr( "for", "id" + i ) ); + + controls.push( control ); + element.append( control ); + } + + // Refresh the controlgroup now that its populated + element.controlgroup( "refresh" ); + for ( i = 0; i < 4; i++ ) { + strictEqual( controls[ i ].is( ":ui-" + widget ), true, + name + ": " + widget + " " + i + ": is a " + widget + " widget" ); + } + + // Check that we have the right classes + checkCornerClasses( classes ); + + // hide each element and then check its classes + iterateHidden( true ); + + // Set the exclude option to false so we no longer care about hidden + element.controlgroup( "option", "excludeInvisible", false ); + + // Iterate hiding the elements again and check their corner classes + iterateHidden(); + + // Disable the first control + controls[ 0 ].prop( "disabled", true ); + + element.controlgroup( "refresh" ); + + assert.hasClasses( controls[ 0 ][ widget ]( "widget" ), "ui-state-disabled" ); + + // remove the controlgroup before we start the next set + element.remove(); + + }); + }); +}); + +} ); diff --git a/tests/unit/controlgroup/options.js b/tests/unit/controlgroup/options.js new file mode 100644 index 000000000..82375381a --- /dev/null +++ b/tests/unit/controlgroup/options.js @@ -0,0 +1,108 @@ +define( [ + "jquery", + "ui/controlgroup", + "ui/checkboxradio", + "ui/selectmenu", + "ui/button" +], function( $ ) { + +module( "Controlgroup: options" ); + +test( "disabled", function( assert ) { + expect( 4 ); + var element = $( ".controlgroup" ).controlgroup().controlgroup( "option", "disabled", true ); + assert.lacksClasses( element, "ui-state-disabled" ); + equal( element.find( ".ui-state-disabled" ).length, 6, "Child widgets are disabled" ); + + element.controlgroup( "option", "disabled", false ); + assert.lacksClasses( element, "ui-state-disabled" ); + strictEqual( element.find( ".ui-state-disabled" ).length, 0, "Child widgets are not disabled" ); + +}); + +test( "items - null", function() { + expect( 2 ); + var element = $( ".controlgroup" ).controlgroup({ + items: { + "button": null, + "selectmenu": null, + "checkboxradio": null + } + }); + + strictEqual( element.children( ".ui-button" ).length, 0, + "Child widgets are not called when selector is null" ); + + element.controlgroup( "option", "items", { + "button": "button" + }); + strictEqual( element.children( ".ui-button" ).length, 2, + "Correct child widgets are called when selector is updated" ); +}); + +test( "items: custom selector", function() { + expect( 1 ); + var element = $( ".controlgroup" ).controlgroup({ + items: { + "button": ".button" + } + }); + strictEqual( element.children( ".ui-button" ).length, 4, + "Correct child widgets are called when custom selector used" ); +}); + +$.widget( "ui.test", { + _create: function (){ + this.element.addClass( "ui-test ui-button" ); + }, + + // Controlgroup requires a refresh method to exist + refresh: $.noop +}); +test( "items: custom widget", function() { + expect( 2 ); + var element = $( ".controlgroup" ).controlgroup({ + items: { + "test": ".test" + } + }); + + strictEqual( element.children( ".ui-button" ).length, 7, + "Correct child widgets are called when custom selector used" ); + strictEqual( element.children( ".ui-test" ).length, 1, + "Custom widget called" ); +}); + +test( "excludeInvisible", function( assert ) { + expect( 4 ); + var element = $( ".controlgroup" ).controlgroup({ + excludeInvisible: false + }), + buttons = element.children( ".ui-button" ); + + assert.lacksClassStart( buttons.eq( 1 ), "ui-corner" ); + assert.hasClasses( buttons.eq( 0 ), "ui-corner-left", + "ExcludeInvisible: false: First button hidden second button doesn't get a corner class" ); + + element.controlgroup( "option", "excludeInvisible", true ); + assert.lacksClassStart( buttons.eq( 0 ), "ui-corner" ); + assert.hasClasses( buttons.eq( 1 ), "ui-corner-left", + "ExcludeInvisible: true: First button is hidden second button get corner class" ); +}); + +test( "direction", function( assert ) { + expect( 6 ); + var element = $( ".controlgroup" ).controlgroup(), + buttons = element.children( ".ui-button" ).filter( ":visible" ); + + assert.hasClasses( element, "ui-controlgroup-horizontal" ); + assert.hasClasses( buttons.first(), "ui-corner-left" ); + assert.hasClasses( buttons.last(), "ui-corner-right" ); + + element.controlgroup( "option", "direction", "vertical" ); + assert.hasClasses( element, "ui-controlgroup-vertical" ); + assert.hasClasses( buttons.first(), "ui-corner-top" ); + assert.hasClasses( buttons.last(), "ui-corner-bottom" ); +}); + +} ); diff --git a/tests/unit/index.html b/tests/unit/index.html index fe358cb6c..091e39c41 100644 --- a/tests/unit/index.html +++ b/tests/unit/index.html @@ -41,6 +41,7 @@ <li><a href="autocomplete/autocomplete.html">Autocomplete</a></li> <li><a href="button/button.html">Button</a></li> <li><a href="checkboxradio/checkboxradio.html">Checkboxradio</a></li> + <li><a href="controlgroup/controlgroup.html">Controlgroup</a></li> <li><a href="datepicker/datepicker.html">Datepicker</a></li> <li><a href="dialog/dialog.html">Dialog</a></li> <li><a href="menu/menu.html">Menu</a></li> diff --git a/themes/base/base.css b/themes/base/base.css index 7194eba27..3b33e9bc0 100644 --- a/themes/base/base.css +++ b/themes/base/base.css @@ -14,6 +14,7 @@ @import url("autocomplete.css"); @import url("button.css"); @import url("checkboxradio.css"); +@import url("controlgroup.css"); @import url("datepicker.css"); @import url("dialog.css"); @import url("draggable.css"); diff --git a/themes/base/button.css b/themes/base/button.css index fcbcda7bb..599b5ea6a 100644 --- a/themes/base/button.css +++ b/themes/base/button.css @@ -56,6 +56,23 @@ input.ui-button.ui-button-icon-only { margin-left: -8px; } +.ui-button.ui-icon-notext .ui-icon { + padding: 0; + width: 2.1em; + height: 2.1em; + text-indent: -9999px; + white-space: nowrap; + +} + +input.ui-button.ui-icon-notext .ui-icon { + width: auto; + height: auto; + text-indent: 0; + white-space: normal; + padding: .4em 1em; +} + /* workarounds */ /* Support: FireFox >= 4 */ input.ui-button::-moz-focus-inner, diff --git a/themes/base/controlgroup.css b/themes/base/controlgroup.css new file mode 100644 index 000000000..befbdfe3e --- /dev/null +++ b/themes/base/controlgroup.css @@ -0,0 +1,30 @@ +/*! + * jQuery UI Controlgroup @VERSION + * http://jqueryui.com + * + * Copyright 2013 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/controlgroup/#theming + */ + +.ui-controlgroup { + vertical-align: middle; +} +.ui-controlgroup > .ui-button { + float: left; + margin-left: 0; + margin-right: 0; +} +.ui-controlgroup-vertical > .ui-button { + display: block; + float: none; + width: 100%; + margin-top: 0; + margin-bottom: 0; + text-align: left; +} +.ui-controlgroup-vertical label.ui-button { + box-sizing: border-box; +}
\ No newline at end of file diff --git a/ui/.DS_Store b/ui/.DS_Store Binary files differnew file mode 100644 index 000000000..94db3a523 --- /dev/null +++ b/ui/.DS_Store diff --git a/ui/controlgroup.js b/ui/controlgroup.js new file mode 100644 index 000000000..effe42d37 --- /dev/null +++ b/ui/controlgroup.js @@ -0,0 +1,205 @@ +/*! + * jQuery UI Controlgroup @VERSION + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/controlgroup/ + */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ + "jquery", + "./core", + "./widget" + ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } +}( function( $ ) { + +return $.widget( "ui.controlgroup", { + version: "@VERSION", + defaultElement: "<div>", + options: { + disabled: null, + items: { + "button": "input[type=button], input[type=submit], input[type=reset], button, a", + "checkboxradio": "input[type='checkbox'], input[type='radio']", + "selectmenu": "select" + }, + direction: "horizontal", + excludeInvisible: true + }, + + _create: function() { + this._enhance(); + }, + + // To support the enhanced option in jQuery Mobile, we isolate DOM manipulation + _enhance: function() { + this.element.attr( "role", "toolbar" ); + this.refresh(); + }, + + _destroy: function() { + this._callChildMethod( "destroy" ); + this.childWidgets.removeData( "ui-controlgroup-data" ); + this.element.removeAttr( "role" ); + }, + + _initWidgets: function() { + var that = this, + childWidgets = []; + + // First we iterate over each of the items options + $.each( this.options.items, function( widget, selector ) { + var widgets, + options = {}; + + // We assume everything is in the middle to start because we can't determine + // first / last elements until all enhancments are done. + if ( that[ "_" + widget + "_options" ] ) { + options = that[ "_" + widget + "_options" ]( "middle" ); + } + + // Make sure the widget actually exists and has a selector set + if ( $.fn[ widget ] && selector ) { + + // Find instances of this widget inside controlgroup and run method or set options + widgets = that.element.find( selector )[ widget ]( options ); + + // Don't set data or add to the collection if the method is destroy + widgets.each( function() { + + // Set data on the widget element pointing to the this.element of the widget + // and telling us what type of widget this is + var widgetElement = + $( this )[ widget ]( "widget" ).data( "ui-controlgroup-data", { + "widgetType": widget, + "element": $( this ) + } ); + + childWidgets.push( widgetElement[ 0 ] ); + } ); + } + } ); + + this.childWidgets = $( $.unique( childWidgets ) ); + }, + + _callChildMethod: function( method ) { + this.childWidgets.each( function() { + var element = $( this ), + data = element.data( "ui-controlgroup-data" ); + + data.element[ data.widgetType ]( method ); + } ); + }, + + _buildSimpleOptions: function( position, direction, key ) { + var result = { + classes: {} + }; + result.classes[ key ] = { + "middle": null, + "first": "ui-corner-" + ( direction ? "top" : "left" ), + "last": "ui-corner-" + ( direction ? "bottom" : "right" ) + }[ position ]; + + return result; + }, + + _button_options: function( position, direction ) { + return this._buildSimpleOptions( position, direction, "ui-button" ); + }, + + _checkboxradio_options: function( position, direction ) { + return this._buildSimpleOptions( position, direction, "ui-checkboxradio-label" ); + }, + + _selectmenu_options: function( position, direction ) { + return { + width: direction ? "auto" : false, + classes: { + middle: { + "ui-selectmenu-button-open": null, + "ui-selectmenu-button-closed": null + }, + first: { + "ui-selectmenu-button-open": + "ui-corner-" + ( direction ? "top" : "tl" ), + "ui-selectmenu-button-closed": + "ui-corner-" + ( direction ? "top" : "left" ) + }, + last: { + "ui-selectmenu-button-open": + direction ? null : "ui-corner-tr", + "ui-selectmenu-button-closed": + "ui-corner-" + ( direction ? "bottom" : "right" ) + } + + }[ position ] + }; + }, + + _setOption: function( key, value ) { + if ( key === "direction" ) { + this._removeClass( "ui-controlgroup-" + this.options.direction ); + } + + this._super( key, value ); + if ( key === "disabled" ) { + this._callChildMethod( value ? "disable" : "enable" ); + return; + } + + this.refresh(); + }, + + refresh: function() { + var children, + that = this; + + this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction ); + + if ( this.options.direction === "horizontal" ) { + this._addClass( null, "ui-helper-clearfix" ); + } + this._initWidgets(); + + children = this.childWidgets; + + // We filter here because we need to track all childWidgets not just the visible ones + if ( this.options.excludeInvisible ) { + children = children.filter( ":visible" ); + } + + if ( children.length ) { + + // We do this last because we need to make sure all enhancment is done + // before determining first and last + [ "first", "last" ].forEach( function( value ) { + var data = children[ value ]().data( "ui-controlgroup-data" ); + if ( that[ "_" + data.widgetType + "_options" ] ) { + data.element[ data.widgetType ]( + that[ "_" + data.widgetType + "_options" ]( + value, + that.options.direction === "vertical" + ) + ); + } + } ); + + // Finally call the refresh method on each of the child widgets. + this._callChildMethod( "refresh" ); + } + } +} ); +} ) ); |