Isotope Internet Explorer scroll issue when selected using function click - javascript

Firstly, apologies for including the below 'dev' URL, but this shows the functionality much better than me wripping it out into a jsfiddle.
I use isotope on the below page:
http://orchards.t3.ext.starberry.com/property-sales/properties-for-sale-in-london
The functionality
When you scroll down the page to the bottom & click one of the properties, it auto scrolls back to the top to show the selected property details.
When you close the selected property, by clicking the 'X', it scrolls back down to the position that you previously selected/clicked.
The Issue
This works great in Chrome & Safari, but I have to make this work in IE9 & IE10 which it doesn't.
Can anyone advise or see what is wrong with the below JavaScript, stopping this from works in IE9 & 10?
var oldScroll = 0;
jQuery(window).load(function(){
$(function(){
var $container = jQuery('#startekContainer');
$items = jQuery('.quick-view');
$container.isotope({
itemSelector: '.item',
masonry: {
columnWidth: 50
//layoutMode: 'fitColumns'
},
getSortData : {
selected : function( $item ){
// sort by selected first, then by original order
return ($item.hasClass('selected') ? -1000 : 0 ) + $item.index();
}
},
sortBy : 'selected'
});
jQuery('.close-image').click(function(event){
var $this = jQuery(this).parent().parent();
$this.prev().trigger('click', event, this);
});
$items.click(function(event, origEvent){
//event.preventDefault();
var $this = jQuery(this).parent();
if ( $this.hasClass('selected') && !origEvent ) {
// only allow the close button to close
return true;
}
curScroll = $('body').scrollTop();
$('body').scrollTop( 0 );
// don't proceed if already selected
var $previousSelected = jQuery('.selected');
if ( !$this.hasClass('selected') ) {
$this.addClass('selected');
$this.find('.results-image').addClass('hidden');
$this.find('.swiper').removeClass('hidden');
var thisSwiper = $this.find('.swiper .ImageSlider').data('swiper');
thisSwiper.reInit();
thisSwiper.swipeTo(0);
thisSwiper.startAutoplay();
}
else {
$('body').scrollTop(oldScroll);
}
$previousSelected.removeClass('selected');
$previousSelected.find('.results-image').removeClass('hidden');
$previousSelected.find('.swiper').addClass('hidden');
oldScroll = curScroll;
// update sortData for new items size
$container
.isotope( 'updateSortData', $this )
.isotope( 'updateSortData', $previousSelected )
.isotope();
});
});
});
Answering my own question here:
$(document)
instead of either $('body') or $('html,body')

Related

simultaneous events on separate divs?

In my jquery code I am hoping to slide my menu up, thus moving the button up that is used to click it. I would like this to happen at the same time however I am yet to find away to do two methods on different divs at the same time.
The current javascript I am using is:
$( "#mobile-menu-button" ).click(function() {
if ($("#mobile-menu").css("display") == "block") {
$('#mobile-menu').slideUp("slow");
$('#mobile-menu-button').animate({top:"0px" }, 700 );
var h = $('.navigation').css("height").replace("px", "");
}
else{
$('#mobile-menu').slideDown("slow");
var h = $('.navigation').css("height").replace("px", "");
$('#mobile-menu-button').animate({top:h},300);
}
});
Here's a jsfiddle of my current code: http://jsfiddle.net/FM92V/
In order to move elements in any way (or animate them), the time must be the same. If you replace the milliseconds with the string 'slow', it is working correctly.
$( "#mobile-menu-button" ).click(function() {
if ($("#mobile-menu").css("display") == "block") {
$('#mobile-menu').slideUp("slow");
$('#mobile-menu-button').animate({top:"0px" }, 'slow');
var h = $('.navigation').css("height").replace("px", "");
}
else{
$('#mobile-menu').slideDown("slow");
var h = $('.navigation').css("height").replace("px", "");
$('#mobile-menu-button').animate({top:h},'slow');
}
});
Updated jsFiddle: http://jsfiddle.net/FM92V/2/ . Also, remove the height:75% from #mobile-menu in CSS

Unwanted "display: none" added on class change in jQuery

