Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conditional Logic for Custom Fields #3779

Closed
dyerry79 opened this issue Nov 16, 2024 · 6 comments
Closed

Conditional Logic for Custom Fields #3779

dyerry79 opened this issue Nov 16, 2024 · 6 comments
Labels
support request Need assistance with MRBS

Comments

@dyerry79
Copy link

dyerry79 commented Nov 16, 2024

Hi, I added three custom fields (req_chair, req_table, req_internet), following my previous javascript pattern, I managed to hide and display the added custom fields. Here's what I did:

  1. In the edit_entry.php, I added a function patterned with the repeat function to generate two radio buttons (yes/no)

image

Upon loading the input boxes and the checkbox are hidden.

The issue is the gap between the textarea and the radio button

  1. The hide/display functions of the radio is working well.

    • If the user clicks yes, it will display the input boxes and the checkbox as shown in the screenshot:

    image

    Would it be possible that the two input boxes and the checkbox below the radio buttons or beside the radio buttons?

Here's what I got so far:
Radio buttons

function get_field_logistics_toggle() : FieldDiv
{
    // Create the main field container
    $field = new FieldDiv();
    $field->setAttributes(array(
        'id' => 'rep_type',
        'class' => 'multiline' // Add your desired classes
    ))
    ->setLabel('Requirements');

    // Define radio options for "Need Logistics?" (Yes/No)
    $options = array(
        'no' => 'No',
        'yes' => 'Yes'
    );

    // Create the radio group
    $radio_group = new ElementDiv();
    $radio_group->setAttribute('class', 'group long')
                ->addRadioOptions($options, 'logistics', 'no', true); // Default to "No"
    $field->addControlElement($radio_group);

    return $field;
}
  1. in the get_field_custom function, I called the get_field_logistics_toggle function here
  if ($key == 'terms_and_conditions')
  {
        $fieldset = new ElementFieldset();
        $fieldset->setAttribute('id', 'custom_fields');

        // Add the logistics toggle
        $fieldset->addElement(get_field_logistics_toggle());
		
    if (is_book_admin())
    {
      $field = new ElementInputHidden(VAR_PREFIX . $key, '1');  // Auto-checked for admins
    }
    else
    {
      $div = new ElementDiv();
      $a = new ElementA();
	  $a->setAttribute('href', '#');
	  $a->setAttribute('onclick', 'openModal(); return false;');
	  $a->setText("Terms and Conditions");
	  
      $span = new ElementSpan();
      $span->setText("I agree to the ", true);
      $span->addElement($a);

      $control = $field->getControl();
      $field->removeControl();

      $div->addElement($control)->addElement($span);
      $field->addElement($div);
    }

        $fieldset->addElement($field);
        return $fieldset;
  }  
  /*------------end terms and conditions ------------*/
  return $field;
  1. and the javascript
document.addEventListener('DOMContentLoaded', function() {
    // References to the radio buttons
    const logisticsRadios = document.getElementsByName('logistics');
    // References to the input fields and their labels
    const chairInput = document.getElementById('f_req_chair');
    const tableInput = document.getElementById('f_req_table');
    const internetCheckbox = document.getElementById('f_req_internet');
    const chairLabel = document.querySelector('label[for="f_req_chair"]');
    const tableLabel = document.querySelector('label[for="f_req_table"]');
    const internetLabel = document.querySelector('label[for="f_req_internet"]');

    // Function to toggle visibility
    function toggleLogisticsFields(show) {
        const displayValue = show ? '' : 'none'; // '' restores the default display style
        chairInput.style.display = displayValue;
        tableInput.style.display = displayValue;
        internetCheckbox.style.display = displayValue;
        chairLabel.style.display = displayValue;
        tableLabel.style.display = displayValue;
        internetLabel.style.display = displayValue;
    }

    // Add event listeners to the radio buttons
    logisticsRadios.forEach(radio => {
        radio.addEventListener('change', function() {
            if (this.value === 'yes') {
                toggleLogisticsFields(true); // Show the fields
            } else {
                toggleLogisticsFields(false); // Hide the fields
            }
        });
    });

    // Initialize the state to "No" (hidden by default)
    toggleLogisticsFields(false);
});

TIA for your usual help.

