I have a <select> which I need to transform in more functional combobox.
<span class="combo_box">
<select id="state" name="state" tabindex="24">
<option value="" disabled selected style="display:none"></option>
<!-- Some JSP here -->
</select>
</span>
And I transformed it in to widget (so original <select> with id "state" is still there but hidden) like this $("#state").combobox(); What i need is to add an error highlight to this custom widget on form submission if combobox is empty. jQuery UI has a custom CSS class ui-state-error for this.
Validation script (works fine as I debug it)
function setComboboxClassBeforeSubmit(elementID) {
var flag = true;
var element = document.getElementById(elementID);
var combobox = $(element).combobox();
combobox.removeClass('ui-state-error');
if (isEmpty(element)) {
combobox.addClass('ui-state-error');
flag = false;
}
return flag;
}
But adding this CSS class seems like have no effect on widget look. Also tried hardcode like it was shown here, something like $("#state").addClass('ui-state-error') and still no luck.
Also tried this solution, works fine for selectmenu but not for combobox.
Possible solution: (thanks to nowhere)
Editing _createAutocomplete: function() like this:
_createAutocomplete: function() {
var selected = this.element.children( ":selected" ),
value = selected.val() ? selected.text() : "";
this.input = $( "<input>" )
.appendTo( this.wrapper )
.val( value )
.attr( "title", "" )
.attr( "id", "ui-" + this.element.attr("id") + "-input" )
...
Issue is - default API doesn't generate unique ID's for combobox's elements.
Can you try with the code I've made here? I operated by using the jqueryui example: http://jsfiddle.net/b5e83x2q/
function checkValue(item){
item.removeClass('ui-state-error');
if(item.val()==""){
item.addClass('ui-state-error');
}
}
checkValue($(".custom-combobox input"));
.ui-state-error{
background-color:red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="custom-combobox">
<input title="" class="custom-combobox-input ui-widget ui-widget-content ui-state-default ui-corner-left ui-autocomplete-input" autocomplete="off" value="">
</span>
EDIT:
if you need to identify a specific select you should give it a specific id: if you used the same code of the jqueryui example you should have:
_create: function() {
this.wrapper = $( "<span>" )
.addClass( "custom-combobox" )
.insertAfter( this.element );
this.element.hide();
this._createAutocomplete();
this._createShowAllButton();
}
there you might try to add something like:
this.attr('id', 'specificId');
or edit the span wrapper:
_create: function() {
this.wrapper = $( "<span>" )
.addClass( "custom-combobox" )
.insertAfter( this.element )
.attr('id', 'specificId');
this.element.hide();
this._createAutocomplete();
this._createShowAllButton();
}
After that you can use:
checkValue($("#specificId input"));
to change only 1 select.
Related
I already read all the topics there about a similar issue but no real solution.
I just received an old project using Jquery UI, the form has a autocomplete input, it works perfectly on computers & phones, when you type 3 letters minimum, it suggests a list of words.
BUT when you try the same form on iPad, nothing happens. It suggests nothing.
Here the code (based on Jquery 2.2.3 & Jquery UI 1.11.4) :
HTML :
<input type="text" class="form-control autocomplete-multiple-theme-name ui-autocomplete-input" style="width: 100%;" autocomplete="off">
<input type="hidden" class="autocomplete-multiple-theme-id">
JS :
$(".autocomplete-multiple-theme-name").autocomplete({
minLength: 3,
source: 'themes/themes_json.php',
focus: function( event, ui ) {
$(this).val( ui.item.label );
return false;
},
select: function( event, ui ) {
$(this).val( ui.item.label);
return false;
}
})
.autocomplete( "instance" )._renderItem = function( ul, item ) {
return $( "<li>" )
.append( "<div>" + item.label + "</div>" )
.appendTo( ul );
};
Any idea to fix that ?
Thanks a lot everybody !
I have a custom combo box, i search to intercept clic event when select élément of custom combo box. What i should add?
$( function() {
$.widget( "custom.combobox", {
_create: function() {
this.wrapper = $( "<span>" )
.addClass( "custom-combobox" )
.insertAfter( this.element );
this.element.hide();
this._createAutocomplete();
this._createShowAllButton();
},
_createAutocomplete: function() {
var selected = this.element.children( ":selected" ),
value = selected.val() ? selected.text() : "";
....
Thanks for help.
How to implement multiple selection with jquery (jscript) using Shift + click in list:
<div class="custom-multi-select-option">
<span class="custom-multi-select-option-label">Tollet</span>
</div>
<div class="custom-multi-select-option">
<span class="custom-multi-select-option-label">Present</span>
</div>
List on form
Simple selection implement by adding
toggleClass( "custom-multi-select-option-selected" );
I try this, but it not properly work:
var _onClickOnCustomMultiSelect = function( e ){
$( this ).toggleClass( "custom-multi-select-option-selected" );
$( this ).find(".custom-multi-select-option-label").toggleClass( "custom-multi-select-option-selected" );
if(e.shiftKey) {
$('div.custom-multi-select-option-selected').nextUntil(this).toggleClass( "custom-multi-select-option-selected" );
}
};
I have to use two jquery API's, "jquery-1.8.3.js" and "jquery-ui.js" in my code.
But there are already older versions of jquery. And because of this the form is not working properly.
So I search on net for solution and found, we can use
<script>
var jq13 = jQuery.noConflict(true);
</script>
But I have to api's, so I created two variables but still it is not working.
This is my code:-
<script>
(function( $ ) {
$.widget( "ui.combobox", {
_create: function() {
var input,
that = this,
select = this.element.hide(),
selected = select.children( ":selected" ),
value = selected.val() ? selected.text() : "",
wrapper = this.wrapper = $( "<span>" )
.addClass( "ui-combobox" )
.insertAfter( select );
function removeIfInvalid(element) {
var value = $( element ).val(),
matcher = new RegExp( "^" + $.ui.autocomplete.escapeRegex( value ) + "$", "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
$( element )
.val( "" )
.attr( "title", value + " didn't match any item" )
.tooltip( "open" );
select.val( "" );
setTimeout(function() {
input.tooltip( "close" ).attr( "title", "" );
}, 2500 );
input.data( "autocomplete" ).term = "";
return false;
}
}
input = $( "<input>" )
.appendTo( wrapper )
.val( value )
.attr( "title", "" )
.addClass( "ui-combobox-input" )
.autocomplete({
delay: 0,
minLength: 0,
source: function( request, response ) {
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"
), "<strong>$1</strong>" ),
value: text,
option: this
};
}) );
},
select: function( event, ui ) {
ui.item.option.selected = true;
that._trigger( "selected", event, {
item: ui.item.option
});
},
change: function( event, ui ) {
if ( !ui.item )
return removeIfInvalid( this );
}
})
.addClass( "ui-widget ui-widget-content ui-corner-left" );
input.data( "autocomplete" )._renderItem = function( ul, item ) {
return $( "<li>" )
.data( "item.autocomplete", item )
.append( "<a>" + item.label + "</a>" )
.appendTo( ul );
};
$( "<a>" )
.attr( "tabIndex", -1 )
//.attr( "title", "Show All Items" )
.tooltip()
.appendTo( wrapper )
.button({
icons: {
primary: "ui-icon-triangle-1-s"
},
text: false
})
.removeClass( "ui-corner-all" )
.addClass( "ui-corner-right ui-combobox-toggle" )
.click(function() {
// close if already visible
if ( input.autocomplete( "widget" ).is( ":visible" ) ) {
input.autocomplete( "close" );
removeIfInvalid( input );
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();
});
},
destroy: function() {
this.wrapper.remove();
this.element.show();
$.Widget.prototype.destroy.call( this );
}
});
})( jQuery );
$(function() {
$( "#driver_uuidHOS" ).combobox();
});
</script>
And I have declared two variables:-
<script src="js/new/jquery-1.8.3.js"></script>
<script>
var jq13 = jQuery.noConflict(true);
</script>
<script src="js/new/jquery-ui.js"></script>
<script>
var jq131 = jQuery.noConflict(true);
</script>
So please tell me where I have to use jq13 and where jq131 in my code. This code is for searchable autosuggest.
Thanks in advance.
After you load the first version, you can assign it to a variable.
var jq13 = jQuery.noConflict(true); // as you did
And then load your second jQuery version. The first one you load can be accessed with jq13(...) while the second one can be accessed with $(...).
No need for assgning variable to second script...
You want to load one version of jQuery, then all the plugins for that version, then turn on no conflict mode. You can repeat this process as many times as you'd like (once for each version of jQuery core that you need to load).
So, for your specific case what you want to do is:
<script src="js/new/jquery-1.8.3.js"></script>
<script src="js/new/jquery-ui.js"></script>
<script src="path/to/your/code.js"></script>
<script>jQuery.noConflict(true);</script>
The path/to/your/code.js refers to the block of code you have above which defines the combobox widget. In terms of supporting multiple jQuery version, it doesn't matter if this is included in-page as your example does, or as an external file as my example does. The anonymous function wrapper that you have (and all plugins should have), which stores the reference to jQuery is what makes this work. At the time those files are executed, jQuery points to the correct version, and the files stores a local reference to it as $. Later, when you can jQuery.noConflict(true), those files continue to hold their references, even though the global jQuery variable has changed. If you follow this pattern of invoking no conflict mode after loading all other files, you don't need to assign jQuery to a new variable, since all of your code will already have the necessary references. The benefit to this approach, is that you never end up with variable-specific names in your wrapper functions, and it's guaranteed to work with all existing plugins that were developed with this model, which is all official jQuery projects and likely any plugin that has thought about no conflict support.
One last thing: At the bottom of your script, you're referring to jQuery as $, but you're outside of the function wrapper that is storing the $ reference. If this is really two separate files in your app, make sure to include the wrapper in each file. If this is actually a single script as shown above, make sure to move the document ready block inside the wrapper.
I run into a problem with jQuery UI - Autocomplete and IE8.
I'm using combobox method which you can find on jQuery UI website - here
Basically, it is creating autocomplete input + select menu from select/option list.
I'm using jQuery 1.6.4 and jQuery UI 1.8.16; both from google server.
It is working perfectly on Chrome / FF / Opera, but does not work on IE8.
On IE8 - once you select something (after typing), or use dropdown button IE will reload the page. Please not that IE will not crash till you use arrows or try to select something.
res://ieframe.dll/acr_error.htm#, in the URL, in front of the actual path
or a message this tab has been reloaded; a problem with the page causes IE to close and reopen the page
Live example here
Any idea what is causing IE to act like that? Any suggestion much appreciated.
jQuery code:
<script>
(function( $ ) {
$.widget( "ui.combobox", {
_create: function() {
var self = this,
select = this.element.hide(),
selected = select.children( ":selected" ),
value = selected.val() ? selected.text() : "";
var input = this.input = $( "<input>" )
.insertAfter( select )
.val( value )
.autocomplete({
delay: 0,
minLength: 0,
source: function( request, response ) {
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"
), "<strong>$1</strong>" ),
value: text,
option: this
};
}) );
},
select: function( event, ui ) {
ui.item.option.selected = true;
self._trigger( "selected", event, {
item: ui.item.option
});
},
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 $( "<li></li>" )
.data( "item.autocomplete", item )
.append( "<a>" + item.label + "</a>" )
.appendTo( ul );
};
this.button = $( "<button type='button'> </button>" )
.attr( "tabIndex", -1 )
.attr( "title", "Show All Items" )
.insertAfter( input )
.button({
text: false
})
.removeClass( "ui-corner-all" )
.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();
});
},
destroy: function() {
this.input.remove();
this.button.remove();
this.element.show();
$.Widget.prototype.destroy.call( this );
}
});
})( jQuery );
$(document).ready( function() {
$("#combobox").combobox();
});
</script>
I'm still trying to work out why IE8 is crashing but it does work for me when you add a jQueryUI theme to the page, for example:
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/cupertino/jquery-ui.css">
Edit: I think I know which line it is crashing on, but I still do not know why! In the jQueryUI code activate: function( event, item ) {
is the following code which adds style and an attribute to the active item.
this.active = item.eq(0)
.children("a")
.addClass("ui-state-hover")
.attr("id", "ui-active-menuitem")
.end();
For some reason, IE8 crashes here, although for me sometimes does not crash when I remove the .addClass and .attr lines.
Edit 2: OK, for some reason IE is crashing with your .ui-autocomplete style. If you change overflow:scroll; to overflow:auto; then IE8 does not crash. Alternatively change max-height to just height, which also fixes it. Guess it's a bug in IE either with max-height (maybe IE8 overflow:auto with max-height) or overflow.
From the first glance this line look strange to me:
if ( this.value && ( !request.term || matcher.test(text) ) )
return {
But its working fine for me in ie8, in ie7 its not working at all.
Try if(){return{...}}.
quick look finds your script tag is missing required type attribute
<script type="text/javascript">
I reproduced the issue, copied the file local with no CSS and no fails.
Odd, IF on the original page, I disable CSS using the IE developer tools, it does not crash.