Differentiate form actions in GCDWebServer? - html

I am using two forms on an HTML page hosted via GCDWebServer. I have the first form setup like this...
<form name=\"vendorInput\" method=\"post\" enctype=\"application/x-www-form-urlencoded\">
<input type=submit value='Add Vendor' action=\"/\">
and the second form setup like this...
<form name=\"vendorInput\" method=\"post\" enctype=\"application/x-www-form-urlencoded\">
<input type=submit value='Add Item' action=\"/\">
I can't find any documentation that provides support for this; and any action string I type other than / causes the HTML request to break. Is there a way to parse different actions for form submit buttons in GCDWebServer?

You just need to have the action be a different path for each form and then implement a GCDWebServer handler for each path:
[webServer addHandlerForMethod:#"POST"
path:#"/path1"
requestClass:[GCDWebServerURLEncodedFormRequest class]
processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
// Do something with form data i.e. [[(GCDWebServerURLEncodedFormRequest*)request arguments]
return [GCDWebServerDataResponse responseWithHTML:#"<html><body>OK</body></html>"];
}];
[webServer addHandlerForMethod:#"POST"
path:#"/path2"
requestClass:[GCDWebServerURLEncodedFormRequest class]
processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
// Do something with form data i.e. [[(GCDWebServerURLEncodedFormRequest*)request arguments]
return [GCDWebServerDataResponse responseWithHTML:#"<html><body>OK</body></html>"];
}];
See https://github.com/swisspol/GCDWebServer#advanced-example-2-implementing-forms for an example.

Related

Saving vs. submitting a form

