Normal Navigation of Tab button get stuck over this text box in Mozilla Firefox browser. On Tab key press it's not moving to next element. Working fine in IE and Chrome. Can anyone assist me to fix this?
<div class="editor-field">
<div>
<input id="Rentaljeepshop" class="ui-autocomplete-input" type="text" value="Budget Rent A Car" name="Rentaljeepshop" maxlength="50" isautocomplete="true" autocomplete="off" role="textbox" aria-autocomplete="list" aria-haspopup="true"></input>
/div>
</div>
My Jquery is:
(function( $, undefined ) {
$.widget( "ui.autocomplete", {
options: {
appendTo: "body",
delay: 300,
minLength: 1,
position: {
my: "left top",
at: "left bottom",
collision: "none"
},
source: null
},
_create: function() {
var self = this,
doc = this.element[ 0 ].ownerDocument;
this.element
.addClass( "ui-autocomplete-input" )
.attr( "autocomplete", "off" )
// TODO verify these actually work as intended
.attr({
role: "textbox",
"aria-autocomplete": "list",
"aria-haspopup": "true"
})
.bind( "keydown.autocomplete", function( event ) {
if ( self.options.disabled ) {
return;
}
var keyCode = $.ui.keyCode;
switch( event.keyCode ) {
case keyCode.PAGE_UP:
self._move( "previousPage", event );
break;
case keyCode.PAGE_DOWN:
self._move( "nextPage", event );
break;
case keyCode.UP:
self._move( "previous", event );
// prevent moving cursor to beginning of text field in some browsers
event.preventDefault();
break;
case keyCode.DOWN:
self._move( "next", event );
// prevent moving cursor to end of text field in some browsers
event.preventDefault();
break;
case keyCode.ENTER:
case keyCode.NUMPAD_ENTER:
// when menu is open or has focus
if ( self.menu.element.is( ":visible" ) ) {
event.preventDefault();
}
//passthrough - ENTER and TAB both select the current element
case keyCode.TAB:
if ( !self.menu.active ) {
return;
}
self.menu.select( event );
break;
case keyCode.ESCAPE:
self.element.val( self.term );
self.close( event );
break;
default:
// keypress is triggered before the input value is changed
clearTimeout( self.searching );
self.searching = setTimeout(function() {
// only search if the value has changed
if ( self.term != self.element.val() ) {
self.selectedItem = null;
self.search( null, event );
}
}, self.options.delay );
break;
}
})
.bind( "focus.autocomplete", function() {
if ( self.options.disabled ) {
return;
}
self.selectedItem = null;
self.previous = self.element.val();
})
.bind( "blur.autocomplete", function( event ) {
if ( self.options.disabled ) {
return;
}
clearTimeout( self.searching );
// clicks on the menu (or a button to trigger a search) will cause a blur event
self.closing = setTimeout(function() {
self.close( event );
self._change( event );
}, 150 );
});
this._initSource();
this.response = function() {
return self._response.apply( self, arguments );
};
this.menu.element.hide();this.menu = $( "<ul></ul>" )
.addClass( "ui-autocomplete" )
.appendTo( $( this.options.appendTo || "body", doc )[0] )
// prevent the close-on-blur in case of a "slow" click on the menu (long mousedown)
.mousedown(function( event ) {
// clicking on the scrollbar causes focus to shift to the body
// but we can't detect a mouseup or a click immediately afterward
// so we have to track the next mousedown and close the menu if
// the user clicks somewhere outside of the autocomplete
var menuElement = self.menu.element[ 0 ];
if ( event.target === menuElement ) {
setTimeout(function() {
$( document ).one( 'mousedown', function( event ) {
if ( event.target !== self.element[ 0 ] &&
event.target !== menuElement &&
!$.ui.contains( menuElement, event.target ) ) {
self.close();
}
});
}, 1 );
}
// use another timeout to make sure the blur-event-handler on the input was already triggered
setTimeout(function() {
clearTimeout( self.closing );
}, 13);
})
.menu({
focus: function( event, ui ) {
var item = ui.item.data( "item.autocomplete" );
if ( false !== self._trigger( "focus", null, { item: item } ) ) {
// use value to match what will end up in the input, if it was a key event
if ( /^key/.test(event.originalEvent.type) ) {
self.element.val( item.value );
}
}
},
selected: function( event, ui ) {
var item = ui.item.data( "item.autocomplete" ),
previous = self.previous;
// only trigger when focus was lost (click on menu)
if ( self.element[0] !== doc.activeElement ) {
self.element.focus();
self.previous = previous;
}
if ( false !== self._trigger( "select", event, { item: item } ) ) {
self.element.val( item.value );
}
self.close( event );
self.selectedItem = item;
},
blur: function( event, ui ) {
// don't set the value of the text field if it's already correct
// this prevents moving the cursor unnecessarily
if ( self.menu.element.is(":visible") &&
( self.element.val() !== self.term ) ) {
self.element.val( self.term );
}
}
})
.zIndex( this.element.zIndex() + 1 )
// workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
.css({ top: 0, left: 0 })
.hide()
.data( "menu" );
if ( $.fn.bgiframe ) {
this.menu.element.bgiframe();
}
},
destroy: function() {
this.element
.removeClass( "ui-autocomplete-input" )
.removeAttr( "autocomplete" )
.removeAttr( "role" )
.removeAttr( "aria-autocomplete" )
.removeAttr( "aria-haspopup" );
this.menu.element.remove();
$.Widget.prototype.destroy.call( this );
},
What is this code means ? I guess the code given below is not complete.
case keyCode.TAB:
if ( !self.menu.active ) {
return;
}
self.menu.select( event );
break;
Suggestion: Check your firebug console, if there will be any kind of JavaScript error, it will be displayed over there.
Related
When I click a menu item on Underscores that takes me to another page, then use the browser back button, the navigation is shown. I want to remove the active state from the navigation when an item is clicked. I've pasted what I've tried, but I get:
Uncaught TypeError: links.addEventListener is not a function
JS
( function() {
const siteNavigation = document.getElementById( 'navigation-outer' ); //changed from 'site-navigation' in default Underscores
// Return early if the navigation doesn't exist.
if ( ! siteNavigation ) {
return;
}
const button = siteNavigation.getElementsByTagName( 'button' )[ 0 ];
// Return early if the button doesn't exist.
if ( 'undefined' === typeof button ) {
return;
}
const menu = siteNavigation.getElementsByTagName( 'ul' )[ 0 ];
// Hide menu toggle button if menu is empty and return early.
if ( 'undefined' === typeof menu ) {
button.style.display = 'none';
return;
}
if ( ! menu.classList.contains( 'nav-menu' ) ) {
menu.classList.add( 'nav-menu' );
}
// Toggle the .toggled class and the aria-expanded value each time the button is clicked.
button.addEventListener( 'click', function() {
siteNavigation.classList.toggle( 'toggled' );
if ( button.getAttribute( 'aria-expanded' ) === 'true' ) {
button.setAttribute( 'aria-expanded', 'false' );
body.className = body.className.replace( ' noscroll', '' ); // My modification
} else {
button.setAttribute( 'aria-expanded', 'true' );
body.className += ' noscroll'; // My modification
}
} );
// Remove the .toggled class and set aria-expanded to false when the user clicks outside the navigation.
document.addEventListener( 'click', function( event ) {
const isClickInside = siteNavigation.contains( event.target );
if ( ! isClickInside ) {
siteNavigation.classList.remove( 'toggled' );
button.setAttribute( 'aria-expanded', 'false' );
}
} );
// Get all the link elements within the menu.
const links = menu.getElementsByTagName( 'a' );
// Close menu on item click.
links.addEventListener( 'click', function( event ) {
siteNavigation.classList.remove( 'toggled' );
button.setAttribute( 'aria-expanded', 'false' );
body.className = body.className.replace( ' noscroll', '' );
} );
// Get all the link elements with children within the menu.
const linksWithChildren = menu.querySelectorAll( '.menu-item-has-children > a, .page_item_has_children > a' );
// Toggle focus each time a menu link is focused or blurred.
for ( const link of links ) {
link.addEventListener( 'focus', toggleFocus, true );
link.addEventListener( 'blur', toggleFocus, true );
}
// Toggle focus each time a menu link with children receive a touch event.
for ( const link of linksWithChildren ) {
link.addEventListener( 'touchstart', toggleFocus, false );
}
/**
* Sets or removes .focus class on an element.
*/
function toggleFocus() {
if ( event.type === 'focus' || event.type === 'blur' ) {
let self = this;
// Move up through the ancestors of the current link until we hit .nav-menu.
while ( ! self.classList.contains( 'nav-menu' ) ) {
// On li elements toggle the class .focus.
if ( 'li' === self.tagName.toLowerCase() ) {
self.classList.toggle( 'focus' );
}
self = self.parentNode;
}
}
if ( event.type === 'touchstart' ) {
const menuItem = this.parentNode;
event.preventDefault();
for ( const link of menuItem.parentNode.children ) {
if ( menuItem !== link ) {
link.classList.remove( 'focus' );
}
}
menuItem.classList.toggle( 'focus' );
}
}
}() );
Try catching elements by id with getElementById instead of getElementsByTagName.
I am using the snippet found at to http://tympanus.net/Development/MorphingSearch/ enlarge a search box when it is clicked..
<script>
(function() {
var morphSearch = document.getElementById( 'morphsearch' ),
searchlink = document.getElementById( 'mybtn' ),
input = morphSearch.querySelector( 'input.morphsearch-input' ),
ctrlClose = morphSearch.querySelector( 'span.morphsearch-close' ),
isOpen = isAnimating = false,
// show/hide search area
toggleSearch = function(evt) {
// return if open and the input gets focused
if( evt.type.toLowerCase() === 'focus' && isOpen ) return false;
if( isOpen ) {
classie.remove( morphSearch, 'open' );
// trick to hide input text once the search overlay closes
// todo: hardcoded times, should be done after transition ends
if( input.value !== '' ) {
setTimeout(function() {
classie.add( morphSearch, 'hideInput' );
setTimeout(function() {
classie.remove( morphSearch, 'hideInput' );
input.value = '';
}, 300 );
}, 500);
}
input.blur();
}
else {
classie.add( morphSearch, 'open' );
}
isOpen = !isOpen;
};
// events
searchlink.addEventListener( 'click', toggleSearch );
ctrlClose.addEventListener( 'click', toggleSearch );
// esc key closes search overlay
// keyboard navigation events
document.addEventListener( 'keydown', function( ev ) {
var keyCode = ev.keyCode || ev.which;
if( keyCode === 27 && isOpen ) {
toggleSearch(ev);
}
} );
/***** for demo purposes only: don't allow to submit the form *****/
morphSearch.querySelector( 'button[type="submit"]' ).addEventListener( 'click', function(ev) { ev.preventDefault(); } );
})();
</script>
All works great but as the search box is in a fixed header the page content jumps to the top when the link is clicked.
Previously when this has happened i have inserted the following...
event.preventDefault();
I can't work out where to insert this in this code though, can anyone help?
You insert it in the function that is called by the click event handlers
toggleSearch = function(evt) {
if (evt.type === 'click') {
evt.preventDefault();
}
// rest of code
}
searchlink.addEventListener( 'click', toggleSearch );
ctrlClose.addEventListener( 'click', toggleSearch );
Note the condition, it's to make sure the default action isn't prevented when the keydown handler is calling the same function
So I have a multipush menu which is great ... it has a js file that you can add classes of things that also get pushed when the menu is activated, which is also great... problem is ie9 doesn't understand the jquery plugin and i am trying to create a i.e9 snippet to help here is the original code ...
$(document).ready(function(){
// HTML markup implementation, overlap mode
$( '#menu' ).multilevelpushmenu({
containersToPush: [$( '.tile-area-title'), ( '.navbtn'), ( '.tile-area-main' ), ('#logo-title'), ('.submenu-ctn')],
collapsed: true,
// Just for fun also changing the look of the menu
wrapperClass: 'mlpm_w',
menuInactiveClass: 'mlpm_inactive'
});
this is the code for the .navbtn when clicked do some stuff which also works with all browsers...
$(document).ready(function () {
var $navToggle = $('.nav-toggle');
$(".navbtn").click(function (e) {
e.stopPropagation();
if($navToggle.hasClass('active')){
$('#menu').multilevelpushmenu('collapse');
$navToggle.removeClass('active');
$(this).addClass('active');
}
else{
$('#menu').multilevelpushmenu('expand');
$navToggle.addClass('active');
$(this).removeClass('active');
}
});
$(".navbtn").hover(function () {
$('.nav-toggle').addClass('hover');
},function(){
$('.nav-toggle').removeClass('hover');
});
$('#menu').on('click', function(e) {
e.stopPropagation();
});
$('body').on('click', function(e){
$('#menu').multilevelpushmenu('collapse');
$navToggle.removeClass('active');
});
});
But I have added in this i.e9 detection and do stuff script which i have appended to the above code ...
if ((old_ie > -1) || (new_ie > -1)) {
ms_ie = true;
}
if ( ms_ie ) {
$(".navbtn").click(function (e) {
({
containersToPush: [$( '.tile-area-title'), ( '.navbtn'), ( '.tile-area-main' ), ('#logo-title'), ('.submenu-ctn')],
collapsed: false
});
}
)}
but it doesn't work... all I want to do is push a couple of classes on the screen when the menu opens/closes can someone help out ?
EDIT :-
When the menu button is clicked f12 developer options reveals the folloowing ....
multilevelpushmenu.js, line 612 character 6
SCRIPT5007: Unable to get value of the property 'defaultView': object is null or undefined
and that relates to this code in the js file ...
// Push container(s) of choice
function pushContainers( absMove ) {
if( instance.settings.containersToPush == null ) return false;
$.each( instance.settings.containersToPush, function() {
var lMr = parseInt( $( this ).css( 'margin-left' ) ),
lM = isInt( lMr ) ? lMr : 0,
rMr = parseInt( $( this ).css( 'margin-right' ) ),
rM = isInt( rMr ) ? rMr : 0;
$( this ).stop().animate({
marginLeft: lM + ( ( instance.settings.direction == 'rtl' ) ? (-1) : 1 ) * absMove,
marginRight: rM + ( ( instance.settings.direction == 'rtl' ) ? 1 : (-1) ) * absMove
});
});
}
... so i am thinking the function pushContainers is not right for ie9 ?
I do not want my Fire Event function in the following code to return a boolean. I think this can be done by removing the event listener but I am not sure how.
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 ); } } }
Please help. Thanks :)
i have a function which selects a div when double clicked, the problem is i can't unselect it afterwards , here is the script
CSS:
div.editable
{
border: solid 2px Transparent;
padding-left: 15px;
padding-right: 15px;
}
div.editable:hover
{
border-color: black;
}
</style>
SCRIPT:
// Uncomment the following code to test the "Timeout Loading Method".
// CKEDITOR.loadFullCoreTimeout = 5;
window.onload = function() {
// Listen to the double click event.
if ( window.addEventListener )
document.body.addEventListener( 'dblclick', onDoubleClick, false );
else if ( window.attachEvent )
document.body.attachEvent( 'ondblclick', onDoubleClick );
};
function onDoubleClick( ev ) {
// Get the element which fired the event. This is not necessarily the
// element to which the event has been attached.
var element = ev.target || ev.srcElement;
// Find out the div that holds this element.
var name;
do {
element = element.parentNode;
}
while ( element && ( name = element.nodeName.toLowerCase() ) &&
( name != 'div' || element.className.indexOf( 'editable' ) == -1 ) && name != 'body' );
if ( name == 'div' && element.className.indexOf( 'editable' ) != -1 )
replaceDiv( element );
}
var editor;
function replaceDiv( div ) {
if ( editor )
editor.destroy();
editor = CKEDITOR.replace( div );
}
</script>
DIV:
<div class="editable" style="height:490px;overflow:auto;" id="text2">
<p>Click Here to edit</p>";
</div>
what i want to achieve is when i click outside or click another object or a button the div will unselect automatically.
The same way as you already handle the double click:
// Listen to the click event.
if ( window.addEventListener )
document.body.addEventListener( 'click', yourCallback, false );
else if ( window.attachEvent )
document.body.attachEvent( 'click', yourCallback );
This event will fire until another click handler is attached to a child element of body. In yourCallback you can end the edit mode.