Drupal : Relationship between two or more webform - redirect

Drupal 7
Webform 7.x-4.15
Example:
Webform 1: Fill up Particular
Webform 2: Category details
When a user submits the first webform 1, I have the confirmation page there I have a listing (For the first time is empty), when I click on another button that is in this page I redirect to second form here I will pass at the same time the last user ID save (SID)
How can I make a relationship between the forms (Webform 1 and Webform 2)?
Schema relationship between two forms

You can add custom submit callback and go to next form with it.
hook_form_alter
function MYMODULE_form_alter(&$form, &$form_state, $form_id){
if($form_id == 'id_step_one'){
$form['#submit'][] = '__custom_submit_function'; // add callback submit
}
}
function __custom_submit_function($form, &$form_state){
// do some stuff if you want
drupal_goto('/your_form_step2'); // redirect to step 2 of webform
}

Related

Drupal, what's the best way to make a huge form

I have to make a huge form in a drupal website, it's for a travel agency and it's a satisfaction questionnaire.
At the beggining of the form the user choose the type of travel he do, and after this all the fields depend of the first answer, for each type of travel there is different fields to complete.
So my question is what's the best way to do this form (there is 12 type of travel, so 12 different set of fields (~50 field / type)).
I think webform could be usable with the webform conditionnal fields, but the problem I think i'll have with webform is when I want to export the data, in the CSV I'll have ALL the fields of ALL the travel type, and this will be illisible.
I search for it but doesn't find if this is possible to hide fields of the csv programmatically.
A second way I found in internet is the CCK, but I have no experience with this.
Do you have any suggestion ?
you can use hook provided by webform module :
/**
* Alter a Webform submission's data when exported.
*/
function hook_webform_csv_data_alter(&$data, $component, $submission) {
// If a value of a field was left blank, use the value from another
// field.
if ($component['cid'] == 1 && empty($data)) {
$data = $submission->data[2]['value'][0];
}
}
Found in webform.api.php into webform module folder
Also you can modify submit function by own altering form process :
function hook_form_alter(&$form, &$form_state , $form_id){
if ($form_id == 'myformid'){
$form['#submit']= array('mycustomsubmit'); // or loop on existing to suppress only unwanted submit callbacks
}
}
function mycustomsubmit($form , &$form_state){
// do your stuffs csv exports
}

In-line item editing in Lift / handling 2 different form submit needs on one page