I am working on an application process using Laravel 4.2.
Users applying with my form need to be able to save their form input for later, or submit it. So right now I have two different buttons, Save and Submit.
The key difference between saving and submitting would be a status. When a user saves their application, their application status will be marked as "in progress", when they submit their application the status would be marked as "completed".
My question is:
In terms of my form HTML structure, How do I differentiate between a saved and submitted application? Just checking whether or not they have filled out all the required inputs would not be reliable, because there is the possibility that the user wanted to add more to it later.
I tried doing a form inside of a form, but quickly realized this would not work.
Does anyone have an idea as to how to accomplish this?
You can have two submit buttons inside a form with different names and values:
<button type="submit" name="action" value="save">Save</button>
<button type="submit" name="action" value="submit">Submit</button>
You can then check the value in your controller action:
public function postSubmission()
{
if (Request::get('action') == 'save')
{
// Save form for later
}
elseif (Request::get('action') == 'submit')
{
// Immediately submit form
}
}
Lets say your code is something like this (this is from Laravel5 but as far as i remember it's mostly the same).
{!! Form::open(array('route' => array('admin.editApplication'), 'method' => 'PATCH')) !!}
....
<button type="submit" name="save" value="save">Save</button>
<button type="submit" name="edit" value="edit">Edit</button>
{!! Form::close() !!}
Then in your controller you can do something like this (check if the value is set in edit (you might want to call it something else than edit and save)
public function editApplication(Request $request) {
if(isset($request->input('save')){
// Your code to save here
}else{
// Your code to edit here.
}
}

How to autofill HTML form?

Stage
Suppose an HTML page in some URL (i.e. http://mysite.com/registry.html) and this HTML file contains a HTML form, like this:
<form action="/">
<input name="firstname">
<input name="lastname">
<textarea name="message"></textarea>
</form>
If I want to prefill this form how can I do this?
Maybe I thought that I can prefill this form on URL request. But I do not know if it is possible.
Restriction
I do not have access to mysite.com server nor registry.html.
Maybe with some JavaScript sorcery, load the page (http://example.com/registry.html) via AJAX:
function loadPage()
{
jQuery.ajax({
type: "GET",
url: "http://example.com/registry.html",
success: successFn
});
}
function successFn(data)
{
var result=jQuery(data).find("#idOfTheInput").html()
//modify the default value
//re attach the input into the html
//render the html
}
The rest is up to you; dig into the dom and put the values you want.
You can try to pass parameters by the url.
Something like this:
http://test.com?param1
This url is passing a parameter (param1), so you can set up the members of this form to be able to receive these parameters.
Regards,
Otacon.

Mapping one item posted in json object to the list object in Spring MVC

I have in trouble with posting json object and mapping it with List object in Spring MVC controller. I have the form that has several checkboxes. When a user checks and submits, data in the form is deserialized, sent to Spring MVC controller and mapped to List type object. When a user checks two or more checkboxes, it works fine. but for just one box, it doesn't.
When a user checks two or more, the data is deserialized like below.
{"users":["137","138"]}
However, when a user checks just one checkbox, it is like
{"users":"138"}
and 400 bad request error is returned.
Is there any workaround or solution for this?
The jQuery codes are:
$(document).ready(function() {
$('#groupusers').submit(function() {
var users = $(this).serializeObject();
$.postJSON("${context}/admin/groups/${group.seq}/users", users, function(result) {
...
});
return false;
});
And the form is:
<form id="groupusers" method="post" accept-charset="UTF-8" action="/" class="edit_group">
...
<div id="users">
<c:forEach var="user" items="${users}">
<label><input id="users" name="users" type="checkbox" value="${user.seq}" /> ${user.firstName} ${user.lastName}</label><br>
</c:forEach>
</div>
</form>
List object mapped to the form data:
public class AssignedUsers {
private List<Long> users;
...
}
Thanks in advance.
What is the implementation of the serializeObject() function? You might need to modify that to always return an array, so even if you only checked one box, the object should be: {"users":["138"]}
The server returned a 400 probably because the Jackson at threw a parsing exception at the backend.
Fojas' jQuery Serialize
This is the solution I have found and since been using which does excatly what you are requesting.
Example
HTML
<form id="myForm">
<input name="data[]" value="some data"/>
<input name="data[]" value="more data"/>
<input name="users[]" value="137"/>
</form>
jQuery
$('#myForm').serializeObject();
Output
{
data: ["some data", "more data"]
users: [137]
}

Using 2 buttons in same ASP.NET MVC Form

In general, is it possible to have two different buttons within the same form that post to different controller actions in ASP.NET MVC?
I am essentially trying to have two input (type="button") tags in the same form, but I want them to perform different controller actions. I would like to do this in a few cases because I think it provides a good aesthetic to be able to click buttons as opposed to hyperlinks. Is there a way to do this or should I design it differently?
Not really possible without using Javascript. With Javascript you'd just have to define different click handlers that invoked the proper action.
$(function() {
$('#button1').click( function() {
$(form).attr( 'action', '<% Url.Action( "action1" ) %>' )
.submit();
return false; // prevent default submission
});
$('#button2').click( function() {
$(form).attr( 'action', '<% Url.Action( "action2" ) %>' )
.submit();
return false; // prevent default submission
});
});
Some thoughts about handling this in the browser:
You can use links which are styled to look like buttons. This is easy to do, either with images or by putting the link in a block element with borders.
You can use two buttons which don't directly submit; they instead call a javascript function that sets the form action before submitting.
If all you want is something like OK & Cancel buttons, then have a look at this post by David Findley.
I'm using this method on my Edit view, where I have an Edit button and a Delete button. The delete button only requires the Id of the item. In the code below you can see that I've named my attribute "AcceptFormValueAttribute". This is method good for me, because my Delete [Get] action just shows a message asking for confirmation, so needs the redirect.
[ActionName("Edit")]
[AcceptFormValue(Name = "Action", Value = "Delete")]
[AcceptVerbs(HttpVerbs.Post)]
[ValidateAntiForgeryToken]
public ActionResult EditDelete(int? id)
{
return RedirectToAction("Delete", new { id = id });
}
This has nothing to do with ASP.NET MVC but with html. The only way I see how you could do this is by modifying the action attribute of the form tag using javascript on submission of the form by checking which button was pressed.
Well there are a few ways you could handle this. Assuming you aren't sending data with the button click I'd go with option 3. If data must be included then consider option 1 with some sort of temporary data store (like TempData).
One form posts to one controller
action on submit and the controller
action checks which button was
clicked and then dispatches a
RedirectToAction(). (Not great)
Multiple forms on one page post to multiple controller actions (Better)
Inside or outside a form create an input type="button" and give it an onclick handler
that redirects the user to a controller action (Best)
Haven't tried this, but given the ID of the clicked button does get sent VIA http POST, you could probably do something like:
<input type="submit" name="GO" ID="GO" value="GO BUTTON" />
<input type="submit" name="STOP" ID="STOP" value="STOP BUTTON" />
Then on the mvc end, just have two methods, one with a go parameter, one with a stop parameter.
Method #1
How about using two different forms wrapping the buttons, then using CSS to position one of them so that it appears (visually) to be inside the "main" form?
A really quick example:
<fieldset id="CombinedForm">
<form ... action="Method1">
...form stuff here...
<input id="Button1" type="submit" value="Do something">
</form>
<form ... action="Method2">
...form stuff here...
<input id="Button2" type="submit" value="Do something else">
</form>
</fieldset>
...Then using CSS as follows:
#CombinedForm {
position: relative;
padding-bottom: 2em; /* leave space for buttons */
}
#Button1, #Button2 {
position: absolute;
bottom: 0;
}
#Button1 {
left: 0;
}
#Button2 {
right: 0;
}
The result should be that you have a fieldset or div which looks like a form, having two actual HTML forms inside it, and two buttons which are positioned within the parent box, yet submitting to different locations.
Method #2
Another method occurs: have both buttons in the same form, pointing to one controller action, that then decides (based on the value of the button clicked) which action to redirect to.
Its not Javascript required...
how about this
public ActionResult DoSomething()
{
// Some business logic
TempData["PostedFormValues"] = Request.Form;
if (Request.Form("ButtonA") != null)
{
return RedirectToAction("ActionA", RouteData.Values);
}
return RedirectToAction("ActionB", RouteData.Values);
}
I think that I can suggest more simple one.
For example you have two buttons : ButtonA,ButtonB and want to perform different
action on each one.
Simplest solution is : just use BeginForm statement:
#using ( Html.BeginForm("ButtonA" , "Home") )
{
<input type="submit" value="ButtonA"/>
}
#using ( Html.BeginForm("ButtonB" , "Home") )
{
<input type="submit" value="ButtonB" />
}
You must also declare ButtonA,ButtonB actions in your Home controller :
[HttpPost]
public ActionResult ButtonA()
{ . . . }
[HttpPost]
public ActionResult ButtonB()
{ . . . }

When submitting a GET form, the query string is removed from the action URL

Consider this form:
<form action="http://www.blabla.com?a=1&b=2" method="GET">
<input type="hidden" name="c" value="3" />
</form>
When submitting this GET form, the parameters a and b are disappearing.
Is there a reason for that?
Is there a way of avoiding this behaviour?
Isn't that what hidden parameters are for to start with...?
<form action="http://www.example.com" method="GET">
<input type="hidden" name="a" value="1" />
<input type="hidden" name="b" value="2" />
<input type="hidden" name="c" value="3" />
<input type="submit" />
</form>
I wouldn't count on any browser retaining any existing query string in the action URL.
As the specifications (RFC1866, page 46; HTML 4.x section 17.13.3) state:
If the method is "get" and the action is an HTTP URI, the user agent takes the value of action, appends a `?' to it, then appends the form data set, encoded using the "application/x-www-form-urlencoded" content type.
Maybe one could percent-encode the action-URL to embed the question mark and the parameters, and then cross one's fingers to hope all browsers would leave that URL as it (and validate that the server understands it too). But I'd never rely on that.
By the way: it's not different for non-hidden form fields. For POST the action URL could hold a query string though.
In HTML5, this is per-spec behaviour.
See Association of controls and forms - Form submission algorithm.
Look at "4.10.22.3 Form submission algorithm", step 17. In the case of a GET form to an http/s URI with a query string:
Let destination be a new URL that is equal to the action except that
its <query> component is replaced by query (adding a U+003F QUESTION
MARK character (?) if appropriate).
So, your browser will trash the existing "?..." part of your URI and replace it with a new one based on your form.
In HTML 4.01, the spec produces invalid URIs - most browsers didn't actually do this though...
See Forms - Processing form data, step four - the URI will have a ? appended, even if it already contains one.
What you can do is using a simple foreach on the table containing the GET information. For example in PHP :
foreach ($_GET as $key => $value) {
$key = htmlspecialchars($key);
$value = htmlspecialchars($value);
echo "<input type='hidden' name='$key' value='$value'/>";
}
As the GET values are coming from the user, we should escape them before printing on screen.
You should include the two items (a and b) as hidden input elements as well as C.
I had a very similar problem where for the form action, I had something like:
<form action="http://www.example.com/?q=content/something" method="GET">
<input type="submit" value="Go away..." />
</form>
The button would get the user to the site, but the query info disappeared so the user landed on the home page rather than the desired content page. The solution in my case was to find out how to code the URL without the query that would get the user to the desired page. In this case my target was a Drupal site, so as it turned out /content/something also worked. I also could have used a node number (i.e. /node/123).
If you need workaround, as this form can be placed in 3rd party systems, you can use Apache mod_rewrite like this:
RewriteRule ^dummy.link$ index.php?a=1&b=2 [QSA,L]
then your new form will look like this:
<form ... action="http:/www.blabla.com/dummy.link" method="GET">
<input type="hidden" name="c" value="3" />
</form>
and Apache will append 3rd parameter to query
When the original query has array, for php:
foreach (explode("\n", http_build_query($query, '', "\n")) as $keyValue) {
[$key, $value] = explode('=', $keyValue, 2);
$key = htmlspecialchars(urldecode($key), ENT_COMPAT | ENT_HTML5);
$value = htmlspecialchars(urldecode($value), ENT_COMPAT | ENT_HTML5);
echo '<input type="hidden" name="' . $key . '" value="' . $value . '"' . "/>\n";
}
To answer your first question yes the browser does that and the reason is
that the browser does not care about existing parameters in the action URL
so it removes them completely
and to prevent this from happening use this JavaScript function that I wrote
using jQuery in:
function addQueryStringAsHidden(form){
if (form.attr("action") === undefined){
throw "form does not have action attribute"
}
let url = form.attr("action");
if (url.includes("?") === false) return false;
let index = url.indexOf("?");
let action = url.slice(0, index)
let params = url.slice(index);
url = new URLSearchParams(params);
for (param of url.keys()){
let paramValue = url.get(param);
let attrObject = {"type":"hidden", "name":param, "value":paramValue};
let hidden = $("<input>").attr(attrObject);
form.append(hidden);
}
form.attr("action", action)
}
My observation
when method is GET and form is submitted, hidden input element was sent as query parmater. Old params in action url were wiped out. So basically in this case, form data is replacing query string in action url
When method is POST, and form is submitted, Query parameters in action url were intact (req.query) and input element data was sent as form data (req.body)
So short story long, if you want to pass query params as well as form data, use method attribute as "POST"
This is in response to the above post by Efx:
If the URL already contains the var you want to change, then it is added yet again as a hidden field.
Here is a modification of that code as to prevent duplicating vars in the URL:
foreach ($_GET as $key => $value) {
if ($key != "my_key") {
echo("<input type='hidden' name='$key' value='$value'/>");
}
}
Your construction is illegal. You cannot include parameters in the action value of a form. What happens if you try this is going to depend on quirks of the browser. I wouldn't be surprised if it worked with one browser and not another. Even if it appeared to work, I would not rely on it, because the next version of the browser might change the behavior.
"But lets say I have parameters in query string and in hidden inputs, what can I do?" What you can do is fix the error. Not to be snide, but this is a little like asking, "But lets say my URL uses percent signs instead of slashes, what can I do?" The only possible answer is, you can fix the URL.
I usually write something like this:
foreach($_GET as $key=>$content){
echo "<input type='hidden' name='$key' value='$content'/>";
}
This is working, but don't forget to sanitize your inputs against XSS attacks!
<form ... action="http:/www.blabla.com?a=1&b=2" method ="POST">
<input type="hidden" name="c" value="3" />
</form>
change the request method to' POST' instead of 'GET'.