I have a "Property" content type created for a real estate web site. The Property content type has a taxonomy field called "Type" where type can be House, Office, Apartment and so on...

I want to create a "code" field that has to be something like "H-1" where H is for Home and 1 must be an incremental number, so houses will have each a different code: "H-1", "H-2", "H-3" ... "H-188", etc. And so on for Offices "O-1", "O-2"..."O-479". I see that there is a Serial module, but that module helps me only creating autoincremental numbers for each content type, not based on other fields of that content type.

I was planning to use auto_nodetitle + serial module + rules to create the letter+number format for my field, but I will have the same problem: If I create "H-1" and then create an Office, it will have "O-2" code, and not "O-1" code.

Is there a module than can help me? If not, how can I make it?

  • I can voice for the serial module. Works very well. – Sam152 Jul 27 '13 at 3:21
  • What do you want to happen if a node gets deleted ? do you want the increment to carry on ? like node ids – jowan sebastian Nov 26 '14 at 18:40
  • Hello Yaazkai, have you solved your problem? I would be interested in your solution for a similar case. Thanks – Toki Aug 24 '16 at 12:39

The obvious option would be to have a serial field for each type. Whether or not that is feasible based on your business rules (are there lots of types, are the types likely to change, etc.) is another question.

Another module that may be very useful in these types of problems is the computed field module.

Another option (probably the one I would choose) is to make it completely custom. Either a custom entity property or a custom field of some sort that does database queries to determine the next value instead of auto_nodetitle + serial module + rules.
Be careful of race conditions when doing something like this though.

| improve this answer | |

Just thinking out loud.

In rules (after saving content), set data value of the field. To set the field (direct input), use php code that counts all nodes of that particular type with 'Type" as house for example and echo H-(count+1).

| improve this answer | |
  • Hi andrew, thanks for comment. But this solution has a problem, if a node is deleted then I will have the same code for two different Houses and if more nodes are deleted so it will decrease and repeat. How can I garantee that it is unique and incremental? Regards ! – Yaazkal Oct 12 '12 at 21:03
  • Hello @andrew. Thanks again. Could be, but what if there are 1000+ nodes? will take time to save a node while check all. I think I have the answer, but it is a half answer. Create a rule that: Check if the saved node has "field_code" Then, fetch the previous recent node that has the same 'type' (is a tax term) and just increment it in the recent node, if there is no previous node, then is the first. This will be incremental and unique, And didn't care to fill empty codes, dosen't matter. But I don't know how to make the rule :( can you tell me how to do it? Regards ! – Yaazkal Oct 12 '12 at 23:18
  • Hi andrew, that is my proposition and my first option. But, you know, clients/users want to have the properties codes in the other way :) – Yaazkal Oct 13 '12 at 0:19
  • Hi andrew ! Well, I was thinking in make a substring eliminating the two first characters and just make the increment. But if I have to add another field just to make it easy dosen't matter. I'm using D7. I'm trying with rules but is the first time to me with this module so I guess is question of learning it. Thanks. – Yaazkal Oct 13 '12 at 1:17

The comments were turning into a discussion, so here's some code that will retrieve the 'latest' node and retrive the code ($code) for that node.

$terms = taxonomy_get_term_by_name($home);
$tid = $terms[0]->tid;
$query = new EntityFieldQuery();
  ->entityCondition('entity_type', 'node')
  ->entityCondition('bundle', 'your_content_type')
  ->fieldCondition('term_fieldname', 'tid', $tid)
  ->propertyCondition('status', 1)
  ->propertyOrderBy('created', 'DESC');
$result = $query->execute();
$nid = array_keys($result['node']);
$picked_node = $nid['0'];
$node = node_load($picked_node);
$wrapper = entity_metadata_wrapper('node', $node); 
$current_code = $wrapper->field_code->value();
$new_code += $current_code;
$field_to_set = "H-$new_code";

Here I'm assuming that you are going with the idea of having an extra integer field. This is pretty rough and untested so try it out on a simple page with php input format. echo the vars to see what you get...

| improve this answer | |
  • 1
    If you only want the first result of your query don't waste resources selecting and building an array of all results. Use EntityFieldQuery::range() to limit the results. Also, whenever you are selecting a value from the database then incrementing it then saving the incremented value back to the database, be very aware of potential race conditions. What if 2 processes run at the same time and both select the same current code? You end up with multiple nodes having the same new code. – rooby Oct 25 '14 at 3:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.