How to create nested forms.

Even though I write this article with the perspective on a plugin for WordPress the solution can used anywhere. The example I’ll use to explain how to create a form within a form, aka nested forms, will have no direct links to WordPress but will merely show how to create a form within a form.

For my AVH Amazon plugin I wanted to add a metabox with a form on the Post and Page pages. The purpose of the metabox was to give the user the ability to create the shortcode without having to remember, and type for that matter, all the options.

I wanted users to have the ability to look up their wishlist, show them a the items on their wishlist and give them the option to select one. The problem with this is not so much the form itself, that is pretty straight forward, but the Post and Page pages are almost completely wrapped in a form. The metabox resides with in that form and by design you can’t have a form inside a form in HTML.
It was jQuery, the awesome javascript framework, that bailed me out.

This is what I try to accomplish but is invalid HTML code.

<form action="post.php" method="post">
    <textarea cols="20" rows="5" name="post"> 
    <input type="submit" value="Post">
    <form method="post" action="search.php">
        Item: <input type="text" size="10" name="item">
        <input type="submit" value="Search">
    <div id="output"></div>
    </form>
</form>
</body>
</html>

Explanation:
The form has a text area for writing a article and on hitting the submit button the file post.php would be called.
When you fill out the Item box and hit the Search button the file search.php is called. In that file a search will be performed and the output, a list of items, will be displayed between the div tag.

The basic HTML

As mentioned earlier I’ll be using jQuery to get this done so you have to make sure you include jQuery in your HTML. I have to remove the nested form, change the submit button into a regular button, wrap the nested form in a div tag and to make things easier later on give the items of the nested form an id tag.

<html>
<head>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript"><!--
  // we will add our javascript code here
// --></script>
</head>
<body>
<form method="post" action="post.php">
    <textarea rows="5" cols="20" wrap="physical" name="post"> 
    <input type="submit" value="Post">
    <div id="nestedform">
        Item: <input type="text" size="10" id="text" name="item">
        <input type="button" id="search" value="Search">
        <div id="output"></div>
    </div>
</form>
</body>
</html>

Adding the actions to the elements

To add an action when you you click on the Search button or press enter when you are typing something in the Item box we need to add some javascript to intercept these actions.

jQuery(document).ready(function() {
	jQuery('#search').click( submit_search );
	jQuery('#nestedform).find('input').keydown(keypressed);
	}
	);

Explanation
Line 2: When the element with id search is clicked we call the function submit_search
Line 3: Within the section defined by id #nestedform we search for the element input. When a key is down in those input fields, in our situation it’s only one input filed, we call the function keypressed.

These are the two functions we call:

function submit_search( event ) {
	var values = new Array;
	event.preventDefault;
	values[0] = jQuery('#item').attr('value');
	if (values[0]) {
		do_submit('#output',values);
	} else {
		alert ('No Item given');
	}
	return false;
}

function keypressed( event ) {
	var charcode = (event.which) ? event.which : window.event.keyCode ;
	if ( charcode == 13 ) {
		return submit_search( event );
	}
	return true;
}

Explanation:
Line 3: We prevent any default actions to take place, we only want our action to run.
Line 4: We add the value, whatever we typed, of the input filed with id item in an array
Line 5-9: We check if there is a value, if there is we call a function which I’ll explain later, otherwise we show an alert on the screen.
Line 14: We get the character code of teh key that is pressed down. In IE we don’t have event.which so we have to use window.event.keyCode.
Line 15-17: If the enter key was pressed we call the submit function, making it similar to pressing the button.

The submit function

To submit the “form” we have do an ajax call with jQuery.

function do_submit(submit_output, submit_values) {
	jQuery(submit_output).hide();
	jQuery.post(
		"search.php",
		{ action: 'search_values[]': submit_values }, 
		function(data, textStatus) {
			jQuery(submit_output).html(data.substr(0,data.length));
			});
			jQuery(submit_output).show();
			}
	);
}

Explanation
Line 2: In case we do a second search we want to hide the previous output.
Line 3-11: The actual call to search through Ajax.
Line 4: The php file we want to call.
Line 5: The actions passed to the php file. Similar to the search?action
Line 7: The output will be shown at the element with the ID passed on to submit_output.
Line 9: We have to show the output to the user.

The final HTML

The final HTML looks like this.

<html>
<head>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript"><!--
jQuery(document).ready(function() {
	jQuery('#search').click( submit_search );
	jQuery('#nestedform).find('input').keydown(keypressed);
	}
	);
function submit_search( event ) {
	var values = new Array;
	event.preventDefault;
	values[0] = jQuery('#item').attr('value');
	if (values[0]) {
		do_submit('#output',values);
	} else {
		alert ('No Item given');
	}
	return false;
}

function keypressed( event ) {
	var charcode = (event.which) ? event.which : window.event.keyCode ;
	if ( charcode == 13 ) {
		return submit_search( event );
	}
	return true;
}
function do_submit(submit_output, submit_values) {
	jQuery(submit_output).hide();
	jQuery.post(
		"search.php",
		{ action: 'search_values[]': submit_values }, 
		function(data, textStatus) {
			jQuery(submit_output).html(data.substr(0,data.length));
			});
			jQuery(submit_output).show();
			}
	);
}
// --></script>
</head>
<body>
<form method="post" action="post.php">
    <textarea rows="5" cols="20" wrap="physical" name="post"> 
    <input type="submit" value="Post">
    <div id="nestedform">
        Item: <input type="text" size="10" id="text" name="item">
        <input type="button" id="search" value="Search">
        <div id="output"></div>
    </div>
</form>
</body>
</html>

I hope I gave you a basic understanding how to nest forms with jQuery. For my plugin I had to change some minor things because of the way WordPress handles the Page and Post pages. If anybody is interested I could write up a follow up explaining what I ran into.

This article is filed under the categories Software » Web and has the following tags associated with it: , , , , , , , , .
Showing 6 comments
Skip to the end and leave a comment.
  1. Jayson

    Hey Peter, nice job. I have been trying to figure out how to put a form in a wordpress post that will update my meta data from some custom fields. Or is it possible to create a form in the metaboxes themselves on the admin post write panel? One other question, I do have a nice write panel with my custom fields and would like an “update” ajax button as the custom fields have in wp. Any thoughts? Thanks Peter.

  2. Peter

    I wrote this article because I wanted to create a form in a metabox for my AVH Amazon plugin. The problem was that the page/post pages in admin are wrapped in a form, in other words I had to create a nested form. I came up with this solution and it works perfectly. I also use an AJAX call in the plugin to update the metabox.

    Just download my AVH Amazon plugin to see how I implemented both solutions, check the shortcode file. If you have more questions don’t hesitate to email me personally, just use the Contact Me page to send me an email, I’ll be happy to help you out.

    • Richard

      Peter,

      Where can I download jquery.js?

  3. lakshmipathy

    hi to all,

    is it possible, to display two or more command buttons in single line from different forms and when the buttons are submitted, it should pass the values from which the form action s there.

    can anyone help this ………..

    advance thanks

  4. dilip

    Its not working

  5.  

Leave a comment

For questions and/or support consider using the forums.