jQuery calculate hours function not working - javascript

I am trying to pass $(this) value to a jQuery function. The function is below but does not work. There are no errors in console.
The function is firing because when I place an alert at the top it works.
(function($){
$.fn.calculateHours = function() {
var tbody = $(this).closest('tbody'); // get closest tbody
var table = $(this).closest('table'); // get closest table
var params = table.find('.disguise').serialize(); // parameters
$.ajax({
type: 'post',
dataType: 'json',
url: '/calculateHours',
data: params,
success: function (response) {
// loop over object
$.each(response.rows, function(index, array) {
$.each(array, function(key, value) {
$('#row_' + index).find('.' + key).html(value);
});
});
if($.isPlainObject(response.columns)) {
$.each(response.columns, function(day, hour) {
$('.totalsRow').find('.total_' + day).html(hour);
});
}
$('.totalsRow').find('.grand_total').html(response.grand_total);
}
});
}
})(jQuery);
$(document).on('change', '.disguise', function(e) {
$.fn.calculateHours();
});

Adding functions to $.fn is meant to extend the jQuery object. In other words, you should be calling .calculateHours on your jQuery object:
$(document).on('change', '.disguise', function(e) {
$(this).calculateHours();
});

You want jquery to set the context automatically. To do that just pass a reference to the function as the handler.
$(document).on('change', '.disguise', $.fn.calculateHours);

Related

change event doesn't work on dynamically generated elements - Jquery

