jQuery bind to submit causing problems - javascript

I show a form using jQuery Fancybox -- in the form, the user has the option to edit the record or delete the record.
The JS config for this popup is as follows:
$('tr.record').click(function() {
var record_id = $(this).attr("id");
var link = 'http://' + window.location.hostname + '/expenses/expenses_edit/' + record_id;
$.fancybox({
'transitionIn': 'none',
'transitionOut': 'none',
'type': 'ajax',
'href': link,
'onClosed': function() {
parent.location.reload(true);
}
});
$.bind("submit", function() {
$.fancybox.showActivity();
$.ajax({
type: "POST",
cache: false,
data: $(this).serializeArray(),
success: function(data) {
$.fancybox(data);
}
});
return false;
});
});
This works perfectly when the user changes his data and clicks save, as below:
<form>
<button>
<span>
Save
</span>
</button>
</form>
Next I opened a new form for the delete button
<form>
<button onclick="confirmDeleteRecord();">
<span>
Delete
</span>
</button>
</form>
Which onClick runs this:
function confirmDeleteRecord() {
var agree = confirm("This expense will be removed and you can't undo this action. Are you sure you want to remove this record?");
if (agree) return true;
else return false;
}
The problem I'm having is that when I click on 'Cancel' in the browser modal confirmation, the form is still submitted and the record is deleted.
I suspect this has to do with the bind to submit -- anyone know how to fix this issue? 'Cancel' should just close the browser modal.
Thanks for helping, much appreciated.

Change the button HTML to as follows(use return confirmDeleteRecord();):
<button onclick="return confirmDeleteRecord();">
<span> Delete </span>
</button>
Edit:
Better way is to attach a click event handler to the delete button in an unobstrusive way.
You can try this as an alternative:
<button id="deleteBtn">
<span> Delete </span>
</button>
<script type="text/javascript">
$(function(){
$("#deleteBtn").click(confirmDeleteRecord);
});
</script>

