programing

다중 입력이 있는 사용자 지정 중력 양식 필드

css3 2023. 10. 7. 12:07

다중 입력이 있는 사용자 지정 중력 양식 필드

저는 고객을 위해 Gravity Forms 확장 작업을 해왔습니다.개념은 입력이 4개인 새로운 필드 유형을 추가하는 것입니다.저는 사람들이 맞춤 중력 폼 필드를 만드는 방법에 대해 10가지 정도의 다양한 변형을 시도했지만, 계속해서 같은 문제에 부딪힙니다.

사용자 정의 필드를 작성할 때 다음의 명명 규칙에 따라 입력을 1개만 사용할 경우input_{field_id}양식이 제대로 저장되고 검증됩니다.하지만 이름을 사용하여 두 개 이상의 필드를 추가하려고 하는 순간input_{field_id}.{i}필드에 내장된 것처럼 양식은 더 이상 내 데이터를 저장하지 않습니다.

<?php if ( ! class_exists( 'GFForms' ) ) { die(); }

class GF_Field_Attendees extends GF_Field {

    public $type = 'attendees';

    public function get_form_editor_field_title() { return esc_attr__( 'Attendees', 'gravityforms' ); }

    public function get_form_editor_button() {
        return array(
            'group' => 'advanced_fields',
            'text'  => $this->get_form_editor_field_title(),
            'onclick'   => "StartAddField('".$this->type."');",
        );
    }

    public function get_form_editor_field_settings() {
        return array(
            'conditional_logic_field_setting',
            'prepopulate_field_setting',
            'error_message_setting',
            'label_setting',
            'admin_label_setting',
            'rules_setting',
            'duplicate_setting',
            'description_setting',
            'css_class_setting',
        );
    }

    public function is_conditional_logic_supported() { return true; }

    public function get_field_input( $form, $value = '', $entry = null ) {
        $form_id    = $form['id'];
        $field_id   = intval( $this->id );

        $first  = esc_attr( GFForms::get( 'input_' . $this->id . '_1', $value ) );
        $last   = esc_attr( GFForms::get( 'input_' . $this->id . '_2', $value ) );
        $email  = esc_attr( GFForms::get( 'input_' . $this->id . '_3', $value ) );
        $phone  = esc_attr( GFForms::get( 'input_' . $this->id . '_4', $value ) );

        $disabled_text = $is_form_editor ? "disabled='disabled'" : '';
        $class_suffix  = $is_entry_detail ? '_admin' : '';

        $first_tabindex = GFCommon::get_tabindex();
        $last_tabindex  = GFCommon::get_tabindex();
        $email_tabindex = GFCommon::get_tabindex();
        $phone_tabindex = GFCommon::get_tabindex();

        $required_attribute     = $this->isRequired ? 'aria-required="true"' : '';
        $invalid_attribute      = $this->failed_validation ? 'aria-invalid="true"' : 'aria-invalid="false"';

        $first_markup = '<span id="input_'.$field_id.'_'.$form_id.'.1_container" class="attendees_first">';
            $first_markup .= '<input type="text" name="input_'.$field_id.'.1" id="input_'.$field_id.'_'.$form_id.'_1" value="'.$first.'" aria-label="First Name" '.$first_tabindex.' '.$disabled_text.' '.$required_attribute.' '.$invalid_attribute.'>';
            $first_markup .= '<label for="input_'.$field_id.'_'.$form_id.'_1">First Name</label>';
        $first_markup .= '</span>';

        $last_markup = '<span id="input_'.$field_id.'_'.$form_id.'.2_container" class="attendees_last">';
            $last_markup .= '<input type="text" name="input_'.$field_id.'.2" id="input_'.$field_id.'_'.$form_id.'_2" value="'.$last.'" aria-label="Last Name" '.$last_tabindex.' '.$disabled_text.' '.$required_attribute.' '.$invalid_attribute.'>';
            $last_markup .= '<label for="input_'.$field_id.'_'.$form_id.'_2">Last Name</label>';
        $last_markup .= '</span>';

        $email_markup = '<span id="input_'.$field_id.'_'.$form_id.'.3_container" class="attendees_email">';
            $email_markup .= '<input type="text" name="input_'.$field_id.'.3" id="input_'.$field_id.'_'.$form_id.'_3" value="'.$email.'" aria-label="Email" '.$email_tabindex.' '.$disabled_text.' '.$required_attribute.' '.$invalid_attribute.'>';
            $email_markup .= '<label for="input_'.$field_id.'_'.$form_id.'_3">Email</label>';
        $email_markup .= '</span>';

        $phone_markup = '<span id="input_'.$field_id.'_'.$form_id.'.4_container" class="attendees_phone">';
            $phone_markup .= '<input type="text" name="input_'.$field_id.'.4" id="input_'.$field_id.'_'.$form_id.'_4" value="'.$phone.'" aria-label="Phone #" '.$phone_tabindex.' '.$disabled_text.' '.$required_attribute.' '.$invalid_attribute.'>';
            $phone_markup .= '<label for="input_'.$field_id.'_'.$form_id.'_4">Phone #</label>';
        $phone_markup .= '</span>';

        $css_class = $this->get_css_class();

        return "<div class='ginput_complex{$class_suffix} ginput_container {$css_class} gfield_trigger_change' id='{$field_id}'>
                    {$first_markup}
                    {$last_markup}
                    {$email_markup}
                    {$phone_markup}
                    <div class='gf_clear gf_clear_complex'></div>
                </div>";
    }

