I created a unit module which allows to set up a unit for a number field. E.g. if you create 'download speed' field using 'number_decimal' field type, you can set up the unit to be 'kb/s'. I used hook_form_alter() to add a textfield to the widget setup form, where the user can define the unit for this text field.

My problem is: to show the unit of a field together with its value, when the node is viewed, I need to change the default formatter of the number module. There is no hook which allows an other module to append or change a formatter of a certain field module, right? So I see no way to achieve this without modifying number_field_formatter() in number.module directly. So maybe it would be better if the number.module would support units on its own, instead of writing a module that enables number.module to have units.

An other widget setting should configure, if the unit should be a prefix (e.g. in the case of '$') or a suffix (in most cases) to the value when the node is viewed.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

yojoe’s picture

Status: Active » Needs review
FileSize
2.72 KB

I created a patch that allows number.module to set up units. You can setup the unit string (e.g. $, €, m², ...) and the position of the unit string (prefix or suffix) and if the value and the unit string should be seperated by a space (&nbsp).

yojoe’s picture

Well, it would be good, if the unit would be displayed when the node is edited too, so the person that edits the node knows which unit the value is supposed to have.
E.g. if the field label is 'length' the person that edits the node doesn't know if it should enter the length in mm, cm, m, px, ft, ...

But I don't know where to place it! Best would be as prefix or suffix next to the textfield... but if you have a theme where all textfields have 100% width this would place the unit-string above / below the textfield which looks pretty ugly.

yched’s picture

you might want to look at #field_prefix and #field_suffix FAPI properties.
http://api.drupal.org/api/HEAD/file/developer/topics/forms_api_reference...

I guess if a theme does not play well with these, it can be considered non-FAPI compliant ?

yojoe’s picture

FileSize
4.66 KB

#field_prefix and #field_suffix are exactly what I was looking for. Thanks!

My patch lets the user setup a unit for a number now. You setup any string to be the unit-string. You can also setup the position of the unit-string (prefix or suffix) next to the value. You can also choose if you want a space separator between the value and the unit-string. When the field is to be viewed, the default formatter of the number.module adds the unit-string (if one was setup) to the value, according to the position and space separator settings. When the value is to be edited with the edit form of the content type, the unit string is shown next to the input textfield of the number. This is only the case, if textfield was chosen as widget type for this number field. To show the unit string with select list, radios or checkboxes, I would need to make changes to optionwidgets.module. But select lists, radios and checkboxes allow you to define key|value pairs, so the unit string could be defined with the label (e.g. 1.99|$1.99).

Garland, the default theme of Drupal 5.0 is non-FAPI compliant, because the unit string is placed above (when marked as prefix) or below (when marked as suffix) the text input field. Textfields are always 100% in Garland.

yojoe’s picture

I never contributed a patch before. My question is: Are you interested in integrating my patch officially to number.module? If so, how shall I proceed? Is it sufficient to post it here? My patch patches the number.module version which is packaged with the current stable version of CCK (5.x-1.2). Is this OK or do I have to make a patch respectively to the head-version of number.module?

KarenS’s picture

Assigned: Unassigned » KarenS

Yes, you need to do your patches on the HEAD versions rather than stable releases because there have been changes. One of them is that formatting has already been applied to the number field, and in addition to adding commas and decimals it added a few currency formats. However, I like this approach better, so I'll alter the module to do the formatting for commas and decimals only, then use your method for allowing a prefix or suffix to the field. This needs to appear in both the edit and view, and needs to be done so that it also works in Views. Plus I found through my own experimenting that you can't send the euro symbol through check_plain() without getting it garbled, so it will need to be check_markup().

Don't worry about rolling a patch. You've provided enough for me to be able to finish the job. I'll post back here when it's ready. This is a pretty simple fix that shouldn't break anything, so I'm just going to go ahead and do it.

yojoe’s picture

Assigned: KarenS » Unassigned

