Jquery Ajax Define variables based on which form was submitted


#1

I have a function that will be used by two different forms:

$("#modalForm, #footerForm").on("submit", function(e) {

Based on which form was submited I need to declare a few variables. I tried:

		var form1 = $("#modalForm");
		var form2 = $("#footerForm");
		if (form1){
			var form = $("#modalForm");
			var mesg = $('#modal-messages');
		} 
		else if (form2) {
			var form = $("#footerForm");
			var mesg = $('#footer-messages');		
		}

But no matter which of the two forms I submit, Only modal form is submited. What is wrong in what i’m doing?

Thank you in advance


#2

As long as an element with the ID modalForm exists, form1 will always be truthy and hence pass the if check. You might however check for the ID like so:

$('#modalForm, #footerForm').on('submit', function () {
  var form = $(this)
  var msg

  if (this.id === 'modalForm') {
    msg = $('#modal-messages')
  } else if (this.id === 'footerForm') {
    msg = $('#footer-messages')
  }

  // ...
})

Or better yet, store the message selector in a data-* attribute so that you don’t have to check for the ID at all:

<form id="modalForm" data-msg="#modal-messages">...</form>
<form id="footerForm" data-msg="#footer-messages">...</form>
$('#modalForm, #footerForm').on('submit', function () {
  var form = $(this)
  var msg = $(this.dataset.msg)

  // ...
})

#3

@m3g4p0p. Thanks a lot for the reply and solution. It is probably is quite a straightforward solution for javascript gurus, but for me it’s briliant. Thanks a lot.

Edit: One last question aboutthe second solution: The messages divs are the divs where the http_response messages will appear. So can I add the data-msg attribute to a div as well? Like:

<div id="modal-messages" data-msg="#modal-messages"></div>

and if it is how do I call them?

Thank you in advance


#4

No worries! :-)


#5

@m3g4p0p. Sorry I was cheering a bit to early. When using:

console.log(form or msg);

It indeed showed me the right value for both. But putting it into real action (submitting one of the two forms) nothing is happening. This is what I have:

$("#modalForm, #footerForm").on("submit", function(e) {
	e.preventDefault();	
	var form = $(this);
	var msg;		 
  	if (this.id === 'modalForm') {
		msg = $('#modal-messages')
  	} else if (this.id === 'footerForm') {
    	msg = $('#footer-messages')
  	}
	var formfield 		= $('.form-control');
		
	$.ajax({
		type: "POST",
		url: $(this).attr('action'),
		data: $(this).serialize(),		
	})
	.done(function(response) {
		// Process data and success message
		
	})
	.fail(function(data) {
		// Error handling	
	});		
});

When I use two separate functions everything works fine, but that is obviously not what I want… Can you see what I’m doing wrong?

Thank you in advance


#6

@donboe how far do you get? Can you tell that you can’t even get into the form function? You said that console.log showed you the right value for form and msg, So I assume that you get at least until your first if clause.

When you debug the function with breakpoints in your devtools, how far do you get? Is there an error shown in the console?

So I guess your problem is the $.ajax function. Do you get the XHR request shown in your network tab?
What is the response? Of course - if the response statusCode is nothing between 200 and 300, jquery will execute the .fail function.

So do you get any data in there?

Best,
Martin


#7

Immediate Programmer reaction: “I have an if, and an elseif, but no else. Check the Else.”
Second immediate response:
Well yes, it does nothing. You havent put anything into the .done function. console.log(response); (or better yet, make it a Success function rather than a done one, since done will fire on both success and failure.)


#8

@m_hutley. In the example I posted there was indeed nothing in the .done function. I had actually done that not to make the message too long and thought that everyone would understand In the real function ofcource there is something in the .done function:

.done(function(response) {
	// Add success class to msg div.
	$(msg).addClass('success');
	$(msg).removeClass('error');
			
	// Clear form fields and fadout form.
	$(formfield).val('');
	$(form).fadeOut(500);
			
	// return success message
	$(msg).html('');
	$(msg).html(response);
})

I have been wondering for quite some time what would be better. I have been googling for the right answer quite some times and the opinions about this are rather divided. There were quite a few people who thought that .success() is deprecated and shouldn’t be used. That’s mainly the reason I am using done. I would like to hear your opinion on this


#9

Yes, the success member is deprecated. Thats why it appears in the documentation and every example on the jQuery website. Wait… :wink:

No,it’s not deprecated. No it’s not going anywhere. What WAS deprecated was using success as a follow-on function. You cannot do

$.ajax({....}).success(....)

anymore. That was replaced by .done.

the success member of the settings object is perfectly valid to use, as is the error member for failures. done is actually a method of the jqXHR class, which is what an ajax query returns. It’s a deferred action (think of the Promise structure that javascript implements today).

So you can declare a success in the settings, you can declare an error in the settings, but to declare a done, you must invoke it on the returned object.
$.ajax(...).done(.....);

And I confused myself in my previous post; Done is a replacement for Success [I have readability issues with this, tbh]. The replacement for Error is .fail(), and the ‘fire no matter what’ is .always().

What’s the difference? Nowadays not a whole lot. before success could take only a single function, but now it can take an array, so it’s the same as chaining multiple .done’s together…


#10

@m_hutley. Thank you so much for the responce and clear explanation. The entire debat confused me a lot. This makes it a lot clearer.


#11

Yes, you can add any data attributes you like to any element (also check the MDN link!). With jQuery these can be accessed using .data(), or like any other attribute with .attr():

var modalMessages = $('#modal-messages')

console.log(modalMessages.attr('data-msg'))
// Or:
console.log(modalMessages.data('msg'))

The .data() method behaves a bit differently from what you might expect though; e.g. when setting a value it will get stored internally, and not get reflected as an actual attribute like via the native .dataset property (and can’t then be accessed this way either).

I don’t see anything inherently wrong with your code… did you set breakpoints and check the network panel as @MartinMuzatko suggested?

BTW, there’s no need to repeatedly call $(this) – that’s already stored in the form variable.


#12

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.