    public function get_css_class() {
        $first_input = GFFormsModel::get_input( $this, $this->id . '_2' );
        $last_input  = GFFormsModel::get_input( $this, $this->id . '_3' );
        $email_input = GFFormsModel::get_input( $this, $this->id . '_4' );
        $phone_input   = GFFormsModel::get_input( $this, $this->id . '_5' );

        $css_class = '';
        $visible_input_count = 0;

        if ( $first_input && ! rgar( $first_input, 'isHidden' ) ) {
            $visible_input_count++;
            $css_class .= 'has_first_name ';
        } else {
            $css_class .= 'no_first_name ';
        }

        if ( $last_input && ! rgar( $last_input, 'isHidden' ) ) {
            $visible_input_count++;
            $css_class .= 'has_last_name ';
        } else {
            $css_class .= 'no_last_name ';
        }

        if ( $email_input && ! rgar( $email_input, 'isHidden' ) ) {
            $visible_input_count++;
            $css_class .= 'has_email ';
        } else {
            $css_class .= 'no_email ';
        }

        if ( $phone_input && ! rgar( $phone_input, 'isHidden' ) ) {
            $visible_input_count++;
            $css_class .= 'has_phone ';
        } else {
            $css_class .= 'no_phone ';
        }

        $css_class .= "gf_attendees_has_{$visible_input_count} ginput_container_attendees ";

        return trim( $css_class );
    }

    public function get_value_submission( $field_values, $get_from_post ) {
        if(!$get_from_post) {
            return $field_values;
        }

        return $_POST;
    }
}

GF_Fields::register( new GF_Field_Attendees() );

저는 이것을 작동시키기 위해 다양한 수정을 시도하고 인터넷을 검색하는 데 약 20시간을 소비했지만, 그것을 보여주는 행운은 없었습니다.한때 다른 방법(아래 참조)을 사용하여 양식 필드를 저장할 수 있었지만 필드를 필수로 만들거나 조건부 로그인을 사용할 수는 없었습니다.

$group_title = "Attendees";
$group_name = "attendees";
$group_fields = array(
    'attendee_first' => 'First Name',
    'attendee_last' => 'Last Name',
    'attendee_email' => 'Email',
    'attendee_phone' => 'Phone'
);
$group_values = array();

add_filter('gform_add_field_buttons', add_field);
function add_field($field_group)
{
  global $group_title, $group_name;

  foreach ($field_group as &$group) {

    if ($group['name'] == 'advanced_fields') {
      $group['fields'][] = array (
        'class'     => 'button',
        'value'     => __($group_title, 'gravityforms'),
        'onclick'   => "StartAddField('".$group_name."');",
        'data-type' => $group_name
      );
      break;
    }
  }

  return $field_group;
}

add_filter('gform_field_type_title', add_field_title, 10, 2);
function add_field_title($title, $field_type)
{
  global $group_title, $group_name;

  if ($field_type == $group_name) {
    $title = __($group_title, 'gravityforms');
  }

  return $title;
}

add_filter('gform_field_input', 'render_fields', 10, 5);
function render_fields($input, $field, $value, $entry_id, $form_id)
{
  global $group_name, $group_fields;

  if ($field->type == $group_name)
  {
    $i = 1;
    $input = '<div class="ginput_complex ginput_container">';
    foreach ($group_fields as $key => $val) {
        $input .= '<span id="input_'.$field['id'].'_'.$form_id.'_'.$i.'_container" class="name_suffix ">';
            $input .= '<input type="text" name="input_'.$field['id'].'_'.$i.'" id="input_'.$field['id'].'_'.$form_id.'_'.$i.'" value="'.$value[$field['id'].'.'.$i].'" class="'.esc_attr($key).'" aria-label="'.$val.'">';
            $input .= '<label for="input_'.$field['id'].'_'.$form_id.'_'.$i.'">'.$val.'</label>';
        $input .= '</span>';
        $i ++;
        if ($i % 10 == 0) { $i++; }
    }
    $input .= '</div>';
  }

  return $input;
}

