This should be fairly easy but I've tried a few things with no luck.
I have a series of Html.TextBoxFor fields on a page, each inside their own Ajax.BeginRouteForm. Next to each box I have a submit button, and this, when clicked, performs the Ajax update as desired.
I'd like to automate this so that when the user changes a value in a field (the onchange event) the form is submitted the same way it currently using using the submit button.
I tried using the htmlattributes to assign a JavaScript function to the onchange event (as shown below) and this causes the form to submit, but it redirects the page instead of working in the ajax fashion (as opposed to clicking the submit button which works correctly).
#(Html.TextBoxFor(model => answer.Value, new { onchange = "document.forms[" + answer.AnswerID + "].submit()" }));
(fortunately my answer.AnswerID is numeric and matches up with the numeric position of the appropriate form in the forms collection; I was referencing them by name but Razor (or something) was htmlencoding my JavaScript code...)
My only guess is that I'm breaking something by attaching code directly to the onchange event, but I'm at a loss as to the "right" way to hook into that event chain.
If you're willing to use JQuery, it's very simple to do:
http://net.tutsplus.com/tutorials/javascript-ajax/submit-a-form-without-page-refresh-using-jquery/
Calling submit() on a form will ignore any submit event handlers, as seen here. You can either
call the event handler directly, or
call click() on the submit button for the form.
The former works best if you use onsubmit and return false instead of using the event argument to the callback, because otherwise you need to pass another messy object or something.
Related
So I tried a couple of things when I using JS and try submitting inputs, and there are odd things I didn't understand the logic.
There is a difference between <input tpye="submit/> inside and outside of <form> tag. If it's inside the form tag I need to use preventDefault() function, but if it's outside form tag I am not required to do that if write simple js vanilla code.
Why is that?
What the difference between onsubmit and onclick ? especially in a form tag. Because If I use onsubmit the js code doesn't really work.
If I use preventDefault(event) it's preventing from the form to be sended into a server, and instead it doing the calculations with the browser only ?
Thanks !
By default, if you have an input of type "submit" in a form then clicking that input (or hitting enter after filling in ANY inputs in the form) will send a post or get request to the server, redirecting the current page to the server's response.
This was the original way to submit form data to a server, without using javascript. If you want to prevent this from happening, you can either replace the submit input with a plain button (<button onclick="doSomething()">Submit</button>), or prevent the default submission event: (form.onsubmit = event => event.preventDefault()).
The difference between onsubmit and onclick is that onsubmit only fires when a submission event is emitted from the form. To emit a submit event, the form needs an <input type="submit"> to be clicked, or for the user to trigger a submission by hitting enter.
Another way to prevent this default behavior is to return false in the submission handler.
onclick only gets fired when an element is clicked. Because events in javascript propagate up to parents, this will also trigger any onclick handlers on all parent elements.
If you want to completely ignore the default form submission behavior, then you can define a button with an onclick handler to handle your custom submission logic.
If you have a type="submit" input (Note, The default value for the type attribute of button elements is "submit") inside a form, the default action on click is to submit that form. To prevent it from submitting, place the button outside the </form>. This works because the button doesn't refer to any form to submit. You can instead, add a listener and call event.preventDefault(). This works because you are telling the browser NOT to take the default action (submitting the form)
onsubmit is used mostly on <form> elements. It triggers right before the form is submitted regardless of how it is submitted. onclick can be emitted from just about any element. It occurs when you click on an element. This could be on an <input>, a <button>. or even an entire <form>
Don't use this.
I've been trying to submit a form through mootools (1.4.5) on FF 14. The form does not contain an input named submit (which is often the problem). What I want is onchange in a select to submit the form. After half an hour the code below was my first attempt that got it working. objSelect is a select object that is contained within the form that I need to submit.
$(''+objSelect.getParent('form').get('id')).submit();
.
What the reason that the code below doesn't work as well?
// Without the explicit cast to string (''+); doesn't work
$(objSelect.getParent('form').get('id')).submit();
nor
// Most obvious way; doesn't work
objSelect.getParent('form').submit();
you can't have child nodes with reserved names that get exported via old DOM level API - see here how forms are being represented: http://www.quirksmode.org/js/forms.html#access
So basically - at an element level, if you have:
form
input[name=foo]
input[name=bar]
form.foo and form.bar will reference these element on the form element object.
the problem in your case is:
form (with a .submit and .reset method)
button[name=submit]
now form.submit stops referencing the submit method and starts referencing the input element.
you still submit this form by doing either:
rename the element that is wrong or remove from the form.
cheat by calling submit from a clean form.
new Element("form").submit.call(this.getParent("form"));
basically you create a new form element with a clean submit method. that returns an object and you call the method with the other "dirty" form as context.
this is just the same as doing
Array.prototype.slice.call(arguments)
I have a page where a series of checkboxes are displayed next entries from a database, they each have an onClick event to do an Ajax write of their value to the database.
I want to have a button on the form that toggles all the checkboxes, so I used the following function/jQuery:
function toggle_chk_links(){
$(".chk_user_link").click();
};
It works fine visually, the only problem is that although it triggers the onClick event as required the checkbox is read with it's old value, so the database gets the opposite value to the one required! This is the line reading the checkbox in its' onClick event:
active=Number($("#chk_brandlink"+brand_ID).prop("checked"));
I need users to be able to manually click on each checkbox, as well as toggle them all, ideally using one onClick function call. Any suggestions?
The easiest solution is to handle the onchange event instead of the onclick event.
$(".chk_user_link").change(function() {
// your change handler
});
Example: http://jsfiddle.net/7zHRm/1/
Our webapp has a form with fields and values that change depending on values entered. Each time there is a change event on one of the form elements, we use an expensive AJAX call to update other elements on the page.
This works great for selects, radio buttons and checkboxes. The issue comes in when a user adds content to a text field, and then clicks a link without taking the focus from the text field. The browser moves to a new page, and the contents of the text field are never saved. Is there an easy way to code around this? The AJAX call is too expensive to call with each key press.
Here's an example of my Prototype code at the moment:
$$('.productOption input.text').invoke('observe', 'change', saveChangeEvent);
Have you considered hooking into the window unload() event? Here is a c/p jQuery example using .unload().
$(window).unload(function() {
var input = $("#MyInput"); // Text field to check for
if(input.length > 0)
{
//Ajax call to save data, make sure async:false is set on ajax call.
}
});
This lets you work around making a call on each key press, by making one if they leave the page.
using prototype, you can have a PeriodicExecuter listen while you're typing and sending off an ajax query when nothing has happened for e.g. 2 seconds and value has changed since the last AJAX request. Start the executor using a focus event and shut it down using a blur event, that way you only need one executor at a time
I'm working on the Web GUI of an appliance-like product.
I have an HTML form that works fine: it shows a list of things with checkboxes, the user checks some of them and clicks the "remove" button which submits the form. The server gets the POST, removes the items, and refreshes the page. All fine.
There's a requirement to add an "are you sure?" confirmation to the form. If I add a call to
confirm("are you sure?");
as the onsubmit method in the FORM tag, or the onclick in the submit button tag, it works fine but uses the ugly browser-native confirm dialog.
Elsewhere in the product we have a nice custom CSS-styled confirm dialog I'd like to use, but it works like this: At the appropriate place, you put a call to
myConfirm("Confirm", "Are you sure", "Yes", "No", confirmCallback);
This puts up a clickmask, customizes a dialog, centers and displays it, and then returns FALSE and the form doesn't submit.
Later when the user decides, if they press "Yes", it calls the confirmCallback function. In the other, Ajax based pages of the product this gathers info, creates a postBody and uses Prototype's Ajax object to post it, and all is fine. (If "No", then the dialog and clickmask are removed and things continue.)
On this simpler page, with the pure HTML form, I have a confirmCallback function that looks like this:
var confirmCallback = function() {
document.myForm.submit();
}
and it fires OK, but when the form is submitted, the remove button has ALREADY been clicked, and the false returned by the custom confirm suppressed submission. Instead, this is considered a new submission, and the remove button was not actually clicked, so it is not considered "successful" in terms of W3.org's HTML 4 standard section 17.13.3. The server gets the data, no remove button, says "I got it but I dunno what you want me to do with it" and just does nothing but serve the next page.
If you're read this far, THANK YOU, and here is my actual question. How can I, in my confirmCallback javascript function, in a crossbrowser manner, cause the remove button to fire, become "successful" and submit along with the rest of the data?
Sounds like you're gonna need a hidden field to pretend to be the pressed button, and each button will require no name, but instead an onclick event to manipulate the value of the hidden field.
If the name of the buttons are all different, you might need to use DOM methods to add the hidden field because I don't think you can change the name of a field once it has been added to the DOM in all browsers.
If you require this solution to still work without JS, then you may need play around with the JS logic a little more (to do more modifications to your initial DOM tree) or modify the server code. You could even put the "Are you sure" behaviour into the response then...
Assuming that the remove button is the submit button for that form then probably the easiest solution is to give the form an id
<form id="submitForm"...
Then in your confirm call the form submit
document.getElementById("submitForm").submit()
I think that will do what you're asking but it seems like you were pretty much at that solution already so if you're asking something else let me know.
In your callback, remove the onclick handler for the button (causing the confirmation), then trigger a click on the button. This will cause the button click to submit the form and result in the button causing the submit to be posted back along with the form data.
var confirmCallback = function() {
$('submitButton').stopObserving('click');
$('submitButton').click();
}