@dyerry79 dyerry79 added the support request Need assistance with MRBS label Nov 16, 2024
@dyerry79 dyerry79 changed the title Anohter Conditional Logic for Custom Fields Conditional Logic for Custom Fields Nov 17, 2024
@campbell-m
Copy link
Contributor

You could simplify the code in get_field_logistics_toggle() by using the class FieldInputRadioGroup. I think this would also arrange your options horizontally rather than vertically.

You could also simplify your JavaScript by using jQuery. I know some people don't like using jQuery, but as the library is loaded anyway you might as well use it.

The issue is the gap between the textarea and the radio button

I don't know what's causing this. You'll need to see what's happening by looking at the CSS and layout using your browser's developer tools.

Would it be possible that the two input boxes and the checkbox below the radio buttons or beside the radio buttons?

You can change the field order by using the config setting $edit_entry_field_order.

@dyerry79
Copy link
Author

Hi Campbell, I managed to have it his way for admin

image

However, the display is different for non-admin users

.image
As you can see, there's a huge gap between the logistics and radio buttons.

I'm pretty sure it's the placement of the terms and conditions checkbox has something to with it. Here's how I did it

  if ($key == 'terms_and_conditions')
  {

	$fieldset = new ElementFieldset();
	$fieldset->setAttribute('id', 'rep_info');
	// Add the logistics toggle
	$fieldset->addElement(get_field_logistics_toggle());
		
    if (is_book_admin())
    {
      $field = new ElementInputHidden(VAR_PREFIX . $key, '1');  // Auto-checked for admins
    }
    else
    {
      $div = new ElementDiv();
      $a = new ElementA();
	  $a->setAttribute('href', '#');
	  $a->setAttribute('onclick', 'openModal(); return false;');
	  $a->setText("Terms and Conditions");
	  
      $span = new ElementSpan();
      $span->setText("I agree to the ", true);
      $span->addElement($a);

      $control = $field->getControl();
      $field->removeControl();

      $div->addElement($control)->addElement($span);
      $field->addElement($div);
    }
       
      $fieldset->addElement($field);
      return $fieldset;
  }  
  /*------------end terms and conditions ------------*/
  return $field;

Any idea?

@campbell-m
Copy link
Contributor

I don't know how you've generated the three extra fields (Chair Qty etc.), but you'd be better off just letting them each be their own field, rather than part of another one. That way they'll appear in a vertical column and you won't have that big gap. It'll also work better on a narrow screen such as a smart phone.

@dyerry79
Copy link
Author

Thanks Campbell.

I've been trying to play around without overriding the original method MRBS was designed to deal with custom fields, but to no avail, I haven't made it work. I've managed to display the requirements (chairs, tables and internet) vertically by doing some revisions in the get_field_custom. I'll post the code and the screenshot for your reference.

