JQuery Autocomplete will not allow selection from dropdown IE - javascript

My code works on the I.E. 9, Chrome, and Safari, but numerous people are having problems with older versions of Internet Explorer and current version of Firefox. It displays the drop down selections as it is supposed to but will not allow the users to click a selection. Here is the code:
<script type="text/javascript" src="js/jquery-1.6.2.js"></script>
<script type="text/javascript" src="js/jquery.ui.core.js"></script>
<script type="text/javascript" src="js/jquery.ui.datepicker.js"></script>
<script type="text/javascript" src="js/jquery.ui.widget.js"></script>
<script type="text/javascript" src="js/jquery.ui.position.js"></script>
<script type="text/javascript" src="js/jquery.ui.autocomplete.js"></script>
<link type="text/css" href="css/jquery-ui-1.8.17.custom.css" rel="Stylesheet" />
<style>
.ui-autocomplete-loading { background: white url('images/ui-anim_basic_16x16.gif') right center no-repeat; }
</style>
<script>
$(function() {
function log( message ) {
$( "<div/>" ).text( message ).prependTo( "#inputString" );
$( "#inputString" ).scrollTop( 0 );
showCar(message);
}
$( "#inputString" ).autocomplete({
source: "ajax/search.php",
minLength: 1,
select: function( event, ui ) {
log( ui.item ?
"Selected: " + ui.item.value :
"Nothing selected, input was " + this.value );
}
});
});
</script>
Using the development tools, it shows up this error in the console: SCRIPT65535: Unexpected call to method or property access.
jquery-1.6.2.js, line 5609 character 5
which points to this:
prepend: function() {
return this.domManip(arguments, true, function( elem ) {
if ( this.nodeType === 1 ) {
this.insertBefore( elem, this.firstChild );
}
});
},
EDIT
Now its throwing an error saying: SCRIPT438: Object doesn't support property or method 'prepend'
jquery-1.6.2.js, line 5975 character 4
which is :
jQuery.each({
appendTo: "append",
prependTo: "prepend",
insertBefore: "before",
insertAfter: "after",
replaceAll: "replaceWith"
}, function( name, original ) {
jQuery.fn[ name ] = function( selector ) {
var ret = [],
insert = jQuery( selector ),
parent = this.length === 1 && this[0].parentNode;
if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
insert[ original ]( this[0] );
return this;
} else {
for ( var i = 0, l = insert.length; i < l; i++ ) {
var elems = (i > 0 ? this.clone(true) : this).get();
jQuery( insert[i] )[ original ]( elems );
ret = ret.concat( elems );
}
return this.pushStack( ret, name, insert.selector );
}
};
});
Line 5974 is the top line in this section:
if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
insert[ original ]( this[0] );
return this;
}

If you use compilation for your project, you might consider to install and add at the top of your entry point - file
import 'core-js'
At the moment core-js polyfill library is the easiest way to make Cross Browser Support

Related

How can I use this multiselect dropdown twice on one page so each instance outputs to its own array?

I want to place two separate multiselct dropdown menus on one page for a form I am designing.
I found this lovely dropdown with checkboxes that I would like to use:
https://codepen.io/bseth99/pen/fboKH
I am trying to figure out the best way to run two instances of this dropdown on the same page, so that each dropdown's selections are saved in their own array.
var options = [];
$( '.dropdown-menu a' ).on( 'click', function( event ) {
var $target = $( event.currentTarget ),
val = $target.attr( 'data-value' ),
$inp = $target.find( 'input' ),
idx;
if ( ( idx = options.indexOf( val ) ) > -1 ) {
options.splice( idx, 1 );
setTimeout( function() { $inp.prop( 'checked', false ) }, 0);
} else {
options.push( val );
setTimeout( function() { $inp.prop( 'checked', true ) }, 0);
}
$( event.target ).blur();
console.log( options );
return false;
});
Right now, if I place two instances of the button's HTML on my page, both dropdowns will modify the same "options" array because it's using a class selector for dropdown-menu. I know I can use an ID selector instead of a class selector, and then just use the same block of jQuery over again with a different array, but is that really the best way to do this? I am new to jQuery but that seems bloated.
$( '.dropdown-menu a' ).on( 'click', function( event ) {
var $target = $( this ),
val = $target.data( 'value' ),
$inp = $target.find( 'input' ),
idx;
var options = $target.closest('.dropdown-menu').data('options') || [];
if ( ( idx = options.indexOf( val ) ) > -1 ) {
options.splice( idx, 1 );
setTimeout( function() { $inp.prop( 'checked', false ) }, 0);
} else {
options.push( val );
setTimeout( function() { $inp.prop( 'checked', true ) }, 0);
}
$target.closest('.dropdown-menu').data('options', options);
$( event.target ).blur();
return false;
});
console.log($( '.dropdown-menu:eq(0)' ).data('options'));

