I have an HTML form that is trigged with AJAX to submit using a Rails backend. However, after submitting the first time, the form stops submitting. From reading other posts, I realize part of the problem is that the issue is related to including $(document) and not the form submit handler in the JQUERY call, but changing it to something like $('.new_todo form').submit will return the page as a JSON object instead of just the instantiated object {} response that I get with using $(document) in the Jquery.
I'm essentially trying to create an object and then to keep appending it to the index page, which works on the first submit, but as noted not on subsequent ones.
I'd really appreciate any insight because I've been staring at this for hours and while tons of answers address similar challenges (unbinding etc), nothing I found successfully addresses this use case.
The current AJAX call is:
$(document).on('submit', '.new_todo', (e) => {
e.preventDefault()
$.ajax({
type: "POST",
url: "/todos",
data: {
'authenticity_token': $("input[name='authenticity_token']").val(),
'todo': {
'name': $("#todo_name").val()
}
},
success: function(response) {
$("#todo_name").val("")
$("#todo_location").html("")
$("#todo_date").html("")
let newTodo = new Todo(response)
let todoHtml = newTodo.formatIndex()
$('.todo-list').append(todoHtml)
}
})
})
The controller action for my create is:
def create
#todo = Todo.new(todo_params)
#todo.save
render json: #todo
end
Thank you!!
Related
Due to the nature of my current project, I often find myself having to create HTML <form> elements which must support dynamic add/remove functionality of items for posting collections to the server.
My issue is that I find myself constrained by the name attribute of the form elements because I have to keep track of indices, ex.: Room[1].Tourists[0].Name. This is giving me hard times when I would like, for example, to remove an existing input element from the beginning.
I am currently building these dynamic forms with react.js which is enabling great flexibility, but I was wondering if there was some way that I could collect form data on submit event and just serialize it to match the expected model in the controller's action and post it?
Okay so you just want to solution about this i think you were stuck somewhere in your code that's why i am asking about the sample code no worry back to this try this:
<script type="text/javascript">
$(document).ready(function () {
$("#btn_submit").on('click', function () {
$.ajax({
type: "POST",
url: "Give URL here",
async: false,
data: $("#FormID").serialize(),
success: function (result) {
//Do what you want
},
error: function (response) {
//Do what you want
}
});
});
});
</script>
Once the validation runs, fails, and proceeds to redirect to the same controller index.
if (!$this->form_validation->run())
{
$this->index();
}
The form is a simple, two dropdowns, one dependent on the other, once the view is reloaded though, the second dependent dropdown stops working.
Here is the JS
$(document).ready(function()
{
$('#manufacturer_dropdown').change(function()
{
$("#sw_names > option").remove();
var id = $('#manufacturer_dropdown').val();
$.ajax({
type: "POST",
url: "software/get_software_names/"+id,
datatype : "JSON",
success: function(sw_names)
{
$.each(sw_names,function(id,software_name)
{
var opt = $('<option />');
opt.val(software_name);
opt.text(software_name);
$('#sw_names').append(opt);
});
}
});
});
});
If I manually refresh the page, the dropdowns work again. Not sure what is happening, maybe the document ready function stops checking or something. I'm no JS expert...
I can post more of the code if needed.
Edit: My JS URL was missing a /
Works now
If you are making an ajax request, you must give an ajax response
You cannot redirect the page in the middle of a request like that.
I've written something up going through all of this type of problem, as it's such a common one. Hopefully this will steer you along: http://codebyjeff.com/blog/2013/04/how-do-i-use-ajax-with-framework-x
Scenario:
I have written an MVC wizard that automatically uses ajax if javascript is enabled in the browser. Each step of the wizard is a PartialView (I'm using ASP.NET MVC 3).
All works fine.
The problem is refreshing the page if, for example, the user's status changes as a result of how she fills in the wizard. EG, if the wizard logs the user in, or registers them. As the wizard 'moves' from step to step by getting Partial Views via AJAX, the page doesn't get refreshed to reflect the change in the user's status (eg, an anonymous user is now registered).
What I want to do:
Essentially, when I need a full page refresh, I need to AUTOMATICALLY run the following on the client AFTER delivering the Partial View corresponding to the current step of the wizard via AJAX:
location.reload();
The Problem:
As the DOM has been modified via AJAX, I don't know how to make my javascript (location.reload();) run WITHOUT user intervention (eg, clicking a button).
Any suggestions? I have been off work for a while and am struggling to get back up to speed.
For now, I have solved my problem using the code in the following article:
Redirecting after AJAX call, when using ASP.NET MVC
I like the approach discussed in the article because it results in reusable code, in a very MVC way - I already have a base controller (AjaxController.cs) where I encapsulate all my AJAX aware code and this is a nice addition to it.
However, there are two issues with this approach:
I have to redirect away from my wizard, so it only works for the final step of the wizard. If the user's status changes half way through the wizard, I am still jiggered.
I would still like to know how to refresh my page after an AJAX call, rather than just redirecting like this.
So if anyone has the answer, I will gladly give them the biscuit.
I am not quite sure how your ajax calls are structured, but if you are using the MVC Ajax helper you can just call location.reload(); in the OnComplete method, like so:
#using (Ajax.BeginForm(new AjaxOptions{OnComplete = "javascriptfunction"}))
{
//Data and submit button
}
<script>
function javascriptfunction(){
location.reload();
}
</script>
// C# code
public ActionResult Foo(Bar bar)
{
// code here
return Json(new
{
Success = true,
Value = this.RenderPartialViewToString("PartialViewName", bar),
Callback = "window.location.href = 'http://yourdomainurl.com/';"
});
}
// jQuery Ajax
$.ajax({
type: "POST",
url: "/urlWhereToPost",
data: ("form#id").serialize(),
dataType: 'json',
async: false,
beforeSend: function() {
// some instruction
},
error: function(e) {
alert(e.responseText);
},
success: function(data) {
if (data.Success) {
if (data.Callback != null) {
if (data.Callback.length > 0) {
jQuery.globalEval(data.Callback);
}
}
}
else {
// do something
}
}
});
For those of you that use the Datatables js plugin, how can I create this example with server side data?
The example uses data that is hardcoded in the HTML.
You would basically do the following:
Serialize the form data (using jquery serialize as the example shows)
Submit said data to your form handling scrip (php etc)
They already provide the jquery serialize code so I won't show that, however the jQuery AJAX function will be needed (at the least):
$.ajax({
type: "POST",
url: "some.php",
data: YOUR-SERIALIZED-DATA-HERE,
success: function(msg){
alert( "Data Saved: " + msg );
}
});
And on your Server side PHP file you just grab the correct form array and parse your values ($_POST).
I had the same problem and didn't want to do an ajax save, so I did this:
var table = $("#mytable").datatable();
$("#myform").submit(function () {
var hiddenArea = $("<div></div").hide().appendTo("#myform");
table.$('input:hidden').detach().appendTo(hiddenArea);
// Prevent original submit and resubmit, so the newly added controls are
// taken into account
this.submit();
return false;
});
The idea is that I take all the inputs that are currently not in the dom and move them inside a hidden container.
Hey all. I was fortunate enough to have Paolo help me with a piece of jquery code that would show the end user an error message if data was saved or not saved to a database. I am looking at the code and my imagination is running wild because I am wondering if I could use just that one piece of code and import the selector type into it and then include that whole json script into my document. This would save me from having to include the json script into 10 different documents. Hope I'm making sense here.
$('#add_customer_form').submit(function() { // handle form submit
The "add_customer_form" id is what I would like to change on a per page basis. If I could successfully do this, then I could make a class of some sort that would just use the rest of this json script and include it where I needed it. I'm sure someone has already thought of this so I was wondering if someone could give me some pointers.
Thanks!
Well, I hit a wall so to speak. The code below is the code that is already in my form. It is using a datastring datatype but I need json. What should I do? I want to replace the stupid alert box with the nice 100% wide green div where my server says all is ok.
$.ajax({
type: "POST",
url: "body.php?action=admCustomer",
data: dataString,
success: function(){
$('#contact input[type=text]').val('');
alert( "Success! Data Saved");
}
});
Here is the code I used in the last question, minus the comments:
$(function() {
$('#add_customer_form').submit(function() {
var data = $(this).serialize();
var url = $(this).attr('action');
var method = $(this).attr('method');
$.ajax({
url: url,
type: method,
data: data,
dataType: 'json',
success: function(data) {
var $div = $('<div>').attr('id', 'message').html(data.message);
if(data.success == 0) {
$div.addClass('error');
} else {
$div.addClass('success');
}
$('body').append($div);
}
});
return false;
});
});
If I am right, what you are essentially asking is how you can make this piece of code work for multiple forms without having to edit the selector. This is very easy. As long as you have the above code included in every page with a form, you can change the $('#add_customer_form') part to something like $('form.json_response'). With this selector we are basically telling jQuery "any form with a class of json_response should be handled through this submit function" - The specific class I'm using is not relevant here, the point is you use a class and give it to all the forms that should have the functionality. Remember, jQuery works on sets of objects. The way I originally had it the set happened to be 1 element, but every jQuery function is meant to act upon as many elements as it matches. This way, whenever you create a form you want to handle through AJAX (and you know the server will return a JSON response with a success indicator), you can simply add whatever class you choose and the jQuery code will take over and handle it for you.
There is also a cleaner plugin that sort of does this, but the above is fine too.
Based on your question, I think what you want is a jQuery selector that will select the right form on each of your pages. If you gave them all a consistent class you could use the same code on each page:
HTML
<form id="some_form_name" class="AJAX_form"> ... </form>
Selector:
$('form.AJAX_form")