I have all these functions that work together to create functionality on a page. Is the structure of these functions OK? Can I do anything to speed this up or make my code better? I'm not exactly sure what namespaces are, but might they help me here?
This code is for a responsive/adaptive calendar website. On the homepage, there is a calendar with events listed by day. These functions filter the events using the ISOTOPE plugin, open and close dropdowns, etc.
If anyone is really interested. I can send you a link + login to the PW protected site.
var $eventwrap = $j('.tw-lists'),
$daywrap = $j('.tw-day'),
$dayfilter = $j('#tw-filter-days li a');
$daywraphide = $j('tw-day.hide'),
$catwrap = $j('.tw-list-filter'),
$viewctrls = $j('.tw-view a'),
$selectdays = $j('.select-days option'),
$selectbarrio = $j('.select-barrio option'),
$selectcats = $j('.select-cats option');
filters = {};
var opday = [],
opcategory = [],
opbarrio = [];
function optionArray(select,options) {
$j(select).find('option').each(function() {
options.push($j(this).attr('data-filter'));
});
return options;
}
// CHECK IF A GIVEN DAY HAS EVENTS
function filterToggle(element,x,y) {
element.each(function(){
var $me = $j(this),
isli = $me.is('li');
if(isli) {
var myvalue = $me.find('a').attr('data-filter');
} else {
var myparent = $me.parent().attr('data-filter-group'),
myvalue = $me.attr('data-filter');
}
if(!x) {x = ''}
if(!y) {y = ''}
var eventcount = $j('.tw-list'+ myvalue + x + y).length;
if(eventcount == 0) {
if(isli) {
$me.addClass('empty tdn');
} else {
$me.attr('disabled','disabled');
}
} else {
if(isli) {
$me.removeClass('empty tdn');
} else {
$me.removeAttr('disabled');
}
}
});
}
function filterAll() {
var currentbarrio = $j('#tw-filter-barrio .current a').attr('data-filter'),
currentcats = $j('#tw-filter-cats .current a').attr('data-filter'),
currentday = $j('#tw-filter-days .current a').attr('data-filter'),
selectbarrio = $j('.select-barrio :selected').attr('data-filter'),
selectcats = $j('.select-cats :selected').attr('data-filter'),
selectday = $j('.select-days :selected').attr('data-filter');
filterToggle($j('#tw-filter-days li'),currentbarrio,currentcats);
filterToggle($j('#tw-filter-barrio li'),currentcats,currentday);
filterToggle($j('#tw-filter-cats li'),currentday,currentbarrio);
filterToggle($selectdays,selectbarrio,selectcats);
filterToggle($selectbarrio,selectcats,selectday);
filterToggle($selectcats,selectday,selectbarrio);
$j('#tw-filter-days .current a').click();
return false;
}
// SELECT FILTER ON CLICK
function filterDrop(dropdown) {
dropdown.find('.tw-filter-drop-options a').on('click',function(){
var $me = $j(this);
if($me.parent().hasClass('empty')){
//No events for that option
return false;
} else {
var $toggle = dropdown.find('.tw-filter-drop-toggle'),
toggleText = $toggle.find('span').html(),
myDropText = $me.html();
dropdown.removeClass('open');
if (myDropText == toggleText) {
return false;
} else {
var $parent = $me.parents('.tw-filter-dropdown'),
parentId = $parent.attr('id');
dropdown.find('.tw-filter-drop-options li').removeClass('current');
$me.parent().addClass('current');
dropdown.find('.tw-filter-drop-label').html(myDropText);
filterAll();
}
}
});
}
// FILTER CLICK
function filterClick($element) {
$element.on('click',function(){
var $me = $j(this),
$parent = $me.parent(),
myvalue = $me.attr('data-filter'),
$mytwin = $j(".tw-filter-select").find("[data-filter='"+myvalue+"']");
if($parent.hasClass('empty') || $parent.hasClass('current')) {
return false;
}
if($me.parents('#tw-filter-days').length !== 0) {
$j('#tw-filter-days li').removeClass('current');
$parent.addClass('current');
}
var $optionSet = $me.parents('ul'),
group = $optionSet.attr('data-filter-group');
filters[ group ] = myvalue;
var isoFilters = [];
for ( var prop in filters ) {
isoFilters.push( filters[ prop ] )
}
var selector = isoFilters.join(''),
currentday = $j('#tw-filter-days .current a').attr('data-filter'),
$dayheader = $j('.tw-day-header');
$dayheader.hide();
$dayheader.filter(currentday).show();
$j('.tw-list-filter').isotope({ filter: selector, animationEngine : 'css' });
$mytwin.attr('selected','selected');
filterAll();
return false;
});
}
// SWITCH VIEWS
function switchViews($element, $events) {
$element.on('click',function(){
var $me = $j(this),
$parent = $me.parent();
myclass = $me.attr('class').split('-');
myview = myclass[0];
if($me.hasClass('selected')) {
return false;
}
var selector = $j('#tw-filter-days .current a').attr('data-filter');
if(myview == 'list') {
$events.removeClass('grid-wrap');
$j('.tw-list-filter').isotope({ animationEngine : 'css' });
} else {
$events.addClass('grid-wrap');
$j('.tw-list-filter').isotope({ animationEngine : 'css' });
}
$parent.removeClass('list grid').addClass(myview);
$element.removeClass('selected');
$me.addClass('selected');
});
}
// SETUP SCROLLABLE
function scrollableSetup($textslide, $imgslide, $homeslide) {
$textslide.scrollable({easing: 'swing', keyboard: true, speed: 500}).navigator();
$imgslide.scrollable({keyboard: false, speed: 950}).navigator();
if($textslide.length) {
var textscroll = $textslide.data("scrollable");
textscroll.onSeek(function() {
if(!$imgslide.is(':visible')) {
var myindex = this.getIndex(),
$myslide = $textslide.find('.item:eq('+myindex+')'),
myheight = $myslide.find('.text-inner').height(),
homeslideHeight = $homeslide.css('height'),
homeslideHeight = homeslideHeight.replace('px','')
if(homeslideHeight != myheight){
$homeslide.removeAttr('style').css('height',myheight);
}
}
return false;
});
}
$j(document).keydown(function(e){
if (e.keyCode == 37) {
$textslide.scrollable().prev();
$imgslide.scrollable().prev();
return false;
}
if (e.keyCode == 39) {
$textslide.scrollable().next();
$imgslide.scrollable().next();
return false;
}
});
}
// OPEN AND CLOSE DROPDOWN
function openDropDowns($droptoggle, $dropdown) {
$droptoggle.on('click',function() {
$j('.tw-filter-dropdown.open').removeClass('open');
var $me = $j(this)
var toggletext = $me.find('span').html();
$me.parent().addClass('open');
});
//Hide drop downs on click off
$j(document).bind('click', function (e) {
$j('.tw-filter-dropdown').removeClass('open');
});
$dropdown.bind('click', function(e) {
e.stopPropagation();
});
}
// FOCUS FUNCTION FOR MOBILE SELECTS
function mobileFocus($select) {
$select.focus(function(){
var $me = $j(this),
previousval = $me.value,
$previous = $me.find(':selected');
}).change(function(){
var $me = $j(this),
myvalue = $me.find(':selected').attr('data-filter'),
$myoption = $me.find("[data-filter='"+myvalue+"']");
mygroup = $me.attr('data-filter-group'),
$mytwin = $j('.tw-filter a[data-filter="'+myvalue+'"]');
if($myoption.attr('disabled') == 'disabled') {
alert('No hay eventos en este barrio y día');
return false;
}
filters[ mygroup ] = myvalue;
var isoFilters = [];
for ( var prop in filters ) {
isoFilters.push( filters[ prop ] )
}
var selector = isoFilters.join(''),
currentday = $j('.select-days :selected').attr('data-filter'),
$dayheader = $j('.tw-day-header .white-bub, .tw-day-header');
$dayheader.hide();
$dayheader.filter(currentday).show();
$j('.tw-list-filter').isotope({ filter: selector, animationEngine : 'css' });
$mytwin.click();
filterAll();
});
}
$j(window).smartresize(function(){
$j('.tw-list-filter').isotope({animationEngine : 'css'});
$j('#tw-filter-barrio .current a').click();
if($j(this).height() > 500) {
$j('.navi .active').click();
$j('.home-slide').removeAttr('style')
}
});
Then in my HTML:
<script>
$j(document).ready(function($){
var $textslide = $('.text-slide'),
$imgslide = $('.img-slide'),
$homeslide = $('.home-slide'),
$filters = $('.tw-filter ul a'),
$views = $('.tw-view a'),
$droptoggle = $('.tw-filter-drop-toggle'),
$dropdown = $('.tw-filter-dropdown'),
$select = $('.tw-filter-select'),
$filterdays = $('#tw-filter-days'),
$filtercats = $('#tw-filter-cats'),
$filterbarrio = $('#tw-filter-barrio'),
$events = $('.tw-lists');
scrollableSetup($textslide, $imgslide, $homeslide);
filterClick($filters);
switchViews($views, $events);
mobileFocus($select)
filterDrop($filterbarrio);
filterDrop($filtercats);
openDropDowns($droptoggle, $dropdown);
$('.list-view').click();
$dayfilter.not('.empty > a').first().click();
});
functional-programming
seems to not apply here. \$\endgroup\$