I've got a weird bug happening on a music library site that I'm working on. The intended functionality (take a form of checkboxes, dynamically change them into selectable words that highlight and "check" the associated checkbox on click, then automatically update the songs below based on the highlighted tags) works fine -- but when you click a selected tag to remove it, it does the correct functionality with the data below and the highlight is removed, but all other selected tags are getting "display: none" added to them.
Here, I think, is the function causing the weird issue:
// Given an label "$label," if it hasn't been selected, then
// highlight the label area and set the "checked" value of the
// appropriate checkbox input to true; if it is already selected,
// remove the highlight and set the "checked" value of the appropriate
// checkbox to "false"
function highlightAndCheck( $label )
{
var id = $label.attr("id"),
$checkbox = $label.prev(),
val = $checkbox.attr("value");
if( id === val )
{
if( $label.hasClass("clicked") )
{
$checkbox.prop("checked", false);
$label.removeClass("clicked");
} else
{
$checkbox.prop("checked", true);
$label.addClass("clicked");
}
}
}
Here's the full jQuery code for the page. I can provide more code if anything is confusing, but I hope the labeling, etc. are straightforward:
$(function() { //on document ready
var $categoriesAndTags = $("div#categories-and-tags"),
$tagCategory = $categoriesAndTags.find("div.tag-category"),
$searchButton = $categoriesAndTags.find("input#public-user-tag-search-submit");
// First, hide the checkboxes and search button, since we don't need them in the dynamic version
$tagCategory.addClass("tag-spinner-skin")
.find("input[type=checkbox]").hide();
$tagCategory.find("br").hide();
$searchButton.hide();
// Make it so then clicking on the text of a tag makes the hidden select box "select"
$tagCategory.find("label").each(function(){
$(this).on("click",function(){
var $this = $(this);
highlightAndCheck( $this );
searchByTags();
//While the unwanted "display:none" bug is happening, use this to make them re-appear on next click
$this.siblings("label").show();
});
});
// Make the search update automatically when a select box is clicked or unclicked.
var tagIDs = getUrlVarValArray( "tagID" );
$tagCategory.find("label").each(function(){
var $this = $(this),
id = $this.attr("id");
if( tagIDs.indexOf( id ) > -1 )
{ highlightAndCheck( $this ); }
});
});
function searchByTags( tags )
{
data = $("form#tag-select input").serialize()
if( data.length > 0 )
{
data += "&search=search";
}
$.ajax({
url: "songs/",
data: data,
type: "GET",
success: function(data){
// DO THIS if we successfully do the Ajax call
$newSongPlayers = $(data).find("div#songs-area");
$("div#songs-area").replaceWith( $newSongPlayers );
$.getScript("javascripts/public.js");
}
});
}
// Given an label "$label," if it hasn't been selected, then
// highlight the label area and set the "checked" value of the
// appropriate checkbox input to true; if it is already selected,
// remove the highlight and set the "checked" value of the appropriate
// checkbox to "false"
function highlightAndCheck( $label )
{
var id = $label.attr("id"),
$checkbox = $label.prev(),
val = $checkbox.attr("value");
if( id === val )
{
if( $label.hasClass("clicked") )
{
$checkbox.prop("checked", false);
$label.removeClass("clicked");
} else
{
$checkbox.prop("checked", true);
$label.addClass("clicked");
}
}
}
function getUrlVarValArray( needle )
{
var results = [],
hash,
hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for(var i = 0; i < hashes.length; i++)
{
hash = hashes[i].split('=');
if( needle.length > 0 )
{
if( hash[0] === needle )
{
results[ results.length ] = hash[1]; // array[ array.length ] is a faster way to apend than array.push() in small arrays
}
}
}
return results;
}
Thanks in advance for your help! If it's helpful to login and see this in context, please go to the test site and use username: stackoverflowuser; password: HelpMeFigureThisOut -- once you're logged in, click on "View Songs"and the jQuery is referencing the tags at the top of the page.
Look at the following code in the public.js file:
$("html").on("click", function(event){
if(!$(event.target).is('.options-button')
&& !$(event.target).is('input.add-new-playlist')
&& !$(event.target).is('button.submit-new-playlist')
&& !$(event.target).is('button.add-song-to-playlist')
&& !$(event.target).is('button.playlist-popup-button')
)
{
if(!$(event.target).is('.clicked') && !$(event.target).is('.clicked > div') )
{ $(".clicked").hide().removeClass("clicked"); }
}
});
This handler gets executed because the click event propagates from the <label> element to the <html> element. It executes after the click handler on the <label> element, which removes the "clicked" class from the <label> element. Since the <label> element is the event.target and no longer has the "clicked" class, the following line is executed:
$(".clicked").hide().removeClass("clicked");
That line hides all the labels that still have the "clicked" class.

