JavaScript Refactoring / Avoid Repitition - javascript

I need to refactor this to avoid code repetition.
$('#showmore-towns').toggle(
function() {
$('.popularTownsAdditional').show();
console.log(this);
$('#showmore-town .showless').show();
$('#showmore-town .showmore').hide();
$('#showmore-town').removeClass('sd-dark28').addClass('sd-dark28down');
return false;
},
function() {
$('.popularTownsAdditional').hide();
$('.showless').hide();
$('.showmore').show();
$('#showmore-towns').addClass('sd-dark28').removeClass('sd-dark28down');
});
$('#showmore-cities').toggle(
function() {
$('.popularCitiesAdditional').show();
$('#showmore-cities .showless').show();
$('#showmore-cities .showmore').hide();
$('#showmore-cities').removeClass('sd-dark28').addClass('sd-dark28down');
return false;
},
function() {
$('.popularCitiesAdditional').hide();
$('#showmore-cities .showless').hide();
$('#showmore-cities .showmore').show();
$('#showmore-cities').addClass('sd-dark28').removeClass('sd-dark28down');
});
basically, it shows the same functionality but only on different divs with different IDs.

Probably just need to reference a named function or two instead of the anon ones.
function showStuff(typeToShow) {
$('.popular' + typeToShow + 'Additional').show();
$('#showmore-' + typeToShow + .showless').show();
$('#showmore-' + typeToShow + .showmore').hide();
$('#showmore-' + typeToShow).removeClass('sd-dark28').addClass('sd-dark28down');
return false;
}
function hideStuff(typeToHide) {
$('.popular' + typeToHide + 'Additional').hide();
$('#showmore-' + typeToHide + .showless').hide();
$('#showmore-' + typeToHide + .showmore').show();
$('#showmore-' + typeToHide ).addClass('sd-dark28').removeClass('sd-dark28down');
}
NOTE: a) You could probably make these methods a bit slicker, but you get the idea!
NOTE: b) You'd need to rename '#showmore-town' to '#showmore-towns' (with an S) if you want to use the substitution suggested.
Then in your toggle you could reference these functions:
$('#showmore-towns').toggle(showStuff(towns),
hideStuff(towns));
$('#showmore-cities').toggle(showStuff(cities),
hideStuff(cities));

I mean...if it's always going to start with #showmore-...we can work it down
$('[id^=showmore-]').toggle(
function() {
var id = $(this).prop('id');
id = id.split('-')[1];
var upperID = id.charAt(0).toUpperCase() + id.slice(1);
$('.popular'+upperID+'Additional').show();
$('#showmore-'+id+' .showless').show();
$('#showmore-'+id+'.showmore').hide();
$('#showmore-'+id).removeClass('sd-dark28').addClass('sd-dark28down');
return false;
},
function() {
var id = $(this).prop('id');
id = id.split('-')[1];
var upperID = id.charAt(0).toUpperCase() + id.slice(1);
$('.popular'+upperID+'Additional').hide();
$('#showmore-'+id+' .showless').hide();
$('#showmore-'+id+' .showmore').show();
$('#showmore-'+id).addClass('sd-dark28').removeClass('sd-dark28down');
});

you could do:
(function() {
$('#showmore-towns').toggle(
function() { showmorelessOn('#showmore-town'); },
function() { showmorelessOff('#showmore-town'); }
);
$('#showmore-cities').toggle(
function() { showmorelessOn('#showmore-town'); },
function() { showmorelessOff('#showmore-town'); }
);
var showmorelessOn = function(context) {
$('.popularCitiesAdditional').show();
$('.showless', context).show();
$('.showmore', context).hide();
$(context).removeClass('sd-dark28').addClass('sd-dark28down');
return false;
};
var showmorelessOff = function(context) {
$('.popularCitiesAdditional').hide();
$('.showless', context).hide();
$('.showmore', context).show();
$(context).addClass('sd-dark28').removeClass('sd-dark28down');
};
})();
though I agree, could perhaps be better served on codereview.stackexchange.com

I would do this almost entirely in the CSS. Only use .toggleClass() and determine what is shown and what is hidden in the CSS.

(function() {
$('#showmore-towns').toggle(
function() { showmorelessOn.call($('#showmore-town')); },
function() { showmorelessOff.call($('#showmore-town')); }
);
$('#showmore-cities').toggle(
function() { showmorelessOn.call($('#showmore-town')); },
function() { showmorelessOff.call($('#showmore-town')); }
);
var showmorelessOn = function() {
$('.popularCitiesAdditional').show();
$('.showless', this).show();
$('.showmore', this).hide();
$(this).removeClass('sd-dark28').addClass('sd-dark28down');
return false;
};
var showmorelessOff = function() {
$('.popularCitiesAdditional').hide();
$('.showless', this).hide();
$('.showmore', this).show();
$(this).addClass('sd-dark28').removeClass('sd-dark28down');
};
})();
(function() {
$('#showmore-towns').toggle(
function() { showmoreless(); }
);
$('#showmore-cities').toggle(
function() { showmoreless(); }
);
var showmoreless = function() {
if(this.hasClass('sd-dark28'){
$('.popularCitiesAdditional').show();
$('.showless', this).show();
$('.showmore', this).hide();
$(this).removeClass('sd-dark28').addClass('sd-dark28down');
}
else
{
$('.popularCitiesAdditional').hide();
$('.showless', this).hide();
$('.showmore', this).show();
$(this).addClass('sd-dark28').removeClass('sd-dark28down');
}
}.bind($('#showmore-town'));
})();

Related

how to add and than remove eventlistener in JavaScript

new_line=function()
{
var conteiner=document.createElement('div');
conteiner.classList.add('conteiner');
conteiner.addEventListener('click', function (event){on_click(event, conteiner);}, false);//this is an anonymous function so it is always new
document.body.appendChild(conteiner);
create_el(conteiner);
};
I have this function and in it addEventListener. I know that when I'm giving: function (event){on_click(event, conteiner);} I can't remove this EventListener, but I need give on_click function second parameter.
delete_conteiner=function(which)
{
which.removeEventListener("click", function (event){on_click(event, conteiner);}, false);//this isn't working
document.body.removeChild(which);
};
Is it posible to add EventListener, which execute on_click, and than remove it in oder EventListener? Here full code:
(function()
{
var create_ul, user_names, menage_ul, open, look_for, save_as, user_name, real_name, on_click, set_up, create_el, show_hide_btn_click, delete_el, on_load, get_object_to_save, change_all, save, delete_conteiner, change_see_able, restart, new_line, new_cubes, scroll_with_ctrl;
create_el=function(where, options)
{
var configs=options || {
class_names:'textbox',
value:''
};
var block=document.createElement('textarea');
block.className=configs.class_names;
block.value=configs.value;
where.appendChild(block);
};
delete_el=function(where, which)
{
where.removeChild(which);
};
delete_conteiner=function(which)
{
which.removeEventListener("click", function(event){on_click(event, conteiner);}, false);//I know that won't work
document.body.removeChild(which);
};
change_see_able=function(where)
{
var is_see_able=true;
where.classList.forEach(function(str){
if(str=='none_see_able')
{
is_see_able=false;
}
});
if(is_see_able)
{
where.classList.add('none_see_able');
}
else
{
where.classList.remove('none_see_able');
}
};
on_click=function(ev, conteiner)
{
var is_box_cliked=false;
ev.target.classList.forEach(function(className){
if(className=='textbox')
{
is_box_cliked=true;
}
});
if(is_box_cliked)
{
if(ev.shiftKey)
{
if(!ev.ctrlKey)
{
if(!ev.altKey)
{
create_el(conteiner);
}
}
}
else if(ev.ctrlKey)
{
if(!ev.altKey)
{
delete_el(conteiner, ev.target);
}
}
else if(ev.altKey)
{
change_see_able(ev.target);
}
else
{}
}
else
{
if(ev.ctrlKey)
{
delete_conteiner(conteiner);
}
else
{
if((conteiner.querySelector('.textbox')==null) || ev.shiftKey)
{
create_el(conteiner);
}
}
}
};
get_object_to_save=function()
{
var conteiners=document.body.querySelectorAll('.conteiner'), conteiners_to_save=Array();
conteiners.forEach(function(textboxes){
var textboxes=textboxes.querySelectorAll('.textbox'), textboxes_to_save=Array();
textboxes.forEach(function(textbox){
var textbox_to_save={
class_names:textbox.className,
value:textbox.value
};
textboxes_to_save.push(textbox_to_save);
});
conteiners_to_save.push(textboxes_to_save);
});
return [user_name, JSON.stringify(conteiners_to_save)];
};
new_line=function()
{
var conteiner=document.createElement('div');
conteiner.classList.add('conteiner');
create_el(conteiner);
conteiner.addEventListener('click', function(event){on_click(event, conteiner);}, false);
document.body.appendChild(conteiner);
};
load=function(conteiners)
{
if(conteiners.length===0)
{
new_line();
}
else
{
conteiners.forEach(function(textboxes){
var conteiner=document.createElement('div');
conteiner.classList.add('conteiner');
conteiner.addEventListener('click', function(event){
on_click(event, conteiner);
}, false);
document.body.appendChild(conteiner);
textboxes.forEach(function(options_for_textbox){
create_el(conteiner, options_for_textbox);
});
});
}
}
save=function()
{
localStorage.setItem(real_name, JSON.stringify(get_object_to_save()));
};
look_for=function()
{
for(i=localStorage.length-1; i>=0; i--)
{
if(localStorage.key(i)!='name_last')
{
if(user_name===JSON.parse(localStorage.getItem(localStorage.key(i)))[0])
{
return [true, localStorage.key(i)];
}
}
}
user_names.push(user_name);
localStorage.setItem('names', JSON.stringify(user_names));
return [false, 'c_'+new Date().getTime()];
};
open=function()
{
if(document.querySelector('.buttons > .open > input').value!='')
{
var conteiners=document.querySelectorAll('.conteiner');
conteiners.forEach(function(conteiner)
{
delete_conteiner(conteiner);
});
user_name=document.querySelector('.buttons > .open > input').value;
document.querySelector('.buttons > .open > input').value='';
var is=look_for();
real_name=is[1];
localStorage.setItem('name_last', real_name);
if(!is[0])
{
localStorage.setItem(real_name, JSON.stringify([user_name, JSON.stringify(new Array())]));
}
conteiners=JSON.parse(JSON.parse(localStorage.getItem(real_name))[1]);
load(conteiners);
}
};
save_as=function()
{
if(document.querySelector('.buttons > .save_as > input').value!='')
{
user_name=document.querySelector('.buttons > .save_as > input').value;
document.querySelector('.buttons > .save_as > input').value='';
real_name=look_for();
localStorage.setItem('name_last', real_name);
localStorage.setItem(real_name, JSON.stringify(get_object_to_save()));
}
};
on_load=function()
{
var name=localStorage.getItem('name_last');
if(localStorage.length===0)
{
user_names=new Array();
localStorage.setItem('names', JSON.stringify(new Array()));
user_name='first';
real_name=look_for()[1];
localStorage.setItem('name_last', real_name);
localStorage.setItem(real_name, JSON.stringify([user_name, JSON.stringify(new Array())]));
}
else
{
real_name=name;
user_name=JSON.parse(localStorage.getItem(real_name))[0];
user_names=JSON.parse(localStorage.getItem('names'));
}
var conteiners=JSON.parse(JSON.parse(localStorage.getItem(real_name))[1]);
load(conteiners);
};
new_cubes=function()
{
var conteiners=document.querySelectorAll('.conteiner');
conteiners.forEach(function(conteiner){
create_el(conteiner);
});
};
restart=function()
{
var conteiners=document.querySelectorAll('.conteiner');
conteiners.forEach(function(conteiner){
delete_conteiner(conteiner);
});
new_line();
};
change_all=function()
{
var value=document.querySelector('.buttons > .to_all > textarea').value;
document.querySelector('.buttons > .to_all > textarea').value='';
var textboxes=document.querySelectorAll('.textbox');
textboxes.forEach(function(textbox){
textbox.value=value;
});
};
set_size=function()
{
//textareas in menu prepare for calculations
var textareas=document.querySelectorAll('label textarea');
textareas.forEach(function(textarea){
textarea.style.height='0px';
});
//inputs in menu prepare for calculations
var inputs=document.querySelectorAll('label input');
inputs.forEach(function(input){
input.style.height='0px';
});
//show_hide_btn prepare for calculations
var show_hide_btn=document.querySelector('.button.show_hide_menu');
show_hide_btn.style.height='0px';
//get height for textareas and inputs
var width=textareas[0].offsetWidth+'px';
var height=document.querySelector('.to_all .to_all').offsetHeight+'px';
var uls=document.querySelectorAll('label ul');
uls.forEach(function(ul){
ul.style.bottom=height;
});
//textareas set height
textareas.forEach(function(textarea){
textarea.style.height=height;
});
//inputs set height
inputs.forEach(function(input){
input.style.height=height;
input.style.width=width;
});
//show_hide_btn set height
show_hide_btn.style.height=document.querySelector('.buttons_place').offsetHeight+'px';
};
show_hide_btn_click=function(btn)
{
if(btn.style.transform==='')
{
document.querySelector('.buttons_place').style.transform='translateX('+document.querySelector('.buttons').offsetWidth+'px)'
btn.style.transform='rotateY(180deg)';
setTimeout(function()
{
btn.style.borderTopLeftRadius='0';
btn.style.borderBottomLeftRadius='0';
btn.style.borderTopRightRadius='10px';
btn.style.borderBottomRightRadius='10px';
}, 750);
}
else
{
document.querySelector('.buttons_place').style.transform='';
btn.style.transform='';
setTimeout(function()
{
btn.style.borderTopLeftRadius='';
btn.style.borderBottomLeftRadius='';
btn.style.borderTopRightRadius='';
btn.style.borderBottomRightRadius='';
}, 750);
}
};
ul_click=function(where, value)
{
where.querySelector('input').value=value;
};
create_ul=function(where, names_to_show)
{
var ul=where.querySelectorAll('ul');
if(ul!=null)
{
ul.forEach(function(ul_one_object)
{
where.removeChild(ul_one_object);
});
}
if(names_to_show.length!=0)
{
ul=document.createElement('ul');
names_to_show.forEach(function(name)
{
var li=document.createElement('li');
li.textContent=name;
ul.appendChild(li);
});
ul.addEventListener('click', function(ev){ul_click(where, ev.target.textContent);}, false);
ul.style.bottom=document.querySelector('.to_all .to_all').offsetHeight+'px';
where.appendChild(ul);
}
};
menage_ul=function(label, value)
{
var names_to_show=user_names.filter(function(name){
return name.indexOf(value)==0;
});
create_ul(label, names_to_show)
};
set_up=function()
{
var show_hide_btn=document.querySelector('.button.show_hide_menu');
show_hide_btn.addEventListener('click', function(event){show_hide_btn_click(show_hide_btn);}, false);
var width=document.body.offsetWidth;
setInterval(function()
{
if(width!=document.body.offsetWidth)
{
width=document.body.offsetWidth;
set_size();
}
}, 500);
set_size();
var add_new_line_btn=document.querySelector('.new_line');
add_new_line_btn.addEventListener('click', new_line, false);
var add_new_cubes_btn=document.querySelector('.new_cubes');
add_new_cubes_btn.addEventListener('click', new_cubes, false);
var restart_btn=document.querySelector('.restart');
restart_btn.addEventListener('click', restart, false);
var save_structure_btn=document.querySelector('.save');
save_structure_btn.addEventListener('click', save, false);
var to_all_btn=document.querySelector('.to_all .to_all');
to_all_btn.addEventListener('click', change_all, false);
var save_as_btn=document.querySelector('.save_as .save_as');
save_as_btn.addEventListener('click', save_as, false);
var open_btn=document.querySelector('.open .open');
open_btn.addEventListener('click', open, false);
var labels=document.querySelectorAll('label');
labels.forEach(function(label)
{
var input=label.querySelector('input');
if(input!=null)
{
input.addEventListener('keyup', function(ev){menage_ul(label, input.value);}, false);
}
});
on_load();
};
set_up();
})();
The removeEventListener() method removes an event handler that has been attached with the addEventListener() method.
Note: To remove event handlers, the function specified with the addEventListener() method must be an external function, like in the example below (click_event_func).
Anonymous functions, like "function (event){on_click(event, conteiner);}" will not work.
click_event_func = function(event) {
on_click(event, conteiner);
};
new_line = function() {
var conteiner = document.createElement('div');
conteiner.classList.add('conteiner');
conteiner.addEventListener('click', click_event_func, false);
document.body.appendChild(conteiner);
create_el(conteiner);
};
delete_conteiner = function(which) {
which.removeEventListener("click", click_event_func, false);
document.body.removeChild(which);
};
If you want to pass another param to an event listener you have to bind it to the function, as eventlistener will only pass the event itself (click event in your example). If you pass the exact same params and the same function when you remove it will remove it successfuly according to MDN.
https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener
I think your problem is you don't use named functions.
Try to do like this:
function NameHere(event) { on_click(event, conteiner); }
new_line=function() {
var conteiner=document.createElement('div');
conteiner.classList.add('conteiner');
conteiner.addEventListener('click', NameHere, false);
document.body.appendChild(conteiner);
create_el(conteiner);
};
delete_conteiner=function(which) {
which.removeEventListener("click", NameHere, false);//this isn't working
document.body.removeChild(which);
};
The problem is when you try to remove the listener without using names, you will remove a different function from the one you added before.
By example:
which.removeEventListener("click", function (event){on_click(event, conteiner);}, false);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// This here creates a new function. It's not related to
// the function you created with addEventListener earlier.
// Trying to remove it from eventlisteners on "which" is silly
// because it doesn't exist there.
Instead:
var eventHandler = function(event){on_click(event, conteiner);}; // Store for later
conteiner.addEventListener('click', eventHandler); // Add.
conteiner.removeEventListener('click', eventHandler); // Remove.
You can remove eventListeners as long as you referencing the same function.

jQuery search toggle

on my website I have a div .toggle-search that if you click on it it expands to .search-expand where a search form is. This is the code in jQuery
/* Toggle header search
/* ------------------------------------ */
$('.toggle-search').click(function(){
$('.toggle-search').toggleClass('active');
$('.search-expand').fadeToggle(250);
setTimeout(function(){
$('.search-expand input').focus();
}, 300);
});
Now the only way to close the .search-expand is to click once again on the .toggle-search. But I want to change that it closes if you click anywhere else on the site. For an easier example I have the Hueman theme, and I'm talking about the top right corner search option. http://demo.alxmedia.se/hueman/
Thanks!
Add the event on all elements except the search area.
$('body *:not(".search-expand")').click(function(){
$('.toggle-search').removeClass('active');
$('.search-expand').fadeOut(250);
});
or another way,
$('body').click(function(e){
if(e.target.className.indexOf('search-expand') < 0){
$('.toggle-search').removeClass('active');
$('.search-expand').fadeOut(250);
}
});
var isSearchFieldOpen = false;
var $toggleSearch = $('.toggle-search');
var $searchExpand = $('.search-expand');
function toggleSearch() {
// Reverse state
isSearchFieldOpen = !isSearchFieldOpen;
$toggleSearch.toggleClass('active');
// You can use callback function instead of using setTimeout
$searchExpand.fadeToggle(250, function() {
if (isSearchFieldOpen) {
$searchExpand.find('input').focus();
}
});
}
$toggleSearch.on('click', function(e) {
e.stopPropagation();
toggleSearch();
});
$(document.body).on('click', function(e) {
if (isSearchFieldOpen) {
var target = e.target;
// Checking if user clicks outside .search-expand
if (!$searchExpand.is(target) && !$searchExpand.has(target).length) {
toggleSearch();
}
}
});
I have a second search on the site with the same code as before only
with div .toggle-serach2 and .expand-search2, how can i make your code
so it wont overlap. just changing the name to $('toggle-search2')
doesn't cut it
in that case, I would suggest you convert your code into a plugin:
(function($, document) {
var bodyHandlerAttached = false;
var openedForms = [];
var instances = {};
var defaults = {
activeClass: 'active'
};
function ToggleSearch(elem, options) {
this.options = $.extend({}, defaults, options);
this.$elem = $(elem);
this.$btn = $(options.toggleBtn);
this.isOpen = false;
this.id = generateId();
this.bindEvents();
instances[this.id] = this;
if (!bodyHandlerAttached) {
handleOutsideClick();
bodyHandlerAttached = true;
}
}
ToggleSearch.prototype = {
bindEvents: function() {
this.$btn.on('click', $.proxy(toggleHandler, this));
},
open: function() {
if (this.isOpen) { return; }
var _this = this;
this.$btn.addClass(this.options.activeClass);
this.$elem.fadeIn(250, function() {
_this.$elem.find('input').focus();
});
openedForms.push(this.id);
this.isOpen = true;
},
close: function(instantly) {
if (!this.isOpen) { return; }
this.$btn.removeClass(this.options.activeClass);
if (instantly) {
this.$elem.hide();
} else {
this.$elem.fadeOut(250);
}
openedForms.splice(openedForms.indexOf(this.id), 1);
this.isOpen = false;
},
toggle: function() {
if (this.isOpen) {
this.close();
} else {
this.open();
}
}
};
var toggleHandler = function(ev) {
ev.stopPropagation();
this.toggle();
};
var handleOutsideClick = function(e) {
$(document.body).on('click', function(e) {
if (openedForms.length) {
var target = e.target;
var instance;
for (var id in instances) {
instance = instances[id];
if (!instance.$elem.is(target) && !instance.$elem.has(target).length) {
instance.close(true);
}
}
}
});
};
function generateId() {
return Math.random().toString(36).substr(2, 8);
}
$.fn.toggleSearch = function(options) {
return this.each(function() {
if (!$.data(this, 'toggleSearch')) {
$.data(this, 'toggleSearch', new ToggleSearch(this, options));
}
});
};
})(window.jQuery, document);
And then use it like this:
$('.search-expand').toggleSearch({
toggleBtn: '.toggle-search'
});
$('.search-expand2').toggleSearch({
toggleBtn: '.toggle-search2'
});
JSFiddle example
You could add a click handler to the main window that removes the active class:
$(window).click(function(){
$('.toggle-search').removeClass('active');
}
and then prevent the class removal when you click inside of your toggle-search elem
$('.toggle-search').click(function(e){
e.stopPropagation();
// remainder of click code here
)};
Try to add body click listener
$('body').click(function(e){
if ($(e.target).is('.toggle-search')) return;
$('.toggle-search').removeClass('active');
$('.search-expand').fadeOut(250);
});

JavaScript singleton patterns - differences?

This may seem like a silly question, but what are the functional differences, if any, between these two patterns? Is there no real functional difference and it's just a matter of organization preference? What are some instances when you would want to use one and not the other? I'm trying to find a design pattern I feel most comfortable with. Thanks!
$(function(){
Core.init();
});
var Core = {
init: function() {
//some initialization code here
}
_plugins: function() {
//instantiate some plugins here
}
_display: function() {
//some more code here
}
_otherfunctions: function() {
....
}
}
and
$(function(){
Core.init();
Plugins.init();
Display.init();
});
var Core = {
init: function() {
//some initialization code here
}
}
var Plugins = {
init: function() {
//start plugins
}
_modify: function() {
//more code
}
}
var Display = {
init: function() {
//some init code
}
}
The main organizational difference is that the first pattern pollutes the global namespace less.
If you do want to separate your code into packages like in the second example, then the better way, within your example, would be:
$(function(){
Core.init();
});
var Core = {
init: function() {
//some initialization code here
},
plugins: {
init: function() {
//start plugins
}
_modify: function() {
//more code
}
},
display: {
init: function() {
//some init code
}
}
}
and refer to the packages through your main namespace:
Core.plugins.init();
I am not saying that this is the best way to do so in general (some of it is a matter of preference, like private members and methods), but in your example - I'd prefer mine.
Have a look at this framework I have built. Seems to work pretty well.
var gtg = gtg || {};
(function () {
var _this = this;
this.registerNamespace = function (namespace) {
var root = window,
parts = namespace.split("."),
i;
for (i = 0; i < parts.length; i++) {
if (typeof root[parts[i]] === "undefined") {
root[parts[i]] = {};
}
root = root[parts[i]];
}
return this;
};
}).call(gtg);
// Register Namespaces
gtg.registerNamespace("gtg.core");
gtg.registerNamespace("gtg.infoBar");
gtg.registerNamespace("gtg.navBar");
gtg.registerNamespace("gtg.tabBar");
gtg.registerNamespace("gtg.utils");
(function () {
var _this = this;
this.initialize = function () { };
}).call(gtg.core);
(function () {
var _this = this,
$container,
$messageContainer,
$message;
function configureMessage(message) {
var className = "info",
types = ["error", "info", "warning"];
for (var i in types) {
$message.removeClass(types[i]);
}
switch (message.MessageType) {
case 0:
className = "error"
break;
case 1:
className = "info"
break;
case 2:
className = "warning"
break;
}
$message.addClass(className).html(message.Message);
}
this.initialize = function () {
$container = $(".info-bar-container");
$messageContainer = $container.find(".message-container");
$message = $messageContainer.find(".message");
$messageContainer.find(".close a").bind("click", function () {
_this.close();
});
};
this.close = function () {
$messageContainer.fadeOut(300, function () {
$container.slideUp(300);
});
};
this.show = function (message) {
if ($container.css("display") !== "none") {
$messageContainer.fadeOut(300, function () {
configureMessage(message);
$messageContainer.fadeIn(300);
});
} else {
$container.slideDown(300, function () {
configureMessage(message);
$messageContainer.fadeIn(300);
});
}
};
}).call(gtg.infoBar);
(function () {
var _this = this;
function initializeNavBar() {
var paths = window.location.pathname.split("/"),
navId;
$("#nav-bar ul.top-nav li a[data-nav]").bind("click", function () {
_this.switchNav($(this));
});
if (paths[1] != "") {
switch (paths[1]) {
case "Customer":
navId = "customers-nav";
break;
case "Order":
navId = "orders-nav";
break;
case "Product":
navId = "products-nav";
break;
case "Report":
navId = "reports-nav";
break;
case "Tool":
navId = "tools-nav";
break;
}
if (navId != "") {
_this.switchNav($('#nav-bar ul.top-nav li a[data-nav="' + navId + '"]'));
}
} else {
_this.switchNav($('#nav-bar ul.top-nav li a[data-nav="home-nav"]'));
}
}
this.initialize = function () {
initializeNavBar();
};
this.switchNav = function (navItem) {
$("#nav-bar ul.top-nav li a[data-nav]").each(function (i) {
$(this).removeClass("selected");
$("#" + $(this).data("nav")).hide();
});
navItem.addClass("selected");
$("#" + navItem.data("nav")).show();
};
}).call(gtg.navBar);
(function () {
var _this = this;
this.initialize = function () {
$(".tab-bar ul li a[data-tab-panel]").bind("click", function () {
_this.switchTab($(this));
});
};
this.switchTab = function (tab) {
$(".tab-bar ul li a[data-tab-panel]").each(function (i) {
$(this).removeClass("selected");
$("#" + $(this).data("tab-panel")).hide();
});
tab.addClass("selected");
$("#" + tab.data("tab-panel")).show();
};
}).call(gtg.tabBar);
(function () {
var _this = this;
this.focusField = function (fieldId) {
$("#" + fieldId).select().focus();
};
this.loadJQTemplate = function (templateName, callback) {
$.get("/Content/JQTemplates/" + templateName + ".html", function (template) {
callback(template);
});
};
}).call(gtg.utils);
$(document).ready(function () {
gtg.core.initialize();
gtg.infoBar.initialize();
gtg.navBar.initialize();
gtg.tabBar.initialize();
});

Jquery - Access variable from outside the plugin

I got a simple plugin as below:
$.fn.ajaxSubmit = function(options){
var submisable = true;
}
I want to able to change/access the variable myvar from outside the plugin, by doing something like below:
$(function(){
$('form').ajaxSubmit();
$('div').click(function(){
submisable =false;
});
});
You can also create methods to access the variables that are inside a plug in:
$.fn.ajaxSubmit = function(options){
var submisable = true;
$.fn.ajaxSubmit.setSubmissable = function(val){
submisable = val;
}
}
Then you can call it like this.
$('form').ajaxSubmit();
$('form').ajaxSubmit.setSubmissable(false);
This solution is not straight forward, but follows the jquery plugin guidelines.
(function($) {
var myVar = "Hi";
var methods = {
init: function(option) {
return this.each(function() {
$(this).data("test", myVar);
});
},
showMessage: function() {
return this.each(function() {
alert($(this).data("test"));
});
},
setVar: function(msg) {
return this.each(function() {
$(this).data("test", msg);
});
},
doSomething: function() {
//perform your action here
}
}
$.fn.Test = function(method) {
// Method calling logic
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof method === 'object' || !method) {
return methods.init.apply(this, arguments);
} else {
$.error('Method ' + method + ' does not exist on jQuery.Test');
}
};
})(jQuery);
$("form").Test("init");
$("#getCol").click(function() {
$("form").Test("setVar", "Hello World").Test("showMessage");
});
Are you thinking to access them as properties? Something like:
$.fn.ajaxSubmit = function(options) {
var defaults = {},
o = $.extend({}, defaults, options);
var _myvar = 'blue'
this.myvar = new function(){
return _myvar;
}
this.setmyvar = function(_input){
_myvar = _input
}
return this.each(function() {
if (_myvar == 'blue') {
alert('hi');
}
if (_myvar == 'red') {
alert('bye');
}
});
}
And set like:
this.setmyvar('red');

Multiple replaceWiths in jQuery?

Why doesn't this work? What would be a plausible solution to get this effect?
$(document).ready(function() {
$('#myLink1').click(
function() {
$('#myLink1').replaceWith('<a id="myLink2" href="#panel2">#panel2</a>');
});
$('#myLink2').click(
function() {
$('#myLink2').replaceWith('<a id="myLink3" href="#panel3">#panel3</a>');
});
});
I'm new to loops and how I'm supposed to add strings and variables.
$(document).ready(function() {
var panelNum = 8;
for (i=1;i<=panelNum;i++){
$('#myLink'+i).click(function() {
$('#myLink'+i).replaceWith('<a id="myLink'+(i+1)+'" href="#panel'+(i+1)+'">#panel'+(i+1)+'</a>');
});
};
});
The problem is myLink2 doesn't exist until mylink is clicked. You have to add the mylink2 handler after it is created. Try the following:
function add_replace_with(i){
$('#myLink'+i).click(
function() {
do_replace_with(i)
return false;
});
}
function do_replace_with(i){
$('#myLink'+i).replaceWith('<a id="myLink'+(i+1)+'" href="#panel'+(i+1)+'">#panel'+(i+1)+'</a>');
$('#myLink'+(i+1)).click(
function() {
do_replace_with(i+1)
});
}
$(document).ready(function() {
add_replace_with(1);
});
I should note, that you might be better of hard-coding the links and just using .show() to toggle them.
Alternatively:
$(function() {
$('body')
.delegate('#myLink1', 'click', function() {
$(this).replaceWith('<a id="myLink2" href="#panel2">#panel2</a>');
})
.delegate('#myLink2', 'click', function() {
$(this).replaceWith('<a id="myLin32" href="#panel3">#panel2</a>');
})
;
});
To generalize this for a whole bunch of such link, with similar naming convention:
$(function() {
for (var link = 1; link < 8; ++link)
(function(link) {
$('body').delegate('#myLink' + link, 'click', function() {
var nxt = link + 1;
$(this).replaceWith('<a id="#myLink' + nxt + '" href="#panel' + nxt + '">panel ' + nxt + '</a>');
});
})(link);
});

Categories