OK, so first off, let's start with me acknowledging that the bind( ... ) way of binding Lift forms is so last week! :) I do know that, and I just haven't gone back to update this code yet. Also, I trust now that there's some really slick Lifty way to do this. That's what I seek. I'm stumped as to even how to hack something together. That said...
I have a list of Items that I initially display non-editable, and the title of each Item is an ajax-enabled link that calls to the server and replaces that line-item with an editable form of the Item (I use SetHtml to swap the form in at the < li> that listed that Item).
"parent" Items List view looks something like this
< form data-lift="form.ajax">
< div data-lift="creategamewizard?multipart=true" id="wizardform">
< ul>
< li>Item 1< /li>
< li>Item 2< /li>
< /ul>
some more form elements
< button>Submit< /button>
< input type="hidden" id='298356928734' />
< /div>
< form>
This ajax submit (via the hidden field) calls processSubmit().
The SetHtml that swaps in the editableItem form looks something like this.
NOTE: At the end of the following listing, the "save" binding has no server-side code tied to it because the "parent" submit button is already on the page, and when I put another hidden field in this binding or tried to tie any code directly to the Edit Item Save button, that code and the "parent" submit got triggered. So the approach below was to try to use the "parent" submit for both the parent submit as well as the Edit Item submit.
<a href="javascript://" onclick={ajaxOnClickHandler(editItemClickHandler(item.id.get))}>{item.title.get}</a>
def ajaxOnClickHandler(jsHandler: ()=>JsCmd) =
{
SHtml.onEvent( e => jsHandler()).toJsCmd+";return false;"
}
def editItemClickHandler(itemId: String): ()=>JsCmd = ()=>
{
trace.logAjaxComm("ExistingItem.Edit()")
JsCmds.SetHtml("LiId"+itemId, getEditableItem(promo) )
}
def getEditableItem(itemId) =
{
bind( ...
"promotitle" -> SHtml.text(editablePromo.get.promotitle.is,
(s:String) => {
trace.logUIDataManipulation("Saving new promo Title["+s+"]");
editablePromo.get.promotitle(s)
}, "id" -> "promotitle"),
"save" -> SHtml.button("Save", ()=> {})
)
}
Then when the user selects an Item, and the editable Item form is plugged in, there's "another" submit button that should ajax submit the form data for that item, and then swap back in the (now updated) nonEditable version of the data.
The problem for me is the submission. In addition to the Edit Item form above, I've got a ajaxified submit button on the "parent" non-editable list page to handle submitting some fields below the list. The Edit Item "save"-> binding adds a button, which should do (and in fact does) nothing for itself, but it does trigger the "Parent" submit button. And I route that submit to do the save of the Edit Item form.
The non-editable Item and the editable item code swaps fine, but changes made in the editable Item form is not saved, and I figured out that that was happening because the elements in the editable Item form are not being submitted at all, following is an example of a log message I don't see at all...
bind( ... "promotitle" -> SHtml.text(editablePromo.get.promotitle.is,
(s:String) => {
trace.logUIDataManipulation("Saving new promo Title["+s+"]");
editablePromo.get.promotitle(s)
}, "id" -> "promotitle")
)
In a normal ajaxified form, all element handlers are called (if there are changes to the field, I guess...) in order of rendering, with the submit/hidden elements' handlers being called last (if they're last in the bind list.
so finally, let's get around to my question:
if you're doing in-place editing like this, how do I manage 2 submit buttons (the one for the non-editable list page plus the additional one that gets added when editing an item)?
I'm sure I don't need to refresh the page, but I can't figure out how you'd do this with Ajax.
Maybe alternatively, the in-place editable form can be submitted as a non-submit ajax action, ie. somehow that doesn't trigger the parent submit?
For anyone tripping over this question, I figured I'd share the solution I eventually found...
1)The problem was that the submit (for AJAX this is the hidden html tag) happened before the editable Item's field handlers were called. So when the AJAX update that collapsed the editable Item back into just a non-Editable list item, the data hadn't yet been updated. So what was displayed in non-editable form didn't show the update, yet if I refreshed the page in the browser, the update had been saved to the database and now showed properly.
2)The reason for the mal-ordering is that Lift assigns each form tag's server-side handler an id (which are "monotonically increasing" with an additional string added to the end). That's fine until you do an ajax live-update of a form and add fields (as I did when I inserted the Editable Item fields). These newly-added fields were assigned server-side ids that came after the hidden field that got generated as part of the initial page rendering.
3)The solution was to explicitly shove the hidden field into a much higher id using S.formGroup. See here for more details...
The example from the last link below is as follows (and differs from mine in that it uses SHtml.submit, whereas I use SHtml.hidden). It adds the constant 1,000 to the submit button's server-side handler id:
"type=submit" #> S.formGroup(1000) {
SHtml.submit("Submit", process)
}
Discussion of a problem that is essentially the same as mine: https://groups.google.com/forum/#!topic/liftweb/MYJQeVlOYFM
Description of id assignment and S.formGroup under heading "Server side function order.":
https://www.assembla.com/spaces/liftweb/wiki/cool_tips
And lastly, linked to from the last link is some example code:
https://groups.google.com/forum/#!topic/liftweb/E9z7PVhogQw

Drupal 7 Hook for Webform Pagebreak Submission

When inside a webform, that was created with the module webform - I need to validate / check the entries of a page when submit/"next step" is clicked- So before the user moves to the next page(pagebreak).
I want to check if the email address was entered already - if so show this as an error without moving to the next page.
I need a hook .. or a way to tell drupal "go to step 1" instead of showing step 2.
You can use a hook to check the value of the form. In hook form alter you can check your field values.
$form['#validate'][] = 'function_to_validate_field';
function check_for_company_validate($form, &$form_state) {
//do stuff
}
You can see this for drupal 7 to create an error:
https://api.drupal.org/api/drupal/includes!form.inc/function/form_set_error/7