jquery single slide handle

I have a HTML page with an ordinary jquery slider from jquery 1.12.1
But the slider has 2 handles and I can't manage to find the line of code that generates two handles. I've deleted the "values [x,y]" part in the script on my html, but it still gives two handles.
I think this is the JavaScript that generates it, but I'm not familiar with JS, so
_createHandles: function() {
var i, handleCount,
options = this.options,
existingHandles = this.element.find( ".ui-slider-handle" ),
handle = "<span tabindex='0'></span>",
handles = [];
handleCount = ( options.values && options.values.length ) || 1;
if ( existingHandles.length > handleCount ) {
existingHandles.slice( handleCount ).remove();
existingHandles = existingHandles.slice( 0, handleCount );
}
for ( i = existingHandles.length; i < handleCount; i++ ) {
handles.push( handle );
}
this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
this._addClass( this.handles, "ui-slider-handle", "ui-state-default" );
this.handle = this.handles.eq( 0 );
this.handles.each( function( i ) {
$( this )
.data( "ui-slider-handle-index", i )
.attr( "tabIndex", 0 );
} );
I think this is the piece that does something, but I can't understand it's variables; where they come from.
for ( i = existingHandles.length; i < handleCount; i++ ) {
handles.push( handle );
}
If somebody knows how to delete this piece of code whilst making the handle appear afterwards (I tried to delete different lines, but that didn't work), Thank you very much in advance!
That is a for loop that I believe creates a handle as long as i is less than the variable handleCount. You will need to change the variable handleCount so that the for loop only executes once, thus creating one handle.
something like:
handleCount = 1;
You just need to remove the range: true option.
When this is removed, you are left with a slider with only 1 handle.
range: If set to true, the slider will detect if you have two handles
and create a styleable range element between these two.
http://api.jqueryui.com/slider/#option-range
Also, if you only want one handle, you should probably just use the value property, instead of values.
http://api.jqueryui.com/slider/#option-value
$(function(){
//creates 2 handles
$( ".example-a" ).slider({
range: true,
values: [0]
});
//creates 1 handle slider
$( ".example-b" ).slider({
values: [0]
});
//also creates 1 handle slider
$( ".example-c" ).slider({
value: 0
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.0/jquery-ui.min.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<h2>Example A - 2 handles<h2>
<div class="example-a"></div>
<h2>Example B - 1 handle (values)<h2>
<div class="example-b"></div>
<h2>Example C - 1 handle (value)<h2>
<div class="example-c"></div>
Okay, so that's fixed, but one thing remains and that is that JS now searches for the other handle to create a colour in the spacing between the two.
if ( !this.range || !this.range.length ) {
this.range = $( "<div>" )
.appendTo( this.element );
this._addClass( this.range, "ui-slider-range" );
} else {
this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" );
// Handle range switching from true to min/max
this.range.css( {
"left": "",
"bottom": ""
} );
}
if ( options.range === "min" || options.range === "max" ) {
this._addClass( this.range, "ui-slider-range-" + options.range );
}
} else {
if ( this.range ) {
this.range.remove();
}
this.range = null;
}
},
Maybe this is something I have to rewrite. I don't know.
// Handle range switching from true to min/max
this.range.css( {
"left": "",
"bottom": ""

Uncaught TypeError: Cannot read property 'match' of undefined

with this piece of jQuery I check if some fields are match or are not empty, but I get this error.
Uncaught TypeError: Cannot read property 'match' of undefined
Can anyone tell me what I am doing wrong here?
if ( width.match( /^\d+$/ ) && height.match( /^\d+$/ ) && type.length > 0 && color.length > 0 ) {
This is the full code:
if( $( "#config" ) ) {
$( 'input, select' ).on( 'change', function(){
var width = $( "#config-steps #width" ).val();
var height = $( "#config-steps #height" ).val();
var type = $( "#config-steps #type" ).val();
var color = $( "#config-steps #selected-color" ).val();
if ( width.match( /^\d+$/ ) && height.match( /^\d+$/ ) && type.length > 0 && color.length > 0 ) {
$( "#checkout-message" ).show();
// Change visible price
$( "#change-price" ).html( calculate_price().toFixed( 2 ) );
} else {
return false;
}
});
}
if( $( "#config" ) ) {
is always going to be true with jQuery since jQuery returns an object and objects are truthy. The check should be checking the length which will return a number and zero is false.
if ($("#config").length) {
Now when jQuery does not find an element, than val() will return undefined, so it is not finding the element.

If query fails with AND but works with OR

I search a JSON tree with jQuery on keyup-event. If the input is equal to the desired entry the input will disabled.
Now I need to call a function if they all are filled and correct. The if queries are long so i have written them into variables.
I've tried this, but it fails:
if (simple_present && simple_past && past_participle) {
alert('All right!');
}
Now, when I write something like this, it works:
if (simple_present || simple_past || past_participle) {
alert('All right!');
}
Here's a fiddle of what I have so far.
Any ideas?
BTW: What is the best way to combine long if queries with reg expressions​?
Consider this:
var json = {
"vocables": {
"irregular": {
"sein": {
"simple_present": "be",
"simple_past": "was were",
"past_participle": "been"
},
"schlagen": {
"simple_present": "beat",
"simple_past": "beat",
"past_participle": "beaten"
},
"werden": {
"simple_present": "become",
"simple_past": "became",
"past_participle": "become"
}
}
}
};
var word = $( 'h1' ).text();
$( 'input' ).on( 'keyup', function () {
if ( this.value === json.vocables.irregular[ word ][ this.id ] ) {
$( this ).prop( 'disabled', true ).next( 'input' ).focus();
}
if ( $( 'input:not(:disabled)' ).length === 0 ) {
alert( 'SUCCESS' );
}
});
Live demo: http://jsfiddle.net/NnAMu/1/
As you can see, I have:
changed the JSON structure to suit my needs better,
cached the current word into a variable.
With those changes, the resulting "keyup" handler code is much simpler.
You run all of the following code in the same event handler for each element:
$this.attr('id') == 'simple_present'
$this.attr('id') == 'simple_past'
$this.attr('id') == 'past_participle'
They can't be all true, so && is guaranteed to give you false.
Add a debug line just before the if:
alert( simple_present.toString() + '\n' + simple_past.toString() + '\n' + past_participle.toString() );

Trigger onmouseover event programmatically in JavaScript

Is there a way to programmatically trigger the onmouseover event in plain JavaScript? or "extract" the method from the onmouseover event to call it directly?
eg
<div id="bottom-div" onmouseover="myFunction('some param specific to bottom-div');">
<div id="top-div" onmouseover="????????"></div>
</div>
top-div is above bottom-div, so the onmouseover won't get fired in bottom-div. i need a way of calling myFunction('some param specific to bottom-div'); from top-div
const mouseoverEvent = new Event('mouseover');
whateverElement.dispatchEvent(mouseoverEvent);
This worked for me in IE9 at least. Should be cross-browser compatible or close to it...
function FireEvent( ElementId, EventName )
{
if( document.getElementById(ElementId) != null )
{
if( document.getElementById( ElementId ).fireEvent )
{
document.getElementById( ElementId ).fireEvent( 'on' + EventName );
}
else
{
var evObj = document.createEvent( 'Events' );
evObj.initEvent( EventName, true, false );
document.getElementById( ElementId ).dispatchEvent( evObj );
}
}
}
For onmouseover example, call the function like this
FireEvent( ElementId, "mouseover" );
For me following worked:
​document.getElementById('xyz').dispatchEvent(new MouseEvent('mouseover', { 'bubbles': true }));
Also:
​document.getElementById('xyz').dispatchEvent(new MouseEvent('mouseover', { 'view': window, 'bubbles': true, 'cancelable': true }));
Without going into too much detail, I had an img with rollovers, i.e. mouseout/overs that set the img src to hidden form values (or this could have done in a different context with gloabl variables). I used some javascript to swap both of my over/out image values and I called the called FireEvent( ElementId, "mouseover" ); to trigger the change. My javascript was hiding / displaying elements on the page. This caused the cursor to sometimes be over the img I used to trigger the event - which was the same as the one I was swapping out, and sometimes the cursor was not over the img after the click.
Mouseover/out does not fire unless you exit and re-enter an element, so after my event was triggered the mouseover/out needed "retriggering" to account for the new cursor position. Here is my solution. After I hide / display various page elements, and to do my img src swapping as described, I call the function RefreshMouseEvents( ElementId ) instead of FireEvent( ElementId, "mouseover" ).
This works in IE9 (not sure about other browsers).
function RefreshMouseEvents( ElementId )
{
FireEvent( ElementId, 'mouseover' );
setTimeout( "TriggerMouseEvent( '" + ElementId + "' )" , 1 );
}
function TriggerMouseEvent( ElementId )
{
if( IsMouseOver( ElementId, event.clientX, event.clientY ) )
FireEvent( ElementId, 'mouseover' );
else
FireEvent( ElementId, 'mouseout' );
}
function IsMouseOver( ElementId, MouseXPos, MouseYPos )
{
if( document.getElementById(ElementId) != null )
{
var Element = document.getElementById(ElementId);
var Left = Element.getBoundingClientRect().left,
Top = Element.getBoundingClientRect().top,
Right = Element.getBoundingClientRect().right,
Bottom = Element.getBoundingClientRect().bottom;
return ( (MouseXPos >= Left) && (MouseXPos <= Right) && (MouseYPos >= Top) && (MouseYPos <= Bottom))
}
else
return false;
}
function FireEvent( ElementId, EventName )
{
if( document.getElementById(ElementId) != null )
{
if( document.getElementById( ElementId ).fireEvent )
{
document.getElementById( ElementId ).fireEvent( 'on' + EventName );
}
else
{
var evObj = document.createEvent( 'Events' );
evObj.initEvent( EventName, true, false );
document.getElementById( ElementId ).dispatchEvent( evObj );
}
}
}
I had to revise my RefreshMouseEvents set of functions after more testing. Here is the seemingly perfected version (again only IE9 tested):
function RefreshMouseEvents( ElementId )
{
FireEvent( ElementId, 'mouseover' );
setTimeout( "TriggerMouseEvent( '" + ElementId + "', '" + event.clientX + "', '" + event.clientY + "' )", 1 );
}
function TriggerMouseEvent( ElementId, MouseXPos, MouseYPos )
{
if( IsMouseOver( ElementId, (1*MouseXPos), (1*MouseYPos) ) )
FireEvent( ElementId, 'mouseover' );
else
FireEvent( ElementId, 'mouseout' );
}
function IsMouseOver( ElementId, MouseXPos, MouseYPos )
{
if( document.getElementById(ElementId) != null )
{
var Element = document.getElementById(ElementId);
var Left = Element.getBoundingClientRect().left,
Top = Element.getBoundingClientRect().top,
Right = Element.getBoundingClientRect().right,
Bottom = Element.getBoundingClientRect().bottom;
return ( (MouseXPos >= Left) && (MouseXPos <= Right) && (MouseYPos >= Top) && (MouseYPos <= Bottom))
}
else
return false;
}
function FireEvent( ElementId, EventName )
{
if( document.getElementById(ElementId) != null )
{
if( document.getElementById( ElementId ).fireEvent )
{
document.getElementById( ElementId ).fireEvent( 'on' + EventName );
}
else
{
var evObj = document.createEvent( 'Events' );
evObj.initEvent( EventName, true, false );
document.getElementById( ElementId ).dispatchEvent( evObj );
}
}
}
I needed to do something similar, but I'm using jQuery, and I found this to be a better solution:
Use jQuery's trigger function.
$j('#top-div' ).trigger( 'mouseenter' );
You can also add parameters to it if you need to. See the jQuery documentation on .trigger.
​<a href="index.html" onmouseover="javascript:alert(0);" id="help"​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​>help</a>​​​​​​​​​​​​​​​​​​​​​​​​​​​
​document.getElementById('help').onmouseover();​​​​​​​
I was working with Angular and trying to do a similar thing.
I fall on this answer from StackOverflow Click here
Basically the idea is to add and remove the hover class
public addHoverOnClick() {
const yourElement = document.getElementById('elementID') as HTMLElement;
yourElement .classList.add('hover')
}
public removeHoverOnClick() {
const yourElement = document.getElementById('elementID') as HTMLElement;
yourElement .classList.remove('hover')
}
You would do it something like this:
document.getElementById('top-div').onmouseover();
However, as mentioned in the comments, it would be worth testing before being considered an issue.

Categories

Resources