add_action('gform_editor_js_set_default_values', set_default_values);
function set_default_values()
{
  global $group_title, $group_name, $group_fields;
  ?>
  case '<?php echo $group_name; ?>' :
    field.label = '<?php _e($group_title, 'gravityforms'); ?>';
    field.inputs = [
        <?php
        $i = 1;
        foreach ($group_fields as $key => $val) { ?>
            new Input(field.id + 0.<?php echo $i; ?>, '<?php echo esc_js(__($val, 'gravityforms')); ?>'),
        <?php
            $i++;
            if ($i % 10 == 0) { $i++; }
        } ?>
    ];
    break;
  <?php
}

add_filter( 'gform_entry_field_value', 'category_names', 10, 4 );
function category_names( $value, $field, $lead, $form )
{
  global $group_name, $group_values;

  if($field->type == $group_name)
  {
    $array = array();
    $output = "";
    foreach($field->inputs as $input)
    {
      $array[$input['label']] = $value[$input['id']];

      $output .= "<strong>".$input['label'].":</strong> ";
      $output .= $value[$input['id']]."<br>";
    }
    $group_values[] = $array;

    return $output;
  }

  return $value;
}

어느 문제든 도와줄 수 있는 사람이 있다면 대단히 감사하겠습니다.

클래스 업데이트:

  • 정리됨get_field_input

  • 추가된get_value_submission

며칠 동안 Gravity Forms 지원팀과 함께 작업한 끝에 이 해결책을 생각해 낼 수 있었습니다.이제 모든 것이 잘 되는 것 같습니다.이것이 미래에 누군가에게 도움이 되길 바랍니다.

class GF_Field_Attendees extends GF_Field {

    public $type = 'attendees';

    public function get_form_editor_field_title() {
        return esc_attr__( 'Attendees', 'gravityforms' );
    }

    public function get_form_editor_button() {
        return array(
            'group' => 'advanced_fields',
            'text'  => $this->get_form_editor_field_title(),
        );
    }

    public function get_form_editor_field_settings() {
        return array(
            'conditional_logic_field_setting',
            'prepopulate_field_setting',
            'error_message_setting',
            'label_setting',
            'admin_label_setting',
            'rules_setting',
            'duplicate_setting',
            'description_setting',
            'css_class_setting',
        );
    }

    public function is_conditional_logic_supported() {
        return true;
    }

    public function get_field_input( $form, $value = '', $entry = null ) {
        $is_entry_detail = $this->is_entry_detail();
        $is_form_editor  = $this->is_form_editor();

        $form_id  = $form['id'];
        $field_id = intval( $this->id );

        $first = $last = $email = $phone = '';

        if ( is_array( $value ) ) {
            $first = esc_attr( rgget( $this->id . '.1', $value ) );
            $last  = esc_attr( rgget( $this->id . '.2', $value ) );
            $email = esc_attr( rgget( $this->id . '.3', $value ) );
            $phone = esc_attr( rgget( $this->id . '.4', $value ) );
        }

        $disabled_text = $is_form_editor ? "disabled='disabled'" : '';
        $class_suffix  = $is_entry_detail ? '_admin' : '';

        $first_tabindex = GFCommon::get_tabindex();
        $last_tabindex  = GFCommon::get_tabindex();
        $email_tabindex = GFCommon::get_tabindex();
        $phone_tabindex = GFCommon::get_tabindex();

        $required_attribute = $this->isRequired ? 'aria-required="true"' : '';
        $invalid_attribute  = $this->failed_validation ? 'aria-invalid="true"' : 'aria-invalid="false"';

        $first_markup = '<span id="input_' . $field_id . '_' . $form_id . '.1_container" class="attendees_first">';
        $first_markup .= '<input type="text" name="input_' . $field_id . '.1" id="input_' . $field_id . '_' . $form_id . '_1" value="' . $first . '" aria-label="First Name" ' . $first_tabindex . ' ' . $disabled_text . ' ' . $required_attribute . ' ' . $invalid_attribute . '>';
        $first_markup .= '<label for="input_' . $field_id . '_' . $form_id . '_1">First Name</label>';
        $first_markup .= '</span>';

        $last_markup = '<span id="input_' . $field_id . '_' . $form_id . '.2_container" class="attendees_last">';
        $last_markup .= '<input type="text" name="input_' . $field_id . '.2" id="input_' . $field_id . '_' . $form_id . '_2" value="' . $last . '" aria-label="Last Name" ' . $last_tabindex . ' ' . $disabled_text . ' ' . $required_attribute . ' ' . $invalid_attribute . '>';
        $last_markup .= '<label for="input_' . $field_id . '_' . $form_id . '_2">Last Name</label>';
        $last_markup .= '</span>';

        $email_markup = '<span id="input_' . $field_id . '_' . $form_id . '.3_container" class="attendees_email">';
        $email_markup .= '<input type="text" name="input_' . $field_id . '.3" id="input_' . $field_id . '_' . $form_id . '_3" value="' . $email . '" aria-label="Email" ' . $email_tabindex . ' ' . $disabled_text . ' ' . $required_attribute . ' ' . $invalid_attribute . '>';
        $email_markup .= '<label for="input_' . $field_id . '_' . $form_id . '_3">Email</label>';
        $email_markup .= '</span>';

        $phone_markup = '<span id="input_' . $field_id . '_' . $form_id . '.4_container" class="attendees_phone">';
        $phone_markup .= '<input type="text" name="input_' . $field_id . '.4" id="input_' . $field_id . '_' . $form_id . '_4" value="' . $phone . '" aria-label="Phone #" ' . $phone_tabindex . ' ' . $disabled_text . ' ' . $required_attribute . ' ' . $invalid_attribute . '>';
        $phone_markup .= '<label for="input_' . $field_id . '_' . $form_id . '_4">Phone #</label>';
        $phone_markup .= '</span>';

        $css_class = $this->get_css_class();

        return "<div class='ginput_complex{$class_suffix} ginput_container {$css_class} gfield_trigger_change' id='{$field_id}'>
                    {$first_markup}
                    {$last_markup}
                    {$email_markup}
                    {$phone_markup}
                    <div class='gf_clear gf_clear_complex'></div>
                </div>";
    }

