Can we have the ability to add a code snippet (php or jquery) to set the value of the dependent field when a certain condition is true with the dependee.

My use case is like this:
I have the following 4 fields on a form:
field_total_amount - e.g. 10000.00
field_full_duration - e.g. 24 (months)
field_frequency - a drop down list with options: monthly, quarterly, annually, fullterm
field_installment - should be calculated and set based on the values above.
If selected value of field_frequency is 'fullterm' the field_installment should be hidden and set to value of field_total_amount otherwise it should be visible (but not editable) and set to (total_amount)/(full_duration/frequency)

I think this module already has most of functionality to implement this feature.

Comments

chalee’s picture

Looks like the feature I'm requesting here is almost what the dependent_fields module solves, however the module doesn't have D7 version yet.

Anyone with ideas of other approaches I can use at the mean time.

peterpoe’s picture

Part of this functionality is already present, though undocumented (I have just committed a fix for a bug that prevented it, so if you want to try download the latest from git).

Here the steps to create a custom jQuery effect when editing fields:

1) Add a new "Effect" to the list supplied by conditional_fields_effects(), by altering the $effects variable:

function MYMODULE_conditional_fields_effects_alter(&$effects) {
  $effects['EFFECT_NAME'] = t('EFFECT DESCRIPTION');
}

2) Edit your dependency, select the new effect, and save. You might have to clear caches from the "Performance" page first to see the new option.

3) When editing the fields, conditional_fields.effect.js will now try to execute a function 'EFFECT_NAME', which you can define as any jQuery plugin. So create a new javascript file, include it either through a custom module or a theme, and fill it with the following:

(function ($) {
  {
    $.fn.EFFECT_NAME = function(e) {
      // You code here...
      // See conditional_fields.effect.js to see examples of how this is implemented with the 'fade' and 'slide' effects.
    };
  }
})(jQuery);

An example: I want the text "LOL!" to be appended before my dependent field any time the dependency is triggered.

1) Create a "lol" module, open lol.module and paste:


function lol_conditional_fields_effects_alter(&$effects) {
  $effects['lol'] = t('LOL!');
}

/**
 * Implements hook_js_alter().
 */
function lol_js_alter(&$javascript) {
  // Include lol.js when conditional_fields.effect.js is present.
  if (isset($javascript[drupal_get_path('module', 'conditional_fields') . '/js/conditional_fields.effect.js'])) {
    drupal_add_js(drupal_get_path('module', 'lol') . '/lol.js');
  }
}

3) Create a file lol.js and place it in the module folder. Paste:

(function ($) {

{
  $.fn.lol = function(e) {
    this.closest('.form-item, .form-submit, .form-wrapper')[e.value ? 'show' : 'hide']().before('LOL!');
  };
}

})(jQuery);

4) Activate the module, select "LOL!" as dependency effect, and voilà!

Please note that CF is still in development, so any of the above may change. I will post here any variation. Soon it will be possible to add behaviors when showing content as well, so you can for example render a dependent in a way when the dependency is triggered, and in another when it's triggered.

chalee’s picture

@peterpoe: Thanks for the reply. I will try this before end of week. Your instructions look quite straight forward, but I have to learn JQuery first. I suppose JQuery would allow me to pull data from the server (by calling a php function) to populate the dependent field's list options based on the dependee's value. FYI I had implemented this functionality using ajax following examples in 'example' module but would favor your approach if its simpler.

chalee’s picture

I implemented your code in #3 and it worked like charm. Now related to this, I wanted to implement a custom condition. In particular I want an 'Field Value Changed' condition which should happen when user changes selected option on a 'select list' field. I noticed there is a hook_conditional_fields_conditions_alter(&$conditions) which I have tried to use but my code doesn't seem to get executed though the new 'condition' is appearing on the CF admin page. Is it ever possible to monitor the onChange event of a field using this module.

Below is my JQuery code in my MODULE.js file:

(function ($) {

{
  $.fn.field_value_changed = Function(e) {
  	
  	return $(this).change (function() {
					   		alert('works!'); 
                                                        return TRUE;
						}
				);
  }
}

})(jQuery);

peterpoe’s picture

I haven't tested, but I think that to implement the new condition you just have to bind a new event to the document, like states.js does:

  $(document).bind('state:CONDITION_NAME', function(e) {
    // ...
  });

