Jquery how to bind element when iterating through .each to class method - javascript

I have a simple js class where i am trying to bind 'click' event on an object to the functions. I am iterating through a list of elements:
<ul id="cp">
<li><button id="panel_button_light">Turn Light On</button></li>
<li>
<div class="arrow-up" id="panel_button_temp_up"></div>
<div class="arrow-down" id="panel_button_temp_down"></div>
</li>
</ul>
I am not sure what i need to enter in the code below when iterating through the elements so that I can call the class method when clicking them.
This is the js code that i am using:
<script type="text/javascript">
var CP = function(widget){
this.widget_name = widget;
var self = this;
this.init = function(){
$('#'+this.widget_name).children('li').children('*[id*=panel_]').each(function(self){
//I need function here to bind the click event to the class CP
$("#" + this.id).on('click', $.proxy(this.id, this));
});
}
};
CP.prototype.panel_button_temp_up= function(){
};
CP.prototype.panel_button_temp_down= function(){
};
CP.prototype.panel_button_light = function(){
};
$( document ).ready(function(){
var c = new CP("cp");
c.init();
});

this.id is a string, so $.proxy(this.id, this) doesn't make sense. If you want to access the property with the same name on the instance of cp, you have to do something like instance[this.id].
For example:
var self = this;
this.init = function() {
$('#'+this.widget_name).find('[id^=panel_]').each(function() {
$(this).on('click', self[this.id]);
});
};

Related

How to get the dom element as an argument using data-bind attribute - knockout to manipulate with in my javascript code?

I want to pass the content of an li element as an argument to my function while using data-bind attribute, click method.
For example
<ul>
<li data-bind='click: titleClick(argument)'>(CONTENT)</li>
</ul>
What to put instead of argument to pass (CONTENT) to my titleClick function?
This is my processing in the js file
var MapProcess = function(){
this.titleClick = function(titleName){
for (var i = 0; i<model.markers.length; i++){
if (titleName == model.markers[i].title){
var infoWindow = new google.maps.InfoWindow({
});
infoWindow.setContent(model.markers[i].buborek)
infoWindow.open(map, model.markers[i]);
break;
};
};
};
};
I want the parameter titleName in my function above to equal the content retrieved from the html.
Thanks in advance.
The second argument in a click handler will be the click event. From that you can get the target element and its associated content.
https://knockoutjs.com/documentation/click-binding.html
var MapProcess = function() {
this.titleClick = function(data, event) {
console.log(event.target.textContent);
}
}
ko.applyBindings(new MapProcess());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<ul>
<li data-bind='click: titleClick'>(CONTENT)</li>
</ul>

Access a specific element clicked

