jQuery Click Event CheckBox Changed Ajax Call - javascript

I have three checkboxes that who have checked/unchecked values populated from a model. I'm using an Ajax post on button click event to call controller actions for each checkbox changed event in order to update the DB.
Here is the code for one of the checkboxes (apart from the selector ID, they are all the same):
$(document).ready(function () {
//document.getElementById('UpdateButton').onclick = function () {
$("UpdateButton").click = function () {
$('#NatAm').change(function () {
// if ($('#NatAm').is(':checked')) {
$.ajax({
//url: '#Url.Action("NativeUpdate", "Transactions")',
url: '/Transactions/NativeUpdate',
//data: { isNativeUp: true },
type: 'POST',
dataType: "json"
});
//}
});
Edit (HTML/View Code):
#Html.CheckBox("NatAm", (bool)#ViewBag.NativeAm)
<input name="UpdateButton" id="UpdateButton" type="submit" value="Update" style="margin-left: 15px; margin-top: 3px;" class="btn btn-success" />
I cannot get this to work. Before adding the button, the ajax post was working fine. Thank you for your help!

Your click handler isn't right. You need to pass in the id of the button and use jQuery click handler. You also need not to nest the handlers:
$(document).ready(function() {
$("#UpdateButton").click(update);
$('#NatAm').change(update);
});
function update() {
$.ajax({
url: '/Transactions/NativeUpdate',
type: 'POST',
dataType: 'json'
});
}
JSFiddle Demo: https://jsfiddle.net/vLzwuwdo/

You're telling JQuery to look for 'UpdateButton' tags which in your case does not exist. You're missing the # which indicates an ID in your button.
Try this
$(document).ready(function () {
//document.getElementById('UpdateButton').onclick = function () {
$("#UpdateButton").click(function () {
$('#NatAm').change(function () {
// if ($('#NatAm').is(':checked')) {
$.ajax({
//url: '#Url.Action("NativeUpdate", "Transactions")',
url: '/Transactions/NativeUpdate',
//data: { isNativeUp: true },
type: 'POST',
dataType: "json"
});
//}
}));

id should be unique in same document (NatAm and UpdateButton), replace the duplicate ones by global classes will solve the first problem.
You should not define event inside another since every time you trigger the first it will create new event for the element, in your case every time you click new change event will be created and attached to the first element with NatAm.
Hope this helps.

Related

Fullcalendar updateEvent doesn't rerender

I want to add events to my DB via fullcalendar. So I want to add an event and set its id to the id it gets in my DB.
function addCalEvent(event) {
var jEvent = {};
jEvent['startTime'] = moment(event.start).unix();
jEvent['worker']="GUZ"
jEvent['title']=event.title;
if (event.end) {
jEvent['endTime'] = moment(event.end).unix();
}
$.ajax({
url: 'dux.html',
type: 'POST',
data: {
type: 'addNewEvents',
event: jEvent,
REQUEST_TOKEN: "REQUEST_TOKEN>",
},
datatype: 'json',
success: function(data) {
event.id=data;
event.title="NEW";
$('#calendar').fullCalendar('updateEvent', event);
},
});
}
The ajax retrieves the id of the added event and the id and title do get changed, but the 'updateEvent' method doesn't seem to be called, because there is no change to the rendered events title or id.
Ok,
apperently if you make a asynchronous ajax call the order in which commands are executed isn't the order you write it.
I need to add async: false to make this work.
You can manually call rerender events with $('#calendar').fullCalendar( ‘rerenderEvents’ )
Link to docs here

Binding an each statement

If I wanted to bind each statement to the #container div how would I go about this?
Here is an example of the each statement im trying to code:
$.each($(".product-comment"), function (key, value) {
var showmoreHtml = $(this).html();
var showlessHtml = showmoreHtml.substr(0, 400);
if (showmoreHtml.length > 400) {
$(this).html(showlessHtml).append("<a href='' class='product-comment-more'> (...Show More)</a>");
}
$(this).on("click", ".product-comment-more", function (event) {
event.preventDefault();
$(this).parent(".product-comment").html(showmoreHtml).append("<a href='' class='product-comment-less'> (Show less)</a>");
});
$.ajax({
method: 'POST',
url: urlCreateReview,
data: form_data,
cache: false,
processData: false,
contentType: false,
success: function(data) {
$(".tab-comment-holder").load(" .tab-comment-holder");
},
You can call the jquery function on your selector, call .each() and pass a function:
$("#container div").each(function() {
//do something
console.log($(this));
});
EDIT:
Apparently the div is "reloaded" in the callback of an AJAX. The solution is to make sure its items are properly initialized inside the callback. There is an .each() for this purpose, but it uses commands such as
$(this).on("click", ".product-comment-more", function (event) {
//...
}
which creates a click handler for every tag having the class of product-comment-more each time, this means that if there are n such tags and a user happens to click on one of those, the click handler will be executed n times. It's better to create a single handler for each of them. showmoreHtml is not well defined.

How to execute javascript after after ajax call inside a on() method

I am trying to execute a $.ajax() inside a function called by a .on() method, so that in the newlly attached data, it would be possible to execute a script on a .click() event - I know this is probably something similar to other requests, but i have tryed and tryed, and can't find what is wrong withthe code...
The ajax function is called by a change in a select, and 'this' is passed as a variable to the function.
The data is correctly inserted inside the targeted div, but it seems that there is no bubbling, because no javascript runs from it (but runs outside of targeted div).
I used .on() so it would bubble up, and update the DOM, and I dont see wath I am doing wrong with it...
The ajax is called with:
$("body").on("change", "[data-project-ajaxSelect='true']", {select: this},Select_AjaxCall);
function Select_AjaxCall(event) {
$select = event.data.select;
if (typeof $select.data === "undefined" || $select.data === null) {
var $select = $(this);
}
var options = {
url: $select.attr("data-project-action"),
type: $select.attr("data-project-method"),
target: $select.attr("data-target"),
data: { guid: $select.val() }
}
$.ajax({
type: options.type,
url: options.url,
data: options.data,
dataType: "html",
success: function (data) {
console.log(data)
$(options.target).html(data);
}
});
return false;
};
From that code, a button is added with the following View code:
<button id=#Model.Guid
class="button default cycle-button"
data-toggle="modal"
data-target="#modalDiv"
data-backdrop="static"
data-keyboard="true"
data-modal-modal="true"
data-modal-controller="Fin_Movement_Type"
data-modal-action="Create"
data-modal-var-guid=#Model.Guid
data-modal-var-modal=#ViewBag._modal>
<span class="icon mif-plus"></span>
</button>
And by cicking on this button, the following .click() event should be fired...
$("[data-modal-modal='true']").click(function () { ... }
But it isn't.
Please Help me find where is the bug with my code... thank you.
Edit
It seems you need live functionality that has been removed from jQuery, but you can use on instead of that, this way:
$(function () {
$(document).on("click","[data-modal-modal='true']", function () {
alert('clicked');
});
});
Original
You can add your code at the end of your success method:
success: function (data) {
console.log(data);
$(options.target).html(data);
$("[data-modal-modal='true']").on("click", function() {
alert('clicked!');
});
}
Also you can load the button with suitable script in onclick attribute, for example:
<button id="#Model.Guid"
...
onclick="alert('clicked!');">
<span class="icon mif-plus"></span>
</button>

Can't access object made by ajax call

I have this ajax request:
$.ajax({
type: "POST",
dataType: "json",
data: dataString,
url: "app/changeQuantity",
success: function(data) {
$('#table').append('<tr><td><a id="uid">click</a></td></tr>');
});
as you can see it makes new row in #table. But this new objects made by ajax are not accessible from next functions. Result from ajax is not a regullar part of DOM, or what is the reason for this strange behavior?
$('#uid').on('click', function () {
alert('ok');
});
Use event delegation:
$(document).on('click','#uid', function () {
alert('ok');
});
Note that ajax calls are asynchronous. So whatever you do with the data you need to do it in a callback within the success function (that is the callback which is called when the ajax call returns successfully).
Jquery on doesn't work like that. Use have to give a parent which not loaded by ajax, and the specify ajax load element like this
$('#table').on('click','#uid' ,function () {
// what ever code you like
});
Is simple and complex at the same time. Simple to solve but complex if you are getting started with javascript...
Your event handler - onclick is being fired and bound to an object that doesnt yet exist.
So when you append the object to the #table, you need to set up your click handler as the object now exists.
So in your success part of the ajax return add the click handler event there.
success: function(data) {
$('#table').append('<tr><td><a id="uid">click</a></td></tr>');
$('#uid').on('click', function () {
alert('ok');
});
});
Or how about you make it dynamic and create a function to do it for you.
function bindClick(id) {
$('#' + id).click(function() {
//Do stuff here
console.log('I made it here' + id);
});
}
Then:
success: function(data) {
$('#table').append('<tr><td><a id="uid">click</a></td></tr>');
bindClick(uid);
});
}
This is a super contrived example but you get the idea you just need to make the rest of it dynamic as well. for example some name and counter generated id number: id1, id2, id3...
Try it like this, add this $('#uid').on('click', function () { into the success
$.ajax({
type: "POST",
dataType: "json",
data: dataString,
url: "app/changeQuantity",
success: function(data) {
$('#table').append('<tr><td><a id="uid">click</a></td></tr>');
$('#uid').on('click', function () {
alert('ok');
});
});
});

jQuery plugin bsmSelect doesn't update its values when it is called again and its select options have changed

I'm using bsmSelect jQuery plugin. Basically, what it does is changing the way a select-multiple is rendered to make easier to pick up the options. It hides the select element and shows a list instead.
So, first of all I'm applying the plugin function to my select-multiple element:
$(document).ready(function() {
...
$('#my_select_multiple').bsmSelect({
plugins: [$.bsmSelect.plugins.sortable()],
title: 'Add',
removeLabel: 'Remove'
});
...
});
On the other way, I have another select element (this one is simple) which has an ajax request bind to its change event. This ajax request get new #my_select_multiple options depending on the select simple value. Ajax response is the new HTML for #my_select_multiple options. So I have:
function getNewOptions(val) {
var r = $.ajax({
type: 'GET',
url: /*My URL*/
}).responseText;
return r;
}
...
$(document).ready(function() {
...
$('#my_select_simple').change() {
$('#my_select_multiple').html(getNewOptions($(this).val()));
}
...
});
AJAX is working as expected. New options are got correctly and they are inserted into #my_select_multiple (which is hidden by bsmSelect plugin, but I can check it with Firebug). But bsmSelect didn't realize new changes and doesn't get updated.
So, I think what I want is to reapply $('#my_select_multiple').bsmSelect(); with its new options.
I've been looking around a little bit and here is what I have tried.
1. I've tried to call again the funcion with the success and complete (one at time) of the AJAX request. Didn't work:
function getNewOptions(val) {
var r = $.ajax({
type: 'GET',
url: /*My URL*/,
success: function() { $('#my_select_multiple').bsmSelect(); }
}).responseText;
return r;
}
2. I've tried to bind the function with the on jQuery function. Didn't work:
$('#my_select_simple').on('change', function() {
$('#my_select_multiple').bsmSelect();
});
3. I've tried 1 and 2 removing previosly the HTML generated by bsmSelect. Didn't work.
Thank you very much.
UPDATE: The exact code
First I have a global.js file which apply bsmSelect plugin to some select multiples (.quizzes):
$('.quizzes').bsmSelect({
plugins: [$.bsmSelect.plugins.sortable()],
title: 'Add',
removeLabel: 'Remove'
});
And then, in the php file I define the updateQuizzes function and bind it to the select simple (project_id) change event:
<script type="text/javascript">
function updateQuizzes(project_id) {
var r = $.ajax({
type: 'GET',
url: '<?php echo url_for('event/updateQuizzes')?>'+'<?php echo ($form->getObject()->isNew()?'':'?id='.$form->getObject()->getId()).($form->getObject()->isNew()?'?project_id=':'&project_id=')?>'+project_id,
success: function() { $('.quizzes').bsmSelect({
plugins: [$.bsmSelect.plugins.sortable()],
title: 'Add',
removeLabel: 'Remove'
}); }
}).responseText;
return r;
}
$('#project_id').change(function(){
$('.quizzes').html(updateQuizzes($(this).val()));
});
</script>
As I told, the AJAX request works without problems, but not the calling bsmSelect the second time...
Not sure if this is what the problem is, but you could try
$('#my_select_simple').change() {
$('#my_select_multiple').html(getNewOptions($(this).val())).trigger('change');
}
This triggers a change event on select_multiple, and might fire bsmSelect. I'm not sure what the problem here is exactly, but that's the best I can come up with.
I think you want to set your HTML in the success of the Ajax call, something like:
function loadNewOptions(val) {
$.ajax({
type: 'GET',
url: /*My URL*/,
success: function(data) {
$('#my_select_multiple').html(data).bsmSelect();
}
});
}
And then calling like:
$('#my_select_simple').change() {
loadNewOptions($(this).val());
}
$(document).ready(function() {
$('#my_select_simple').change() {
$('#my_select_multiple').load("your Url", function(){
$('#my_select_multiple').bsmSelect();
});
}
});
something like this should work.
.load will put whatever your url returns into #my_select_multiple
the first parameter is the url to load, and the 2nd is a function to call when it is done. which is where you need to set up your fancy selector.
Ok, I opened a ticket and bsmSelect developer has answered me in minutes. Great!
To let bsmSelect know about its select changes, you have to trigger a change event on the select. There is no need to call bsmSelect again.
So it can be that way:
function loadNewOptions(val) {
var r = $.ajax({
type: 'GET',
url: /*My URL*/,
success: function(data) {
$('#my_select_multiple').html(data).trigger('change');
}
}).responseText;
return r;
}
$('#my_select_simple').change(function() {
loadNewOptions($(this).val());
});

Categories