Reputation: 541
I am working on a small project with jQuery, so far so good, but I am having an issue with jQuery's .live() function.
In my source code below you will see:
colourMenu.children('li').live('click', selectColour);
The list elements are populated to an empty UL element via an ajax request which parses JSON. Can anyone tell me why it wont apply the live function? If it was working it would update a hidden input field by the notion of updateOption();
NOTE: the json request is called after the selectMaterial method has been actioned
(function($) {
$.fn.juniperNotebooks = function() {
/*
== Default
*/
var ajaxFile = 'notebookAPI.php';
var nopt = $('#notebookSelectedOpts');
var complete = false;
var debug = true;
/*
== Attributes
*/
// Steps
var actions = {
size: false,
material: false,
colour: false,
paper: false
}
// Extras
var extras = {
emboss: false,
elastic: false,
pen: false,
pocket: false
}
// Buttons
var sizeButton = $('.btn.size');
var materialButton = $('.btn.material');
var colourButton = $('.btn.matcolour');
// Menu's
var sizeMenu = $('.menu.size');
var materialMenu = $('.menu.mats');
var colourMenu = $('.menu.colour');
init();
/*
== Plugin Functions
*/
function init() {
// CSS Opacity for all but the first button
$('.btn').css('opacity', 0.5).first().css('opacity', 1).addClass('req');
// Attach refresh function to reset link
$('.refresh').bind('click', resetPage);
// Attach click to first button: Size
sizeButton.bind('click', showSizes);
// Attach click handlers to options:
sizeMenu.children('li').bind('click', selectSize);
materialMenu.children('li').bind('click', selectMaterial);
colourMenu.children('li').live('click', selectColour);
}
/*
== Plugin Functions
*/
/*
== Menu Selector Functions
*/
function showSizes() {
delegateActiveButtonState(sizeButton);
toggleMenu(sizeMenu);
}
function showMaterials() {
delegateActiveButtonState(materialButton);
toggleMenu(materialMenu);
}
function showColours() {
delegateActiveButtonState(colourButton);
toggleMenu(colourMenu);
}
/*
== Additional Menu Selector Functions
*/
function toggleMenu(menu) {
if( menu.is(':hidden') ) {
menu.slideToggle(500);
} else {
menu.slideToggle(500);
}
}
function hideMenu(menu) {
return menu.slideToggle(500);
}
/*
== Option Selector Functions
*/
function selectSize() {
var option = $(this).data('size');
delegateActiveButtonState(sizeButton);
if( !checkComplete() ) {
updateOption('selectedSize', option);
debug__(option+' size has been selected.');
if( option == 'a4' ) {
updateOption('selectedPaper', 'lined');
debug__('Lined paper has been selected by default.');
} else { updateOption('selectedPaper', ''); }
hideMenu(sizeMenu);
sizeButton.removeClass('req');
actions.size = true;
materialButton.unbind('click', showMaterials).bind('click', showMaterials).css('opacity', 1).addClass('req');
} else {
// Do stuff after we have already made a notebook
}
}
function selectMaterial() {
var option = $(this).data('matid');
delegateActiveButtonState(materialButton);
if( !checkComplete() ) {
updateOption('selectedMaterial', option);
debug__('Material ID: '+option+' has been selected.');
hideMenu(materialMenu);
materialButton.removeClass('req');
actions.material = true;
colourButton.unbind('click', showColours).bind('click', showColours).css('opacity', 1).addClass('req');
colourMenu.empty();
getAvailableColours( option );
} else {
// Do stuff after we have already made a notebook
}
}
function selectColour() {
var option = $(this).data('colourid');
delegateActiveButtonState(colourButton);
if( !checkComplete() ) {
updateOption('selectedColour', option);
debug__('Colour ID: '+option+' has been selected.');
hideMenu(colourMenu);
colourButton.removeClass('req');
actions.colour = true;
// if for paper selection here..
//colourButton.bind('click', showMaterials).css('opacity', 1).addClass('req');
} else {
// Do stuff after we have already made a notebook
}
}
/*
== Global Functions
*/
function getAvailableColours(materialID) {
if( colourMenu.children('li').length == 0) {
$.getJSON('json.php?mid='+materialID, function(data) {
var items = [];
$.each(data, function(key, val) {
items.push('<li data-colourid="' + key + '">' + val + '</li>');
});
colourMenu.append(items.join(''));
});
}
}
function updateOption(opt, val) {
return nopt.children('#'+opt).val(val);
}
function getOption(opt) {
return nopt.children('#'+opt).val();
}
function resetPage() {
if( confirm('Are you sure you want to reset this page? All data will be lost.') ) {
location.reload();
}
return false;
}
function delegateActiveButtonState(btn) {
if( !btn.hasClass('active') ) {
return btn.addClass('active');
} else { return btn.removeClass('active'); }
}
function checkComplete() {
if( complete ) {
return true;
}
}
function debug__(msg) {
if(debug) {
console.log(msg);
}
}
};
})(jQuery);
Upvotes: 0
Views: 575
Reputation: 77966
I imagine it has to do with checkComplete();
That function is looking at the value of the global var complete
. If that variable has been set to true
by another click listener, then your colourmenu
code will not execute.
Upvotes: 0
Reputation: 816422
.live()
[docs] only works directly on selectors:
DOM traversal methods are not supported for finding elements to send to
.live()
. Rather, the.live()
method should always be called directly after a selector, as in the example above.
There might be other issues with your code, but that is definitive one. Instead of posting a bunch of code and having us trying to figure out how it works, you should create a http://jsfiddle.net/ demo.
Upvotes: 2