code:
` $field = get_field_entry_input($params);

if ($key == 'req_type') {
	$fieldset = new ElementFieldset();
	$fieldset->setAttribute('id', 'requirements');

	// Add the logistics toggle using the provided function
	$fieldset->addElement(get_field_logistics_toggle());
	
	// Input for Number of Chairs
	$chairsDiv = new ElementDiv();
	$chairsDiv->setAttribute('id', 'chairsDiv'); // Set ID for JavaScript
	$chairsLabel = new ElementLabel();
	$chairsLabel->setText('Chairs'); // Updated label
	$chairsInput = new FieldInputNumber('num_chairs', '1'); // Default value is 1
	$chairsInput->setAttribute('min', '1'); // Minimum value is 1
	$chairsDiv->addElement($chairsLabel);
	$chairsDiv->addElement($chairsInput);
	$chairsDiv->setAttribute('style', 'display: none;'); // Initially hidden
	$fieldset->addElement($chairsDiv);

	// Input for Number of Tables
	$tablesDiv = new ElementDiv();
	$tablesDiv->setAttribute('id', 'tablesDiv'); // Set ID for JavaScript
	$tablesLabel = new ElementLabel();
	$tablesLabel->setText('Tables'); // Updated label
	$tablesInput = new FieldInputNumber('num_tables', '1'); // Default value is 1
	$tablesInput->setAttribute('min', '1'); // Minimum value is 1
	$tablesDiv->addElement($tablesLabel);
	$tablesDiv->addElement($tablesInput);
	$tablesDiv->setAttribute('style', 'display: none;'); // Initially hidden
	$fieldset->addElement($tablesDiv);

	// Checkbox for Internet Requirement
	$internetDiv = new ElementDiv();
	$internetDiv->setAttribute('id', 'internetDiv'); // Set ID for JavaScript
	$internetLabel = new ElementLabel();
	$internetLabel->setText('Internet'); // Updated label
	$internetCheckbox = new FieldInputCheckbox('internet', '1'); // Checkbox name and value
	$internetDiv->addElement($internetLabel); // Add the label before the checkbox
	$internetDiv->addElement($internetCheckbox); // Add the checkbox after the label
	$internetDiv->setAttribute('style', 'display: none;'); // Initially hidden
	$fieldset->addElement($internetDiv);

	return $fieldset;
}

if ($key == 'actual_start' or $key == 'actual_end' or $key == 'actual_status'){
	$field = new ElementInputHidden();
}

if ($key == 'contact_requirements') {
	$div = new ElementDiv();

	// Add the main control element (e.g., the textarea)
	$control = $field->getControl();
	$field->removeControl();
	$div->addElement($control);

	// Check if the user is NOT an admin
	if (!is_book_admin()) {
		$a = new ElementA();
		$a->setAttribute('href', '#');
		$a->setAttribute('onclick', 'openNModal(); return false;');
		$a->setText("Notation");

		$span = new ElementSpan();
		$span->addElement($a);

		// Add the span containing the "Notation" link after the textarea
		$div->addElement($span);
	}

	$field->addElement($div);
}
return $field;

}

$full_class = NAMESPACE . "\Form\$class";
$field = new $full_class();

$field->setLabel(get_loc_field_name(_tbl('entry'), $key))
->setControlAttributes(array('name' => VAR_PREFIX . $key,
'disabled' => $disabled,
'required' => !empty($is_mandatory_field["entry.$key"])));

if ($custom_field['nature'] == 'decimal')
{
list( , $decimal_places) = explode(',', $custom_field['length']);
$step = pow(10, -$decimal_places);
$step = number_format($step, $decimal_places);
$field->setControlAttribute('step', $step);
}

if ($class == 'FieldTextarea')
{
if (isset($custom_fields[$key]))
{
$field->setControlText($custom_fields[$key]);
}
if (null !== ($maxlength = maxlength("entry.$key")))
{
$field->setControlAttribute('maxlength', $maxlength);
}
}
elseif ($class == 'FieldInputCheckbox')
{
$field->setControlChecked(!empty($custom_fields[$key]));
}
else
{
$field->setControlAttribute('value', (isset($custom_fields[$key])) ? $custom_fields[$key] : null);
}

/------------implement terms and conditions ------------/
if ($key == 'req_chair' OR $key == 'req_table' OR $key == 'req_internet'){
$field = new ElementInputHidden();
}
if ($key == 'terms_and_conditions')
{
if (is_book_admin())
{
$field = new ElementInputHidden(VAR_PREFIX . $key, '1');
}
else
{
$div = new ElementDiv();
$a = new ElementA();
$a->setAttribute('href', '#');
$a->setAttribute('onclick', 'openModal(); return false;');
$a->setText("Terms and Conditions");

  $span = new ElementSpan();
  $span->setText("I agree to the ", true);
  $span->addElement($a);

  $control = $field->getControl();
  $field->removeControl();

  $div->addElement($control)->addElement($span);
  $field->addElement($div);
}

}
/------------end terms and conditions ------------/
return $field;`

screenshot
image

Issue: The location of the terms and conditions

You help is very much appreciated. TIA

@campbell-m
Copy link
Contributor

I don't know. You need to look at the HTML structure in your developer tools. It looks like the terms and conditions field is a level too low.

I still think there's no need for you to have any code for the chairs etc. MRBS should just do it all automatically.

@dyerry79
Copy link
Author

I still think there's no need for you to have any code for the chairs etc. MRBS should just do it all automatically.

Thanks for your patience Campbell. I got what I want now. I created the radio buttons within the get_field_custom function instead of creating them through a function (get_field_logistics_toggle()).

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
support request Need assistance with MRBS
Projects
None yet
Development

No branches or pull requests

2 participants