Drupal 7's new and improved Form API makes using AJAX a breeze. It enables you to add, replace, or remove form elements via AJAX without ever really having to get your hands dirty.
I recently had the opportunity to give it a whirl. Here's a the deal:
I have content type `Resume` and Profile2 type `Job Seeker Profile.` I'd like my users to be able to create up to 5 resumes, and I'd like them to have the option of importing information from their profile into their brand-spanking new resume. So, I'm going to create an 'Import from profile' button that will populate the resume fields with profile field values via AJAX.
Note: It is possible to accomplish something like this by setting default values via a token. However, in this case, I'd like to be able to import things like field collections, addresses, and fields with unlimited cardinality. Here's the code that accomplished it!
/** * Implements hook_form_FORM_ID_alter(). * Resume node form. */ function grasmash_form_resume_node_form_alter(&$form, &$form_state, $form_id) { // Load user's current profile. $uid = $form['uid']['#value']; $author = user_load($uid ); $profile = profile2_load_by_user($author, 'seeker_profile'); // Add button permitting users to import Work Experience from their Profile. if (array_key_exists('und', $profile->field_work_experience)) { // It's good to first check that there's actually something to import. // Wrapping the element with HTML lets us easily define the scope of the AJAX replacement later. $form['field_work_experience']['#prefix'] = '<div id="field-work-experience-wrapper">'; $form['field_work_experience']['#suffix'] = '</div>'; $form['field_work_experience']['import_work_experience'] = array( '#type' => 'submit', '#value' => 'Import work experience from your profile', '#description' => t('This will overwrite anything you have entered into the Work Experience field!'), '#weight' => -20, '#attributes' => array('class' => array('field-add-more-submit')), '#limit_validation_errors' => array(), // Don't validate when the button is clicked! '#ajax' => array( 'callback' => 'grasmash_js_import_work_experience', 'wrapper' => 'field-work-experience-wrapper', 'effect' => 'fade', 'method' => 'replace', ), ); } } /* * Define AJAX return functions for Work Experience field. */ function grasmash_js_import_work_experience($form, $form_state) { $field_collection = 'field_work_experience'; // Load the correct field collection using another function. This approach allows us to easily repeat this process with another field collection if desired. $element = grasmash_js_import_field_collection($field_collection, $form, $form_state); return $element; } /* * Import pre-populated field_collection form element from a user's job seeker profile. */ function grasmash_js_import_field_collection($field_collection, &$form, &$form_state) { // Load author profile if necessary. $uid = $form['uid']['#value']; $author = user_load($uid); //module_load_include('inc', 'profile2_page', 'profile2_page'); // loading with hook_init instead $profile2 = profile2_by_uid_load($uid, 'seeker_profile'); $profile2_form = entity_ui_get_form('profile2', $profile2, 'edit'); if (isset($profile2_form)) { // Pull in corresponding form element from profile form. $element = $profile2_form['profile_seeker_profile'][$field_collection]; // Process the imported element. $element = grasmash_process_ajax_import($element); return $element; } } /** * Recursively removes profile2 field prefixes from each array row. * This ensures that all input names on the destination form are correct. */ function grasmash_process_ajax_import($element){ foreach ($element as $key => $value){ if (is_string($element[$key]) && !is_numeric($element[$key])){ $element[$key] = preg_replace('@(profile_seeker_profile){1}(\[){1}([^\]]+){1}(\]){1}@','$3$5', $element[$key]); $element[$key] = str_replace('profile-seeker-profile-','', $element[$key]); $element[$key] = str_replace('profile_seeker_profile_','', $element[$key]); if ($element[$key] == 'profile_seeker_profile') { unset($element[$key]); } } elseif (is_array($element[$key])){ $element[$key] = grasmash_process_ajax_import($element[$key]); } } return $element; }
Comments
patrickd (not verified)
Tue, 12/13/2011 - 12:54
Permalink
Cool
Thanks for sharing!
Anonymous (not verified)
Sat, 03/31/2012 - 10:58
Permalink
GREAT JOB FOR YOU!!! The
GREAT JOB FOR YOU!!! The digital volcano vaporizer is one of the latest inventions of vaporizers today. For the first time on the market it was introduced in 2007.
Pedro (not verified)
Tue, 12/13/2011 - 16:17
Permalink
field_attach_form
Maybe you could achieve the same result with field_attach_form and filter out those that you don't need.
madmatter23
Thu, 12/15/2011 - 09:52
Permalink
Seems interesting
Pedro, I think that field_attach_form would work. Deciding to use it would probably depend on how many fields you'd like to import at once, and how closely the source and target forms match.
I haven't used field_attach_form yet, what happens when you attach a form from a source that contains fields which aren't present in the target? Do they get added or ignored?
Anonymous (not verified)
Wed, 03/28/2012 - 00:58
Permalink
Great post, I am still
Great post, I am still looking.Bags
Add new comment