Created
April 16, 2012 21:09
-
-
Save boonebgorges/2401529 to your computer and use it in GitHub Desktop.
Add an "Other" option at the end of a list of BuddyPress profile checkbox options, where users can enter custom text
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Add an 'Other' type to xprofile fields | |
* | |
* @link https://buddypress.trac.wordpress.org/ticket/3775 | |
* @link http://redmine.gc.cuny.edu/issues/1199 | |
*/ | |
class CAC_Xprofile_Other { | |
function __construct() { | |
add_action( 'xprofile_field_additional_options', array( &$this, 'render_admin' ) ); | |
add_action( 'xprofile_fields_saved_field', array( &$this, 'save_admin_field' ) ); | |
add_action( 'bp_get_the_profile_field_options_checkbox', array( &$this, 'render_field' ), 10, 5 ); | |
add_action( 'xprofile_data_after_save', array( &$this, 'save_field_data' ) ); | |
// Call early to beat race condition for auto-links | |
add_action( 'bp_get_the_profile_field_value', array( &$this, 'render_public_field' ), 5, 3 ); | |
} | |
function render_admin() { | |
$field_id = isset( $_GET['field_id'] ) ? (int)$_GET['field_id'] : NULL; | |
$other_toggle = 'yes' == bp_xprofile_get_meta( $field_id, 'field', 'cac_other_field' ); | |
?> | |
<div id="titlediv"> | |
<h3>'Other' field</h3> | |
<label for="cac-other-field">Add an "Other" option at the end of this list (a checkbox/radio button + a text field)?</label><br /> | |
<input type="radio" name="cac-other-field" value="yes" <?php checked( $other_toggle, true ) ?>/> Yes<br /> | |
<input type="radio" name="cac-other-field" value="no" <?php checked( !$other_toggle, true ) ?>/> No | |
</div> | |
<?php | |
} | |
function save_admin_field( $field ) { | |
if ( isset( $_POST['cac-other-field'] ) ) { | |
// When creating a new field, no field_id will have been set yet. We'll | |
// look it up based on the $field object passed to the hook | |
if ( empty( $this->field_id ) ) { | |
$this->field_id = BP_XProfile_Field::get_id_from_name( $field->name ); | |
} | |
$data = 'yes' == $_POST['cac-other-field'] ? 'yes' : 'no'; | |
bp_xprofile_update_field_meta( $this->field_id, 'cac_other_field', $data ); | |
} | |
} | |
function render_field() { | |
$field_id = func_get_arg( 2 ); | |
$field = wp_cache_get( 'xprofile_parent_field_' . $field_id, 'bp' ); | |
if ( !$field ) { | |
$field = new BP_XProfile_Field( $field_id ); | |
wp_cache_set( 'xprofile_parent_field_' . $field_id, $field, 'bp' ); | |
} | |
$siblings = wp_cache_get( 'xprofile_siblings_' . $field_id, 'bp' ); | |
if ( !$siblings ) { | |
$siblings = $field->get_children(); | |
wp_cache_set( 'xprofile_siblings_' . $field_id, $siblings, 'bp' ); | |
} | |
// Only continue if this is the last in the list | |
$position = func_get_arg( 4 ) + 1; | |
if ( $position != count( $siblings ) ) { | |
return func_get_arg( 0 ); | |
} | |
// Only continue if the Other field is enabled for this item | |
if ( 'yes' != bp_xprofile_get_meta( $field_id, 'field', 'cac_other_field' ) ) { | |
return func_get_arg( 0 ); | |
} | |
$current_value = new BP_XProfile_ProfileData( $field_id, bp_displayed_user_id() ); | |
if ( isset( $current_value->id ) ) { | |
$is_checked = 'yes' == bp_xprofile_get_meta( $current_value->id, 'data', 'cac_other_field' ); | |
$other_text = bp_xprofile_get_meta( $current_value->id, 'data', 'cac_other_field_text' ); | |
} else { | |
$is_checked = false; | |
$other_text = ''; | |
} | |
/* | |
$field_name = 'field_' . $field_id . '_other'; | |
if ( 'checkbox' == $field->type ) { | |
$field_name .= '[]'; | |
} | |
*/ | |
$checked = $is_checked ? ' checked="checked" ' : ''; | |
$html = func_get_arg( 0 ) . '<label><input type="' . $field->type . '" name="field_' . $field_id . '[other]" id="field_' . $field_id . '_other" value="cac_other_value"' . $checked . '> Other </label> <input class="other-text" type="text" name="field_' . $field_id . '_other_text" value="' . esc_attr( $other_text ) . '" />'; | |
return $html; | |
} | |
function save_field_data( $fielddata ) { | |
// Groan | |
if ( 'yes' != bp_xprofile_get_meta( $fielddata->field_id, 'field', 'cac_other_field' ) ) { | |
return; | |
} | |
$fid = $fielddata->field_id; | |
$current_value = new BP_XProfile_ProfileData( $fid, bp_displayed_user_id() ); | |
if ( isset( $_POST['field_' . $fid] ) && is_array( $_POST['field_' . $fid] ) && !empty( $current_value->id ) ) { | |
if( !empty( $_POST['field_' . $fid]['other'] ) ) { | |
if ( isset( $_POST['field_' . $fid . '_other_text'] ) ) { | |
bp_xprofile_update_meta( $current_value->id, 'data', 'cac_other_field_text', $_POST['field_' . $fid . '_other_text'] ); | |
bp_xprofile_update_meta( $current_value->id, 'data', 'cac_other_field', 'yes' ); | |
} | |
} else { | |
bp_xprofile_update_meta( $current_value->id, 'data', 'cac_other_field', 'no' ); | |
} | |
} | |
} | |
function render_public_field( $html, $type, $fid ) { | |
if ( in_array( $type, array( 'textbox', 'textarea' ) ) ) { | |
return $html; | |
} | |
$current_value = new BP_XProfile_ProfileData( $fid, bp_displayed_user_id() ); | |
$is_checked = 'yes' == bp_xprofile_get_meta( $current_value->id, 'data', 'cac_other_field' ); | |
if ( $is_checked ) { | |
$other_text = bp_xprofile_get_meta( $current_value->id, 'data', 'cac_other_field_text' ); | |
if ( $other_text ) { | |
$html .= ', ' . $other_text; | |
} | |
} | |
return $html; | |
} | |
} | |
new CAC_Xprofile_Other(); |
Other option not able to save data. #Boone Gorges please suggest how to do that.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi,
I needed to add an "Other" option with an input to a radio field in the profile part, so I've found your code (line 27 you indicate "checkbox/radio button"). Thanks for your code, because it is Wonderland for me, regarding my lack of knowledge. I try to understand it... But I can't make it work, the message "an error occurred while your informations were updated. Please try again" (this is a translation from French...) when I want to save a profile with the "other" option checked or with the input filled in. Maybe it's because of the BuddyPress version (3.1.0 now), or something else. Do you have a clue how to solve this?
And two things went in the way of getting what I need:
Do you know how to do the same for a radio button?
I've worked "a little" on this number 2 (and I'm just beginning to use JavaScript again and I had a very low level so I'm just trying to figure it out by making attempts) - it took me a couple of hours...
So far, using JavaScript, I've managed to show the input element only when the "Other" option is checked, and hide it when it's not, but I have absolutely no skill to judge the quality of the code.
I copy my changes here, if you could have a look and tell me if it's ok to change your code that way, that would be tremendous, or maybe this would at least help someone to find a clean solution.
What I've done:
I changed line 91 like that:
$html = func_get_arg( 0 ) . '<label><input type="' . $field->type . '"id="field_' . $field_id . '[other]_id" name="field_' . $field_id . '[other]" value="cac_other_value"' . $checked . ' onClick="onClickOther('.$field_id.')"> Other </label> <input class="other-text" type="hidden" name="field_' . $field_id . '_other_text" id="field_' . $field_id . '_other_text_id" value="' . esc_attr( $other_text ) . '" />';
I created a js file in a js folder in my child theme folder:
child-theme-folder/js/myfile.js
I added this function at the end of my functions.php file (in my child theme folder) to call the script:
`// enqueue javascript
function add_js(){
wp_enqueue_script( 'onClickOther',
get_stylesheet_directory_uri() . '/js/myfile.js',
array() );
}
add_action( 'wp_footer', 'theme_js' );`
Maybe there is a solution elsewhere, I haven't found it yet. But it was an opportunity to meet JavaScript again! Now I would love this code to work.
Thanks in advance!