Keep tabbing within modal pane only

On my current project we have some modal panes that open up on certain actions. I am trying to get it so that when that modal pane is open you can't tab to an element outside of it. The jQuery UI dialog boxes and the Malsup jQuery block plugins seem to do this but I am trying to get just that one feature and apply it in my project and it's not immediately obvious to me how they are doing that.
I've seen that some people are of the opinion that tabbing shouldn't be disabled and I can see that point of view but I am being given the directive to disable it.
This is just expanding on Christian answer, by adding the additional input types and also taking into consideration the shift+tab.
var inputs = $element.find('select, input, textarea, button, a').filter(':visible');
var firstInput = inputs.first();
var lastInput = inputs.last();
/*set focus on first input*/
firstInput.focus();
/*redirect last tab to first input*/
lastInput.on('keydown', function (e) {
if ((e.which === 9 && !e.shiftKey)) {
e.preventDefault();
firstInput.focus();
}
});
/*redirect first shift+tab to last input*/
firstInput.on('keydown', function (e) {
if ((e.which === 9 && e.shiftKey)) {
e.preventDefault();
lastInput.focus();
}
});
I was finally able to accomplish this at least somewhat by giving focus to the first form element within the modal pane when that modal pane is open and then if the Tab key is pressed while focus is on the last form element within the modal pane then the focus goes back to the first form element there rather than to the next element in the DOM that would otherwise receive focus. A lot of this scripting comes from jQuery: How to capture the TAB keypress within a Textbox:
$('#confirmCopy :input:first').focus();
$('#confirmCopy :input:last').on('keydown', function (e) {
if ($("this:focus") && (e.which == 9)) {
e.preventDefault();
$('#confirmCopy :input:first').focus();
}
});
I may need to further refine this to check for the pressing of some other keys, such as arrow keys, but the basic idea is there.
Good solutions by Christian and jfutch.
Its worth mentioning that there a few pitfalls with hijacking the tab keystroke:
the tabindex attribute might be set on some elements inside the modal pane in such a way that the dom order of elements does not follow the tab order. (Eg. setting tabindex="10" on the last tabbable element can make it first in the tab order)
If the user interacts with an element outside the modal that doesn't trigger the modal to close you can tab outside the modal window. (Eg. click the location bar and start tabbing back to the page, or open up page landmarks in a screenreader like VoiceOver & navigate to a different part of the page)
checking if elements are :visible will trigger a reflow if the dom is dirty
The document might not have a :focussed element. In chrome its possible to change the 'caret' position by clicking on a non-focussable element then pressing tab. Its possible that the user could set the caret position past the last tabbable element.
I think a more robust solution would be to 'hide' the rest of the page by setting tabindex to -1 on all tabbable content, then 'unhide' on close. This will keep the tab order inside the modal window and respect the order set by tabindex.
var focusable_selector = 'a[href], area[href], input:not([disabled]):not([type="hidden"]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, *[tabindex], *[contenteditable]';
var hide_rest_of_dom = function( modal_selector ) {
var hide = [], hide_i, tabindex,
focusable = document.querySelectorAll( focusable_selector ),
focusable_i = focusable.length,
modal = document.querySelector( modal_selector ),
modal_focusable = modal.querySelectorAll( focusable_selector );
/*convert to array so we can use indexOf method*/
modal_focusable = Array.prototype.slice.call( modal_focusable );
/*push the container on to the array*/
modal_focusable.push( modal );
/*separate get attribute methods from set attribute methods*/
while( focusable_i-- ) {
/*dont hide if element is inside the modal*/
if ( modal_focusable.indexOf(focusable[focusable_i]) !== -1 ) {
continue;
}
/*add to hide array if tabindex is not negative*/
tabindex = parseInt(focusable[focusable_i].getAttribute('tabindex'));
if ( isNaN( tabindex ) ) {
hide.push([focusable[focusable_i],'inline']);
} else if ( tabindex >= 0 ) {
hide.push([focusable[focusable_i],tabindex]);
}
}
/*hide the dom elements*/
hide_i = hide.length;
while( hide_i-- ) {
hide[hide_i][0].setAttribute('data-tabindex',hide[hide_i][1]);
hide[hide_i][0].setAttribute('tabindex',-1);
}
};
To unhide the dom you would just query all elements with the 'data-tabindex' attribute &
set the tabindex to the attribute value.
var unhide_dom = function() {
var unhide = [], unhide_i, data_tabindex,
hidden = document.querySelectorAll('[data-tabindex]'),
hidden_i = hidden.length;
/*separate the get and set attribute methods*/
while( hidden_i-- ) {
data_tabindex = hidden[hidden_i].getAttribute('data-tabindex');
if ( data_tabindex !== null ) {
unhide.push([hidden[hidden_i], (data_tabindex == 'inline') ? 0 : data_tabindex]);
}
}
/*unhide the dom elements*/
unhide_i = unhide.length;
while( unhide_i-- ) {
unhide[unhide_i][0].removeAttribute('data-tabindex');
unhide[unhide_i][0].setAttribute('tabindex', unhide[unhide_i][1] );
}
}
Making the rest of the dom hidden from aria when the modal is open is slightly easier. Cycle through all the
relatives of the modal window & set the aria-hidden attribute to true.
var aria_hide_rest_of_dom = function( modal_selector ) {
var aria_hide = [],
aria_hide_i,
modal_relatives = [],
modal_ancestors = [],
modal_relatives_i,
ancestor_el,
sibling, hidden,
modal = document.querySelector( modal_selector );
/*get and separate the ancestors from the relatives of the modal*/
ancestor_el = modal;
while ( ancestor_el.nodeType === 1 ) {
modal_ancestors.push( ancestor_el );
sibling = ancestor_el.parentNode.firstChild;
for ( ; sibling ; sibling = sibling.nextSibling ) {
if ( sibling.nodeType === 1 && sibling !== ancestor_el ) {
modal_relatives.push( sibling );
}
}
ancestor_el = ancestor_el.parentNode;
}
/*filter out relatives that aren't already hidden*/
modal_relatives_i = modal_relatives.length;
while( modal_relatives_i-- ) {
hidden = modal_relatives[modal_relatives_i].getAttribute('aria-hidden');
if ( hidden === null || hidden === 'false' ) {
aria_hide.push([modal_relatives[modal_relatives_i]]);
}
}
/*hide the dom elements*/
aria_hide_i = aria_hide.length;
while( aria_hide_i-- ) {
aria_hide[aria_hide_i][0].setAttribute('data-ariahidden','false');
aria_hide[aria_hide_i][0].setAttribute('aria-hidden','true');
}
};
Use a similar technique to unhide the aria dom elements when the modal closes. Here its better
to remove the aria-hidden attribute rather than setting it to false as there might be some conflicting
css visibility/display rules on the element that take precedence & implementation of aria-hidden
in such cases is inconsistent across browsers (see https://www.w3.org/TR/2016/WD-wai-aria-1.1-20160721/#aria-hidden)
var aria_unhide_dom = function() {
var unhide = [], unhide_i, data_ariahidden,
hidden = document.querySelectorAll('[data-ariahidden]'),
hidden_i = hidden.length;
/*separate the get and set attribute methods*/
while( hidden_i-- ) {
data_ariahidden = hidden[hidden_i].getAttribute('data-ariahidden');
if ( data_ariahidden !== null ) {
unhide.push(hidden[hidden_i]);
}
}
/*unhide the dom elements*/
unhide_i = unhide.length;
while( unhide_i-- ) {
unhide[unhide_i].removeAttribute('data-ariahidden');
unhide[unhide_i].removeAttribute('aria-hidden');
}
}
Lastly I'd recommend calling these functions after an animation has ended on the element. Below is a
abstracted example of calling the functions on transition_end.
I'm using modernizr to detect the transition duration on load. The transition_end event bubbles up
the dom so it can fire more than once if more than one element is transitioning when the modal
window opens, so check against the event.target before calling the hide dom functions.
/* this can be run on page load, abstracted from
* http://dbushell.com/2012/12/22/a-responsive-off-canvas-menu-with-css-transforms-and-transitions/
*/
var transition_prop = Modernizr.prefixed('transition'),
transition_end = (function() {
var props = {
'WebkitTransition' : 'webkitTransitionEnd',
'MozTransition' : 'transitionend',
'OTransition' : 'oTransitionEnd otransitionend',
'msTransition' : 'MSTransitionEnd',
'transition' : 'transitionend'
};
return props.hasOwnProperty(transition_prop) ? props[transition_prop] : false;
})();
/*i use something similar to this when the modal window is opened*/
var on_open_modal_window = function( modal_selector ) {
var modal = document.querySelector( modal_selector ),
duration = (transition_end && transition_prop) ? parseFloat(window.getComputedStyle(modal, '')[transition_prop + 'Duration']) : 0;
if ( duration > 0 ) {
$( document ).on( transition_end + '.modal-window', function(event) {
/*check if transition_end event is for the modal*/
if ( event && event.target === modal ) {
hide_rest_of_dom();
aria_hide_rest_of_dom();
/*remove event handler by namespace*/
$( document ).off( transition_end + '.modal-window');
}
} );
} else {
hide_rest_of_dom();
aria_hide_rest_of_dom();
}
}
I have just made few changes to Alexander Puchkov's solution, and made it a JQuery plugin. It solves the problem of dynamic DOM changes in the container. If any control add it to the container on conditional, this works.
(function($) {
$.fn.modalTabbing = function() {
var tabbing = function(jqSelector) {
var inputs = $(jqSelector).find('select, input, textarea, button, a[href]').filter(':visible').not(':disabled');
//Focus to first element in the container.
inputs.first().focus();
$(jqSelector).on('keydown', function(e) {
if (e.which === 9) {
var inputs = $(jqSelector).find('select, input, textarea, button, a[href]').filter(':visible').not(':disabled');
/*redirect last tab to first input*/
if (!e.shiftKey) {
if (inputs[inputs.length - 1] === e.target) {
e.preventDefault();
inputs.first().focus();
}
}
/*redirect first shift+tab to last input*/
else {
if (inputs[0] === e.target) {
e.preventDefault();
inputs.last().focus();
}
}
}
});
};
return this.each(function() {
tabbing(this);
});
};
})(jQuery);
For anyone coming into this more recently like I was, I've taken the approaches outlined above and I've simplified them a bit to make it a bit more digestible. Thanks to #niall.campbell for the suggested approach here.
The code below can be found in this CodeSandbox for further reference and for a working example
let tabData = [];
const modal = document.getElementById('modal');
preventTabOutside(modal);
// should be called when modal opens
function preventTabOutside(modal) {
const tabbableElements = document.querySelectorAll(selector);
tabData = Array.from(tabbableElements)
// filter out any elements within the modal
.filter((elem) => !modal.contains(elem))
// store refs to the element and its original tabindex
.map((elem) => {
// capture original tab index, if it exists
const tabIndex = elem.hasAttribute("tabindex")
? elem.getAttribute("tabindex")
: null;
// temporarily set the tabindex to -1
elem.setAttribute("tabindex", -1);
return { elem, tabIndex };
});
}
// should be called when modal closes
function enableTabOutside() {
tabData.forEach(({ elem, tabIndex }) => {
if (tabIndex === null) {
elem.removeAttribute("tabindex");
} else {
elem.setAttribute("tabindex", tabIndex);
}
});
tabData = [];
}

Target only the first click in jQuery

I have this piece of code, and I need to target only the first click for one line and normal clicks for the rest.
$esCarousel.show().elastislide({
imageW : 240,
onClick : function( $item ) {
if( anim ) return false;
anim = true;
// only in the FIRST CLICK click show wrapper (expected but don't work)
_addImageWrapper();
// on click show image
_showImage($item);
// change current
current = $item.index();
}
});
When i click the item, everything works great, but when I click again I need only the “$_showImage($item);” and not the “_addImageWrapper();”.
Can you help me? I'm really a newbie about js :(
UPDATE:
When I close (close with fadeOut) It won't open again! It must be because the carousel is already been clicked… how can I “reset” the click?
$navClose.on('click.rgGallery', function( event ) {
$('.rg-image-wrapper').fadeOut('2000');
return false;
});
Thanks for the help, I'm learning this (I think :x)!
You could set a variable outside this code:
var clickedCarousel = false;
$esCarousel.show().elastislide({
imageW : 240,
onClick : function( $item ) {
if( anim ) return false;
anim = true;
// only in the FIRST CLICK click show wrapper (expected but don't work)
if(!clickedCarousel) {
_addImageWrapper();
clickedCarousel = true;
}
// on click show image
_showImage($item);
// change current
current = $item.index();
}
});
Does this fit your need?
UPDATE:
Regarding this update:
UPDATE: When I close (close with fadeOut) It won't open again! It must be because the carousel is already been clicked… how can I “reset” the click?
fadeOut() takes a callback of this form:
obj.fadeOut( [duration] [, callback] )
callback can be an inline function or a predefined one, so you could use this (inline):
$navClose.on('click.rgGallery', function( event ) {
$('.rg-image-wrapper').fadeOut(2000,function(){
clickedCarousel = false; // reset to false after fade out is complete
});
return false;
});
Does that help?
Wrap _addImageWrapper() in an if (!this.clicked) condition, then set this.clicked = true;
Add a variable to keep track of if it's already been clicked.
$(function() {
var alreadyClicked = false;
}
$esCarousel.show().elastislide({
imageW : 240,
onClick : function( $item ) {
if( anim ) return false;
anim = true;
if (!alreadyClicked) {
alreadyClicked = true;
_addImageWrapper();
}
// on click show image
_showImage($item);
// change current
current = $item.index();
}
});

jqTransform Select - Scroll to letter typed

I've got a form that uses jqTransform to replace the standard select boxes and radio buttons. It all works fine and dandy, except one thing that annoys me:
Since it replaces the select box with a list of links, when you type a letter to scroll it doesn't do anything. For instance, you click to open up the select, then type an S. It should scroll to the first S in the list, but nothing happens. Is there a way to re-instate this functionality? Below is the jqTransform code for the select box. I don't see a handler for this type of thing:
/***************************
Select
***************************/
$.fn.jqTransSelect = function(){
return this.each(function(index){
var $select = $(this);
if($select.hasClass('jqTransformHidden')) {return;}
if($select.attr('multiple')) {return;}
var oLabel = jqTransformGetLabel($select);
/* First thing we do is Wrap it */
var $wrapper = $select
.addClass('jqTransformHidden')
.wrap('<div class="jqTransformSelectWrapper"></div>')
.parent()
.css({zIndex: 10-index})
;
/* Now add the html for the select */
$wrapper.prepend('<div><span></span></div><ul></ul>');
var $ul = $('ul', $wrapper).css('width',$select.width()).hide();
/* Now we add the options */
$('option', this).each(function(i){
var oLi = $('<li>'+ $(this).html() +'</li>');
$ul.append(oLi);
});
/* Add click handler to the a */
$ul.find('a').click(function(){
$('a.selected', $wrapper).removeClass('selected');
$(this).addClass('selected');
/* Fire the onchange event */
if ($select[0].selectedIndex != $(this).attr('index') && $select[0].onchange) { $select[0].selectedIndex = $(this).attr('index'); $select[0].onchange(); }
$select[0].selectedIndex = $(this).attr('index');
$('span:eq(0)', $wrapper).html($(this).html());
$ul.hide();
return false;
});
/* Set the default */
$('a:eq('+ this.selectedIndex +')', $ul).click();
$('span:first', $wrapper).click(function(){$("a.jqTransformSelectOpen",$wrapper).trigger('click');});
oLabel && oLabel.click(function(){$("a.jqTransformSelectOpen",$wrapper).trigger('click');});
this.oLabel = oLabel;
/* Apply the click handler to the Open */
var oLinkOpen = $('a.jqTransformSelectOpen', $wrapper)
.click(function(){
//Check if box is already open to still allow toggle, but close all other selects
if( $ul.css('display') == 'none' ) {jqTransformHideSelect();}
if($select.attr('disabled')){return false;}
$ul.slideToggle('fast', function(){
var offSet = ($('a.selected', $ul).offset().top - $ul.offset().top);
$ul.animate({scrollTop: offSet});
});
return false;
})
;
// Set the new width
var iSelectWidth = $select.outerWidth();
var oSpan = $('span:first',$wrapper);
var newWidth = (iSelectWidth > oSpan.innerWidth())?iSelectWidth+oLinkOpen.outerWidth():$wrapper.width();
$wrapper.css('width',newWidth);
$ul.css('width',newWidth-2);
oSpan.css({width:iSelectWidth});
$ul.css({height:'420px','overflow':'hidden'});
// Calculate the height if necessary, less elements that the default height
//show the ul to calculate the block, if ul is not displayed li height value is 0
$ul.css({display:'block',visibility:'hidden'});
var iSelectHeight = ($('li',$ul).length)*($('li:first',$ul).height());//+1 else bug ff
(iSelectHeight < $ul.height()) && $ul.css({height:iSelectHeight,'overflow':'hidden'});//hidden else bug with ff
$ul.css({display:'none',visibility:'visible'});
});
};
Here is what we tried to do to implement this:
var oLinkOpen = $('a.jqTransformSelectOpen', $wrapper)
.keypress(function (e) {
$.each(myArray, function (i, l) {
var sc = l.substr(0, 1).toLowerCase();
var kc = String.fromCharCode(e.which);
if (sc == kc) {
$select[0].selectedIndex = i;
$('span:eq(0)', $wrapper).html(l);
$ul.hide();
return false;
}
});
});
Oh dang. I was missing the big picture without the code. Now I see what's going on... yeah, there's no "reinstating" the functionality since the new list of links is not actually a select box anymore. If jqTransform doesn't include a scrollable option by default I think you'll have to implement one.
If you look at their demo page, their "plain" select box works as expected (although it's hard to notice since all options start with "O", it WILL jump to the first "Option") and their styled select box does not.
Without looking deeper at the code, I suspect that means that a keypress capture is not implemented in the plug-in itself.
I'm afraid this isn't the "answer" you were probably hoping for. With any luck someone who has done this sort of thing before will hear your plea. ;-)
solution for jqTransform select keypress work link visit http://www.techapparatus.com/jqtransform-select-problem-with-keyboard-type-solution
Add the following code at the end of return this.each(function(index){ ... }); that is inside of $.fn.jqTransSelect function.
Also you have to install the scrollTo jquery plugin.
CODE:
var newChar;
$(document).bind("keydown", function (e) {
var char = String.fromCharCode(e.which);
var code = e.keyCode || e.which;
var charFound;
if( $ul.css('display') != 'none' ){
if (newChar != char){
newChar = char;
$ul.find('a').each(function(){
// Find first occurence of li that starts with letter typed
if ($(this).text().substr(0,1).toUpperCase() == char && $(this).text() != "Choose"){
charFound = true;
$('a.selected', $wrapper).removeClass('selected');
$(this).addClass('selected');
$select[0].selectedIndex = $(this).attr('index');
$($select[0]).trigger('change');
$that = $(this);
return false;
}
});
if (charFound == true){
// Scroll to selected value
$ul.scrollTo($('a.selected', $ul), 400);
}
}
//If Enter has been pressed, select the value
if(code == 13) {
$('span:eq(0)', $wrapper).html($that.html());
$ul.hide();
return false;
}
}
});

Categories

Resources