I want to display the computed field in real time as the user fills out the form. So that it can add how many items requested and the total price BEFORE the form is submitted. Is this possible?
thanks

Comments

tlash’s picture

I am interested in this as well.

palik’s picture

subscribing

mErilainen’s picture

+1 This would be really awesome.

Is there any way to even fill some other CCK field with Computed Field when you create a new node?

jjjames’s picture

I actually got some custom jQuery to perfom this task as you can see below (this particular one is for webform, but should work on CCK too):

<script type="text/javascript">

$(document).ready(function() {
            $("#webform-component-entrees input:text, #webform-component-additional_items input:text, #webform-component-beverages input:text").keypress(function(e) {
                if(window.event) {
                    if(!(e.keyCode > 47 && e.keyCode < 58 || e.keyCode == 8 || e.keyCode == 0)) {
                        return false;
                    }
                } else if(e.which) {
                    if(!(e.which > 47 && e.which < 58 || e.which == 8 || e.which == 0)) {
                        return false;
                    }
                }
            });
            $("#webform-component-entrees input:text, #webform-component-additional_items input:text, #webform-component-beverages input:text").keyup(function(e) {
                if(window.event) {
                    if(e.keyCode > 47 && e.keyCode < 58 || e.keyCode == 8 || e.keyCode == 0) {
                        $calculate();
                    } else {
                        return false;
                    }
                } else if(e.which) {
                    if(e.which > 47 && e.which < 58 || e.which == 8 || e.which == 0) {
                        $calculate();
                    } else {
                        return false;
                    }
                }
            });
            var $calculate = function() {
                var $entrees = 0;
                $("input[name^='submitted[entrees]']").each(function() {
                    $entrees += +$(this).val() * $(this).parent().find("span.field-suffix").text().replace(/[^\d\.]*/g, '');
                });
                var $additional = 0;
                $("input[name^='submitted[additional_items]']").each(function() {
                    $additional += +$(this).val() * $(this).parent().find("span.field-suffix").text().replace(/[^\d\.]*/g, '');
                });
                var $beverages = 0;
                $("input[name^='submitted[beverages]']").each(function() {
                    $beverages += +$(this).val() * $(this).parent().find("span.field-suffix").text().replace(/[^\d\.]*/g, '');
                });
                var $grandTotal = $entrees+$additional+$beverages;
                $("#final_total").html("Entrees Per Person Total : $" + $entrees.toFixed(2) + "<br/>" +
                                       "Additional Items Total : $" + $additional.toFixed(2) + "<br/>" +
                                       "Beverages Total: $" + $beverages.toFixed(2) + "<br/>" +
                                       "Grand Total : $" + $grandTotal.toFixed(2));
            };
        }); 

</script>
omisar’s picture

I'm also using WEBFORM module and I 'been looking for a way to sum fields and show the total on another field before the form is submited , I try the script above from superjames but it doesnot work for me, I'm not a programmer , javascript or php guy so is hard to find why is not working , I would appreciate advice how to mmake this script works or another way to achive the same, thank You.

obrienmd’s picture

I would be willing to sponsor a patch for this.

jjjames’s picture

If you can reverse engineer it, that jquery I posted is how I did it and should be straight forward to make it work for your needs.

gapa’s picture

I would like to use this code for custom cck fields. Where should I put the code above? Into page.tpl.php?

dharmanerd’s picture

in response to...
#3
mErilainen

yes. it's really easy, just create one computed field to do all of your computations, then assign any cck field the value of your calculations...

here's an example from my calculated field. I'm populating multiple cck fields with default values if the field is empty...

//CS PSF
$node->field_o_cs_psf[0]['value'] = NULL;

//%RETURN
$node->field_o_return[0]['value'] = 10;

//MB AMT
$node->field_o_mb_amt[0]['value'] = 2 + $node->field_o_return[0]['value'];

each time the node saves, the existing value of the fields above will be overwritten. if you only need this to happen once, or just if the field is empty you can do things like...

if (the field has a value do nothing)
} else there is no value {
set a default (like above)
}

tomsm’s picture

subscribing

Problue Solutions’s picture

subscribing

joecanti’s picture

subscribing

118218’s picture

subscribing

Shawn DeArmond’s picture

Version: 6.x-1.0-beta2 » 7.x-1.x-dev
Category: support » feature

Looks like most development on this is now in the 7.x version. Moving. Also, it's a "feature request".

haradhansharma’s picture

subscribing

rustyblue100’s picture

subscribing

adamtong’s picture

subscribing

8bitplateau’s picture

I needed this too, so did a little hacking around.
I added a two extra field hooks to render a form element in the input form to act as a placeholder for displaying live js based calculations in

/**
 * Implements hook_element_info().
 */
function computed_field_element_info() {
  $elements = array();
  $elements['computed'] = array(
    '#input' => TRUE,
    '#process' => array('computed_field_field_process'),
    '#theme' => 'computed',
    '#theme_wrappers' => array('form_element'),
  );
  return $elements;
}

