0

I have a main.php page with multiple divs. I load whole pages in these divs using AJAX. Some of these pages have forms with submit buttons. The structure of the pages is like so:

For acc_settings.php

<form enctype="multipart/form-data" method="post" action="acc_settings.php"  >
.
.
<button type='submit' name='update' >UPDATE</button>
</form>

So the form is processed by acc_settings.php itself. When the submit button is pressed, the form info is sent to acc_settings but the browser loads up acc_settings.php

What I want is that the form should remain the way it is but the response should be displayed in the same div in main.php and acc_settings.php should not be opened by the browser.

There might be an AJAX solution to this.

3
Contributors
10
Replies
11
Views
7 Years
Discussion Span
Last Post by psyb0rg
0

You need to call an ajax function not the submit form action - then target the div you wish to display back too
[sorry for quick reply]

0

You need to call an ajax function not the submit form action - then target the div you wish to display back too
[sorry for quick reply]

I know but how? :)

0

I mean how do I call an AJAX function instead of the form submit?Please keep in mind that there are many such buttons and a solution which can be applied to all without many changes would be good.

0

psyb0rg,

Ajax is indeed the way to go.

First some javascript:

function createRequestObject(){
   if(window.XMLHttpRequest) {
      return new XMLHttpRequest(); // IE 7, Firefox, Safari, Opera...
   }
   else if(window.ActiveXObject) {
      return new ActiveXObject("Microsoft.XMLHTTP"); // Internet Explorer 6, 5
   }
   else { alert('Problem creating the XMLHttpRequest object'); }
   return false;
}

function ajaxFormSubmit(form){
	var params = getParams(form);
	var action = form.getAttribute('action');
	var httpRequest = createRequestObject();
	if(!httpRequest) return false;
	httpRequest.onreadystatechange = function() {
		if(httpRequest.readyState == 4) {
			//Here do whatever you need to with the response (httpRequest.responseText)
			//document.getElementByid('myDiv').innerHTML = httpRequest.responseText;//for example
		}
	}
	httpRequest.open('POST', action, true);
	httpRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	//httpRequest.setRequestHeader("Content-type", "multipart/form-data");//Possible alternative?
	httpRequest.setRequestHeader("Content-length", params.length);
	httpRequest.setRequestHeader("Connection", "close");
	httpRequest.send(params);
	return false;
}
function getParams(form) {
	var params = [];
	for (i=0; i<form.elements.length; i++){
		var e = form.elements[i];
		var n = e.getAttribute('name');
		if (!n) continue;
		if (e.tagName == "INPUT"){
			switch (e.getAttribute('type')){
				case "text":
					params.push(n + "=" + URLEncode(e.value));
				break;
				case "checkbox":
					if (e.checked) { params.push(n + "=" + URLEncode(e.value)); }
					else { params.push(n + "="); }
				break;
				case "radio":
					if (e.checked) { params.push(n + "=" + URLEncode(e.value)); }
				break;
			}
		}
		if (e.tagName == "TEXTAREA"){
			params.push(n + "=" + URLEncode(e.value));
		}
		if (e.tagName == "SELECT"){
			params.push(n + "=" + URLEncode(e.options[e.selectedIndex].value));
		}
	}
	return '?' + params.join('&');
}
function URLEncode(clearString){
	// Encode strings to be compatible with php's urldecode().
	// Based on "Javascript URL encoding and decoding", http://cass-hacks.com/articles/code/js_url_encode_decode/
	if(!Number.toString) { return clearString; }//Very old browsers
	var output = [];
	var x = 0;
	clearString = clearString.toString();
	var regex = /(^[a-zA-Z0-9_.]*)/;
	while (x < clearString.length) {
		var match = regex.exec(clearString.substr(x));
		if (match != null && match.length > 1 && match[1] != '') {
			output.push(match[1]);
			x += match[1].length;
		}
		else {
			if (clearString.substr(x,1) == ' '){ output.push('+'); }
			else {
				var charCode = clearString.charCodeAt(x);
				var hexVal = charCode.toString(16);
				output.push('%' + ( hexVal.length < 2 ? '0' : '' ) + hexVal.toUpperCase());
			}
			x++;
	    }
	}
	return output.join('');
}

Now a mod to your HTML:

<form enctype="multipart/form-data" method="post" action="acc_settings.php" onsubmit="return ajaxFormSubmit(this);">
.
.
<button type='submit' name='update' >UPDATE</button>
</form>

Changes should be easy, because you just have to add onsubmit="....." to each of your form tags.

I've only done some rudimentary testing not involving PHP so please foregive slips and plese test thoroughly yourself.

Airshow

0

Thanks for the reply Airshow. It worked.

One correction, line 23 should be

httpRequest.open('POST', action [B]+ params[/B], true);
0

That's great psyb0rg.

I'm a bit puzzled about that correction though because the line httpRequest.send(params); is supposed to look after the params for the "POST" method. Tacking onto the url is the "GET" way to do it. Maybe try httpRequest.send(null); and see if it still works.

Server-side, do you pick up the parameters in $_GET or $_POST?

Another thing to try: revert to my code but change the line return '?' + params.join('&'); to return params.join('&'); . It may be that the leading ? was messsing up the POST.

Airshow

0

@Airshow, yes you're right. I changed back the changes.

There is one more problem. How do I capture the button that was clicked. The getParams() function gets values of ALL the elements on a form including all the buttons, but I also need the button which was pressed by the user as I have multiple buttons per page, for example NEXT and PREVIOUS buttons.

0

@Airshow, yes you were right. Made the changes.

One more problem. How do I know which button was pressed in the form? I need the information in getParams(), which right now gets ALL the controls in a form. I have many buttons in my forms and need to know which was actually pressed.
Thanks

0

psybOrg,

This is slightly tricky as there's no naturally occurring button property to test, to see which submit button was clicked. For a normal (non-AJAX) form submission it's easy because HTML does the hard work and you can test server-side.

The only solution I can think of for this AJAX-POST is to establish an onclick event handler for each submit button. From that point, there must be a million ways to proceed - I have chosen to tuck away the value of the clicked button in a contrived form attribute "s", which can then be read in the getParams function.

In my javascript :

//-- Find
	return params.join('&');
//--Insert before
	params.push("submit=" + URLEncode(form.getAttribute('s')));

In my HTML, replace the submit button with :

<input type="submit" value="UPDATE" onclick="this.form.setAttribute('s', this.value);">
	<input type="submit" value="OTHER_1" onclick="this.form.setAttribute('s', this.value);">
	<input type="submit" value="OTHER_2" onclick="this.form.setAttribute('s', this.value);">

That will add "&submit=UPDATE" (or "OTHER_1" etc.) to the params list, so server-side you can test $_POST to see which submit button was clicked.

Client-side tested in IE6, FF 3.0.13 and Opera 9.01.

I have wracked my brain to think of a reason it might not be reliable but can't think of one.

Good luck with it.

Airshow

0

Thanks for the reply.
I used a similar solution. For the form:

onSubmit='return ajaxFormSubmit(this, window.clicked)

and

onclick="window.clicked=this.value;"

for every button.

I sent the button as an argument because that allows me to use it other places as well.

Thanks!

This article has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.