Without submit button validate form elements in Magento

To add multiple steps before submit form. like:
Registration page:
Step 1 - Enter first, last name and email (validate on click of next button and show next step)
Step 2 - Enter Password and Confirm password and submit
Step 1 and step 2 are separate DIV's (Show/hide on Next Click)
You can give a try of this JS snippet:
var formToValidate = $('place the id of the form, that I want to validate');
var validator = new Validation(formToValidate);
if(validator.validate()) {
/* The logic, that you want to execute if you pass the validation. */
......
......
}
Good luck!

Zend Framework: Post to different action then return to original action if fails validation AND keep form fields

This might sound like an odd scenario, but I've got two forms on one page. One is just posting back to itself. I made the second post to another action to keep the code cleaner. Maybe not the right choice...
The problem I'm having now is that if that second form doesn't validate, I redirect back to the page with the form but I don't know how to keep my form fields filled in with the original information the user entered. Is there a way to do that and keep posting to two separate actions, or do I need to just bite the bullet and have both forms post back to the same action and deal with the messy logic?
I would submit both forms to the same action. There really shouldn't be anything too messy about it. In each form include a hidden field to signify which form is being submitted.
Application_Form_Login:
/* other form elements */
$this->addElement('hidden', 'login', array(
'value' => 1
));
Application_Form_Register:
/* other form elements */
$this->addElement('hidden', 'register', array(
'value' => 1
));
Controller:
$loginForm = new Application_Form_Login();
$registerForm = new Application_Form_Register();
if($this->_request->isPost()) {
if($this->_request->getPost('login')) {
if($loginForm->isValid($this->_request->getPost())) {
// validated, redirect
$this->_helper->redirector('profile', 'user');
}
}
if($this->_request->getPost('register')) {
if($registerForm->isValid($this->_request->getPost())) {
// validated, proceed as needed
}
}
}
$this->view->loginForm = $loginForm;
$this->view->registerForm = $registerForm;
View:
echo $this->loginForm;
echo $this->registerForm;
With this type of a setup, if either of your forms fail validation, isValid() will preserve any data that has been entered and you still redirect on a successful validation of one or both of the forms.
Personally, I think that each form should post to its own controller, as you have. This keeps the code for processing that form in a single place. The issue here is that you want to return to the original page on failed validation. But why? Why not simply redisplay the form in the target controller, just like you would if there were a single form on the page?
For example, consider a login form that appears on every page of a sie (perhaps because it in the site template/layout). It posts to something like AuthController::loginAction(). If the login fails, then you don't typically send him back to the page from which he came. You leave him at the login page, with the form as pre-filled from the $_POST as you want it to be (probably a username, but not his password).
See this answer for a similar discussion.
Update: Had another thought in this. If you really want to handle the processing in two different controllers in order to keep him on the page from which he posted the form, at least extract that form processing out into an action helper. This way, you could at least keep that form-processing DRY.
Update: Rob Allen has just written a great blog post "A form in your layout" in which he describes a method that uses an action-helper with a preDispatch() method that instantiates and processes the form. Very nice.
How do you redirect? I don't see the problem if you just display the form page again. You can prefill you forms using Zend_Form::populate().
Well, I would just keep both forms submitting on the same page.
I don't see why your code should get any less readable. Learn how to use action helpers and your controllers will suddenly look extremely simple and readable:
public function indexAction()
{
$request = $this->getRequest();
// send forms to view, so we can print them
// but also so we can access them in action helpers
$this->view->form = $this->_getForm('Form1', '/');
$this->view->form2 = $this->_getForm('Form2', '/');
if ($request->isPost())
{
// process the first form
if (isset($_POST['form_submit_button']) && $this->view->form->isValid($_POST))
{
$this->_helper->form($this->view->form->getValues());
}
// process the second form
else if (isset($_POST['form2_submit_button']) && $this->view->form2->isValid($_POST))
{
$this->_helper->form2($this->view->form2->getValues());
}
}
Each form's processing would have its own action helper.