Onclick not working on Knockout array binded fields - javascript

Im working on a CRUD Table populated using Knockout. jQuery Click event is not working on new pushed elements to the observable array
click event function
$('td').on('click', function () {
var spanElement = $(this).find('span');
$(this).find('span').hide();
$(this).find('input').show().select().on('blur', function () {
$(this).hide();
spanElement.show();
});
});
This code is working for all rows populated on-load, but not for those I add using add button.
Why is it so? How to fix it?
JSFiddle

It does not work because you are adding the event handler directly to the table cells. When you add new rows, you never add the click element.
To solve this problem, apply the click event to the table and let event delegation take over
$('table').on('click', 'td', function () {
var spanElement = $(this).find('span').hide();
$(this).find('input').show().select().on('blur', function () {
$(this).hide();
spanElement.show();
});
});

Try this
$(document).on('click', 'table td', function () {
//Your Functions
});

Related

Same click event for multiple elements, specific case

I don't want to repeat my code so I am trying to figure out how to work with a click event on multiple elements:
$(document).ready(function() {
var realStateBtn = $('#real-estate-center').parent();
var link = $('#real-estate-center > .linkwidth');
realStateBtn.css('zIndex', 9999);
realStateBtn.click(function() {
console.log('TRIGGERED');
window.location.href='http://realestatecenter.bankofamerica.com/';
});
link.click(function() {
window.location.href="http://realestatecenter.bankofamerica.com/";
});
});
as you see the vars realStateBtn and link take you to the same place/has the same function applied so what can I do in order to put the same code into one function?
I know I can do something like this:
$('.class1, class2').click(...)
but in this case I have this elements:
$('#real-estate-center').parent();
$('#real-estate-center > .linkwidth');
Suggestions?
You can use the .add() method to combine jQuery objects.
realStatebtn.add(link).click(function() {
console.log('TRIGGERED');
window.location.href='http://realestatecenter.bankofamerica.com/';
}
It's exactly as you said: move the code into a single function:
function move() {
window.location.href='http://realestatecenter.bankofamerica.com/';
}
realStateBtn.click(move);
link.click(move);
Here is a jsfiddle showing the concept: https://jsfiddle.net/b0ynfnmn/
You could add a common class and listen the click event on this class:
// Store the elements you want to an array
var elems = [];
elem.push(realStateBtn);
elem.push(link);
// You can add more elements ...
Now iterate the array and add the same class:
for(var elem in elems) {
elems[elem].addClass('my-element');
}
Add the appropriate event listener (using event delegation in order to work):
// Add event listener using event delegation
$(document).on('click', '.my-element', function() {
window.location.href="http://realestatecenter.bankofamerica.com/";
});

jquery onblur not firing

I am trying to get an onblur/onfocus combination working for a pair of text boxes which I am selecting via class in jquery. I am not getting any errors in debug, but the blur function never seems to be called. When debugging my breakpoint in the blur function is not hit.
$(document).ready(function () {
var row = $(this).closest('tr');
$('.editClass').click(function () {
var editBoxes = $(row).find('.editClass');
var focus = 0;
$(editBoxes).focus(function () { focus++ });
$(editBoxes).blur(function () {
focus--;
setTimeout(function () {
if (!focus) {
alert('LOST FOCUS'); // both lost focus
}
}, 50);
});
});
});
Pretty sure the problem here was that the editBoxes were dynamically added to the page. This was not apparent in my question. Since they were dyncamically added I need to use
$(document).on('blur', '.editBoxes', function (){
...
}
The last two lines of your code example should be this
});
});
This is needed for closing the ready and click function call.
Another possible problem is that you wrap the focus and blur listeners in a click handlers. Why did you do this?

Can't apply for on click function on each of the checkboxes

I want to apply for onclick function on each of the checkbox that is being added in a datatable row.
Here's the image:
Now the issue is that I am writing a code like this
var tablei = $('#domains_list').DataTable();
$('#domains_list').find("input[name='chk[]']:checked").each(function()
{
$(this).on('click',function ()
{
// make a class change to the parent tr having the checkbox;
} );
}
});
But the problem is, I can't write the rest of the code.
You don't need each to bind event. Also you should check checked in the click handler
Use
$('#domains_list').find("input[name='chk[]']").on('click', function() {
//Perform your operation
if (this.checked) {
$(this).closest('tr').addClass('smclass');
} else {
$(this).closest('tr').removeClass('smclass');
}
});
OR
$('#domains_list').find("input[name='chk[]']").on('click', function() {
//Perform your operation
$(this).closest('tr').toggleClass('smclass', this.checked);
});
You do not need to iterate over elements individually to bind the event:
$('#domains_list').find("input[name='chk[]']:checked").click(function(){
$(this).closest('tr').addClass('smclass');
});
I think what you want is to use on()...
var tablei = $('#domains_list').DataTable();
$('#domains_list').on('click', "input[name='chk[]']", function () {
// Verify here if the checkbox is checked or not, but you could prefer the change event
// make a class change to the parent tr having the checkbox;
});
But the better way is to attach then event when you add the row (if you are able to do that).
The manual: http://api.jquery.com/on/
Because all of your checkboxes have the same function attach to it, so you dont need to loop all the element using each. An easier way to do that
$('document').on('click', "input[name='chk[]']:checked", function(){
//make sure you reset all tr before applying new class
$(this).closest('tr').addClass('custom-class');
});

