View Full Version : Is it possible to submit a form without reloading the page?
I have more than one form on the same page. The first is a tiny form that displays a drop-down with the client names so the user can select the correct client. This form does not actually load a table but rather just retrieves the client ID from the client table so that the second form can load it with the data into another table.
The problem is that when the user chooses a name from the drop-down, it reloads the entire page, which is rather annoying. I would like it to just display the name and let the user enter the data without changing the page until the user clicks the submit button.
I have tried combining the forms, moving the ID# field from one form to the other, using $_GET variables, changing the $_GET to $_POST, adding fields, removing fields, mucking about until now the nice drop-down that Blue Walrus helped me with doesn't even work anymore. The $_POST values don't seem to pass from one form to the other. I just can't start all over again.
Are there any examples anywhere of this type of form configuration? Tutorials? I don't have another whole day to spend on this. Sorry to be such a dummy. Thanks for any assistance.
djr33
04-24-2010, 02:14 AM
There's no way to do this without doing a request to the server.
You can do a reload or you can do it dynamically using Javascript (Ajax), but submitting forms with Ajax can be a little complicated (and not something I can give much advice on since it's not really my area).
You could also preload everything into Javascript and use Javascript to "submit" the form by dynamically changing the data on the page without needing to request anything on the server.
Both methods have advantages and benefits, but both would work.
Remember though that Javascript needs a backup for uses who don't have a browser that supports it, so you'll need to do the two-page method anyway for that, or perhaps lose those visitors and/or suggest they use a different browser.
prasanthmj
04-24-2010, 03:08 AM
There are different ways to do this:
Use Iframes (http://www.w3schools.com/tags/tag_iframe.asp). For example, put the form (that is loaded based on the drop down selection) in an iframe. When the user chooses an option from the drop down, you can load the iframe with the updated form. A small piece of JavaScript will do this.
window.frames[iframeName].location =url;
or you can use the name of the iframe as the 'target' attribute of the first form.
Hi Daniel! The only people who can access the page are the owners and the 2 agents who work in the gallery, and they have javascript enabled. I am using javascript already to trigger the lookup. I know minimal javascript.
<select name="client_id" onChange="document.SelectClient.submit()">
As there are 34,777 clients it has to present in the dropdown, perhaps the 1+ second delay is because of the volume of data. I just want to make sure it is not the fault of my code. Is it better to use GET or POST for this type of look-up? I left out the action and it still seems to do it. Is it better to do it as one form? What determines when you have to use 2 forms?
The ironic thing is that it worked before I "improved" the code and it drives me crazy that I don't know how I broke it. If GET is better, then I can probably get it to work again. I just like to know the best way to do things and it seems inefficient to have to do a whole new query just to display the variable value in the drop-down. Why is it not possible to store the value in a variable from the original query? And worse, I can't get the values from that query to display in the second form. If it's not possible that is one thing, but if I'm just doing something wrong, I'd like to fix it. Very frustrating. Just the answer to the GET/POSt dilemma would at least get me moving in some direction. Any ideas? Thanks. :)
Dear Prasanthmj: Iframes is a very cool idea. I'll have to try one to see if it will work. I'm not sure where this goes (?).
window.frames[iframeName].location =url;
djr33
04-24-2010, 04:25 AM
GET will be sent through the URL and that's possible with forms, but it's not the usual way. Given that POST data was sent, $_POST should contain all the values you need.
print_r($_POST); will give you the info so you can see what is sent.
1.php
<form method="post" action="2.php">
<input type="hidden" name="a" value="1">
</form>
Submitted to 2.php:
print_r($_POST);
Result:
array ( a => 1)
From that you should be able to work out all the details.
prasanthmj
04-24-2010, 04:32 AM
That code is to reload the second form. So it should be triggered when an item is selected in the drop down
<select name="client_id" onChange="loadtheform()">
...
...
<script>
function loadtheform()
{
//get the client_id from the drop down
window.frames['frm2frame'].location =url+'?id='+client_id;
}
</script>
Of course, you should have the iframe with that name.
<iframe src='url' width=300 height=300 name='frm2frame'></iframe>
Dear Daniel:
I wasn't quite sure what you meant, but I inserted the print_r($_POST); into my code and it hung my browser. I had to open a new browser to send this. I must have done something wrong.
I ended up changing it back to $_GET and it works great except there is still the 1+ second delay loading the form. Perhaps this is unavoidable.
Now I have a new challenge. There are 2 main girls who add the data and they each want their name to be the default in the agent drop-down to save having to click there each time. I thought that would be easy to fix but this code doesn't seem to work...
<p><label>* Agent:</label>
<select name="agent">
<?php if(isset($_POST['agent']) && $_POST['agent'] != "" && $_POST['agent'] == "DD"){ ?>
<option value="DD">Debbie</option>
<option value="JV">Joanne</option>
<?php } elseif(isset($_POST['agent']) && $_POST['agent'] != "" && $_POST['agent'] == "JV"){ ?>
<option value="JV">Joanne</option>
<option value="DD">Debbie</option>
<?php } ?>
<option value="DD">Debbie</option>
<option value="JV">Joanne</option>
<option value="TT">Tom</option>
<option value="JJ">Joe</option>
</select></p>
What am I doing wrong? Thanks, e :)
djr33
04-25-2010, 06:07 PM
It sounds like it got into an endless loop and overwhelmed your browser. Place print_r($_POST); before everything else, or even just replace the whole page with it-- then you can see what you're working with. That is-- if you want to take that approach.
If it's working I'd just leave it.
Here's a way to approach the selected issue:
<p><label>* Agent:</label>
<select name="agent">
<?php
$agent = array('AA'=>'Agent A','AB'=>'Agent B','AC'=>'Agent C');
foreach ($agent as $agentv=>$agentn) {
$selected = (isset($_POST['agent']) && $_POST['agent'] == $agentv)?' selected'':'';
echo "<option value=\"$agentv\"$selected>$agentn</option>";
}
?>
</select></p>Replace the names and values as you need. Untested, but that should work.
Note that you don't need to use all of : isset($x) && $x!='' && $x=='value';
Instead, you just need to use the first and last-- make sure the value you're using exists and then make sure it matches; checking against a blank value is only useful if you aren't checking against another. It's not hurting anything in the code, but it's also not helping (and aside from just keeping it cleaner for readability, it'll run slightly faster, not that it's really relevant especially for a small admin system).
Dear Daniel: Thank you so much for your great advice and feedback about keeping my code clean... I love that. I have spent the entire day cleaning up the data and it is now ready so this will allow me to move on to the sales part. I was feeling like giving up only a day ago.
Here is my version of your code. Have to admit I don't understand agentv and agentn and I screwed it up (sorry):
<p><label>* Agent:</label>
<select name="agent">
<?php
$agent = array('DD'=>'Debbie','JV'=>'Joanne','HS'=>'House');
foreach ($agent as $agentv=>$agentn) {
$selected = (isset($_POST['agent']) && $_POST['agent'] == $agentv)?' selected''';
echo "<option value=\"$agentv\" $selected>$agentn</option>";
} ?>
</select></p>
Here is the error message:
Parse error: syntax error, unexpected T_CONSTANT_ENCAPSED_STRING in .../client-history-add2.php on line 55
Garden time now :)
bluewalrus
04-26-2010, 04:11 AM
Hey,
Sorry to jump in our your thread Kuau. I was wondering about the code djr33 used "$selected = (isset($_POST['agent']) && $_POST['agent'] == $agentv)?' selected'':'';" . I think this says
if (isset($_POST['agent']) && $_POST['agent'] == $agentv)) {
$selected = "" ;
} else {
$selected = "selected";
}
but just wanted to make sure. I've only seen this used in javascript but it looks more efficient is there a name for this shorthand version? Thanks.
As for your problem Kuau which line is line 55?
djr33
04-26-2010, 06:43 AM
Kuau,
1. In my code I intentionally left no space before $selected in the string. This is because there should only be a space if "Selected" is set (and the space is stored in it's value then). This will make the code cleaner in the HTML output. The extra space won't hurt at all, but if you want really clean HTML output, that's the only way to do it (leave no space and include it into the variable $selected as needed).
It's always very difficult to get HTML to look nice after generating it with PHP. This often happens with tabs and then it can be a huge pain to deal with. The good news is that it never affects functionality, just pretty source code...
2. I believe the problem is in the complex line setting $selected. You have at the end three single quotes: '''; That should be like in my post with a colon between them--- ':'';. This is very unusual syntax but it's the shorthand way to make it look clean (if confusing to read). I'll explain below:
bluewalrus, I have no idea what it's called. I originally found it looking through something (forum software, I think) and tried to figure out what it was.
It's probably the least readable and most extraneous thing in PHP, but it can make one line from a few and it's a quick way to set variables based on a single condition.
Here's the syntax:
(CONDITION) ? (TRUE) : (FALSE) ;
Read as: "if CONDITION, do TRUE, else do FALSE", or however you'd like to phrase that.
Or-- X?Y:Z; read as "if X then Y else Z"
So your post is very close, but you have the if and else reversed-- if the conditions in the first bit (before the ?-- I look at it as "if this stuff true (.......)?") then the "selected" text will be used. Otherwise, just use a blank string.
This syntax is useful for rare occasions like this one. Usually it's just annoying. I've even in some cases embedded several layers into one line when there's a complex mess of conditions to deal with, but that's so unreadable that I try to avoid it in most cases.
That would look something like: ($x==1)?$y=1: (($y==1)?$y=2:$y=0);-- useless/random example.
Note that I have no idea if all the parts are required or what happens if you omit one. You can use this as with anything else, just use parentheses and you can even include multiple operations separated by ;s. Also, I don't know what happens with/without parentheses-- it seems like it could get very confusing/ambiguous in certain circumstances.
Finally I can answer someone's question!!! :)
Blue Walrus, this shorthand form of the conditional IF statement is called the php ternary operator.
I just got back from running on the beach (when I do my best thinking) and it occurred to me that perhaps Daniel's method could be used (?) to keep the client name in the drop-down (my original question above), because it takes too long to load the page the way we did it.
Daniel: Thanks for the great explanation. I have to try it again and then it should make more sense. It amazes me that you can just whip something like that off so quickly. I need to stare at it for a while now. I'll let you know what happens. Mahalo plenty! e :)
OK, I tried it exactly as written and got an error on the select line so I removed one of the single quotes after selected at the end of the line here: $agentv)?' selected'''; and the error went away.
But it is not functioning as intended. I added an entry as Debbie and when the page came up again, it said Joanne. Then I added some notes as Joanne then changed to Debbie and it came up Joanne again. I would like it to default to the last agent entered until it is changed and then stay as that agent until it is changed again. Any ideas?
djr33
04-26-2010, 11:53 PM
That's more complex. $_POST refers to values sent from a form. You could add a hidden field to every page so that will always be available:
<input type="hidden" name="agent" value="<?php echo $_POST['agent']; ?>">
Or you can use cookies or sessions.
So basically you'll do this:
//immediately above the foreach loop, add this:
$agent = '';
if (isset($_SESSOIN['agent'])) { $agent=$_SESSION['agent']; }
if (isset($_POST['agent'])) { $agent=$_POST['agent']; $_SESSION['agent'] = $agent;}
//then replace this line:
if (isset($_POST['agent']) && $_POST['agent'] == $agentv)) {
//with:
if ($agent==$agentv) {...
Also, remember session_start(); at the top of your page.
Alternatively replace $_SESSION in the above code with $_COOKIE and for the last bit use setcookie() rather than $_COOKIE['agent']=.....
Dear Daniel: I realized after I wrote the above that the action url was sending me back to the old page without the code so it really was no test of the code at all. I'm going to try it again as I am curious what it will do. What is the code supposed to do if not what I thought?
Is there a way to include the action code, eg. <form name="historyform" method="POST" action="client-history-add-php.php" in the same page as the form? I tried putting all the actions in one file with an if($page="client-history-add.php"){ run action } but couldn't get the variable value to pass through. I don't like all these little files proliferating.
djr33
04-27-2010, 01:33 AM
Yes it is possible. Use action="?page=name" and ifs with $_POST. It can get complex but that's where clean code helps. If you really want separation then you can use includes to separate the php code that will then process as one page or create functions for each action.
It's possible to do this without a variable in the URL if you check isset($_POST['formvar']) to see if data was sent but that takes careful planning.
Which is possible?...
1) putting the action on the same page as the form, or
2) putting all the actions in one file.
You seem to be talking about the latter (?).
I am trying to use the session code but I am so confused I don't know what to put where. Could you please put the whole code without the replace this with that, because I don't have the "this" exactly as you have it so it doesn't make sense.
This is what I have:
<p><label>* Agent:</label>
<select name="agent">
<?php
$agent = array('DD'=>'Debbie','JV'=>'Joanne','HS'=>'House');
//immediately above the foreach loop, add this:
$agent = '';
if (isset($_SESSION['agent'])) { $agent=$_SESSION['agent']; }
if (isset($_POST['agent'])) { $agent=$_POST['agent']; $_SESSION['agent'] = $agent;}
//then replace this line:
if (isset($_POST['agent']) && $_POST['agent'] == $agentv)) {
//with:
if ($agent==$agentv) {...
foreach ($agent as $agentv=>$agentn) {
$selected = (isset($_POST['agent']) && $_POST['agent'] == $agentv)?' selected':'';
echo "<option value=\"$agentv\"$selected>$agentn</option>";
}
?>
</select></p-->
<input type="hidden" name="agent" value="<?php echo $_POST['agent']; ?>">
<p><label>* Agent:</label><?php echo $_POST['agent']; ?>
<select name="agent">
<option value="<?php echo $_POST['agent']; ?>"><?php echo $_POST['agentn']; ?></option>
<option value="JV">Joanne</option>
<option value="DD">Debbie</option>
<option value="HS">House</option>
</select></p>
I've given up. I made 2 copies of the whole page and put one with DD at the top and one with JV at the top. I now have 2 items on the menu so that there is a separate page for each agent. I know this sucks as a solution but at least it works. I can't afford to spend this much time on such a tiny, tiny detail. But thanks for all the help. I'm sorry that I am not able to follow your directions sometimes. You must think I know more than I do. I've never worked with sessions. This is so discouraging that I can't get the simplest thing working.
djr33
04-27-2010, 04:31 AM
You could use cookies if you prefer. Sessions are fairly simple to work with-- just be sure to keep session_start() at the top of every single page and then $_SESSION is an array you can use between pages for the duration of the stay.
As for which I was talking about, you can do both. Point to a single page as needed, and use variables in the URL to specify info; also use $_POST to confirm that data was sent and do different things based on that. Most of that is just based on layout.
Think about a complex forum (like this one*). Everything is run through the same index page and then various actions are performed, usually based on the URL variables but also based on submitted forms and things like whether the user is logged in, etc. The single script then parses everything and serves whatever content should be done by a variety of conditional (if) statements, functions and includes(), sometimes including up to hundreds of pages in a single "script".
(*vbulletin is in the minority of forum software, running several processes through different pages than index.php but it's all still going through the same setup in a complex way; it still follows the same basic principles.)
As always, if it works, then just keep it simple, but this is stuff to think about for the future.
I've never worked with cookies either. I'm not a php programmer. I can get things to work only when I have explicit examples to follow.
I would like to put the action code in the same file as the form but have no clue how to do it.
I'd like to try using sessions for the agent issue but these two lines seem to cancel each other out so it doesn't make sense to me...
<?php
$agent = array('DD'=>'Debbie','JV'=>'Joanne','HS'=>'House');
//immediately above the foreach loop, add this:
$agent = '';
djr33
04-27-2010, 05:03 AM
Oh, yes, I forgot about the $agent variable. Just rename one to something else. They're for different purposes.
Call the new one $currentagent for example.
I understand it can be difficult. This type of situation is where you choose whether it's better to just get it working or to perfect it. Especially for a page that gets limited use (admin pages are a perfect example) I see no point in perfecting it, though as I said it's worth thinking about these ideas for later because you'll probably run into the same general ideas.
If you want to get an idea of a single page doing a lot, consider looking at some free forum software and how it's all setup. It's IMMENSELY complex, but you can get a feel for the whole layout and see some of the syntax for how it all relates.
Basically you use exactly the same tools you've been using, but just larger and larger code blocks and many more levels-- 1000s of lines code and sometimes a dozen tabs in (within ifs and loops, etc).
Of course this specific case wouldn't be anywhere near that complex, but it's the same idea and method-- just build up the same stuff you do know and you'll find you've made a very complex page.
And then you said...
//then replace this line:
if (isset($_POST['agent']) && $_POST['agent'] == $agentv)) {
//with:
if ($agent==$agentv) {...
but there is no line like that, only a line like this...
$selected = (isset($_POST['agent']) && $_POST['agent'] == $agentv)?' selected':'';
Is that the line you meant? And if so, I should replace it with what? I have to take what you say literally and do not know enough to recognize if you meant to say something else. I would really appreciate if you could please put the code in one chunk with everything the way you meant to say it. I would really like to get this working properly.
And this is not for the admin page for a website. It is for a custom app that will be used to run an art gallery. The invoices are piling up while they wait for me to design the CMS, clean up 30 years of data, and write the app. The pressure is killing me.
I am trying to simplify, not make things more complex. In that car rental app you helped me with, I put all the "write to database" modules in one little file no problem. I was just hoping to do the same thing here, but maybe it doesn't work with form actions.
I really appreciate your efforts to help me. God knows I need all the help I can get!
djr33
04-27-2010, 05:21 PM
Sorry, I had accidentally cut and paste from the code that bluewalrus wrote "translating" my original code. Yes, that's the right line.
$selected = ($currentagent == $agentv)?' selected''';
(where $currentagent is that new variable I made...)
It's always a tradeoff whether you want to make things more complex, streamlined and in general "advanced". If it works, don't break it by trying to fix it.
Putting anything into a single page is very possible including form actions. Just output different pages based on what is going on.
The easiest way to get started with this is to comment your entire script and clean up the code as much as you can (tabs, extra lines between different sections) and maybe split it into different files to be included.
Can you please tell me what is wrong with this statement? Or if there is a better way to do it? Thanks.
This does work without the thousands separator...
<?php $result = mysql_query("SELECT COUNT(*) FROM client");?><b><?php echo mysql_result($result,0,0);?>
This doesn't work when I try to add a thousands separator...
<?php $result = mysql_query("SELECT COUNT(*) FROM client");?><b><?php echo mysql_result(number_format($result,0,0));?>
djr33
04-27-2010, 06:38 PM
Isn't that just layered in the wrong order?
mysql_result() gets the data, THEN you want to format is using number_format().
So just do number_format(mysql_result(...))?
Brilliant.. that was it! Mahalo!! :)
Hey Daniel:
You're not going to believe this but I figured out how to get the drop-down to default to the last agent entered! It's no doubt a horrible adulteration of the php language but it works...
I had to change both forms to POST instead of GET, then I added this to the action file of the second form...
if($_POST['agent'] == 'DD'){
header("Location: /admin/php/client-history-add.php?agent=DD");
} elseif($_POST['agent'] == 'JV'){
header("Location: /admin/php/client-history-add.php?agent=JV");
} else {
header("Location: /admin/php/client-history-add.php?agent=HS");
}
Then I put this at the top of the form file...
<?php if(isset($_GET['agent']) && $_GET['agent'] == "DD"){ $ddsel = " selected";
} elseif(isset($_GET['agent']) && $_GET['agent'] == "JV"){ $jvsel = " selected";
} elseif(isset($_GET['agent']) && $_GET['agent'] == "HS"){ $hssel = " selected"; }
?>
And this in the form...
<select name="agent">
<option value="JV"<?php echo $jvsel;?>>Joanne</option>
<option value="DD"<?php echo $ddsel;?>>Debbie</option>
<option value="HS"<?php echo $hssel;?>>House</option>
</select></p>
And that's it! Works like a charm. It came to me while I was running. Feel free to tell me what's wrong about it. Thanks, e :)
djr33
04-28-2010, 08:30 PM
That's a really simple way to do it, actually. Nothing's wrong with it. It's just not expandable/variable. If you do it in a way like I did before it was completely customizable and expandable to more names, etc. But for your purposes that's simpler.
And of course the main problem is that you must include that extra variable in every URL, so pay attention to that.
But I couldn't get your way to work. Could you? I would have used it if it had worked, believe me. I'm not into reinventing the wheel. I don't have time. If you can show me code that works that is better than my simple way, I would be happy to use it. I would have been even happier 2 days ago. But it didn't work!
djr33
04-28-2010, 11:32 PM
I understand. It would require rewriting more than just that section to make it all fit. As I said, there's nothing wrong with the way you did it. It's the everlasting question of doing it the "elegant" way or doing it this simple and "works" way.
It's all about what saves you the most time-- if you put a lot of work into it right now and do all of that, will it save you time in the end? I don't see any reason why it would. If not, then don't bother. Of course in some cases (like setting up PHP rather than using just HTML files), the extra work clearly is worth it. But here I don't see any reason it would be.
Dear Daniel:
I am trying to use your ternary operator and am having trouble. I am trying to output a list of client data (name, address, phone, etc) in table format but I am using css so if the value doesn't exist, the data moves into the wrong column. So I am trying to set the value to a hard space if the value doesn't exist. Perhaps there is a better way to do this (?), but this is what I tried...
<?php ($client['phone1'] != '')?$client['phone1']:' ';?>
and the whole column disappears. Could you please tell me what did I did wrong? Thanks, e :)
djr33
05-04-2010, 12:49 AM
Looks like you forgot echo. Aside from that it's right.
Remember-- if the ternary operator is confuses (as it often is), there's no need to use it. If/else works just as well, but it's a little longer to write.
<?php echo ($client['phone1'] != '')?$client['phone1']:' '; ?>
Also, you might want to use ' ' instead of ' ' because that will actually hold space in the final design. Either will work for the PHP though.
Oh, now I understand... thanks! What puzzles me now is that it worked for the first number but as soon as I added the other columns everything disappeared again...
<div class="col-phone"><?php echo ($client['phone1'] != '')?$client['phone1']:' ';?></div>
<div class="col-phone"><?php echo ($client['phone2'] != '')?$client['phone2']:' ';?></div>
<div class="col-phone"><?php echo ($client['phone3'] != '')?$client['phone3']:' ';?></div>
<div class="col-phone"><?php echo ($client['phone4'] != '')?$client['phone4']:' ';?></div>
It doesn't make logical sense to me that the additional lines would make the first line stop working. Thanks so much for your help. :)
djr33
05-04-2010, 01:39 AM
Not sure about that. Perhaps you had a trailing echo from the last section?... not sure if that's likely.
Sorry, it turns out it does work, but the email address is wrapping to the 2nd line so it looked wrong. I need to work on the formatting more it seems. Sorry to bother you unnecessarily. I REALLY appreciate your help! You are a saint. :)
Powered by vBulletin® Version 4.2.2 Copyright © 2021 vBulletin Solutions, Inc. All rights reserved.