I have the following method
PMm.test = function (){
....plenty of code....
$('.element',this.page).click(function(e){
e.preventDefault();
var self = $(this);
console.log(self);
this.load(someoptions)
}.bind(this));
...plenty of code....
}
PMm.test.prototype.load = function(options){
...some code
}
When console.log(self), it returns the method PMm.test. How do i access the element clicked if $(this) is the entire function scope where i declare my event ? Knowing that i also need to call the .load() method which is declared later on.
I think it'd be best to store the context in a variable an access it using closure in your callback. It'd lead to a more readable code.
PMm.test = function (){
....plenty of code....
// Store the context in a variable.
var that = this;
$('.element',this.page).click(function(e){
e.preventDefault();
// this here references the DOM element (as expected)
var self = $(this);
console.log(self);
// you can access your methods through that.
that.load(someoptions)
});
...plenty of code....
}
PMm.test.prototype.load = function(options){
...some code
}
Hope it helps.
Since you're using this for something else (because of the bind), you can use either:
e.target - This is the element the event actually occurred on, which may be a descendant of the element that you attached the handler to.
or
e.currentTarget - This is the element the handler is attached to. (What's normally this in jQuery callbacks if you don't use bind.)
E.g.:
PMm.test = function (){
// ....plenty of code....
$('.element',this.page).click(function(e){
e.preventDefault();
var elementClicked = $(e.currentTarget); // or $(e.target);
// ...use it...
this.load(someoptions)
}.bind(this));
Example:
function ClickResponder(name, selector) {
this.name = name;
$(selector).on("click", this.handler.bind(this));
}
ClickResponder.prototype.handler = function(e) {
console.log("this.name = " + this.name);
console.log("e.target.tagName = " + e.target.tagName);
console.log("e.currentTarget.tagName = " + e.currentTarget.tagName);
};
new ClickResponder("respond-o-matic", ".foo");
<div>
<div class="foo">
<span>Click me</span>
</div>
<div class="foo">
<span>Click me</span>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Using [function].bind(this) you are binding this (PMm.test) to the jquery event, overwriting this (element) set by jquery.
If you need both inside the function you don't need to bind the object, instead, making the object PMm.test accesible using a variable:
PMm.test = function (){
....plenty of code....
var obj=this; //obj references to PMm.test
$('.element',this.page).click(function(e){
e.preventDefault();
var self = $(this);
console.log(self);
obj.load(someoptions)
}); //no .bind()
...plenty of code....
}
PMm.test.prototype.load = function(options){
...some code
}

How to avoid multiple function call

I have click event function to create a new dom elements. Basically, every time I click a button. It allows create a new hyperlink tag.
I also want to have a functionality that if new created hyperlink clicked, I want to call different function.
Please have a look following code,
var id = 1;
$('#create').on('click', function() {
id ++
$('.players').append('<a href="#" class="new" data-id='+ id + '> ' + id + 'player</a>');
getId()
});
function getId() {
$('.new').on('click', function() {
var id = $(this).data('id')
alert(id);
});
}
My problem is I don't want to run getId() function everytime I clicked a button, But if I run getId() function alone, new created hyperlink won't effent that functionality.
Is anyway I can call getId() function once. and It still going to effect a new created hyperlink?
You can use one method to use the function only for once.
function getId() {
$('.new').one('click', function() {
var id = $(this).data('id')
alert(id);
});
Use delegation, then there is no need to attach the event handler function every time you append. Remove your getId() function and replace it with a delegated on() method:
var id = 1;
$('#create').on('click', function () {
id++;
$('.players').append('<a href="#" class="new" data-id=' + id + '> ' + id + 'player</a>');
});
$('.players').on('click', '.new', function(e) {
e.preventDefault();
var id = $(this).data('id')
alert(id);
});
JSFiddle
Try to use on() for dynamic elements like,
$(function(){
var id = 1;
$('#create').on('click', function() {
id ++;
$('.players').append('<a href="#" class="new" data-id='+id+'>'+id+'player</a>');
});
$(document).on('click','.new', function() {
//use ^ document or your parent element players
var id = $(this).data('id');
alert(id);
});
});

Javascript- send the clicked object as parameter in onClick function

In function clickCircle, i want to use the li which is being clicked. So i want to receive it as a parameter.
<li class="circle" onClick='clickCircle(this)'></li>
But what should i send as an actual paramenter? ie in place of 'this'.
You can use this:
function clickCircle(obj) // the li element clicked in the current scope
{
var element = obj; // This is the DOM object being clicked
var $this = $(obj); // This is the jQuery object being clicked
// Use DOM object like
element.style.color="#ff0000";
// Use jQuery object like
$this.css('color', 'red');
}
Try this instead
<li class="circle"></li>
$('.circle').on('click', function(event) {
event.target // your element
});
You should just use the first parameter as the element.
HTML
<li class="circle" onClick='clickCircle(this)'></li>
JS
clickCircle=function(element)
{
console.log(element)
console.log(element.tagName) // This will show LI
}
JSFiddle: http://jsfiddle.net/edi9999/WhVLm/
you can do it with jquery like this:
$(function () {
$('li.circle').on('click', function () {
clickCircle($(this));
});
});
var clickCircle = function (param) {
// your code here
// param.css('color', 'red').html();
};
or with raw javascript:
HTML
<li id="circle" class="circle"></li>
JAVASCRIPT
var circle = document.getElementById('circle');
circle.addEventListener('click', function (e) {
clickCircle(e.target);
});
var clickCircle = function (param) {
// your code here
// alert(param.nodeName.toLowerCase());
}

dynamically added div will not work when being called on [duplicate]

This question already has answers here:
Events triggered by dynamically generated element are not captured by event handler
(5 answers)
Closed 10 years ago.
I am trying to create a list of divs. When the new layer button is clicked, there is a new div created with a unique ID. When I try to call on these dynamically added divs, there is no response. I am confused because the preexisting divs work.
<input type="submit" id="newLayer" value="New Layer">
<div id="layersContainer" class="layerscontainer">
<div class="layer" id="layer1">fadfa</div>
<div class="layer" id="layer2">2</div>
</div>
var newLayerCounter = 2;
var layerID = "";
var layersArray = new Array();
var clickedElement = "";
function selectLayer(){
$(clickedElement).css({"background-color":"yellow"});
}
$('#layersContainer div').on("click", function(){
clickedElement = $(this).attr("id");
alert(clickedElement);
selectLayer();
});
$('#newLayer').on("click", function(){
newLayerCounter = newLayerCounter + 1;
layerID = "#layer"+ newLayerCounter;
$('<div/>', {
id: "layer"+ newLayerCounter,
class: "layer"
}).appendTo('#layersContainer');
$(layerID).text('hey');
})
Here is a link to a working JSfiddle
http://jsfiddle.net/Q3dSp/24/
Change your
$('#layersContainer div').on("click", function(){
to
$(document).on("click", '#layersContainer div', function () {
clickedElement = $(this).attr("id");
alert(clickedElement);
selectLayer();
});
It is known as delegated event.
Try with $('#layersContainer').on("click", "div", function(){ (...) });
http://jsfiddle.net/3hqfn/1/
change :
$('#layersContainer div').on("click", function(){
with this:
$('#layersContainer').on("click", "div", function(){
Try with this one:
$('#layersContainer').on("click", 'div', function(){
clickedElement = $(this).attr("id");
alert(clickedElement);
selectLayer();
});
In this situation you need a event delegation to existing closest parent when dom was ready.

Categories