Defining click behavior on prototype of object

I would like to have a table that when a tr is clicked in the tbody a function is called that writes something to the console. I would like this object to be something like this
function FancyTable(table) {
this.rows = $(table).find('tbody tr');
//need to add the behavior in the event handler somewhere here
this.rows.click = function () {
console.log('clicked');
}
}
FancyTable.prototype.getData = function (tr) {
var row = $(tr);
console.log(row.text());
}
var fancyTable = new FancyTable('#table1');
//Need to keep this behavior
$('#table1 tbody tr').click(function () {
console.log('this needs to be attached to the FancyTable object');
});
I would like for all of the click behavior to be encapsulated within the FancyTable object instead of having to add the click event handler in the page. What's a basic method for doing something like this? Fiddle
Happy Holidays :)
The click member is a method that takes a callback function, you don't assign a new function to click to bind an event.
Call click with the event handler as parameter, just as you did when you did bind the event in the page:
this.rows.click(function () {
console.log('clicked');
});
Fiddle: http://jsfiddle.net/Guffa/8DGXP/2/

Table onclick rows jQuery

I've a table whose content is getting generated via an AJAX success response.
HTML code
<table class="table table-hover" id="table_content"></table>
AJAX code
$.ajax({
dataType: "json",
type : "POST",
url: "/configuration/",
data : { 'selected_item' : selected_item_id },
success : function(result){
var table_heading = "<tr>"
var table_content = ""
for (var heads in result[1]){
table_heading +="<th style='background-color:#f1f1f1;'>" + result[1][heads] + "</th>"
}
for (var region in result[0]){
table_content += "<tr>"
for (var details in result[0][region]){
table_content += "<td>" + result[0][region][details] + "</td>"
}
}
table_content = table_heading + table_content
$("#table_content").html(table_content)
},
});
I want to apply an onclick function to it. Like this:-
Onclick function code
$(function(){
$('#table_content tr').click(function () {
$('.test').slideUp(0)
$(this).append(($('.test')).slideDown('slow'));
});
});
The issue that I'm facing is that I'm not able to click the row, if I generate the content via AJAX response. If I create a table inside the HTML itself, it'll work, but not when the table is created via AJAX response.
What's the problem? Please sugggest.
EDITED
What I'm trying to achieve is that a div should be slide down just below the row upon clicking the row. I does works for the first time when the data gets generated via AJAX. but it does not works when I'm generating data after the first time, though the event is triggered but $('.test').slideUp(0) $(this).append(($('.test')).slideDown('slow')); does not works after the first time. Nor any error is popped . See http://jsfiddle.net/fVz6D/5/
Updated:
See working demo: http://jsfiddle.net/c5FgG/1/
Your problem was that you attached the test div element to a table row, which dissapeared after repopulating the table. Instead, clone the test div on each click when you are changing the table content, and use the clone instead the original.
Old answer:
Add the onclick function code inside the ajax success function. It works out for me this way:
...
$("#table_content").html(table_content);
$('#table_content tr').click(function () {
alert("Clicked");
//your code
});
...
And don't forget to close the table rows with:
table_content += "</tr>";
The way you are using click to bind the event only binds the event to elements that are present in DOM at time the binding code is executed. You need event delegation for binding event with dynamically generated html elements using on().
$(function(){
$('#table_content').on('click', 'tr', function () {
$('.test').slideUp(0)
$(this).append(($('.test')).slideDown('slow'));
});
});
Delegated events
Delegated events have the advantage that they can process events from
descendant elements that are added to the document at a later time. By
picking an element that is guaranteed to be present at the time the
delegated event handler is attached, you can use delegated events to
avoid the need to frequently attach and remove event handlers, reference.
Try
$(function(){
$('#table_content').on('click', 'tr', function () {
$('.test').slideUp(0)
$(this).append(($('.test')).slideDown('slow'));
});
});
The on() handler should work on newly created elements too.
$(function(){
$('#table_content').on('click', 'tr', function () {
$('.test').slideUp(0)
$(this).append(($('.test')).slideDown('slow'));
});
});
Here Is a list of fiddles :
fiddle1
fiddle2
fiddle3
fiddle4
You can use it as per your requirement.
Use on() for dynamically added elements like,
$('#table_content').on('click',' tr', function () {
$('.test').slideUp(0)
$(this).append(($('.test')).slideDown('slow'));
});
Updated your div will move to tr which you clicked, so when you click on list it will generate new content in table so your div.test will be removed from HTML, thats why you are not getting the desc div again.
To solve this problem you have to add div.desc again in clicking of list like,
if(!$('body > div.test').length){
$("body").append('<div class="test">You slide down a row with content xyz</div>');
}
Full code
$('#list').on('click', 'li', function () {
var id = this.id;
var table_content = "";
// IF id=1,2,3,4,5 Code
$("#table_content").html(table_content);
// add below code foe div.desc
if (!$('body > div.test').length) {
$("body").append('<div class="test">You slide down a row with content xyz</div>');
}
});
Demo
Alternatively, you can use clone() like,
$(function () {
$('#table_content').on('click', 'tr', function () {
$clone=$('.test:not(.new-test)').clone();// clone the first test class element
$('.new-test').remove();// remove the cloned elements
$clone.addClass('new-test').appendTo('body');// add the clone to body
$clone.slideUp(0);// playing with clone now
$(this).append($clone.slideDown('slow'));
});
});
Working demo

Categories

Resources