views:

227

answers:

9

I am wanting to submit a form to different places based on selections made in the form. I had originally been planning to to send all to a central file/location and have it determine where to go next. However, I would like to do without this extra step if I could.

If the user wants to create/edit/delete elements go to page 1.
If the user wants to group/attach elements go to page 3.

I am trying to write a form builder. You can create/edit/delete forms, questions, and answers. I have everything for creating, editing, and deleting done. Those functions are performed without leaving the page, but now I am looking to assign answers to specific questions. The questions page and the answers page are separate. I am wanting to select a group of answers and submit an array of answer Ids (selected check boxes) to the question page where those Ids will then be assigned to a question. So basically the create, edit, and delete functions are on without leaving the page, but the assign function would be performed on a different page.

if(empty($delRowID) || empty(updateRowID) || empty($groupRows)) {
    qInsert();
}else{
    if(!empty($delRowID)) qDelete($delRowID);
    if(!empty(updateRowID)) qUpdate($updateRowID);
    if(!empty($groupRows)) {
        submit $groupRows to Question.php;
    }
}
+1  A: 

No, it can't (at least not without depending on JavaScript).

Submit to one URI, and have a dispatch routine pass the data off to different functions depending on which radio button (or whatever) is selected.

David Dorward
Is depending on Javascript something I should to do without?
Brook Julias
@Brook many people turn js off by default because of trojans and noisy behavior of some sites. It is considered polite to have your site working both with js enabled and disabled.
Col. Shrapnel
@Col. Shrapnel: that would depend on your definition of "many people", as well as how much you care to accommodate said people, considering increased time investment requirements. I'm just saying, whilst it may be "considered polite", sometimes being impolite to a few people gets the job done :P
Jeriko
+3  A: 

Just send them to a central location and use logic to send them somewhere else depending on what they selected.

eg:

<?php
switch($_POST['choice']) {
    case 'edit':
        $page = 'edit.php';
        break;
    case 'group':
        $page = 'group.php';
        break;
}

header("Location: " . $page);

(obviously needs some input filtering and default values)

EDIT: as pointed out by Col. Shrapnel below, using header() for this is pretty pointless as it'll then wipe out your $_POST array - use include() instead, but be careful to only allow your own files and never let the user name the file which will be included (eg using a form field value to pick the included file).

Matt Andrews
This is what I was thinking I had to do, but I would like to try to avoid having an intermediary file/location if I can. I suppose I should edit my original post to include this.
Brook Julias
Well, you don't have to have the intermediary, you can just do all of the logic in one place. In my code, just replace the `$page = 'edit.php'` parts with the logic you want to perform, it'll work the same way.
Matt Andrews
@Matt, it it was include, I'd upvote it. But using location for that purpose is ridiculous.
Col. Shrapnel
Maybe so, I just get wary about including files based on user input. Header redirection is probably equally risky, but somehow feels less arbitrary to me.
Matt Andrews
what is the risk in `include($page);`?
Col. Shrapnel
In this particular code, nothing, but in general I think we should avoid that kind of practice where possible. What's the big problem with using header redirection instead?
Matt Andrews
@Col. Shrapnel - I am currently using include to pull in function there is no point in writing something more than once. Though I suppose I can use include to pull in more than just functions it isn't something I have tried before.
Brook Julias
@Matt OMG you'd just lose entire POST data! Isn't that enough?
Col. Shrapnel
... oh yeah, oops. Touché sir.
Matt Andrews
@Brook actually I do not use includes at all, combining all code in one file. Looks very handy to me, no mess with dozens micro-files.
Col. Shrapnel
+1  A: 

If I was looking at doing this I would pass a vaule of what you want doing by POST.

Then check that value against a set of functions and each function will do a different thing based on it selection

Sleepy Rhino
I am currently doing that. Depending on what comes through POST it will either add, delete, or update an element. The page is getting to be a little unwieldy so I am trying to simply matters a little by splitting things up.
Brook Julias
you could have a functions file with each function in there then include that file and you would just need to do a function call and also then you can pick and choose what to pull on different pages if you need to.
Sleepy Rhino
I currently have three included files-- a classes file, a query builder file, and a database connect file. I am just wanting to allow for something that would have to be handled on another page (ie. assigning answers to a question) while still allowing for actions to be taken on the initial page (ie. add/edit/delete answer).
Brook Julias
+3  A: 

No, you can't have multiple actions just in the html, but you can use javascript to switch up the action depending on what button is hit.

I would do something like this (in pseudo-mootools)

<form action='default.php'>
 ... form elements ...

<button onclick='editButtonClick()' value='edit'/>
<button onclick='deleteButtonClick()' value='delete'/>
</form>

function editButtonClick() {
   $('form').action = 'editaction.php';
   $('form').submit();
}

function deleteButtonClick) {
   $('form').action = 'deleteaction.php';
   $('form').submit();
}
Nathan Reed
+9  A: 

No, a form has only one action.

But you have options:

Javascript

However, you may change the action attribute with javascript:

