Dear backdrop community,

I'm thrilled to build my first backdrop site (coming from D7). I would like to create some fields (used in nodes types and/or taxonomies) with dynamic default values and/or dynamic lists of allowed values.

Default values

  • The default value should inherit its value from a parent, so if I change the value of that parent, the value of the field will also change (only if it is set to default, of course).
  • I want to be able to choose which parent to use as default per node/term, based on another field.

I would prefer not to use rules to change all occurances of a default value when I change the parent value.

Dynamic lists of allowed values

  • Like above: The list should change depending on another field that references the parent.

I'm more of the site-builder type, so if coding will be involved I might need a little help in how that would have to look like. :)

 

Comments

Is this what you were hoping that conditional fields would solve?

klonos's picture

Hello  and congrats on starting your first Backdrop site 👏

I did a bit of research. I've found some related D7 modules like https://www.drupal.org/project/ddf but not any that would do exactly what you are after. Are you aware of any existing module that does that? ...perhaps we could port it to Backdrop then.

To be frank, what you are trying to achieve sounds quite complex. If no existing module, then I'm afraid that you'd have to go with a custom solution.

Here's what I found on the web that you may find helpful:

If you find any functionality missing in Backdrop that exists in Drupal 7 or 8 that would help you achieve what you are after, then please report it. It may be considered for either core or contrib.

Hi @klonos, thanks for the nice welcome!

And thanks for taking the time to look into that. DDF looks like it could solve the second part of what looking for, the dynamic list of allowed values. But that part is more like a convenience feature I could live without (at least for now).
The first part (inheritance of default values) is what I really need. It seems D8 has that now built-in.

I also did some research and these are the Drupal modules I found:

  • Field Inheritance (D8) has all I want, but is very new, so it's probably based on the new D8 capabilities which you have linked above.
  • Field Inherit (D7) lacks views support. I don't know how hard it is to add that.
  • Content Type Inheritance (D6) works with views, but, well D6.

Maybe my original idea was too much focused on the word default, when what I am looking for is in fact inheritance of a field's value from a referenced entity (node or term) in a parent-child-like fashion.

Someone else has asked that question Entity field value inherited from another entity programmatically? without getting an answer.

I looked into the node clone module, but it lacks the dynamic component as it just copies the values to a new node.

I have no idea if the field system is flexible enough to extend the field settings by a reference that (if populated) says "If this field is set to default use the actual value of the corresponding field in the referenced entity instead".

Maybe computed field can help me by only copying the value of a referenced entity as long as the local value is set to default?

Hi @klonos, thanks for the nice welcome!

And thanks for taking the time to look into that. DDF looks like it could solve the second part of what I'm looking for, the dynamic list of allowed values. But that part is more like a convenience feature I could live without.

The first part (inheritance of default values) is what's really important to me. It seems D8 has that now built-in.

I also did some research and these are the Drupal modules I found:

  • Field Inheritance (D8) has all I want, but is very new, so it's probably based on the new D8 capabilities which you have linked above.
  • Field Inherit (D7) lacks views support. I don't know how hard it is to add that.
  • Content Type Inheritance (D6) works with views, but, well D6.

Maybe my original idea was too much focused on the word default, when what I am looking for is in fact inheritance of a field's value from a referenced entity (node or term) in a parent-child-like fashion.

Someone else has asked that question Entity field value inherited from another entity programmatically? without getting an answer.

I looked into the node clone module, but it lacks the dynamic component as it just copies the values to the new node.

I have no idea if the field system is flexible enough to extend the field settings by a reference that (if populated) says "If this field is set to default use the actual value of the corresponding field in the referenced entity instead".

Maybe computed field can help me by only copying the value of a referenced entity as long as the local value is set to default?

OK, finally I could start working on this. I had an idea how to achieve the selective inheritance by using some modules and hopefully only little code:

The modules: Entity reference, Multifield, Computed field

That's what I did:

  • I created a node type question.
  • I added one entity reference field field_myparentthat may point to a node of the same type to inherite values from.
  • For every field that may inherit its value from the parent node I created a multifield with three subfields:
    1. A boolean field field_use_default
    2. The field for the user to enter some value, for instance field_question_text
    3. A computed field actual_value(currently set to recalculate the field value every time, but not to store value in the database).
  • To avoid php code in the database I used the corresponding functions (I thought it would be straight forward, but I had a hard time learning how to fetch all the needed data):
    function computed_field_field_actual_value_compute(&$entity_field, $entity_type, $entity, $field, $instance, $langcode, $items) {
      $multifield_wrapper = entity_metadata_wrapper('multifield', $entity);
      $use_default = $multifield_wrapper->field_use_default->value();
      if ($use_default) {
        // A computed field inside a multifield doesn't seem to know about the node it lives in
        $node = menu_get_object();
        $node_wrapper = entity_metadata_wrapper('node', $node);
        if (isset($node_wrapper->field_myparent)) {
          $parent_node = $node_wrapper->field_myparent->value();
          $entity_field[0]['value'] = $parent_multifield[0]['field_question_text'][und][0][value];
        } else {
          $entity_field[0]['value'] = '';
        }
      } else {
        $entity_field[0]['value'] = $multifield_wrapper->field_question_text->value();
      }
      dpm($$entity_field[0]['value']);
    }
    
    function computed_field_field_actual_value_display($field, $entity_field_item, $entity_lang, $langcode, $entity) {
      return $entity_field_item['value'];
    }
    

When I display a node it works as intended.

But when I try to save it I get

  • Error
    Unknown data property field_use_default

I found out (by seeing my dpm()output twice) that in this case computed_field_field_actual_value_compute()is called multiple times, and in one of them it seems to happen in a place where it doesn't have access to the multifield. Did I hit a bug?

Other than that I need to solve some questions:

  • Generalize the code that it would work with
    • Multiple multifields per note type: I need to identify the corresponding $parent_multifield.
    • Nested inheritance: That would need a recursive function to fetch the value of the topmost $parent_node that doesn't have the corresponding $use_default set. Is that feasable?
  • Style the display of actual_value depending on field_use_default: Haven't looked into that yet.
  • Of course the performance: Recalculation should only happen when the node or its parent changes. That's for later.