Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Apologies if this shouldn't be considered webform specific, but I figured it made more sense here.
I have a client request to auto save drafts and remove the save draft button. I am tantalizingly close, but I'm hoping somebody can help me figure out what I'm missing. My approach is to use AJAX on each form component so that when losing focus a draft is saved. I have this working for the first component, but the save draft does not fire anymore after the first time. Can anybody see something obvious that I am missing?
Code for my module below:
function webform_autodraft_form_alter(&$form, &$form_state, $form_id) {
// restrict to the test form
if(strstr($form_id, 'webform_client_form_158')) {
// get the nid so we can use it in the wrapper value
$nid = $form['#node']->nid;
foreach($form['submitted'] as $k => $c) {
$form['submitted'][$k]['#ajax'] = array(
'callback' => 'webform_autodraft_webform_js_draft',
'wrapper' => 'webform-client-form-' . $nid,
'method' => 'Replace',
'effect' => 'fade',
);
}
}
}
function webform_autodraft_webform_js_draft($form, &$form_state) {
// check for existing submission
global $user;
$n = node_load($form_state['values']['details']['nid']);
$draft_sid = _webform_fetch_draft_sid($n->nid, $user->uid);
$form_state['values']['details']['sid'] = $draft_sid;
// for some reason the form_state has the form_key not the cid. this function wants cid, so convert them over.
$submitted = $form_state['values']['submitted'];
foreach ($submitted as $k => $v) {
// add new key
$newkey = $form_state['complete form']['submitted'][$k]['#webform_component']['cid'];
$form_state['values']['submitted'][$newkey] = $v;
// kill old key
unset($form_state['values']['submitted'][$k]);
}
unset($submitted);
// draft to true then save!
$form_state['save_draft'] = TRUE;
webform_client_form_submit($form, $form_state);
// drupal_set_message('<pre>Sid after:' . print_r($sid, true) . '</pre>');
return $form;
}
Comments
Comment #1
quicksketchAs mentioned in the submission guidelines, I don't provide help with custom coding:
Please refer to other resources such as IRC or Drupal StackExchange to ask your questions.
Comment #2
petednz CreditAttribution: petednz commentedDear Uncle Justin
Did you ever get closer than 'tantalizingly close'?
Comment #3
unclejustin CreditAttribution: unclejustin commentedSadly, no. I eventually had to abandon this idea.
Comment #4
petednz CreditAttribution: petednz commentedThanks for the prompt response. I understand that type of 'tantalising' ;-)
Comment #5
Stefan Vaduva CreditAttribution: Stefan Vaduva commentedHello,
Starting from the code posted by unclejustin, I've managed to make it work with this callback for the ajax request:
Comment #6
mbrowd CreditAttribution: mbrowd commentedHi Stefan,
How would you implement your code on the site? I made a custom module but nothing seems to be happening.
Thanks
Comment #7
Liam MorlandThis would be a valuable feature.
Comment #8
quicksketchHey Liam, this would be neat but probably incredibly difficult. Things get messy when dealing with file uploads and multiple pages. I'd probably prefer to see this implemented as a 3rd party module (at least initially). It depends on the complexity of the implementation whether we'd see this in the main project or not.
Comment #9
Liam MorlandFor file uploads, I would just not handle them and instead have files uploaded when the page is submitted.
For multiple pages, this doesn't really increase the complexity. The Previous and Next buttons would function as before.
All I am suggesting is that when a form component changes, that component's value should be saved via Ajax. Saving a draft when changing pages is already implemented, so this isn't breaking any new ground in that regard.
I won't be working on this today, but I might give it a go sometime.
Comment #10
DanChadwick CreditAttribution: DanChadwick commentedI don't see this happening in webform core. Currently forms that fail validation can be saved as drafts. If you combine that with an onunload handler to save changes prior to leaving page, I think that's as close as we should come. I think that perhaps the feature to save each changed component could be done by an add-on module.
Comment #11
upperholme CreditAttribution: upperholme commentedDid this ever get any further? Is a module available?
Comment #12
swhitters CreditAttribution: swhitters as a volunteer commentedCan someone please take another look at this?
I wasn't completely sure this isn't a separate issue (and if it is I would be happy to open a new issue, as this one seems dead), but need to be able to autosave anonymous user responses as a draft on a multipage form after "next page" is clicked. It doesn't have to be an AJAX solution--I'd take some other module if it is available as well.
Thanks.
Comment #13
Liam MorlandThis issue is about Ajax saving. Draft are already saved when switching pages for authenticated users.
Comment #14
swhitters CreditAttribution: swhitters as a volunteer commentedOh, I didn't see it say authenticated. What about non-authenticated (anonymous) users? That's the problem. Should I start a new issue? I didn't want to duplicate.
Comment #15
Liam MorlandIt would probably get done as part of #1932560: “Save draft” form button for anonymous users.