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>
Related
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.
CODE:
<span class="clickable" id="span_resend">Resend</span>
<script>
$('#span_resend').click(function (e) {
e.preventDefault();
var save_this = $(this);
var middle_this = $('<span class="loader">now_loading</span>');
$(this).replaceWith(middle_this)
$.ajax({
url:'/ajax/',
type:'post',
dataType:'json',
cache:false,
data:{
com: 'some',
},
success:function (data) {
console.log(data)
if (data.res === 'success'){
middle_this.replaceWith(save_this)
}
}
});
})
</script>
It works well when I click resend first.
However cause of script tag, there will be term of now_loading and after loaded, then clicking #span_resend does not works well.
I think it's from that I did not bind click function well on #span_resend.
But I don't know how to do it.
How can I do this?
More explanation: This code is to get ajax response from server, and that ajax response takes some time, maybe 10~15 seconds. So I want to change my resend button to show that ajax is being called, at the same time user cannot click during the waiting of ajax response from server.
The Problem:
Here's what's happening in your code that isn't obvious right away. On first click, you create a jQuery object containing the clicked span, you save this to a variable and after your post completes, you then replace the temporary span with the value of the variable.
Seems like everything should be just fine, but what you've actually done is dynamically added a control to your HTML and while the html of the control is identical to the original span, it is not the same control.
Why does this matter?
Events. It's all about events. When you copy a control, you aren't copying those event listeners associated with it too. So when that event fires again, it looks for the original control and doesn't find it.
You can read in depth about events and event listeners here.
So great, what do you do about all this?
The Solution:
The answer here is to bind those events to a control that is higher than the one you're replacing and won't be replaced itself. So maybe your body tag, or even the document tag. Here's what that would look like in your code:
// Instead of this:
$('#span_resend').click(function (e) {
// Some code.
});
// Do this:
$(document).on('click', '#span_resend', function (e) {
// Some code.
});
This ensures that those event listeners aren't removed when you replace the control.
Here's a mock up of your code using this method:
$(document).on('click', '#span_resend', function (e) {
e.preventDefault();
var save_this = $(this);
var middle_this = $('<span class="loader">now_loading</span>');
$(this).replaceWith(middle_this)
$.ajax({
url:'https://reqres.in/api/users?delay=3',
type:'post',
dataType:'json',
cache:false,
data:{
com: 'some',
res: 'success'
},
success:function (data) {
if (data.res === 'success'){
middle_this.replaceWith(save_this);
}
}
});
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="clickable" id="span_resend">Resend</span>
Hope that helps!
I recommend not replacing the button with a now loading but to hide it and show a separate loading indicator, then revert back once it's done
$(document).ready(function() {
$("#saveBtn").click(saveData);
});
function saveData() {
$('#saveBtn').hide();
$('#nowLoadingInd').show();
//AJAX here instead of timeout (just for demo purpose)
window.setTimeout(function() {
$('#saveBtn').show();
$('#nowLoadingInd').hide();
}, 10000);
}
#saveBtn {
display:inline-block;
background:green;
color:white;
border-radius:10px;
cursor:pointer;
padding:3px 5px
}
#nowLoadingInd {
color:gray
}
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>
<div id="saveBtn">Save!</div>
<div id="nowLoadingInd" style="display:none">Now Loading...</div>
</body>
</html>
Alternatively, you can pass an element to your ajax options and reference it in the then callback with the this object:
$.ajax({
url:"yourUrl",
data:{your:"data"},
extraProperty:$('#yourElem')
}).then(function() {
this.extraProperty.show()
});
I have an MVC application and one of the views contains a button with a condition.
<i class="fa fa-sticky-note-o"></i>Did Not Eat
<button type="button" id="btnRemoveDidNotEat" class="btn btnRemoveDidNotEat">Remove Did Not Eat</button>
On click of btnRemoveDidNotEat,btnRemoveDidNotEat is hidden.
If btnDidNotEat is clicked,btnRemoveDidNotEat is shown.
Here is my JS code.
$('.btnDidNotEat').on('click', function () {
$.ajax({
}).done(function (partialViewResult) {
$('#btnRemoveDidNotEat').show();
});
});
$('#btnRemoveDidNotEat').on('click', function () {
$.ajax({
}).done(function (partialViewResult) {
$('#btnRemoveDidNotEat').hide();
});
});
The functionality works for the first time. On click of ".btnDidNotEat", the other button '#btnRemoveDidNotEat' is shown. On click of '#btnRemoveDidNotEat', it is hidden as required.
However the second time,On click of ".btnDidNotEat", the other button '#btnRemoveDidNotEat' is shown. But the button click function for '#btnRemoveDidNotEat' is not called.
I have tried doing the same with style="display:none;", but that gives me the same issue. I have also tried using toggle.
Am I missing something?
EDIT : Simplified the question to make it more clear.
I am not sure I understand your question right, but it looks like your AJAX response seems to have a partial view result. If you are trying to access the button click event of that partial view of AJAX, it will not hit the click event because it will not be attached to the DOM. So instead of your code, you should use something like this.
$("body").on("click", ".btnRemoveDidNotEat", function() {
$.ajax({
}).done(function (partialViewResult) {
$('#btnRemoveDidNotEat').hide();
});
}
I'm not sure if I understood your question correctly, but here is what I got fiddle
Here is some improvements of your script:
$('.btnDidNotEat').click(function () {
$.ajax({
}).done(function (partialViewResult) {
$('#btnRemoveDidNotEat').toggle();
});
});
$('#btnRemoveDidNotEat').click(function () {
$.ajax({
}).done(function (partialViewResult) {
$('#btnRemoveDidNotEat').toggle();
});
});
You can use toggle() function instead of adding and deleting class.
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.
I am making few ajax requests in my jQuery file. On success of these jQuery requests, I wrote few on click events which are not working.
This is my code
$(document).ready(function (){
$.ajax ({
type: "POST",
url: 'myServlet',
async: false,
success: function (response) {
id = parseInt(response);
setOutputEvents();
}
});
function setOutputEvents() {
for (var queryNumber = 0; queryNumber <= id; queryNumber++) {
$.ajax({
type: "POST",
url: 'myOtherServlet',
data: {queryNumber: queryNumber},
success: success,
async: false
});
var success = function (response) {
//some code here
generateTable();
}
}
}
function generateTable () {
//some code here
pagination();
}
function pagination(){
$(".class").click(function(event) {
alert();
});
}
$("#me").on("click", function(){
alert("me is triggered");
});
});
I understand making multiple ajax requests is a bad programming practice but what could be the reason for on click events not getting triggered?
These are the onclick events which are not working.
function pagination(){
$(".class").click(function(event) {
alert();
});
}
$("#me").on("click", function(){
alert("me is triggered");
});
I am using Google Chrome Version 39.0.2171.95 on Windows 7.
Please do let me know if any further information is necessary.
Since you use ajax to load even the initial content it seems, .class / #me html elements likely do not exist on initial page load of the DOM. As you didn't post html, i'm guessing this is the case.
Thus, you need to use a delegated event click handler to respond to it
so, you would change
$("#me").on("click", function(){
to
$(document).on("click", "#me", function(){
and so forth to link it to the parent element that does exist, the document itself.
This would work:
$(".class").on("click", function(){
alert("me is triggered");
});
function generateTable () {
//some code here
pagination();
}
function pagination(){
$(".class").trigger("click");
}
Some notes:
Event handler must be registered before triggering click.
Triggered click selector must match the class which has the click event registered.
Functions must be defined before the usage.