I generate a dropdownList dynamicly with jquery Ajax , generated dropdown's id
is specificationAttribute . I want create add event for new tag was generated (specificationAttribute) , to do this I created Belowe script in window.load:
$(document).on('change', '#specificationattribute', function () {
alert("Clicked Me !");
});
but it does not work .
I try any way more like click , live but I cant any result.
jsfiddle
Code from fiddle:
$(window).load(function () {
$("#specificationCategory").change(function () {
var selected = $(this).find(":selected");
if (selected.val().trim().length == 0) {
ShowMessage('please selecet ...', 'information');
}
else {
var categoryId = selected.val();
var url = $('#url').data('loadspecificationattributes');
$.ajax({
url: url,
data: { categoryId: categoryId, controlId: 'specificationattribute' },
type: 'POST',
success: function (data) {
$('#specificationattributes').html(data);
},
error: function (response) {
alert(response.error);
}
});
}
});
$(document).on('change', '#specificationAttribute', function () {
alert("changed ");
});
}
Your fiddle has syntax errors. Since a dropdownlist generates a select, let's use one.
For my answer I used THIS HTML, more on this later: things did not match in your code
<select id="specificationAttribute" name="specificationAttribute">
</select>
Code updated: (see inline comments, some are suggestions, some errors)
$(window).on('load', function() {
$("#specificationCategory").on('change',function() {
var selected = $(this).find(":selected");
// if there is a selection, this should have a length so use that
// old: if (selected.val().trim().length == 0) {
if (!selected.length) { // new
// NO clue what this is and not on the fiddle so commented it out
// ShowMessage('please selecet ...', 'information');
alert("select something a category");// lots of ways to do this
} else {
var categoryId = selected.val();
var url = $('#url').data('loadspecificationattributes');
$.ajax({
url: url,
data: {
categoryId: categoryId,
controlId: 'specificationattribute'
},
type: 'POST',
success: function(data) {
// THIS line id does not match my choice of specificationAttribute so I changed it
$('#specificationAttribute').html(data);
},
error: function(response) {
alert(response.error);
}
});
}
});
// THIS should work with the markup I put as an example
$(document).on('change', '#specificationAttribute', function() {
alert("changed ");
});
});// THIS line was missing parts
#Uthman, it might be the case that you have given different id to select and using wrong id in onchange event as i observed in the jsfiddle link https://jsfiddle.net/a65m11b3/4/`
success: function (data) {
$('#specificationattributes').html(data);
},and $(document).on('change', '#specificationAttribute', function () {
alert("changed ");
}); $(document).on('change', '#specificationAttribute', function () {
alert("changed ");
});.
It doesnt work because at the moment of attaching event your html element doesnt existi yet.
What you need are delegated events. Basically, you attach event to parent element + you have selector for child (usually by classname or tagname). That way event fires for existing but also for elements that meet selector added in future.
Check documentation here:
https://api.jquery.com/on/#on-events-selector-data-handler
Especially part with this example:
$( "#dataTable tbody" ).on( "click", "tr",
function() {
console.log( $( this ).text() );
});

Ajax success function and find parent class

On click I run a function that will do an ajax submission for each form that has the .red_active class. After the ajax submission or after the complete function I want to remove the parent's .red_active class. This is what I tried, can you help me spot my mistake?
$('.edit_old').click(function(){
$('.slider_edit').each(function(){
if($(this).hasClass('red_active')){
$(this).find('.edit_form_slide').each(function(){
$(this).on('submit', function(e) {
e.preventDefault();
var data = $(this).serialize();
var url = $(this).attr('action');
$.ajax({
type: "POST",
url: url,
data: data,
success: function (data) {
console.log('submitted '+ url);
//$(this).parent().removeClass('.red_active');
},
error: function () {
console.log('fail');
}
});
});
$(this).submit();
//$(this).submit().parent().removeClass('.red_active');
});
}
});
});
The issue is because within the success handler the this keyword does not reference the .edit_form_slide as it does in the each() handler. You need to store the reference of this in a variable:
$('.edit_old').click(function () {
$('.slider_edit').each(function () {
var $sliderEdit = $(this);
if ($sliderEdit.hasClass('red_active')) {
$sliderEdit.find('.edit_form_slide').each(function () {
var $editFormSlide = $(this); // store 'this' in a variable
$editFormSlide.on('submit', function (e) {
e.preventDefault();
var data = $editFormSlide.serialize();
var url = $editFormSlide.attr('action');
$.ajax({
type: "POST",
url: url,
data: data,
success: function (data) {
console.log('submitted ' + url);
$editFormSlide.parent().removeClass('.red_active'); // to use here, within the other scope
},
error: function () {
console.log('fail');
}
});
});
$editFormSlide.submit();
});
}
});
});
Note that I did the same for the .slider_edit selector too, just to keep things consistent. If you have nested this references it can get confusing to keep track of what is referencing what, without a named variable.
First you can optimize and remove the if and .find lines
$('.slider_edit. red_active . edit_form_slide').each(function(){
has the same effect than :
$('.slider_edit').each(function(){
if($(this).hasClass('red_active')){
$(this).find('.edit_form_slide').each(function(){
And next to find a parents with a class, the best way is to use .parents() and all beware of the this in your function, the this in the success function is not the this you are looking to. You should save the $(this) before the ajax call in a var and reuse it into success callback.
Full correction :
$('.edit_old').click(function() {
$('.slider_edit.red_active .edit_form_slide').each(function() {
var $formSlide = $(this);
$formSlide.on('submit', function(e) {
e.preventDefault();
var data = $(this).serialize();
var url = $(this).attr('action');
$.ajax({
type: "POST",
url: url,
data: data,
success: function(data) {
$formSlide.parents('.red_active:first').removeClass('.red_active');
},
error: function() {
console.log('fail');
}
});
}).submit();
});
});

reinit function after ajax

I'm trying to rewrite some script. This script takes some data from data attributes and rebuild block with them. All was alright, but I need to do it via AJAX. Here my modified script:
(function($){
jQuery.fn.someItem = function()
{
var make = function() {
var _$this = $(this);
var $thumb = _$this.find('.thumb');
function init()
{
$thumb.on('click', function()
{
if (!$(this).hasClass('active')) setNewActiveItem($(this));
return false;
});
}
function setNewActiveItem($newItem)
{
$.ajax({
url: '/ajax-item?id=' + $newItem.data('id'),
type: 'GET',
success: function(response)
{
_$this.replaceWith(response);
**init();**
}
});
}
init();
};
return this.each(make);
};
})(jQuery);
All working fine, but after Ajax call and block replaced, I can't apply ajax-call in modified block again. I guess that I need to reinit "init()" function after "replaceWith()", but how to do it? Thank you for help.
You need to use a delegated event handler in the init() when attaching your click event to the .thumb elements. Try this:
var make = function() {
var _$this = $(this);
function init() {
_$this.on('click', '.thumb', function() {
if (!$(this).hasClass('active'))
setNewActiveItem($(this));
return false;
});
}
function setNewActiveItem($newItem) {
$.ajax({
url: '/ajax-item?id=' + $newItem.data('id'),
type: 'GET',
success: function(response) {
_$this.replaceWith(response);
}
});
}
init();
};
This works by assigning the click handler to the parent element and inspecting the click event as it bubbles up the DOM. It means that you can append any .thumb element at any time and not have to re-assign any new click handlers as the one defined on the parent will catch all.

Navigating a JSON object

total noob here:
I've got a JSON result coming to a .on('click') function which looks like this:
{"1411939719-8696.jpeg":true}
I want to remove a line in a table, based on where the call came from, but for some reason it's not working:
$('#fileupload').fileupload({
dataType: 'json',
done: function (e, data) {
$.each(data.result.files, function (index, file) {
$('<p/>').text(file.name).appendTo(document.body);
var del = $('<button/>')
.addClass('btn btn-danger')
.attr('data-type', 'DELETE')
.attr('data-url', file.deleteUrl)
.text('DELETE');
var thumb = $('<img />',
{ id: file.thumbnailUrl+'_ID',
src: file.thumbnailUrl,
alt:'MyAlt'});
$('#preview').find('tbody')
.append($('<tr>')
.append($('<td>').append(thumb))
.append($('<td>').append(del))
);
});
}
});
and the on click function is here:
$(document).on("click", ".btn-danger", function () {
$.ajax({
url: $(this).attr("data-url"),
type: $(this).attr("data-type")
}).done(function (result) {
$(this).closest("tr").remove(); // to remove the complete row after delete success
});
});
I need to remove the row that contains the delete button, along with the thumbnail image, but this code isn't working?
I think you are calling the wrong scope.
Maybe this could work:
$(document).on("click", ".btn-danger", function () {
//save scope-object to that
var that = this;
$.ajax({
url: $(this).attr("data-url"),
type: $(this).attr("data-type")
}).done(function (result) {
$(that).closest("tr").remove();
});
});

Button click pass argument to callback

I have this code , very simple , not working :
$(function() {
$(document).on('click', '#NetworkSearch', NetworkMarketSearching("NETWORK"));
$(document).on('click', '#MarketSearch', NetworkMarketSearching("MARKET"));
$(document).on('click', '#CableSearch', NetworkMarketSearching("CABLE"));
});
you can see - I am very simply using .on() to make NetworkMarketSearching() fire from a click, here is the function. This function works just fine on its own if called from the console.
function NetworkMarketSearching(types) {
var name, searchType;
if (types == 'NETWORK') { name = $('#NetworkName').val(); searchType = 0; }
else if (types == 'MARKET') { name = $('#MarketName').val(); searchType = 1; }
else if (types == 'CABLE') {name = $('#CableName').val();searchType = 2;}
$.ajax({
type: 'POST',
url: '/Talent_/Common/NetworkMarketSearch',
dataType: 'json',
data: { 'name': name, 'searchType': searchType },
success: function(data) {
}
});
}
The error is 'undefined is not a function' it repeatedly happens when putting NetworkMarketSearching('NETWORK') in the line of .on('click', ...
try this:
$(function() {
$(document).on('click', '#NetworkSearch', function() { NetworkMarketSearching("NETWORK"); });
$(document).on('click', '#MarketSearch', function() { NetworkMarketSearching("MARKET"); });
$(document).on('click', '#CableSearch', function() { NetworkMarketSearching("CABLE"); });
});
The click method doessnt support the string parameter, it expects the event object parameter.
This NetworkMarketSearching("NETWORK") calls the function immediately and attempts to assign its return result (which is undefined) as the callback.
You can use the data argument to pass information to your function calls:
$(function() {
$(document).on('click', '#NetworkSearch', { types: 'NETWORK' }, NetworkMarketSearching);
$(document).on('click', '#MarketSearch', { types: 'MARKET' }, NetworkMarketSearching);
$(document).on('click', '#CableSearch', { types: 'CABLE' }, NetworkMarketSearching);
});
Then the function definition would be:
function NetworkMarketSearching(event) {
and, within the function, the types would be referenced as
event.data.types
This is the way the jQuery docs specify passing arguments to the callback, but it can be done also with an inline anonymous function. That is to say, like this:
$(function() {
$(document).on('click', '#NetworkSearch', function () {
NetworkMarketSearching('NETWORK');
});
$(document).on('click', '#MarketSearch', function () {
NetworkMarketSearching('MARKET');
});
$(document).on('click', '#CableSearch', function () {
NetworkMarketSearching('CABLE');
});
});
Are you sure the function exists at the moment you call it?
Try go simple, use this sample of jquery site (http://api.jquery.com/on/):
function notify() {
alert( "clicked" );
}
$( "button" ).on( "click", notify );
then you pass a parameter, if it works you move to your code.

Categories

Resources