jQuery Sortable Placeholder Height Issue

Today I searched jQuery Sortable Placeholder Height Issue because when I dragged my sortable list the placeholder was shrinking to have a 0 height. It was tough tell where exactly I was moving it to. I needed to get this working or it would drive me crazy. So I tried a couple things before I found a solution. I made sure that there was a height on the element and in my jQuery call I used the options placeholder: ‘ui-state-highlight’ and forcePlaceholderSize:true, none of these things worked. Then I found that you could set the height of the placeholder on the start event of your sortable like this.

$( ".selector" ).sortable({
   placeholder: 'ui-state-highlight',
   start: function(event, ui) {
        ui.placeholder.height(ui.item.height());
   }
});

Once I added this code and refreshed, it a beautiful site to see a jQuery sortable placeholder work.

jQuery UI Combobox Widget Improved

Today I searched for a JQuery UI Combobox. I found a custom widget on the jQuery UI site. By default it populates the combobox off of a select element. I was really wanting to load this off of a Ajax call instead, but only load the top 50 from the DB if they were to click on the arrow to browse. I made some modifications to the Combobox code to allow for the ‘source’ callback which is implemented on their current autocomplete. I also implemented the ‘select’ callback and ‘delay’ property.

I also have it setup to be able to combobox off of a text element if desired, instead of the select.

This widget should go into a js file and be included on the page

(function( $ ) {
		$.widget( "ui.combobox", {
			_create: function() {
				var self = this,
					select = this.element.hide(),
					selected = select.children( ":selected" ),
					value = select.is('input:text') ?
								select.val() :
									selected.val() ?  selected.text() : "";
				var input = this.input = $( "
" )
					.insertAfter( select )
					.val( value )
					.autocomplete({
						delay: self.options.delay ? self.options.delay : 0,
						minLength:  self.options.minLength ? self.options.minLength : 0,
						source: function( request, response ) {
							if (!self.options.source) {
								var matcher = new RegExp( $.ui.autocomplete.escapeRegex(request.term), "i" );
								response( select.children( "option" ).map(function() {
									var text = $( this ).text();
									if ( this.value && ( !request.term || matcher.test(text) ) )
										return {
											label: text.replace(
												new RegExp(
													"(?![^&;]+;)(?!<[^<>]*)(" +
													$.ui.autocomplete.escapeRegex(request.term) +
													")(?![^<>]*>)(?![^&;]+;)", "gi"
												), "$1" ),
											value: text,
											option: this
										};
								}) );
							} else {
								self.options.source(request, response);
							}
						},
						select: function( event, ui ) {
							if (!self.options.select) {
								ui.item.option.selected = true;
								self._trigger( "selected", event, {
									item: ui.item.option
								});
							} else {
								self.options.select(event, ui);
							}
						},
						change: function( event, ui ) {
							if ( !ui.item ) {
								var matcher = new RegExp( "^" + $.ui.autocomplete.escapeRegex( $(this).val() ) + "$", "i" ),
									valid = false;
								select.children( "option" ).each(function() {
									if ( $( this ).text().match( matcher ) ) {
										this.selected = valid = true;
										return false;
									}
								});
								if ( !valid ) {
									// remove invalid value, as it didn't match anything
									$( this ).val( "" );
									select.val( "" );
									input.data( "autocomplete" ).term = "";
									return false;
								}
							}
						}
					})
					.addClass( "ui-widget ui-widget-content ui-corner-left" );

				input.data( "autocomplete" )._renderItem = function( ul, item ) {
					return $( "
  • " ) .data( "item.autocomplete", item ) .append( "" + item.label + "" ) .appendTo( ul ); }; this.button = $( "" ) .attr( "tabIndex", -1 ) .attr( "title", "Show All Items" ) .insertAfter( input ) .button({ icons: { primary: "ui-icon-triangle-1-s" }, text: false }) .removeClass( "ui-corner-all" ) .addClass( "ui-corner-right ui-button-icon" ) .click(function() { // close if already visible if ( input.autocomplete( "widget" ).is( ":visible" ) ) { input.autocomplete( "close" ); return; } // work around a bug (likely same cause as #5265) $( this ).blur(); // pass empty string as value to search for, displaying all results input.autocomplete( "search", "" ); input.focus(); }).find('.ui-button-text').removeClass('ui-button-text'); //added the remove ui-button-text to remove the padding //and make it the same size as our input //see button in Message Center -> New Message for reference }, destroy: function() { this.input.remove(); this.button.remove(); this.element.show(); $.Widget.prototype.destroy.call( this ); } }); })( jQuery );

    Here is an example usage of the widget:

    $('#myTextField').combobox({
    		source: function(req,add) {
                          $.ajax({
                            url: "test.html",
                           dataType:"json",
                           success: function(data, textStatus, XMLHttpRequest){
                             add(data);
                           }
                       });
    
    		},
    		select: function(event, ui) {
                                  //call back when the user selects an item on the list
    	                        alert('Item id selected [' + ui.item.id + ']');
    		},
    		delay: 500
    		});
    

    Here is an example of json structure that the add() method takes above

    [{"id":"1","label":"Option1"},{"id":"2","label":"Option2"},{"id":"3","label":"Option3"}]
    

    This mod does not break the traditional means of creating the combobox off of a select element

    $( "#MySelectElement" ).combobox();
    

    jQuery getJSON() async false

    Today I searched jQuery getJSON() async false because I needed my jQuery Ajax call to be synchronous. It turns out that getJSON is just an Ajax shortcut in jQuery that can not have any extra parameters passed to it according to a post at Stackoverflow.com and then confirmed in the jQuery doc . So I had to turn my call back to normal jQuery.ajax().

    //before
    $.getJSON(url, data, function(json){
                                    //success code
                               });
    
    //after
    $.ajax({
      url: url,
      dataType: 'json',
      data: data,
      async: false,
      success: function(json){
                      //success code
                   }
    });
    

    As you can see the shortcut code is well, shorter, but not as flexible as the basic ajax function. Shortcuts are nice but shouldn’t be leaned on for heavy lifting.

    Round IE Corners

    Today I searched Round IE Corners and found a solution that works great with jquery UI. CurvyCorners is a free JavaScript Library made to handle rounding on all browsers, even browsers that don’t support it. CurvyCorners will use the native css3 border-radius if available other wise it will add the images nessacary to round your element. All you need to do to implement CurvyCorners is add the JavaScript file and add a rounding css class to your elements that you want to round and Curvy does the rest. Below is an example of the CSS that jQuery uses to round corners that works perfectly with CurvyCorners.

    .ui-corner-all {
     -moz-border-radius: 4px/*{cornerRadius}*/;
     -webkit-border-radius: 4px/*{cornerRadius}*/;
    }
    Go back to top