/**
 * Processes the JS and create a placeholder to display content in.
 */
function computed_field_field_process($element, $form_state, $complete_form) {
  $instance = field_widget_instance($element, $form_state);
  $field_name = $instance['field_name'];
  $code = $form_state['field']["$field_name"]['und']['field']['settings']['js'];
  $element['computed'] = array(
    '#type' => 'textfield',
    '#title' => t('Computed Field'),
    '#disabled' => true  
  );
  drupal_add_js($code,'inline'); 
  return $element;
}

and added an extra field in the field settings form for entering javascript, in the computed_field_field_settings_form function.

  $form['js'] = array(
    '#type' => 'textarea',
    '#rows' => 15,
    '#title' => t('live Javascript Code'),
    '#description' => t('put yer js in ere bouy'),
    '#access' => !function_exists($compute_func),
    '#default_value' => !empty($settings['js']) ? $settings['js'] : "$('#formid').val('0');",
  );

together, they render a form element in the node input form which acts as a placeholder and executes the javascript you enter in the field settings using drupal_add_js inline.

this means that you have to write your JS as well as your PHP separetley.
they are not handled by the same function. this is because the calculated fields calulation is done by raw php input and does not translate to JS.
however if this module was to provide and interface similar to conditional fields dependenices form, where the user selects how the calcualtion is handeled, then the settings can be translated into both php and js.

so in away it does compliment the raw php input by providing raw js input and in both cases can be pretty dangerous and break stuff.

example uses can be like mentioned above

$("#my_A_field input:text, #my_B_field input:text").keypress(function(e) {
      var a = $("#my_A_field input:text").val();
      var b = $("#my_B_field input:text").val();
      $("#my_C_field input:text").val(a + b);
 });

hope this helps as an idea :)

8bitplateau’s picture

actually

/**
 * Processes the JS and create a placeholder to display content in.
 */
function computed_field_field_process($element, $form_state, $complete_form) {
  $instance = field_widget_instance($element, $form_state);
  $field_name = $instance['field_name'];
  $code = $form_state['field']["$field_name"]['und']['field']['settings']['js'];
  $element['computed'] = array(
    '#type' => 'textfield',
    '#title' => t('Computed Field'),
  );
  drupal_add_js($code,  array('type' => 'inline', 'scope' => 'footer', 'weight' => 5));
  return $element;
}

js inline needs to be added in footer or has no affect

and example needs to be like;

(function ($) {
  $("body").click(function() {
    $('input').val('x');
  });
}(jQuery));

in the settings form

adigunsherif’s picture

Issue summary: View changes

An easier method that works for me:
in your .module file, we have

function mymodule_form_alter(&$form, &$form_state, $form_id) {
  //dpm($form_id);
  if($form_id == 'equipment_node_form'){
	 $rate = variable_get('small_fixes_current_dollar_rate');
	 $form['live_result'] = array(
		'#type' => 'textfield',
		'#title' => t('Amount Purchased (USD)'),
		'#disabled' => TRUE,
	 );

	 drupal_add_js(drupal_get_path('module', 'mymodule') . '/small_fixes_live.js');
	 drupal_add_js(array('small_fixes' => array('currentrate' => $rate)), 'setting');
	 
  }

Then the js file is located in the same folder as the .module file, with the code below:

(function ($) {
  Drupal.behaviors.mymodule = {
	attach: function () {
		document.getElementById("edit-live-result").defaultValue = document.getElementById('edit-field-amount-ngn-each-und-0-value').value; //this line sets default value for the field
		$('#edit-field-amount-ngn-each-und-0-value').keyup(function(e) {
			var currentRate = Drupal.settings.mymodule.currentrate;
		    var ngn = document.getElementById('edit-field-amount-ngn-each-und-0-value').value;
			
			 $("#edit-live-result").val(ngn/currentRate);
		});
	}
  };
})(jQuery);

change "mymodule" to your module name and ensure you have picked the correct id of the field input.

adigunsherif’s picture

Doing this again with field collections (unlimited value). No PHP. simply add this js to your module and change the elements as needed.
This script adds a div with class .liveamount below the "rate"field for each . Within this div is where the calculation will appear for the user.

(function ($) {
  Drupal.behaviors.myModule = {
    attach: function (context, settings) {
      $('.field-name-field-item tr.draggable').once(function () {
          var ratefield = $(this).find('.field-name-field-rate');
          var quantityfield = $(this).find('.field-name-field-quantity');

          ratefield.append('<div class="liveamount"></div>');

          $(this).keyup(function () {
            var rate = ratefield.find('input').val()
            var quantity = quantityfield.find('input').val();
            amount = quantity * rate;
            $(this).find('.liveamount').text('Total = ' + amount)
          });

      });
    }
  };
})(jQuery);
adigunsherif’s picture

cuman’s picture

Hi

Could you advise how to do it at 8?

baustin27’s picture

Yes ill even chip in for payment to get this as a full module for D8 or even integrated into the computed field module itself. I feel this is a great feature for the world.