Calling function inside javascript class - javascript

I have the following javascript class (really don't know if it is the best solution) and I wan't to call a function that is definded in this class, insinde another function defined in the same class.
step1 = {
init: function(){
this.events();
},
events: function(){
fct = this; // i stored this in a variable so that i don't lose it
$(document).on('click', '.form-line li', function(e) {
e.preventDefault();
fct.changeCategoryValue($(this));
});
$(document).on('click', '.alert-form .confirm', function(e) {
e.preventDefault();
$.fancybox.close(true);
});
},
changeCategoryValue: function(el) {
cat = el.hasClass('has-sub') ? '' : el.data('id');
title = el.hasClass('has-sub') ? '' : el.data('title');
$('#cat-title').val(title);
$("input[name='category']").val(cat);
}
As you an see I wan't to call the changeCategoryValue function but if I call it with this.changeCategoryValue it won't work. Any suggestions on how to improve the code?

Alternatively, you may change the scope of the function callback:
$(document).on('click', '.form-line li', function(e) {
e.preventDefault();
this.changeCategoryValue($(e.currentTarget));
}.bind(this));
Use .bind(this) so the scope of function(e){...} will be the instance of step1 instead of $('.form-line li',document). Now, to still target the clicked/selected .form-line li, you can access the object via e.currentTarget.

try to use:
step1.changeCategoryValue($(this));

you have added property to the class why don't you call it using class name like this :
step1.changeCategoryValue('any_element_ref');

You could create a proper object. This even allows you call init in the constructor if you wan't.
function Step() { this.init(); }
Step.prototype.init = function() { this.events(); };
Step.prototype.events = function() {
var self = this;
$(document).on('click', '.form-line li', function(e) {
e.preventDefault();
self.changeCategoryValue($(this));
});
$(document).on('click', '.alert-form .confirm', function(e) {
e.preventDefault();
$.fancybox.close(true);
});
};
Step.prototype.changeCategoryValue = function(el) {
cat = el.hasClass('has-sub') ? '' : el.data('id');
title = el.hasClass('has-sub') ? '' : el.data('title');
$('#cat-title').val(title);
$("input[name='category']").val(cat);
};
var step1 = new Step();

you can try use clojure like this:
step1 = (function(){
function events(){
$(document).on('click', '.form-line li', function(e) {
e.preventDefault();
changeCategoryValue($(this));
});
$(document).on('click', '.alert-form .confirm', function(e) {
e.preventDefault();
$.fancybox.close(true);
});
}
function changeCategoryValue(el) {
cat = el.hasClass('has-sub') ? '' : el.data('id');
title = el.hasClass('has-sub') ? '' : el.data('title');
$('#cat-title').val(title);
$("input[name='category']").val(cat);
}
function init(){
events();
}
return {
init:init,
changeCategoryValue: changeCategoryValue
}
})()

Related

Call function in prototype from other prototype

I have two prototypes in my jquery script :
script1.prototype.initScript = function() {
//first one
this.saveGrid = function () {
alert("here");
}
};
script1.prototype.otherFunction = function () {
//second
//script1.initScript.saveGrid ?
};
I'd like to call saveGrid in otherFunction. How can I do that?
Edit :
And there ?
script1.prototype.initScript = function() {
//first one
this.saveGrid = function () {
alert("here");
}
};
script1.prototype.otherFunction = function () {
//second
$('button').on("click", function(){
//call savegrid here
});
};
Thanks.
You can access the function over this, like you already did in you example while creating the function saveGrid.
You should instead ask yourself, if this is a good idea, to create a function in another function and re-use them elsewere. What will happen, if you call otherFunction before initScript?
function script1() {}
script1.prototype.initScript = function() {
this.saveGrid = function() {
alert("here");
}
};
script1.prototype.otherFunction = function() {
this.saveGrid();
};
var s = new script1();
s.initScript();
s.otherFunction();
For you second example you have to store this before creating your event listener.
function script1() {}
script1.prototype.initScript = function() {
this.saveGrid = function() {
alert("here");
}
};
script1.prototype.otherFunction = function() {
var that = this;
$('button').on("click", function(){
that.saveGrid();
});
};
var s = new script1();
s.initScript();
s.otherFunction();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>click me</button>
Prototype It depends on the type .
the correct way is defined as a prototype , so you can call them in different situations
script1.prototype.saveGrid=function () {
alert("here");
}
script1.prototype.initScript = function() {
//first one
this.saveGrid()
};
script1.prototype.otherFunction = function () {
//second
//this.saveGrid()
};`
or you can define an object which then associates the prototypes
var script1=(function () {
function initScript(){
this.saveGrid();
}
function otherFunction(){
this.saveGrid();
}
script1.prototype.saveGrid=function () {
alert("here");
}
});

$(this) in JavaScript Module Pattern

I'm trying to use the Javascript module pattern for the first time to organize my code. I understand the how "this" works here but cannot figure out how $(this) works. For example, the code below,
$(this).addClass('video-active'); in "chooseVideo" function, I want to apply addClass only for the clicked element. But it does not work. Could anybody give me some advice? Thank you!
;(function() {
'use strict';
if (typeof window.jQuery !== 'function') {
return;
}
var $ = jQuery;
var video = {
init: function() {
this.cacheDom();
this.bindEvents();
this.render();
},
cacheDom: function() {
this.$el = $('#videoWrap');
this.$button = this.$el.find('.video');
},
render: function() {
},
bindEvents: function() {
this.$button.bind('click', this.chooseVideo.bind(this));
},
chooseVideo: function(e) {
e.preventDefault ? e.preventDefault() : e.returnValue = false;
this.$button.removeClass('video-active');
$(this).addClass('video-active');
}
};
video.init();
})();
when you use bind, you are changing the context of this
So you will need to use the event object to get what was clicked.
chooseVideo: function(e) {
e.preventDefault ? e.preventDefault() : e.returnValue = false;
this.$button.removeClass('video-active');
$(e.target).addClass('video-active');

How do I grab this variable in a separate function? (jQuery)

I'm trying to use TsearchResultID in the last function but don't know how to access it... In this function ( $(document).on('click', '.slideYThumbnail', function(event) { )
function QueryGetta0() {
var TTsearchQuery = 'x';
return TTsearchQuery;
}
function QueryGetta1() {
return $.get(
"https://www.googleapis.com/youtube/v3/search",{
part: 'snippet',
maxResults: 1,
q: YTSearchQueryText,
type: 'video',
key: ''}
);
}
$(document).on('click', '.lister ul span', function(event) {
QueryGetta1()
.done(function(data) {
var TsearchResultID = data.items[0].id.videoId;
var target = '<div class="slideYThumbnail"><img class="slideYThumbnailInside" src="http://img.youtube.com/vi/' + TsearchResultID + '/0.jpg"></img></div>';
});
});
$(document).on('click', '.slideYThumbnail', function(event) {
alert(TsearchResultID);
});
You can manage it with creation of an object outside in the global scope:
var obj = {
TsearchResultID : "" // <---declare it here.
};
function QueryGetta0() {
// other code as is.
}
function QueryGetta1() {
// other code as is.
}
$(document).on('click', '.lister ul span', function(event) {
QueryGetta1()
.done(function(data) {
obj.TsearchResultID = data.items[0].id.videoId; // <---put value here.
var target = '<div class="slideYThumbnail"><img class="slideYThumbnailInside" src="http://img.youtube.com/vi/' + TsearchResultID + '/0.jpg"></img></div>';
});
});
$(document).on('click', '.slideYThumbnail', function(event) {
alert(obj.TsearchResultID); // now access it here.
});
If you want to share variables across functions, you will have to define them outside functions. This usually involve Global Variables, but its not a good practice to contaminate global scope.
Alternate is, encapsulate all event bindings inside a function registerEvents() and here if you define a variable outside event handlers, you can access them across handlers but it will still be a part of function hence preventing contamination. Also this helps in keeping all bindings together, making debug easier.
Example
function registerEvents() {
var sharableVar = null;
$("#btnInit").on("click", function() {
sharableVar = Math.floor(Math.random() * 10);
});
$("#btnNotify").on("click", function() {
console.log(sharableVar);
})
}
registerEvents()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button id="btnInit">Initialize</button>
<button id="btnNotify">Notify</button>
Try using an array declared in the global scope.
var TsearchResultIDArray = []; //declaration of array
$(document).on('click', '.lister ul span', function(event) {
QueryGetta1()
.done(function(data) {
TsearchResultIDArray.push = data.items[0].id.videoId;//push the value to the array
var target = '<div class="slideYThumbnail"><img class="slideYThumbnailInside" src="http://img.youtube.com/vi/' + TsearchResultID + '/0.jpg"></img></div>';
});
});
$(document).on('click', '.slideYThumbnail', function(event) {
alert(TsearchResultIDArray[0]); // access the first element of the array.
});
OR
Use session storage to SET/GET the value.
$(document).on('click', '.lister ul span', function(event) {
QueryGetta1()
.done(function(data) {
sessionStorage.setItem('TsearchResultID',data.items[0].id.videoId); //set the value in session
var target = '<div class="slideYThumbnail"><img class="slideYThumbnailInside" src="http://img.youtube.com/vi/' + TsearchResultID + '/0.jpg"></img></div>';
});
});
$(document).on('click', '.slideYThumbnail', function(event) {
alert(sessionStorage.getItem('TsearchResultID')); //get the value from session
});

One mouseleave event logs $(this) as element; another logs it as delegated object

I have attached to mouseleave events to two HTML elements. I'm confused why in one printing $(this) to the console shows the div element the event is attached to, and the other prints out the entire window.
$(function () {
$(document).on({
mouseenter: function (evt) {
$(evt.target).data('hovering', true);
},
mouseleave: function (evt) {
$(evt.target).data('hovering', false);
}
}, "*");
$.expr[":"].hovering = function (elem) {
return $(elem).data('hovering') ? true : false;
};
$(document).on({
mouseenter: function () {
var $menu = $(".menu[data-a='" + $(this).attr("data-a") + "']");
//console.log($menu)
$menu.addClass("menu_vis");
$(".menu").hide();
$menu.show();
},
mouseleave: function () {
console.log($(this)) //the div
var s = setTimeout(function () {
var $menu = $(".menu[data-a='" + $(this).attr("data-a") + "']");
var over_menu = $menu.is(":hovering");
if (!over_menu) {
$menu.hide();
}
}, 100);
}
}, ".activate");
$(document).on({
mouseleave: function () {
var s = setTimeout(function(){
var $activate = $(".activate[data-a='" + $(this).attr("data-a") + "']");
var over_activate = $activate.is(":hovering");
console.log($(this)); //the window ??
if (!over_activate){
$(this).hide();
}
}, 100)
}
}, ".menu");
});
Inside the nested function the this keyword refers to the window. (you're using setTimeout i.e. nested inside mouseleave)
To solve: use a variable before using nested function
var that = $(this);
//now when you use function, use like this:
setTimeout(function(){
console.log(that);//logs the Div
},100)
Or use bind method:
setTimeout(function(){
console.log($(this));//logs the Div
}.bind(this),100)

javascript rotate what to change

I have ,
jQuery(function ($) {
var allArrows = $(".arrow"),
arrowUpUrl = "select_arrow_up.png",
arrowDownUrl = "select_arrow.png";
allArrows.click(function () {
var currentUrl = $(this).attr("src");
$(this).attr("src", currentUrl === arrowDownUrl ? arrowUpUrl : arrowDownUrl);
allArrows.not(this).attr("src", arrowDownUrl);
});
});
my problem is when I click outside arrow do not return first position what I must change ?
i can't use css and toggle whit jquery I need to use images with outside place
http://jsfiddle.net/cYCnD/9/
You should add the following handler:
$(document).on('click', function(e) {
if (!$(e.target).hasClass('arrow')) {
$('.arrow').attr('src', 'select_arrow.png');
}
});
See my fiddle: http://jsfiddle.net/cYCnD/10/
The whole code should look like this:
jQuery(function ($) {
var allArrows = $(".arrow"),
arrowUpUrl = "select_arrow_up.png",
arrowDownUrl = "select_arrow.png";
allArrows.click(function () {
var currentUrl = $(this).attr("src");
$(this).attr("src", currentUrl === arrowDownUrl ? arrowUpUrl : arrowDownUrl);
allArrows.not(this).attr("src", arrowDownUrl);
});
$(document).on('click', function(e) {
if (!$(e.target).hasClass('arrow')) {
allArrows.attr('src', 'select_arrow.png');
}
});
});
If I understand you correctly, you want to reset the arrows positions when a user clicks elsewhere on the page.
If so, I believe this will work:
$(document).click(function(e){
if(!$(e.target).hasClass('arrow'))
$(".arrow").attr("src", select_arrow.png)
});

Categories

Resources