This if for example how the "visible" condition is implemented:

  $(document).bind('state:visible', function(e) {
    if (e.trigger) {
      $(e.target).closest('.form-item, .form-submit, .form-wrapper')[e.value ? 'show' : 'hide']();
    }
  });
peterpoe’s picture

I mixed up things, sorry. The example in #5 refers to states that can be applied to dependent fields when the dependency is triggered.
If you want to add new "monitoring" functions (called "conditions" in conditional fields), you will have to extend the states.Trigger.states object.

chalee’s picture

I thought so. It would be appreciated if you can give a skeleton code structure/example like you did in #3 above.

peterpoe’s picture

I was just doing so by adding two new useful conditions: focused/blurred and touched/untouched. Ended up with this code:

  focused: function(self) {
    // Attach the event callbacks.
    self.element.bind('focus', function () {
      self.element.trigger({ type: 'state:' + self.state, value: true });
    })
    .bind('blur', function () {
      self.element.trigger({ type: 'state:' + self.state, value: false });
    })
    // Initial state.
    .trigger({ type: 'state:' + self.state, value: self.element.is(':focus') });
  },

  touched: {
    'focus': function(e) {
      return (e === undefined && this.is(':not(:focus)')) ? false : true;
    }
  }

This was done by modifying the module. If you want to add new conditions in a contributed module:

1) Implement MYMODULE_conditional_fields_conditions_alter.
2) Add the following code to javascript when needed:

(function ($) {

// If default states events triggering handling is ok... (like empty, checked, etc...)
{
  Drupal.states.Trigger.states['MY_CONDITION'] = { EVENT_NAME: function(e) {
      // Stuff here...
  }};
} 

// If you need more control... (like focused)
{
  Drupal.states.Trigger.states['MY_CONDITION'] = function(self) {
      // Stuff here...
  };
} 

})(jQuery);

Be sure to use the latest Conditional Fields from git since I just committed a patch that contains the two new conditions and a fix to make "focused" work.

chalee’s picture

@peterpoe: Thanks for the code sample above. My use case doesn't seem quite satisfied by this. I implemented a custom condition 'changed' and custom effect 'set_field_value' as below.

In .module file:


function MODULE_NAME_conditional_fields_effects_alter(&$effects) {
  $effects['set_field_value'] = t('Set value of field');
}

function MODULE_NAME_conditional_fields_conditions_alter(&$conditions) {
  $conditions['changed'] = t('Changed');
}

In MODULE_NAME.js filed

Drupal.states.Trigger.states['changed'] = {
    'change': function(e) {
		//alert("Works! Change event encountered");
      	return true;
    }
  };
  
   

(function ($) {
{
 $.fn.set_field_value = function(e) {
   	if (e.value == true){
		$("#field-id-1").val('Some text');
	} else {
		 $("#field-id-1").val('');
	}
  };
}

}

)(jQuery);

I have noted that when I use the condition and effect above together, the effect code is not executed. but when I use the effect with another condition like 'value' the effect works. But the 'change' event seems to be working (code executed) as evidenced by the alert inside the function.

Below is my full use case.

In my form I have 3 form element as follows:
field_1 [ ] A dropdown select field with fixed 3 options (A, B, C)
field_2 [ ] A dropdown select field with a dynamically populated list
field_3 [ ] A simple textfield

Here is how I want to happen:
1. field_2 should only be visible when option 'B' is selected in field_1
2. When field_2 is visible field_3 should be invisible(hidden)
3. While field_3 is hidden, it should be automatically set with value of whatever is selected in field_2

In other words options A & B in field_1 requires that data be manually entered in field_3 while option B requires data to be selected on field_2 and copied to hidden field_3

peterpoe’s picture

I think the easiest solution to your case is just to implement a new state (NOT a new effect or condition) like outlined in #5:

PHP:


function MODULE_NAME_conditional_fields_states_alter(&$states) {
  $states['hide_and_fill_from_field_2'] = t('Hidden and filled with values from field_2');
}

/**
 * Implements hook_js_alter().
 */
function MODULE_NAME_js_alter(&$javascript) {
  drupal_add_js(drupal_get_path('module', 'MODULE_NAME') . '/MODULE_NAME.js');
}

MODULE_NAME.js:

