2010-12-03 15 views
3

J'utilise JavaScript pour créer une liste déroulante personnalisée/personnalisée qui fonctionne parfaitement avec jQuery 1.3.2, mais j'ai une erreur dans 1.4.4. Je veux l'utiliser si quelqu'un peut donner une idée sur ce serait vraiment aide complète.Erreur lors du changement de jQuery 1.3.2 → 1.4.4

L'erreur (this.change[x].call) ne fonctionne pas.

// JavaScript Document 

jQuery(document).ready(function() 
{ 
jQuery('select.jsDropdown').each(function() { var dropdown = this; setTimeout(function() { new GenericDropdown(dropdown) }, 1) }); 
}); 

// GENERIC DROPDOWNS 
GenericDropdown = function(element) 
{ 
var _self = this; 
this.element = this.element ? this.element : element; 
this.field; 
this.ddelement = null; 
this.options = this.options ? this.options : []; 
this.selectedIndex = 0; 
this.width = 0; 
this.position = []; 
this.change = []; 
this.attributes = {}; 
this.className = this.className ? this.className : 'jsDropdown'; 
this.value = null; 
this.keySelected = 0; 

this.eventOpen = this.eventOpen ? this.eventOpen : function(e) { _self.open(e) }; 
this.eventSelect = this.eventSelect ? this.eventSelect : function(e) { _self.select(e) }; 
this.eventKeydown = this.eventKeydown ? this.eventKeydown : function(e) { _self.keydown(e) }; 
this.eventClose = this.eventClose ? this.eventClose : function(e) { _self.close(e) }; 
this.eventCancel = this.eventCancel ? this.eventCancel : function(e) { _self.cancel(e) }; 

if (this.element) 
{ 
    // save options data 
    jQuery(this.element).find('option').each(function(i) 
    { 
     if (!_self.options[i]) _self.options[i] = []; 
     _self.options[i][0] = jQuery(this).val(); 
     _self.options[i][1] = jQuery(this).text(); 
     _self.options[i][2] = jQuery(this).attr('class') 

     if (this.selected) _self.selectedIndex = i; 
    }); 

    // get name 
    var name = jQuery(this.element).attr('name'); 

    // save attributes 
    var attributes = this.element.attributes; 
    for (var x = 0; x < attributes.length; x++) this.attributes[ attributes[x].nodeName ] = attributes[x].nodeValue; 

    // save class names 
    this.className = this.className + ' ' + this.element.className.replace(this.className, ''); 

    // copy over events 
    var events = jQuery.data(this.element, 'events') ? jQuery.data(this.element, 'events')[ 'change' ] : null; 
    if (events) for (var handler in events) this.change.push(events[handler]); 

    // calculate max width 
    var tmp = jQuery('<div class="jsDropdownMenu" style="position:static"><ul><li style="display:inline; padding:0"></li></ul></div>'); 
    jQuery('body').append(tmp); 
    for (var x = 0; x < this.options.length; x++) 
    { 
     tmp.find('li').text(this.options[x][1]); 
     if (tmp.find('li')[0].offsetWidth > this.width) this.width = tmp.find('li')[0].offsetWidth; 
    } 
    tmp.remove(); 

    // draw styled dropdown 
    this.draw(); 

    // save reference to object in jQuery 
    this.element.data('jDropdown', _self); 

    // create hidden field with data 
    this.field = jQuery('<input type="hidden" name="' + name + '" value="' + this.options[this.selectedIndex][0] + '" />'); 
    this.element.after(this.field); 

    // save data into jQuery 
    this.element.data('name', name); 
    this.element.data('value', this.options[this.selectedIndex][0]); 
    this.element.val(this.options[this.selectedIndex][0]); 

    // save selected value 
    this.value = this.options[this.selectedIndex][0]; 

    // bind window close event to replace normal selects for server data 
    // jQuery(window).bind('beforeunload', unload); 
} 
} 

GenericDropdown.prototype.draw = function() 
{ 
var self = this; 

// get id if there is one 
var id = (this.element.id) ? this.element.id : null; 

var widthFactor = jQuery('#selectCatFAQ').length ? 0 : 27; 

// build up dropdown 
var width = (jQuery(this.element).css('width') != 'auto') ? (parseInt(jQuery(this.element).css('width')) > this.width) ? parseInt(jQuery(this.element).css('width')) - widthFactor : this.width + 5 : this.width + 5; 

// setting max width for the dropdowns 
width = width > 340 ? 340 : width; 
var dropdown = jQuery('<a href="#" class="' + this.className + '"><span>' + this.options[this.selectedIndex][1] + '</span></a>'); 

// bind events 
dropdown.width(width); 
dropdown.bind('click', self.eventOpen); 
dropdown.bind('keydown', self.eventKeydown); 
spanwidth=width-17; 
dropdown.find('span').css({ width:spanwidth+'px' }); 
if (id) dropdown.attr('id', id); 

// replace existing dropdown with styled one 
var select = jQuery(this.element); 
this.element = jQuery(dropdown); 
select.replaceWith(this.element); 
// custom width set for accordion 
} 