One thing I noticed is, that computed_field.module has a very sophisticated and flexible solution to format the output. One could think about a similar solution for setting up the output format of the number.module.
E.g. if it was possible to define the code for the output in a textfield like:
$display = sprintf("%s %s", number_format($node_field_item['value'], 2, ",", "."), $node_field_item['unit']);
one could setup output formats like "3.124.511,34 €". This would be very useful!

The only problem is, the unit-string must be loaded with the node. Currently this is not the case, if you set up a custom field type... let's call it field_sea_level and the unit-string to be "m" (Meters), you just have an array with the field-value available, when the node is loaded:
[field_sea_level] => Array( [0] => Array( [value] => 1200 ) )

My idea is to add the unit-string to the array, which would look like this:
[field_sea_level] => Array( [0] => Array( [value] => 1200 [unit] => m ) )

But I don't know where to accomplish this :( Any ideas?

KarenS’s picture

What you're describing is adding a column to the number module that would store the unit, which is one possibility. One thing that is a problem here is trying to do two basically different things -- create a string that can be prefixed or suffixed, like a currency indicator, and give the number an additional characteristic, like a unit. I think the prefix/suffix is simple and flexible and often useful so it belongs in the core number module. Not sure yet that it makes sense to add columns to the field as a part of core. That could be something to be done by an add-on module since not everyone will need this capability.

As to the flexible formatting used by computed_field. The big difference is computed_field is used by programmers and the number module is often not. It might be possible to make something like that an 'Advanced option' so as not to be confusing to non-programmers, and still provide some basic formatting out of the box.

So the approach I'm going to take for now is:

1) Rename your item from 'Unit' (which is not really correct) to 'Append string'
2) Use the number_format() array that was previously added with a prefix or suffix if desired.

I think I'll put off the 'Advanced option' of using sprintf formatting for now, but it would certainly be a legitimate feature request. And adding a unit column would be a legitimate (separate) feature request. If you want, you can create an issue for each of them.

KarenS’s picture

Er, I guess it wouldn't require a column to add a unit, but could instead be a setting. Still, I think I will postpone that and just get this basic feature working for now.

KarenS’s picture

The css issue is a core problem. node.css has this:

.node-form .form-text {
  display: block;
  width: 95%;
}

So we need some cocss to overcome that. The problem is we only want to do it on number fields and I can find no way to create any css that will work for this purpose since we don't have any identifier for the field. I can a 'number' class on the whole form, which is too much, or on the input element itself, which is too little since that element is wrapped by a div that I can't set a class on that is too wide.

yojoe’s picture

Yes, the unit should not be a column, because it is the same for all instances of this field. Storing it in a column would be redundant and in the case you change the unit-string in the field setup, you would have to update every instance-row in the database.

The example I imagine is the following:
1. you define a number field, that has a unit (e.g. field_costs in €)
2. you define an other number field (e.g. field_duration in days)
3. you define a computed_field field, that multiplies both fields (field_total = field_costs * field_duration)
4. the computed_field product (field_total) has obviously the same the unit (€), so you would like to append it using sprintf in the $display definition of the computed field, but the problem is, that the unit of field_costs is not available in the node object, only the value.
5. you could add the unit of the computed field manually with sprintf like: $display = sprintf("%0.2f ", $node_field_item['value']); but what if you change the setting of field_costs to be $ and not € anymore... in this case you would have to manually edit your computed field output definition to show up the correct unit for field_total

I think I'll create a separate feature request for that.

KarenS’s picture

Status: Needs review » Fixed

OK, the basic feature is committed, plus I found a way to get the css to work properly, so the display of the prefix and suffix should work right, too.

Try this out, then feel free to create more issues if you would like to see additional functionality.

yojoe’s picture

Very well, I tested it and it works as expected.
But my numbers are default formated now using 'us_0' number_format() setting. Where can I setup which setting is used for a field?

yched’s picture

Use the 'display fields' tab on the content type page (next to 'manage fields')

Anonymous’s picture

Status: Fixed » Closed (fixed)