<input type="submit" value="Edit" onclick="editform();return true;">
<input type="submit" value="Delete" onclick="deleteform();return true;">

together with a little javascript:

function editform() {
    document.myform.action = '/edit';
}
function deleteform() {
    document.myform.action = '/delete';
}

See also

Multiple forms

If javascript is not an option for you, you may consider multiple forms in your page.

Multiple forms = multiple actions

No problems with javascript disabled clients, and standards compliant.

Multiple submit buttons - server side

Or you may handle the distinction of editing or deleting on the server side. No javascript needed.

Add multiple submit buttons to your form and give them the same name but a different value:

<input type="submit" name="btSubmit" value="Edit">
<input type="submit" name="btSubmit" value="Delete">

You then can retrieve the value of the button which has been clicked. In php, the following should do the job:

$_POST['btSubmit']

See http://www.chami.com/tips/internet/042599I.html for an example with classic asp.

marapet
While using Javascript would be a solution, and initially I wanted to go this route. There has to be a better method.
Brook Julias
I added two alternatives without needing javascript to my answer - multiple forms, and naming the submit button.
marapet
If JS is disabled, multiple submit buttons with unique values is the way to go.
afrazier
+3  A: 

It is possible using javascript, but it's not recommended because many people turn js off by default because of trojans and noisy behavior of some sites. It is considered polite to have your site working both with js enabled and disabled.

Actually you don't need many form actions because every operation can be done using branching in the single form handler script.
Here is the very simple CRUD application example, performing displaying, editing, adding - all in one body and utilizing templates:
index.php

<?  
mysql_connect(); 
mysql_select_db("new"); 
$table = "test"; 
if($_SERVER['REQUEST_METHOD']=='POST') { //form handler part: 
  $name = mysql_real_escape_string($_POST['name']); 
  if ($id = intval($_POST['id'])) { 
    $query="UPDATE $table SET name='$name' WHERE id=$id"; 
  } else { 
    $query="INSERT INTO $table SET name='$name'"; 
  } 
  mysql_query($query) or trigger_error(mysql_error()." in ".$query); 
  header("Location: http://".$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']);  
  exit;  
}  
if (!isset($_GET['id'])) { //listing part: 
  $LIST=array(); 
  $query="SELECT * FROM $table";  
  $res=mysql_query($query); 
  while($row=mysql_fetch_assoc($res)) $LIST[]=$row; 
  include 'list.php'; 
} else { // form displaying part: 
  if ($id=intval($_GET['id'])) { 
    $query="SELECT * FROM $table WHERE id=$id";  
    $res=mysql_query($query); 
    $row=mysql_fetch_assoc($res); 
    foreach ($row as $k => $v) $row[$k]=htmlspecialchars($v); 
  } else { 
    $row['name']=''; 
    $row['id']=0; 
  } 
  include 'form.php'; 
}  
?>

form.php

<form method="POST">
<input type="text" name="name" value="<?=$row['name']?>"><br>
<input type="hidden" name="id" value="<?=$row['id']?>">
<input type="submit"><br>
<a href="?">Return to the list</a>
</form>

list.php

<a href="?id=0">Add item</a>
<? foreach ($LIST as $row): ?>
<li><a href="?id=<?=$row['id']?>"><?=$row['name']?></a>
<? endforeach ?>
Col. Shrapnel
@Col. Shrapnel - Ok, it looks like I am just not fully utilizing include. I will have to start incorporating it more. Thanks for your advice. (I wish I could up-vote this.)
Brook Julias
A: 

on Submit page you can call CURL and give all Get or post variables to that url.

I will have to look into CURL. It looks like something I can use to solve my problem.
Brook Julias
oh no, curl is way too far from your needs @Brook :) Frankly, it's just like to take a plane to get to local store :) All you can get from CURL is include functionality with shitload of unnecessary code and excessive server usage.
Col. Shrapnel
@Col. Shrapnel - Thanks. It looked like could have been useful, but it was going to a bit of work.
Brook Julias
@Brook it cannot be useful by any means. CURL is used to send HTTP requests to other servers. And one would be fool using in on the same server.
Col. Shrapnel
A: 
<input type="submit" value="Add" onclick="submitForm(this,'add')" />
<input type="submit" value="Update" onclick="submitForm(this,'update')" />
<input type="submit" value="Delete" onclick="submitForm(this,'delete')" />

var submitForm = function(context,uri)
{
    form = contenxt.parent; //Go back to the form
    form.action = uri; // Set the action
    form.submit(); //Submit the form;
}

Java script is the best way to handle this, there's not really much alternative unless you create 3 sole forms.

RobertPitt
But what would I do if Javascript was disabled on the user's browser?
Brook Julias
Then detect if JavaScript is enabled within the browser and if not load a different version of the forms, best way to do this is create a template system and within your header use `<noscript><meta http-equiv=refresh content="0; URL=?_noscript=1" /></noscript>` and if this is set then use an alternative template file that does not require javascript.
RobertPitt
A: 

Post your form to a central formhandler script. On that page just use simple logic (using php in this instance) to redirect the user to the specific page you want

RichW