GenericDropdown.prototype.unload = function() 
{ 
var select = jQuery('<select></select>').css({ visibility:'hidden' }); 

// copy back attributes 
jQuery.each(this.attributes, function(key, value) { select[0].setAttribute(key, value) }); 

// add in options 
jQuery.each(this.options, function() { select.append(jQuery('<option value="' + this[0] + '">' + this[1] + '</option>')) }); 

// set selected option 
select.find('option')[ this.selectedIndex ].selected = 'selected'; 

// replace jsDropdown 
this.element.replaceWith(select.removeClass('jsDropdown')); 
this.element = select; 
} 

GenericDropdown.prototype.open = function(e) 
{ 
var self = this; 
if (this.element.attr('disabled') != 'disabled') 
{ 
    // get position for dropdown 
    var in_popup = this.element.parents('#Popup').length ? true : false; 
    // This line is not working with jquery 1.4 so removing border and padding paramaters 
    //var jquery_offset = this.element.offset({ border:true, padding:true }); 
    var jquery_offset = this.element.offset(); 
    this.position = [ jquery_offset.left+2, jquery_offset.top + this.element.outerHeight()-3 ]; 
    var width = (this.element.innerWidth() > this.width) ? this.element.innerWidth() : this.width; 
    var top = this.position[1]; 
    if (in_popup && !(jQuery.browser.msie && jQuery.browser.version < 7)) top = top - jQuery(document).scrollTop(); 

    // create dropdown 
    this.ddelement = jQuery('<div class="jsDropdownMenu"><div class="top-content"><ul class="content"></ul></div></div>').css({ width:width-6 }); 
    this.ddelement.css({ top:top, left:this.position[0]+0+'px' }); 
    if (in_popup && !(jQuery.browser.msie && jQuery.browser.version < 7)) this.ddelement.css({ position:'fixed' }); 
    if (jQuery.browser.msie && jQuery.browser.version < 7 && in_popup) { var dd = this.ddelement; jQuery(window).bind('scroll', function() { dd.css({ top:top + jQuery(document).scrollTop() }) }) }; 
    for (var x = 0; x < this.options.length; x++) 
    { 
     var item = jQuery('<li><span>' + this.options[x][1] + '</span></li>'); 

     if (x == this.selectedIndex) item.addClass('selected'); 

     if (this.options[x][2]) item.addClass(this.options[x][2]) 

     item.bind('click', self.eventSelect); 
     item.bind('mouseover', function(e) 
     { 
      self.ddelement.find('li.selected').removeClass('selected'); 
      jQuery(this).addClass('selected'); 

      self.keySelected = self.ddelement.find('li').index(this); 
     }); 

     this.ddelement.find('ul.content').append(item); 
    } 

    // append dropdown to container 
    jQuery('body').append(this.ddelement); 

    // remove open event and add cancel event 
    this.element.unbind('click', self.eventOpen); 
    this.element.bind('click', self.eventCancel); 

    // add close event 
    setTimeout(function() { jQuery('body').bind('click', self.eventClose) }, 1); 

    //jQuery('.jsDropdownMenu .first span').append(this.options[this.selectedIndex][1]) 

} 

// e.stopPropagation(); 
e.preventDefault(); 
} 

GenericDropdown.prototype.keydown = function(e) 
{ 
if (e.keyCode == 32) // space 
{ 
    if (!this.ddelement) 
    { 
     this.keySelected = this.selectedIndex; 

     this.open(e); 
    } 
    else 
    { 
     this.ddelement.find('li.selected').click(); 

     e.preventDefault(); 
    } 
} 
else if (e.keyCode == 40) // down 
{ 
    if (++this.keySelected > this.options.length - 1) this.keySelected = 0; 

    if (this.ddelement) 
    { 
     this.ddelement.find('li.selected').removeClass('selected'); 
     this.ddelement.find('li:eq(' + this.keySelected + ')').addClass('selected'); 
    } 
    else 
    { 
     this.selectedIndex = this.keySelected; 

     // set text dropdown 
     this.element.find('span').text(this.options[this.selectedIndex][1]); 

     // save value in jQuery 
     this.element.data('value', this.options[this.selectedIndex][0]); 

     // save selected value 
     this.value = this.options[this.selectedIndex][0]; 
     this.element.val(this.options[this.selectedIndex][0]); 
     this.field.val(this.options[this.selectedIndex][0]); 

     // perform custom event listeners if they exist 
     e.target = this.element[0]; 
     if (this.change.length) for (var x = 0; x < this.change.length; x++) this.change[x].call(this, e); 
    } 

    e.preventDefault(); 
} 
else if (e.keyCode == 38) // up 
{ 
    if (--this.keySelected < 0) this.keySelected = this.options.length - 1; 

    if (this.ddelement) 
    { 
     this.ddelement.find('li.selected').removeClass('selected'); 
     this.ddelement.find('li:eq(' + this.keySelected + ')').addClass('selected'); 
    } 
    else 
    { 
     this.selectedIndex = this.keySelected; 

     // set text dropdown 
     this.element.find('span').text(this.options[this.selectedIndex][1]); 

     // save value in jQuery 
     this.element.data('value', this.options[this.selectedIndex][0]); 

     // save selected value 
     this.value = this.options[this.selectedIndex][0]; 
     this.element.val(this.options[this.selectedIndex][0]); 
     this.field.val(this.options[this.selectedIndex][0]); 

     // perform custom event listeners if they exist 
     e.target = this.element[0]; 
     if (this.change.length) for (var x = 0; x < this.change.length; x++) this.change[x].call(this, e); 
    } 

    e.preventDefault(); 
} 
else if (e.keyCode == 13) // return 
{ 
    this.ddelement.find('li:eq(' + this.keySelected + ')').click(); 

    e.preventDefault(); 
} 
else if (e.keyCode == 9 && this.ddelement) // tab 
{ 
    this.ddelement.find('li:eq(' + this.keySelected + ')').click(); 
} 
} 