(function ($) {

$(document).ready(function() {
  $(document).bind('state:hide_and_fill_from_field_2', function(e) {
    if (e.trigger) {
      if (e.value) {
        $(e.target).val($('#edit-field-2-und').val()).closest('.form-item, .form-submit, .form-wrapper').hide();        
      }
      else {
        $(e.target).closest('.form-item, .form-submit, .form-wrapper').show();
      }
    }
  });
});

})(jQuery);

(this js above is buggy and might not give exactly what you expect, but it's a start)

Setup the two dependencies. Descriptions should be something like:
1) field_2 is visible when field_1 has value "B".
2) field_3 is hidden and filled with values from field_2 when field_1 has value: "B".

chalee’s picture

Thank you for the code. It works as expected but in my use #9 above, field_3 does not just get the value of field_2 once. Every time a new select is made on field_2, that value must be copied to field_3. Which means we need to bind to the 'onchange' event of field_2. I'm trying but failing to implement a custom 'changed' condition which should be true when the value of field_2 is changed. My function is like below:

Drupal.states.Trigger.states['changed'] = {
    'change': function(e) {
		// I think I should trigger the 'changed' event here but my line of code below is not working
                $(this).trigger('changed');
	 }
  };
drupov’s picture

subscribe

tekken’s picture

I think this is a much needed feature. As far as I see, with this feature Conditional Fields would also replace the Dependent Fields module which is not ported to D7 and seems inactive.

Can we expect any further development on this soon? Like setting value of the dependent field becoming an official/documented of the feature of the Conditional Fields module?

I wasn't able to get the functionality following the instructions in this thread, so in the meantime further instructions or a patch would be helpful.

peterpoe’s picture

Assigned: Unassigned » peterpoe

Yes this would be useful... Taking it.

tekken’s picture

@peterpoe: Any progress on this issue? Looking forward to it...

chalee’s picture

I'm eagerly waiting for this too.

jaxpax’s picture

+1

ydnar79’s picture

It has been a few months since anything more was said / done in regards to this feature request. I was just curious if there was any further developments?

I see that the Dependent Fields module seems active again.... There was a commit just a few days ago on December 5, 2011. However, there is still no D7 version available. And I highly doubt that there will be since there is an issue pointing back to this post...

In other words, the proverbial ball for D7 functionality of this kind appears to be in Conditional Fields court. So any progress????

tekken’s picture

I've also have been checking every now and then. Too bad there has been no progress on this issue. I'm looking for ways to work around this module now.

Alaa Rihan2’s picture

up

Anonymous’s picture

This example post 2 no longer works as the code as changed.
I now get an error:

Warning: Illegal string offset 'states' in conditional_fields_dependency_edit_form() (Zeile 520 von /home/httpd/vhosts/tortour.com/httpdocs/drupal/sites/all/modules/conditional_fields/includes/conditional_fields.admin.inc).
Warning: in_array() expects parameter 2 to be array, string given in conditional_fields_dependency_edit_form() (Zeile 520 von /home/httpd/vhosts/tortour.com/httpdocs/drupal/sites/all/modules/conditional_fields/includes/conditional_fields.admin.inc).

Is there a chance that you update the example?

faite’s picture

Yeah this would be very useful. it appears none of the other options for changing values of dependees works in any module.

catmurray’s picture

Thanks for this module! Has there been any progress on the ability to set the value of the dependent field?

jdoris’s picture

I'm looking to do pretty much the same thing. Would love to hear any ideas or examples. Getting pretty bogged down trying to customize my own module using #states... ugh.
Meanwhile, I can't seem to even get my dependee (a popup date field) to trigger my dependent (an autocomplete field). Thanks.

  • peterpoe committed e0ffdb5 on 8.x-1.x
    #1220412: Make custom jQuery effects actually work.
    
    
dqd’s picture

Version: 7.x-3.x-dev » 8.x-1.x-dev
Priority: Major » Normal
Issue summary: View changes
Status: Active » Fixed

Has been committed for 8.x and above but forgotten to be set as "fixed". Apart from that:

Thanks for the report and all the efforts in here. But due to inactivity in this issue for some years and because of the upcoming EOL of Drupal 7, I will close this issue on the way by cleaning up the issue queue.

Feel free to re-open as "Needs review" if you found a solution or have a patch to be reported to help others on this outdated version.

If you think this issue or missing feature should be addressed in a newer Drupal core 8 and above compatible version of this project, then please file a new issue to the latest dev.

dqd’s picture

Status: Fixed » Closed (fixed)