I am trying to pop up a confirmation modal when the user presses the delete button on the edit form. The modal pops up fine, but when jQuery should be submitting the form, it's not doing anything. I have delete as a type="button", because when it is of type submit the modal function does not hold up the process and it just deletes the user right away.
The HTML ...
-- EDIT --
(I added the <form>
tags)
<form action="/admin/edit-user" enctype="application/x-www-form-urlencoded" method="post" name="edit_user_form" id="edit_user_form">
...
<p><input type="submit" value="Save" name="submit" id="submit"/></p>
<p><input type="submit" value="Cancel" name="cancel" id="cancel"/></p>
<p><input type="button" value="Delete User" name="delete_btn" id="delete_btn" onclick="confirmDeleteUser();"/></p>
...
</form>
...
<div id="dialog-modal" title="Confirm Delete User">
<p><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 0 0;"></span> Are you sure you wish to delete this user?</p>
<p>To continue editing, click cancel.</p>
</div>
The Javascript:
function confirmDeleteUser()
{
$('#dialog-modal').dialog({
autoOpen: false,
width: 400,
modal: true,
resizable: false,
buttons: {
"Cancel": function() {
$(this).dialog("close");
return false;
},
"Delete User": function() {
var self = $(this);
var form = $('#edit_user_form');
tmpElm = $('<input type="hidden" />');
tmpElm.attr('name', 'delete');
tmpElm.attr('id', 'delete');
tmpElm.val(true);
tmpElm.appendTo(form);
form.submit();
return true;
}
}
});
$('#dialog-modal').dialog('open');
}
When I inspect the source, I'm seeing that the code is properly appending the new hidden element, but the submit just doesn't seem to want to fire. What step am I missing?
HTML
Your html has the following: onclick="confirmDeleteUser();"
Why? jQuery is supposed to make this easier for you, not harder.
Your HTML should be pure and not calling functions (with the exception of ultra-extreme circumstances you are very unlikely to encounter). Why not use the jQuery library to bind the event to the element, rather than mix javascript function calls into your HTML? You should be doing something like this in the <script>
tags, after a document ready statement.
$("#delete_btn").click(function(e){
/*Code that runs on click of the "delete_btn" ID tag*/
});
If you're unfamiliar with jQuery selectors and events then start reading here.
The other reason you should do this is in the event the document isn't correctly/fully loaded in order to prevent it from breaking on your users.
CSS
You've also done this: style="float:left; margin:0 7px 0 0;"
in an HTML tag? That's evil, dude. Just evil. How am I going to maintain this code in five months?
Instead, use CSS.
In your tags, or CSS file, you need an entry such as:
.dialogAdjust {
float: left;
margin: 0 7px 0 0;
}
Then in your HTML you would say:
<span class="ui-icon ui-icon-alert dialogAdjust"></span>
And now you can tweak the thing to your heart's content. It's better if you can make the class on the dialog div, rather than individual HTML elements, and in this case you absolutely can.
JavaScript
Hokay, so, here's your function:
function confirmDeleteUser()
{
$('#dialog-modal').dialog({
autoOpen: false,
width: 400,
modal: true,
resizable: false,
buttons: {
"Cancel": function() {
$(this).dialog("close");
return false;
},
"Delete User": function() {
var self = $(this);
var form = $('#edit_user_form');
tmpElm = $('<input type="hidden" />');
tmpElm.prop('name', 'delete');
tmpElm.prop('id', 'delete');
tmpElm.val(true);
tmpElm.appendTo(form);
form.submit();
return true;
}
}
});
$('#dialog-modal').dialog('open');
}
What's going on here? First step, you should try and use a tool to measure code quality. Two popular ones are JSHint and JSLint. You don't need to follow things they say like it's the only way to write your code, but it's immensely helpful in finding bugs due to small mistakes. I like JSHint, so we're going to run it through that.
And here's the output:
Errors:
Line 17 tmpElm = $('<input type="hidden" />');
'tmpElm' is not defined.
Line 18 tmpElm.attr('name', 'delete');
'tmpElm' is not defined.
Line 19 tmpElm.attr('id', 'delete');
'tmpElm' is not defined.
Line 20 tmpElm.val(true);
'tmpElm' is not defined.
Line 21 tmpElm.appendTo(form);
'tmpElm' is not defined.
Oops. Looks like you've got an undefined variable in there, meaning it's now global. Global variables are bad, they break scope and can make your code function in strange ways.
We need to fix that. You should always declare local variables in local scope. That means putting a var tempElm;
at the top of the "Delete User" function.
Do away with that function wrapper, you won't need it. Your code should create the dialog object and code when the document is done loading, and open the dialog when it's clicked. What is happening in your original code both creating the dialog and opening it every time you click that button. What's the problem with that? You keep creating the object, even though it's created. You're creating the same object again and again and again. In this implementation, you won't notice it, but your design will carry over to places it will unless you take notice of this now.
So, what does that look like? In your <head>
tag you should see something like this:
<script>
/*
This makes all the code inside
run when the window is done loading,
not before, which may cause issues.
*/
$(window).load(function(){
/*
This sets up the dialog
as you've described before
*/
$('#dialog-modal').dialog({
autoOpen: false,
width: 400,
modal: true,
resizable: false,
buttons: {
"Cancel": function() {
$(this).dialog("close");
return false;
},
"Delete User": function() {
var self = $(this);
var form = $('#edit_user_form');
//We've added the var infront of tepElem
var tmpElm = $('<input type="hidden" />');
tmpElm.prop('name', 'delete');
tmpElm.prop('id', 'delete');
tmpElm.val(true);
tmpElm.appendTo(form);
form.submit();
return true;
}
}
});
/*
This is the part where I talked
about selectors and events in the HTML
*/
$("#delete_btn").click(function(e){
$('#dialog-modal').dialog('open');
});
});
</script>
When asking for help, use a tool like jsFiddle to post JavaScript in to make it easier for other people to help you.
Here's a jsFiddle of the revisions we've made so far. Spend a bit of time learning how to use it if you're doing a lot of work in JavaScript and want to test something really quickly.
Here's why I wanted you to learn jsFiddle:
If you want help, don't make people work really hard for it. You won't get good help unless someone is totally insane.
jsFiddle requires you post actual working code (or non-working code) that lets us see if there's a problem with form.submit(), such as any strange attributes or properties on the form element, or any number of other issues that could be kicking around that you excluded.
So let's look at what's breaking your "Delete User" function.
function() {
var self = $(this);
var form = $('#edit_user_form');
tmpElm = $('<input type="hidden" />');
tmpElm.prop('name', 'delete');
tmpElm.prop('id', 'delete');
tmpElm.val(true);
tmpElm.appendTo(form);
form.submit();
return true;
}
form
is a word reserved by used in the DOM, you should avoid using that one to avoid confusion between your variable and the DOM API.How forms should look:
The w3 explains what forms are and the purpose of things.
Key points:
Something weird is going on in your form.
Here's a form that javascript understands how to submit: http://jsfiddle.net/YS8uW/2/
Here's javascript attempting to submit your form (stripped down to bare-bones): http://jsfiddle.net/LfDXh/
What's different here?
Lets look at something you've done, given an ID of submit to something: http://jsfiddle.net/fdLfC/
And what happens when we don't use that as an ID? http://jsfiddle.net/fdLfC/1/
It's like giving it an id of submit won't let you call submit. A proper explanation is, you've re-written it because the dom did it when you assigned that ID and Name, it's trying to call the element.
You can see this if you open up a debugger or something, it gives you an alert to the effect of:
TypeError: Property 'submit' of object # is not a function
A big thank you to @MattMcDonald for linking me to this resource, which explains how to deal with, and why, NAME and ID attributes over-write the built-in HTML DOM methods.
Do the other stuff I said too. Disclaimer: Everyone's going to wage war on me saying it's not absolute that you should be doing all those things, I agree, but I think this post is long enough, and we'll all agree that doing these things is a step forward in code quality, not backwards. It's up to you at the end, but try avoiding mixing things together into a huge messy pot. Think about the execution of your code and how it's happening also.
If you are sure it appends the hidden input, then the problem must be in using duplicate ID. The button and the hidden input have the same ID. Make them different and try again.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With