    public function get_css_class() {
        $first_input = GFFormsModel::get_input( $this, $this->id . '.1' );
        $last_input  = GFFormsModel::get_input( $this, $this->id . '.2' );
        $email_input = GFFormsModel::get_input( $this, $this->id . '.3' );
        $phone_input = GFFormsModel::get_input( $this, $this->id . '.4' );

        $css_class           = '';
        $visible_input_count = 0;

        if ( $first_input && ! rgar( $first_input, 'isHidden' ) ) {
            $visible_input_count ++;
            $css_class .= 'has_first_name ';
        } else {
            $css_class .= 'no_first_name ';
        }

        if ( $last_input && ! rgar( $last_input, 'isHidden' ) ) {
            $visible_input_count ++;
            $css_class .= 'has_last_name ';
        } else {
            $css_class .= 'no_last_name ';
        }

        if ( $email_input && ! rgar( $email_input, 'isHidden' ) ) {
            $visible_input_count ++;
            $css_class .= 'has_email ';
        } else {
            $css_class .= 'no_email ';
        }

        if ( $phone_input && ! rgar( $phone_input, 'isHidden' ) ) {
            $visible_input_count ++;
            $css_class .= 'has_phone ';
        } else {
            $css_class .= 'no_phone ';
        }

        $css_class .= "gf_attendees_has_{$visible_input_count} ginput_container_attendees ";

        return trim( $css_class );
    }

    public function get_form_editor_inline_script_on_page_render() {

        // set the default field label for the field
        $script = sprintf( "function SetDefaultValues_%s(field) {
        field.label = '%s';
        field.inputs = [new Input(field.id + '.1', '%s'), new Input(field.id + '.2', '%s'), new Input(field.id + '.3', '%s'), new Input(field.id + '.4', '%s')];
        }", $this->type, $this->get_form_editor_field_title(), 'First Name', 'Last Name', 'Email', 'Phone' ) . PHP_EOL;

        return $script;
    }

    public function get_value_entry_detail( $value, $currency = '', $use_text = false, $format = 'html', $media = 'screen' ) {
        if ( is_array( $value ) ) {
            $first = trim( rgget( $this->id . '.1', $value ) );
            $last  = trim( rgget( $this->id . '.2', $value ) );
            $email = trim( rgget( $this->id . '.3', $value ) );
            $phone = trim( rgget( $this->id . '.4', $value ) );

            $return = $first;
            $return .= ! empty( $return ) && ! empty( $last ) ? " $last" : $last;
            $return .= ! empty( $return ) && ! empty( $email ) ? " $email" : $email;
            $return .= ! empty( $return ) && ! empty( $phone ) ? " $phone" : $phone;

        } else {
            $return = '';
        }

        if ( $format === 'html' ) {
            $return = esc_html( $return );
        }

        return $return;
    }

}

GF_Fields::register( new GF_Field_Attendees() );

저는 그 가치를 얻는 데 어려움을 겪고 있습니다.rgget현장에서 사용할 수 있도록 하기 위해 다음과 같이 변경해야 했습니다.

rgget( 'input_' . $this->id . '_1', $value )

언급URL : https://stackoverflow.com/questions/43009398/custom-gravity-forms-field-with-multiple-inputs