Your bind will bind to every submit. You need to provide an id or class selector for each submit. For instance:
$('#classname').submit(function() { // your code here }
See: http://api.jquery.com/submit/

You must bind the submit handler TO something. This is your problem line:
$.bind("submit", function() {
You'll need to select the form that is being submitted and bind a submit handler to the form. So, for example, if your form has id myForm, it should say something like this:
$('#myForm').bind("submit", function() {
Or even better, use the shortcut call:
$('#myForm').submit(function() {
For your button, remove onclick="confirmDeleteRecord();, and give it a class or id instead:
<button id="btnDelete">
<span>Delete</span>
</button>
And finally, add a click handler assignment to your jQuery:
$('#btnDelete').click(confirmDeleteRecord);
For the sake of tidiness, you could also simplify your confirm function like so:
function confirmDeleteRecord() {
return confirm("This expense will be removed and you can't undo this action. Are you sure you want to remove this record?");
}

Related

How to Stop Unwanted repeated variable in twitter-bootstrap dialog?

I have multi link to delete via ajax:
<a id="id-1">link1</a>
<a id="id-2">link2</a>
<a id="id-3">link2</a>
<a id="id-4">link2</a>
...
this is a simplified of my code:
$(document).on("click", "[id^=id-]",function(event) {
event.preventDefault();
var btnid = this.id;
alert('1:'+btnid );
// a dialog confirm to aks delete in bootstrap
$("#confirmbtn").on( "click", function(event) {
alert('2:'+btnid );
});
})
when I refresh page for first one I got this in alert:
(click on <a id="id-1">link1</a>)
1:id-1
2:id-2
but for second,third and ... I got wrong!
for example for second:
(click on <a id="id-1">link2</a>)
1:id-2
2:id-1
2:id-2
the third:
(click on <a id="id-1">link3</a>)
1:id-3
2:id-1
2:id-2
2:id-3
I expect
1:id-3
2:id-3
can help me to solve that?
As you are binding event handler inside another event handler, a new event handler is getting attached every the element is clicked, thus you are getting the issue. You can use .data() to persist arbitrary data.
$(document).on("click", "[id^=id-]",function(event) {
event.preventDefault();
var btnid = this.id;
alert('1:'+btnid );
$("#confirmbtn").data('id', this.id)
})
// a dialog confirm to aks delete in bootstrap
$(document).on( "click", "#confirmbtn", function(event) {
alert('2:'+$(this).data('id'));
});
You are binding multiple eventhandlers to the button. With each clicked link (link-1, link-2 etc.) you add a new one to the button, but the existing ones remain. To solve this, you could add an event handler to the confirm-button on initialization and use a variable, which tells you anytime, which link was clicked last. You could do this like this:
$(document).ready(function() {
var lastLinkId;
$("#confirmbtn").click(function() {
alert("2: "+lastLinkId);
});
$(document).on("click", "[id^=id-]",function(event) {
event.preventDefault();
lastLinkId = this.id;
alert('1: '+lastLinkId);
});
});

Change behavior of button using AJAX

I'm trying to figure out how to change behaviour of a button using AJAX.
When the button is clicked, it means that user confirmed order recently created. AJAX calls /confirm-order/<id> and if the order has been confirmed, I want to change the button to redirect to /my-orders/ after next click on it. The problem is that it calls again the same JQuery function. I've tried already to remove class="confirm-button" attribute to avoid JQuery again but it does not work. What should I do?
It would be enough, if the button has been removed and replaced by text "Confirmed", but this.html() changes only inner html which is a text of the button.
$(document).ready(function () {
$(".confirm-button").click(function (b) {
b.preventDefault();
var $this = $(this);
var id = this.value;
var url = '/confirm-order/'+id;
$.ajax({
type: 'get',
url: url,
success: function (data) {
$this.empty();
$this.attr('href','/my-orders/');
$this.parent().attr("action", "/my-orders/");
$this.html('Confirmed');
}
})
});
});
The event handler will be still attached to the button, so this will run again:
b.preventDefault();
which will prevent the default, which is opening the href. You need to remove the event handler on success. You use the jQuery #off() method:
$(".confirm-button").off('click');
or more shortly:
$this.off('click');
You can add to your success function something like: $this.data('isConfirmed', true);
And then in your click handler start by checking for it. If it's true, redirect the user to the next page.
$(".confirm-button").click(function (b) {
b.preventDefault();
var $this = $(this);
if ($this.data('isConfirmed')) {
... redirect code ...
}
else {
... your regular code ...
}
}
You need to use .on() rather than .click() to catch events after the document is ready, because the "new" button appears later.
See http://api.jquery.com/on/
$(document).ready(function() {
$('.js-confirm').click(function(){
alert('Confirmed!');
$(this).off('click').removeClass('js-confirm').addClass('js-redirect').html('Redirect');
});
$(document).on('click', '.js-redirect', function(){
alert('Redirecting');
});
});
<button class="js-confirm">Confirm</button>

datatables jquery click event not working after pagination

I am using http://datatables.net/
<button class='btn btn-success activeAccount'>Activate Account</button>
I trigger ajax call on onclick event, below is ajax call code:
$(".activeAccount").click(function() {
var intCounselorId = $(this).parent().parent().find('input[class="counselorId"]').attr("value");
var intOwnerId = $(this).parent().parent().find('input[class="userID"]').attr("value");
var strAction = 'activateAccount';
performAction(intCounselorId, intOwnerId, strAction);
});
function performAction(intCounselorId, intOwnerId, strAction) {
$.ajax({
url: '/admin/counselormanagement/expertmanagementgridaction',
data: 'intCounselorId='+intCounselorId+'&intOwnerId='+intOwnerId+'&strAction='+strAction,
type: "POST",
async:false,
success: function(intFlag) {
if(intFlag == 1){
location.reload();
}
}
});
}
I'm trying to run an onclick event which works normally on page one, but as soon as I go to page 2 (or any other) it stops working.
I'm using jquery-1.10.2.min.js and 1.9.4 version of datatable
Because the event is attached only to existing elements.
You should change it to:
$("#tableId").on("click", ".activeAccount", function(){
// your code goes here
});
Read more in the documentation of jQuery.on.
$(document).on("click",".activeAccount",function(e){
// your code goes here
});
I had the same issue. Every time my AJAX function(modalContentAjaxRefresh) update the table the paging stop. SO I just had to change my code from :
From :
$('.modal-toggle').off('click', modalContentAjaxRefresh).on('click',
modalContentAjaxRefresh);
to:
$('#DataTables_Table_0_wrapper').on("click", ".modal-toggle",
modalContentAjaxRefresh);
My button inside datatable is :
< a title="Edit" class="btn btn-xs btn-info modal-toggle"
data-style="zoom-in"
href="/setting/account/{{account_turn.uuid}}/update"
data-toggle="modal" data-target="#editAccount" wecare-method="GET">
As #squaleLis said, the event is attached to only existing elements.
So, in my case I defined onclick event for the button and called it.
<button class='btn btn-success activeAccount' onclick="YourMethod();">Activate Account</button>
function YourMethod() {
....same code..
}
$("#product-list").on("click",".btn-delete-product",function(e){
e.preventDefault();
var prodId = $(this).attr("product-id");
.... code to delete the record from the db...
});
product-list is the table where data gets loaded and has paging enabled.
This works perfectly for me.
I thinks a good and easy solution is to use drawCallback option
The main important thing is to reassign the elements when click the pagination.
//function to assign event
var assign_actions = function(){
//Some code
}
//when the page is ready
$( document ).ready(function() {
assign_actions();
//Code to assign event when paginate
$('.paginate_button').on('click', function(){
assign_actions();
});
});

jQuery event priority

I have an element which I bind more than one event handlers:
<div id="info">
<button class="action-delete" type="button">Delete</button>
</div>
$("#info").on("click", ".action-delete", function() {
$.event.trigger({
type: "application",
message: {
name: "item-delete",
item: $("#info").data("item")
}
});
});
Then I want the user to make sure before the delete operation is done, since there are so many elements with action-delete working for different models, so I tried to inject the following scripts to the page(from another js file):
$(document).on("click", ".action-delete", function(e) {
return confirm("Sure to delete?");
})
However I found that event the confirm window displayed, the delete operation is still completed before the user choose.
Any idea to fix it?
The problem is in your confirm call here:
$(document).on("click", ".action-delete", function(e) {
return confirm("Sure to delete?");
})
It should be something like this:
$(document).on("click", ".action-delete", function(e) {
e.preventDefault(); //prevent default behavior
var conf = confirm("Sure to delete?");
if(conf == true){
$("#info").trigger( "click" ); //trigger click event for delete
}
});
Plus I would recommend removing the click event from the parent div. Instead make a delete function and let the confirm dialog ('yes') trigger the function.

AJAX/JQUERY Can't seem to delete data

Well my main problem is the button. I can't seem to find the reason why the button doesn't show up when I already clicked a certain tr
Here is the code that displays the returned employee data from the database
$.each(data, function(index, val) {
$("#employee_list").append('<tr class="emp_delete" id="'+val.emp_id+'"><td>'+val.emp_id+'</td><td>'+val.last_name+'</td><td>'+val.first_name+
'</td><td>'+val.middle_in+'</td>'+
'<td><input type="button" value="Resigned Employee" class="deleteBtn" id="delete_"'+val.emp_id+'"></td></tr>');
});
and here is the code that shows the button if .emp_delete is clicked. then the .deleteBtn code to delete the certain data
$(".emp_delete").click(function(){
var ID=$(this).attr('id');
$("#delete_"+ID).show();
});
$(".deleteBtn").click(function(){
var ID=$(".emp_delete").attr('id');
if (confirm("Are you sure you want to delete?")) {
var dataString = 'emp_id='+ID;
$.ajax({
type: "POST",
url: "<?php echo site_url('c_employee/delete_employee'); ?>",
data: dataString,
cache: false,
success: function(html){
location.reload();
}
});
}
UPDATE
The code that #Satpal gave worked but the .deleteBtn still doesn't show up after going through the each loop.
Here is the updated code:
$('#employee_list').delegate( ".emp_delete", 'click', function() {
var ID=$(this).attr('id');
$("#delete_"+ID).show();
});
$(".deleteBtn").click(function(){
var ID=$(".emp_delete").attr('id');
if (confirm("Are you sure you want to delete?")) {
var dataString = 'emp_id='+ID;
$.ajax({
type: "POST",
url: "<?php echo site_url('c_employee/delete_employee'); ?>",
data: dataString,
cache: false,
success: function(html){
location.reload();
}
});
}
else
return false;
});
As you are adding HTML dynamically.
You need to use Event Delegation. You have to use .on() using delegated-events approach.
Use
$(document).on(event, selector, eventHandler);
In above example, document should be replaced with closest static container.
In Your case
$('#employee_list').on('click', ".emp_delete", function() {
var ID=$(this).attr('id');
$("#delete_"+ID).show();
});
Similarly you have to delegate event for ".deleteBtn"
Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time.
EDIT
As per comment.
Since you are using jQuery 1.5, use .delegate()
$(elements).delegate( selector, events, data, handler );
In Your case
$('#employee_list').delegate( ".emp_delete", 'click', function() {
var ID=$(this).attr('id');
$("#delete_"+ID).show();
});
EDIT 2
Use similar syntax for delete button also
$('#employee_list').delegate( ".deleteBtn", 'click', function() {
});
You mean the button does not fire?
If so, that is because you define the function before you insert the element in the DOM, you need to bind it.
So instead of:
$(".deleteBtn").click(function(){
Put:
$("#employee_list").on("click",".deleteBtn",function(){
Once the document has been fully loaded, each time you add a new object to the DOM dynamically (like adding a new table row with buttons) you'll need to bind the generated element to an event or action, you cannot say "do something when someone clicks any button" you'd say "do something when someone clicks THIS button" meaning that you have to have the object created first in order to "attach" some action to it.
So let's say that you have these:
<button class="action-button" id="1">Button 1</button>
<button class="action-button" id="2">Button 2</button>
And then this javascript:
$(document).ready(function(){
$(".action-button").click(function(){
alert('My id is ' + $(this).attr('id'));
});
});
And then you later decide to add a button with some action on your js/html:
<button class="action-button" id="3">Button 3</button>
Surprise! If you click button 3 you'll get no alert...? Why, because the function that you set up for click event on document.ready parsed only the initial two buttons that existed at that moment, but since you added a third one dynamically later, the document.ready code wasn't aware of it.
So as Emil pointed out, each time you create a new element you'll want to bind it, in our example, for our button 3:
$('#3').bind('click', function(){
alert('My id is ' + $(this).attr('id'));
});
Or by the class, which is not adequate cause it would rebind existing elements and you lose performance:
$('.action-button').bind('click', function(){
alert('My id is ' + $(this).attr('id'));
});
So make sure that if you add elements that do actions or call functions you bind them when you add them, ideally, have a separate function which does whatever the button needs to do and then when you bind the new element, bind it to that function instead of putting a direct callback.
Try jquery version less than 1.9:
$('selector').live('click', function(){
});
you have a problem with the id delete
<div id="di"></div>
Algo
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="http://code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
<script type="text/javascript">
$('#algo').click(function(){
var a = 1;
//THIS IS IMPORTANT , SEE ID = "delete_" <- has a problem
$('#di').html('<td><input type="button" value="Resigned Employee" class="deleteBtn" id="delete_'+a+'"></td></tr>');
});
</script>
Is id="delete_'+val.emp_id+'" and not id="delete_"'+val.emp_id+'" (" <- error)

Categories