GenericDropdown.prototype.select = function(e) 
{ 
// get index of selected item 
var new_selection = -1; 
var target_li = e.target; 
if (target_li.nodeName != 'LI') target_li = jQuery(target_li).parents('li')[0]; 
var list_items = this.ddelement.find('li'); 
for (var x = 0; x < list_items.length; x++) if (list_items[x] == target_li) { new_selection = x; break } 
if (new_selection != this.selectedIndex) 
{ 
    this.selectedIndex = new_selection; 
     // set text dropdown 
     this.element.find('span').html(this.options[this.selectedIndex][1]); 

     // save value in jQuery 
     this.element.data('value', this.options[this.selectedIndex][0]); 

     // save selected value 
     this.value = this.options[this.selectedIndex][0]; 
     this.element.val(this.options[this.selectedIndex][0]); 
     this.field.val(this.options[this.selectedIndex][0]); 

     // perform custom event listeners if they exist 
     e.target = this.element[0]; 
     if (this.change.length); for (var x = 0; x < this.change.length; x++) this.change[x].call(this, e); 
} 

this.eventClose(e); 

e.stopPropagation(); 
e.preventDefault(); 
} 

GenericDropdown.prototype.close = function(e) 
{ 
var self = this; 

this.ddelement.remove(); 
delete this.ddelement; 

// remove close event 
jQuery('body').unbind('click', self.eventClose); 

// add open event and remove cancel event 
setTimeout(function() { self.element.bind('click', self.eventOpen) }, 1); 
this.element.unbind('click', self.eventCancel); 

if (e) e.preventDefault(); 
} 

GenericDropdown.prototype.cancel = function(e) 
{ 
this.eventClose(e); 

e.stopPropagation(); 
} 

GenericDropdown.prototype.reset = function(dropdown) 
{ 
var select = jQuery('<select></select>'); 

// copy back attributes 
jQuery.each(this.attributes, function(key, value) { select[0].setAttribute(key, value) }); 
if (dropdown.id) select[0].id = dropdown.id; 

// add in options 
jQuery.each(this.options, function() { select.append(jQuery('<option value="' + this[0] + '">' + this[1] + '</option>')) }); 

// set selected option 
select.find('option')[ this.selectedIndex ].selected = 'selected'; 

// replace jsDropdown 
jQuery(dropdown).replaceWith(select.removeClass('jsDropdown')); 

// remove adjacent hidden field 
select.next('input[type=hidden]').remove(); 

return select[0]; 
} 
+0

Si vous utilisez également jQuery ui, vous pouvez jeter un oeil au widget 'selectmenu'. Ce lien aurait pu être plus utile lorsque vous avez démarré ce projet :-) https://github.com/fnagel/jquery-ui – prodigitalson

+2

Avez-vous déjà fait du débogage, disons avec Firebug et la version non-minifiée de la bibliothèque jQuery ? – Pointy

+0

Salut, Oui j'ai essayé un débogage pas réussi. Vous pouvez télécharger ma version non-minifiée de javascript à partir d'ici. http://www.educationuk.org/js/genericDropdown.js. –

Répondre

0

Aucune erreur constatée pour jquery 1.4.4 - jsfiddle test here, peut-être que vous avez d'autres bibliothèques jointes qui gâtent le résultat? testé dans Chrome et Firefox

+0

Salut Veuillez lier l'événement change dans ce menu déroulant comme ceci

+0

Oui, je vois votre problème, j'ai mis à jour le jsfiddle et maintenant il génère des erreurs, lorsque la bibliothèque js est 1.4.4. N –

+0

Salut Avez-vous vu un problème quel est le problème dans ce ... –

3

La fonction elle-même est maintenant stockée dans la propriété .handler, vous aurez donc besoin de changer ceci:

if (events) for (var handler in events) this.change.push(events[handler]); 

à ceci:

if (events) for (var handler in events) this.change.push(events[handler].handler); 

You can see the working version here.

+0

Hey, oui ça marche ici, avez-vous modifié le script que vous êtes juste awosome .. Je pense que vous êtes un gourou JS .... S'il vous plaît envoyez-moi la version modifiée du script ... Merci beaucoup –

+0

@Rajiv - vous avez le script ... tout ce qui doit changer est la ligne de la réponse ... –