Reputation: 1569
I have a signup form for a SilverStripe site that handles everything on the server side. Originally, it was only going to be on the home page, so the setup I have worked fine. But then requirements changed and the form needed to appear on subpages as well. Everything still works except the form always submits to the home page regardless of what I have set for the action
parameter.
Originally, the action
parameter was "/home/submit." I changed it to accept a variable that returns the current page url and appends "/submit" to it by making a function called Link
(see code below). That seems to work and puts the correct url into the action
parameter.
But the form still sends the user back to the home page when you hit the submit button, which is not what I want. I want them to stay on the current page that the form is on (be it the home page or any subpage).
I tried getting the current URL and using it for the final line of the submit function like so:
$current = $this->get_current_page()->Link();
return $this->redirect("$current/?redirected=1#signupform");;
But that sends the user to an incorrect url: http://my-site.org/sub-page-title /submit
(this is not valid)
Here is the form code which is stored in Page.php:
public function Link($action='') {
$req = Controller::curr()->getRequest();
$req->setURL(parent::Link($action));
$url = $req->getURL(TRUE); // get the url back but with querystr intact.
return $url ;
}
public function getFirstName() {
return Session::get('first_name');
}
public function getLastName() {
return Session::get('last_name');
}
public function getCompanyName() {
return Session::get('company_name');
}
public function getEmail() {
return Session::get('email');
}
public function submit(SS_HTTPRequest $request) {
$firstName = $request->postVar('first_name');
$lastName = $request->postVar('last_name');
$c = $request->postVar('company_name');
$email = $request->postVar('email');
Session::clear('FORM_ERRORS');
$errors = [];
if (empty($email)) {
array_push($errors, "Email is required");
}
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
array_push($errors, "Email must be in a valid format. Example: [email protected]");
}
if(empty($firstName)){
array_push($errors, "Please enter a first name");
}
if(empty($lastName)){
array_push($errors, "Please enter a last name");
}
if (empty($errors)) {
Session::clear('first_name');
Session::clear('last_name');
Session::clear('email');
Session::clear('company_name');
$comment = new EmailSignUpSubmission();
$comment->FirstName = $firstName;
$comment->LastName = $lastName;
$comment->CompanyName = $c;
$comment->Email = $email;
$comment->write();
} else {
Session::set($this->formErrorsKey, $errors);
Session::set('first_name', $firstName);
Session::set('last_name', $lastName);
Session::set('company_name', $c);
Session::set('email', $email);
}
return $this->redirect("/?redirected=1#signupform");
}
public function getFormErrors() {
$errors = Session::get($this->formErrorsKey);
if ($errors == null || $errors == "") {
return null;
} else {
$errorList = new ArrayList();
foreach ($errors as $error) {
$e = new ArrayData(['Text' => $error]);
$errorList->add($e);
}
return $errorList;
}
}
public function isRedirect() {
$request = $this->getRequest();
return $request->getVar('redirected') == "1";
}
And here is the HTML form itself:
<div class="sign-up" id="signupform">
<div class="form-container">
<% if $isRedirect && not $getFormErrors %>
<div class="row">
<p class="success">
Thank you for your submission. You will hear back from us shortly.
</p>
</div>
<% else %>
<form method="post" action="/$Link/submit">
<h2 class="text-center white subscribe-hdr">Sign up</h2>
<% if $getFormErrors %>
<% loop $getFormErrors %>
<p class="error">$Text</p>
<% end_loop %>
<% end_if %>
<p class="white subscribe-body" style="text-align:center;">Sign up for the latest newsletter.</p>
<div class="form-group">
<input class="form-control" type="text" name="first_name" value="$getFirstName" placeholder="First Name">
</div>
<div class="form-group">
<input class="form-control" type="text" name="last_name" value="$getLastName" placeholder="Last Name">
</div>
<div class="form-group">
<input class="form-control" type="text" name="company_name" value="$getCompanyName" placeholder="Company">
</div>
<div class="form-group">
<input class="form-control" type="email" name="email" value="$getEmail" placeholder="Email">
</div>
<div class="form-group">
<button class="btn btn-primary btn-block" type="submit"
style="width:140px;margin-left:auto;margin-right:auto; float: none; text-align: center">Submit
</button>
</div>
</form>
<% end_if %>
</div>
</div>
Upvotes: 0
Views: 1486
Reputation: 57
Might be a bit late to the party, but this would do the same while not needing a hidden field in the form.
return $this->redirect($this->AbsoluteLink().'?redirected=1#signupform"');
Upvotes: 0
Reputation: 262
You could always use a hidden field:
<input type="hidden" value="{$AbsoluteLink}" name="redirectURL" />
Then use that in your submit method to redirect.
This would be alot easier by extending the Form class because you pass the current Controller object to the form. https://docs.silverstripe.org/en/3/developer_guides/forms/introduction/
Upvotes: 1