i'm trying to join two independent forms (login and register) in the
same page.
My idea is (just looking at the signin form):
Create an action that shows both forms (partials):
public function executeLoginAndRegister(sfWebRequest $request){
$this->form_signin = $this->getUser()->getAttribute('form_signin');
}
Each partial calls to its action:
form action="php?> echo url_for('#sf_guard_signin') ?>" method="post">
In the actions i write this code
public function executeSignin($request)
{
//...
$this->form = new $MyFormclass();
if ($this->form->isValid())
{
//...
}else{
// save the form to show the error messages.
$this->getUser()->setAttribute('form_signin', $this->form);
return $this->forward('sfGuardAuth', 'loginAndRegister');
}
}
It works, but, for example, if i execute LoginAndRegister and submit
incorrectly the signin form and I go to another page and then return to
LoginAndRegister, i will find the submiting error messages...
If i execute LoginAndRegister and submit incorrectly the signin form and
open another browser tab, i will find the submiting error messages in
the signin form of the second tab...
Any idea? any better approach?
I would just use sfDoctrineApplyPlugin if i were you :)
I have it, just writing in the if "request->isMethod('post')":
public function executeLoginAndRegister(sfWebRequest $request){
if($request->isMethod('post')){
$this->form_signin = $this->getUser()->getAttribute('form_signin');
}
}
Anyway if my approach has any big error or is not safety i would
thank anyone who tell me.
Javi
Related
Need a suggestion from people more intelligent than me. I have a modal which has 2 things, essentially, 3 radio buttons (Email, PDF, None)and a Yes and NO submit button.
On press of radio button I flag hidden variables appropriately to know if the user pressed email or pdf in my controller. Than user presses Yes for saving (happy path), and it will call a controller.
This controller will save the changes and redirect to a different page. Now I wanna add to this controller and make it download a pdf. I am doing this by calling my DownloadPDF action.
public ActionResult Main(string id)
//code for doing all the save and other stuff
{
if (viewModel.Email)
{
SendTestingEmail(viewModel.ConsumerEncryptedID);
}
else if(viewModel.PDF)
{
DownloadWelcomePDF()
}
return RedirectToAction("ConsumerIndex", "Consumer")
}
public ActionResult DownloadWelcomePDF(string id)
{
var htmlWelcomeEmail = db.getHtmlBody(id.DecryptID());
var converter = new ConvertToPDF();
var file = converter.ConvertHTMLStringToPDF(htmlWelcomeEmail.EmailBody);
var fileStreamResult = new FileStreamResult(file, "application/pdf") { FileDownloadName = string.Format("Welcome{0}{1}_{2}.pdf", htmlWelcomeEmail.ConsumerFirstName, htmlWelcomeEmail.ConsumerLastName, DateTime.Now.ToString("yyyyMMdd")) };
return fileStreamResult;
}
Now since this will also return pdf content I cannot do both these 2 things (redirecting to a different page and downloading ) at the same time.
Is there any suggestion, I have been searching internet for a long time.
It is essentially download and redirect but download needs to happen only on certain condition (press of radio) and the page should always redirect nonetheless.
You can break this into two steps.
First on submit you do a check in javascript to see if the user wants to download the PDF. If he wants, then call the download action and then call the main method from JS.
Or you can render the customerIndex page first and pass a flag (something like downloadPDFForId). Based on this flag in the JS in CustomerIndex you can download the file.
The first approach would be a cleaner one.
I have a very simple form created with createFormBuilder providing one simple text field only (there is no entity attached to the form).
When the form is submitted I do some logic and then unset form and formData as suggested in many posts to this topic if you want the form to be reset after submitting.
There is some additional action by simple ajax-requests that mainly initiates some UI stuff - not touching the form itself nor reloading the page.
Everything works fine except that the form apparently just doesn't want to be reset - meaning: Whenever the page reload button in the browser is pressed the standard browser dialog appears that asks if you want to submit the form again. And when you do the last value typed in BEFORE the last render call is submitted.
The template kw.html.twig is straight forward - mainly some UI stuff the form rendering and a bit jquery for handling ajax. Nothing special there.
I can't figure out why this is happening - I just want a clean form on any request. Which I thought I get when unsetting thing like in the sample code below.
/**
* #Route("/kw", name="show_kw")
*/
public function showKwAction(Request $request)
{
if($request->isXmlHttpRequest()) {
if( $request->getMethod() == 'POST' ) {
// do some logic...
return $this->json(array('kw_success' => true));
}
}
$kwData = array();
$kwForm = $this->createFormBuilder($kwData)
->add('kd', TextType::class)
->getForm();
if( $request->isMethod('POST') ) {
$kwForm->handleRequest($request);
$formData = $kwForm->getData();
// do some logic with formData...
unset($kwData);
unset($kwForm);
$kwData = array();
$kwForm = $this->createFormBuilder($kwData)
->add('kd', TextType::class)
->getForm();
}
$templateData = array(
'kwForm' => $kwForm->createView()
);
return $this->render(':backend:kw.html.twig', $templateData);
}
Any help is highly appreciated.
EDIT: Using Symfony 3.1
It's exactly what Alsatian said in the comment. Browser is trying to repeat last request.
However I think that instead of destroying this form you can simply redirect to the same route with $this->redirectToRoute once you processed data, of course if it's not a problem.
Also I see you check at least twice if method is post. If it's not colliding with the rest of your application logic you can specify #Method("POST") in annotation so you don't have to check it directly in code anymore.
Best Regards,
R.
My problem is that i want to preview data on index view without saving data in database. For this purpose, I want to send the list of objects in params section of redirect. And on receiving action want to use that list of objects.But when i include as below
def preview(){
//some code
redirect action: "index", params:[planId:params.planId, beamsInfoList: beamsInfoList]
}
I want something like below to happen.
def index() {
//some code
try{
planInfo.beamInfo = (params.beamsInfoList==null)?planInfo.beamInfo:params.beamsInfoList //beamInfo is also list
//some code
Object[] obj = GRMUtils.calculateTotalBeamsPower(planInfo.beamInfo)
totalPlanPower = (Float)obj[0];
beamPowerMap= (Map<Integer, String>)obj[1];
AmMapUtility utility=new AmMapUtility()
output = utility.generateAMmapFromBeams(planInfo.beamInfo, GRMConstants.POWER_MAP_PAGE);
if(null==output){
flash.error = message(code: 'beammap.noinfoerror.message')
}
}catch(Exception e){
log.error "Excepton occured while loading Power Map", e
}
respond beams, model:[centerLong:output.getCenterLongitude(),centerLat:output.getCenterLatitude(),amMapImageProperty:output.getMapImages(),
amMapLinesProperty:output.getMapLines(), planId:params.planId, planInfo:planInfo, powersControlCarrier: powersControlCarrier, powersTrafficCarrier:powersTrafficCarrier,satPower: planInfo.satellite.satelliteMaxPower, totalPlanPower: totalPlanPower, gatewayPower: planInfo.gateway.gatewayAggregateEIRP,fesOutputPowerLimit:fesOutputPowerLimit, beamPowerMap: beamPowerMap,powerRangeColorMap:output.getReuseColorMap()]
}
It does not redirect to index method and not showing any errors. Both actions are in same controller. I have used flash, but its not helping either as value reflected on second request. I have tried session too, but i am getting error
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
on some DB fetch. I am stuck. I am new to grails and groovy. Please help.
Edit: i have found my list is large, that is why its not redirecting. Please help me with another alternative like how can i use request attribute if it is possible?
I think i have solved the problem. Its working now. All i need to do is to use the request setattribute as
request.beams = beams
And no need to pass the list in params of redirect, which i was earlier used to do. Instead of using redirect, i used forward as below:
request.beams = beams
forward action: "index", params:[planId:params.planId]
I have question regarding redirection in Grails web-flow.
I am in a view state which will allow users to enter the answers for a question. On 2 wrong attempts I should be able to re-direct the user to view page from different controller. What i mean is
challengeQuestionOne{
onRender() {
//Display question
}
on('next') {BuildQuestion command ->
bindData(flow.recovery,command)
[return the model to flow]
if(command.hasErrors()) {
flow.command = command
return error()
}
if(check for status. If doesnot pass){
flash.message=message(code:'loginForm.account.locked', default: 'Please Contact Admin.')
redirect(controller : "login",action: "login")//how to redirect from here to diff controller
}
if (//compare answer entered) {
}
else{
//set status not active
}
}.to("challengeQuestionTwo")
on(Exception).to("error")
on('cancel').to('finish')
}
I have tried to redirect from onRender . It was redirecting to the page. But how do I display the error msg on the redirected page. How can i forward the error message from one controller to other??
Ivo Houbrechts wrote an excelent tutorial about grails webflow:
Webflow defines its own flash scope. Although it has the same semantics as the standard grails flash scope (the main purpose is to store objects only until after the next request), it is a different scope. This means that objects stored in webflow's flash scope are not visible in standard grails actions.
import org.springframework.web.context.request.RequestContextHolder
....
RequestContextHolder.currentRequestAttributes().flashScope.message = "YourMessage"
You can read more here:
http://livesnippets.cloudfoundry.com/docs/guide/
Flash scope will not work in this case as expected.
Try to use another approach to show error. E.g. you can pass parameters with redirect. Or you can throw some exception and check it on rendered page as follow:
<g:if test="${flowExecutionException}">
<div class="error"><g:message code="loginForm.account.locked"/></div>
</g:if>
Is there an easy way to check an email address is valid using Ajax? I'm using the sfValidatortEmail widget currently and this only shows an error message on submitting the form.
Thanks
I'm assuming you know how to write ajax requests. In the action you'd have something like
if ($request->isXmlHttpRequest()) {
// handle ajax check
try{
$validator = new sfValidatorEmail();
$validator->clean($request->getParameter('email'));
// good to go
} catch(sfValidatorError $e){
// invalid email
$this->getResponse()->setStatusCode(400);
}
} else {
// handle normal post
}
You'd need to add some Javascript/Jquery to fire an Ajax request to check the email, possibly linked to when the user clicks out of the email input box (blur function). This would be separate from your form class (assuming that the form has other elements too), but you could use the same action to handle the request if you wish:
if ($request->isXmlHttpRequest()) {
// handle ajax check
} else {
// handle normal post
}