Create Dynamic Field

Change the folloing two lines:

      if(xx_extra_field.value == No) {

to:

      if(xx_extra_field.value == 'No') {

(put the single quotes around No)

and

      if(xx_extra_field.value == Yes) {

to:

      if(xx_extra_field.value == 'Yes') {

(put the single quotes around Yes)

PS: Something strange must have happened because in my working example the single quotes are there!
This typo should have been reproted in the browser Console though.

1 Like

This is now working! Thank you very much for all your help.

:wink:

I have a follow up question. Would it be possible for the defect number text field if a certain customer is selected instead of a yes/no dropdown? If so how would I go about this.

Thanks.

Everything is possible!

But I need more precise information!

Additionnally I need to explain something on the code I sent you:
Currently when “No” is selected in the dropdown the defect:number is hidden and its value is deleted.

If you don’t want to delete the value, you have to delete the following two lines:

        var xx_extra_field_sub = document.getElementById('defect_number_c');
        xx_extra_field_sub.value = '';

Hi

Thank you for letting me know about the code however if I can get the defect number text field to appear for specific customers I will probably go down that road.

I have created 2 test customers “Test Customer 1” & “Test Customer 2” I would like the defect number text field to be always hidden until either one of the test customers are selected under the Customers field. If possible I would also like the defect number text field to be mandatory when it pops up.

The field name for the customers field I have is “aos_invoices_accounts_1_name” & the field name for the defect number text field is “defect_number_c”

Is there anything else that I have missed that you require?

Thanks.

Where are you storing the list of customers that will trigger the field?

The code itself is simple.

Solution 1:
You may want to create a target list where you select the customers that you want to trigger the event and base the code on this selection.

Solution 2:
Alternatively you could create a custom module where you select the customers and then base the field on customers that have been selected. The code shouldn’t be so complicated.

Solution 3:
A third and simpler way could be that you manually enter the name of the customers in config_override.php.

Among the potential issues that I see: what if someone edits the name of the customer but the list has not been updated?

I am now working on the last (easiest) solution to show it working (without the compulsory part at the moment. We’ll see that later).

Hi

I have stored the customers under what I believe used to be called accounts. I will wait for the 4th solution and probably go for the 4th and easiest solution to get this up and running.

Here is a working solution:

  1. Edit config_override.php
    Add the following line at the end of the file (before the php closing tag (’?>’) if present:
$sugar_config['dflh_triggers'] = array();
$sugar_config['dflh_triggers'][] = 'Test Customer 1';
$sugar_config['dflh_triggers'][] = 'Test Customer 2';

Please note that, for each account that should trigger the field to be shown, there should be a line:

$sugar_config['dflh_triggers'][] = 'name of account exactly as saved in CRM';
  1. Change the previous working code of view.edit.php to:
<?php
class AOS_InvoicesViewEdit extends ViewEdit
{
  function __construct(){
    parent::ViewEdit();
  }
     public function display(){
        parent::display();
?>

<script type="text/javascript">
  var xx_triggers = <?php echo json_encode($GLOBALS['sugar_config']['dflh_triggers']); ?>;
</script>

<?php
          $javascript = <<<'EOT'
<script type="text/javascript">
  window.onload=function(){
function dflh_isInArray(value, array) {
  return array.indexOf(value) > -1;
}
    function toggle_extra_field(passedValue) {
      alert(' value is: ' + passedValue);
      if(dflh_isInArray(passedValue, xx_triggers) == true) {
        document.querySelector('div[data-label="LBL_DEFECT_NUMBER"]').style.display='';
        document.querySelector('div[field="defect_number_c"]').style.display='';
        document.getElementById('dflh_extra_field_c').value = passedValue;
      }
      if(dflh_isInArray(passedValue, xx_triggers) == false) {
        document.querySelector('div[data-label="LBL_DEFECT_NUMBER"]').style.display='none';
        document.querySelector('div[field="defect_number_c"]').style.display='none';
      }
    }
var xx_extra_field = document.getElementById('billing_account');
var lastxx_extra_fieldValue = xx_extra_field.value;
setInterval(function() {
    var newValue = xx_extra_field.value;
    if (lastxx_extra_fieldValue != newValue) {
        lastxx_extra_fieldValue = newValue;
        toggle_extra_field(newValue);
    }
}, 50); // 20 times/second
    toggle_extra_field(lastxx_extra_fieldValue);
  }
</script>
EOT;
      echo $javascript;
      exit;
     }
}
?>

Please test and let me know if it works. (I have edited it directly in the forum form so I may have introduced a typo).

Caveats:
With this solution you have to update manually the list of accounts that trigger the appearance of the field.

In order to have this updated dynamically we need to implement one of the other solutions (just some extra php code)

1 Like

Thank you for this. I have tested this however it did not work when I tried to create a new invoice I got the error below. Once I clicked OK i was able to continue to create a new invoice however the defect text field did not appear when either test customer was selected.

Sorry.

It’s not an error. I have deliberately added that to test.

You should delete the following two lines:

      alert(' value is: ' + passedValue);

and:

        document.getElementById('dflh_extra_field_c').value = passedValue;

Ah ok, I have removed the two lines and it is still not working

Please be more precise.
What happens?
Are there any errors in the php log or in the browser console?

Have you added the lines in config_override.php? (this file is in the root folder of SuiteCRM): can you post an image of what you pasted?

Are the names of the two accounts the same as I have put in confg_override.php?

Could you paste a screenshot of where you get the value of the account in the form?

Here the solution works perfectly.

Nothing happens when either test customer is selected. I do not get any errors on the browser and I have checked the php logs and nothing is displayed in their either.
I did add add the lines in the config override file please see below a snip of the config override file.
Yes the names of the test customers are exactly how you write it in the code provided.

As for the value of the account in the form are you referring to the HTML code for the customers field?

I have managed to resolve this. My customers field was not called billing_account it is called aos_invoices_accounts_1_name so i changed

var xx_extra_field = document.getElementById(‘billing_account’);

to

var xx_extra_field = document.getElementById(‘aos_invoices_accounts_1_name’);

Once this was done it worked great thank you for your help again. If I needed to add any additional code to the view.edit php how would I go about that can i just add new code below the exsisting code or will i need a line breaker?

It really depends on what you want to achieve.

For this we could have used one of many options.
Initially I suggested a custom logic hook but I solved it with a custom view.edit.php file.

There are still a few more options available. To be honest I started in a different way (injecting the javascript in xx/metadata/editviewdefs.php) but then I preferred this other solution.

I think that you still have to solve the issue regarding the source of the “trigger accounts” (we have used “Test Company 1”/2 adding them manually in config_override.php). The adopted solution is fine if you don’t mind adding them there by hand and the list doesn’t get modified too often. Otherwise you need to get that list dynamically.

The other pending point is to make the field compulsory when present.
This could be achieved by adding some extra javascript to call removeFromValidate(formname, name) or addToValidate(formname, name, type, required, msg), depending on whether the field is removed or added (I have never tried these functions so you may have to try or use some other javascript solution)

I have gone ahead and manually entered all the customers that I want the defect number field to appear for as this list will not change now so I don’t mind leaving it how it is. As for the mandatory field I am going to let users see how they get on with the field not being mandatory for the time being and if it is consistently getting missed then I will look into making it mandatory.

Again thank you for all your help on this you have been more than helpful I wouldn’t of been able to achieve this without you.

Just for completion.

I have added the feature so that it is compulsory only when displayed.

The code now is:

<?php
class AOS_InvoicesViewEdit extends ViewEdit
{
  function __construct(){
    parent::ViewEdit();
  }
     public function display(){
        parent::display();
?>

<script type="text/javascript">
  var xx_triggers = <?php echo json_encode($GLOBALS['sugar_config']['dflh_triggers']); ?>;
</script>

<?php
          $javascript = <<<'EOT'
<script type="text/javascript">
  window.onload=function(){
function dflh_isInArray(value, array) {
  return array.indexOf(value) > -1;
}
    function toggle_extra_field(passedValue) {
      if(dflh_isInArray(passedValue, xx_triggers) == true) {
        document.querySelector('div[data-label="LBL_DEFECT_NUMBER"]').style.display='';
        document.querySelector('div[field="defect_number_c"]').style.display='';
        addToValidate('EditView', 'defect_number_c', 'varchar', true, 'Please fill compulsory fields')
      }
      if(dflh_isInArray(passedValue, xx_triggers) == false) {
        document.querySelector('div[data-label="LBL_DEFECT_NUMBER"]').style.display='none';
        document.querySelector('div[field="defect_number_c"]').style.display='none';
        removeFromValidate('EditView', 'defect_number_c');
      }
    }
removeFromValidate('EditView', 'defect_number_c');
var xx_extra_field = document.getElementById('aos_invoices_accounts_1_name');
var lastxx_extra_fieldValue = xx_extra_field.value;
setInterval(function() {
    var newValue = xx_extra_field.value;
    if (lastxx_extra_fieldValue != newValue) {
        lastxx_extra_fieldValue = newValue;
        toggle_extra_field(newValue);
    }
}, 50); // 20 times/second
    toggle_extra_field(lastxx_extra_fieldValue);
  }
</script>
EOT;
      echo $javascript;
      exit;
     }
}
?>

For you to understand the changes I did:

  1. Added:
        addToValidate('EditView', 'defect_number_c', 'varchar', true, 'Please fill compulsory fields')

in the section that displays the field

  1. Added:
        removeFromValidate('EditView', 'defect_number_c');

in two places:
a. in the section that hides the field
b. immediately after the definition of our function. This is necessary to initialise the feature because, by default the validation is added by SuiteCRM.

Note: since my working example uses different variable names and, although I tried to put the correct field names, I may have not donit correctly so, if this code doesn’t work you can just implement the changes above.

1 Like

Thanks I will let users use the new features tomorrow and if it needs changing i will use the code provided it will probably need changing to a mandatory field! I will let you know how i get on on monday when i am back in the office.