<p>You can use event hooks to hook into the saving process for elements to achieve this behaviour. In particular, you can use the hooks <code>Entry::EVENT_BEFORE_SAVE</code> and <code>Entry::EVENT_AFTER_SAVE</code> to perform some custom action before or after an element is saved. Both hooks receive a <a href="https://docs.craftcms.com/api/v3/craft-base-element.html#method-beforesave" rel="nofollow noreferrer">boolean argument indicating if the element is new</a>. You can use that to either set a starting value for your ID field (if the element is new) or update the global counter (if the element is not new).</p>
<p><strong>However,</strong> your suggested workflow doesn't appear to be very thought out. For one, what if an editor edits the People ID manually? This would mess with the counter in unexpected ways, and in turn mess up subsequent IDs. Also, I'm not sure why you need a custom ID field and the global counter, but it looks like you're trying to replicate functionality that you already get for free out of the box with Craft:</p>
<ul>
<li>If you only need a unique ID for each person, each entry has that by default once it's saved to the database, so you could just use those.</li>
<li>If you need a sequential ID only for people … why? If you just want to know the ordinal number of a person (i.e. how many people there are before a specific person), you can use a simple <a href="https://craftcms.com/docs/3.x/element-queries.html#query-execution" rel="nofollow noreferrer">count query</a> with the <a href="https://craftcms.com/docs/3.x/entries.html#positionedbefore" rel="nofollow noreferrer">positionedBefore parameter</a>.</li>
<li>For the global counter: If you only need that to generate the sequential IDs, you don't need it at all if you use one of the suggestions above. If you need it to get a total of all people, you can use a count query instead.</li>
</ul>
<p>If you edit your question to include the actual problem you're trying to solve, I'm sure someone could suggest a better approach!</p>

CC BY-SA 4.0
2021-06-29T09:34:44.753Z
Hey Moritz, thank you for your answer. The idea is to give people an ID in a simpler (sequential, just numbers) format rather than the UID. The 'People ID' field could be set to 'hidden' or 'unwritable' so that there are no complications. Think of this 'People ID' as a unique number, similar to a sequential invoice number. If you use a count query with the positionedBefore parameter, the 'People ID would always change when an entry is deleted.
nicbent
CC BY-SA 4.0
2021-06-29T10:09:29.687Z
@nicbent Just out of curiosity, what do you need those sequential IDs for? Seems like a lot of work just to have a "nice-looking" ID, since the IDs aren't really supposed to be visible at all. And the sequentiality is already there since all entries have a timestamp. In case you just want something that is less verbose than the UID (for exported reports or something like that?), elements come with both a UID _and_ a [regular ID](https://docs.craftcms.com/api/v3/craft-base-elementtrait.html#id), which is just an integer. Maybe that't sufficient for your use-case?
MoritzLost
CC BY-SA 4.0
2021-06-29T13:53:18.833Z
The functionality is intended for a people database, the 'People ID' would only be invisible in the backend, but visible in the frontend, so that users can search for this value ... I thought about the regular ID, but it is not so elegant, because these are not generated consistently one after the other, but one could possibly overlook this in view of the effort of an extra module
nicbent
CC BY-SA 4.0
2021-06-29T13:59:22.353Z
@nicbent Why would people search for a random ID? If you need to be able to give people a unique identifier to search for a specific person, wouldn't the entry slug work as well? Also, having a sequential ID and exposing it like this allows for user enumeration (or rather, people enumeration), which will be problematic if you ever want to impose any sort of access restrictions. Still, if you absolutely want to do this, the hooks mentioned in my answers should suffice. Let me know if you run into any problems!
MoritzLost
CC BY-SA 4.0
2021-06-29T18:15:47.137Z
@nicbent - is people ID like a customer number or what are you using it for exactly?  As Moritz mentions, if you're exposing it via search, just be careful about what information is exposed unless the users of your front end are already authenticated and trusted with the information...TBH using Craft's ID would probably serve the same purpose and be way easier.  When people are inevitably removed from the database at some future point in time, you're going to get gaps in the sequence regardless.
RitterKnight
CC BY-SA 4.0
2021-06-28T09:59:14.820Z
2021-06-28T10:42:10.423Z
2021-06-28T10:42:10.423Z
MoritzLost
<p>I would like to add sequential numbering to each entry, which is obtained from a global field. After saving the entry, the global field should be assigned the next number (+1). Does anyone have any idea what the code for it would look like (module)?</p>
<p><a href="https://i.sstatic.net/EjxGq.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/EjxGq.png" alt="enter image description here" /></a></p>

<plugin-development><craft3><yii>
Sequential numbering from global field
# Sequential numbering from global field

(Asked by: username_0 on 2021-06-27)

I would like to add sequential numbering to each entry, which is obtained from a global field. After saving the entry, the global field should be assigned the next number (+1). Does anyone have any idea what the code for it would look like (module)?

[![enter image description here](https://i.sstatic.net/EjxGq.png)](https://i.sstatic.net/EjxGq.png)

**Tags:** plugin-development, craft3, yii

---

## 1 answers

### Answer by username_1 on 2021-06-28. Score: 1

You can use event hooks to hook into the saving process for elements to achieve this behaviour. In particular, you can use the hooks `Entry::EVENT_BEFORE_SAVE` and `Entry::EVENT_AFTER_SAVE` to perform some custom action before or after an element is saved. Both hooks receive a [boolean argument indicating if the element is new](https://docs.craftcms.com/api/v3/craft-base-element.html#method-beforesave). You can use that to either set a starting value for your ID field (if the element is new) or update the global counter (if the element is not new).

**However,** your suggested workflow doesn't appear to be very thought out. For one, what if an editor edits the People ID manually? This would mess with the counter in unexpected ways, and in turn mess up subsequent IDs. Also, I'm not sure why you need a custom ID field and the global counter, but it looks like you're trying to replicate functionality that you already get for free out of the box with Craft:

* If you only need a unique ID for each person, each entry has that by default once it's saved to the database, so you could just use those.
* If you need a sequential ID only for people … why? If you just want to know the ordinal number of a person (i.e. how many people there are before a specific person), you can use a simple [count query](https://craftcms.com/docs/3.x/element-queries.html#query-execution) with the [positionedBefore parameter](https://craftcms.com/docs/3.x/entries.html#positionedbefore).
* For the global counter: If you only need that to generate the sequential IDs, you don't need it at all if you use one of the suggestions above. If you need it to get a total of all people, you can use a count query instead.

If you edit your question to include the actual problem you're trying to solve, I'm sure someone could suggest a better approach!

> **Comments:**
> **username_0**: Hey Moritz, thank you for your answer. The idea is to give people an ID in a simpler (sequential, just numbers) format rather than the UID. The 'People ID' field could be set to 'hidden' or 'unwritable' so that there are no complications. Think of this 'People ID' as a unique number, similar to a sequential invoice number. If you use a count query with the positionedBefore parameter, the 'People ID would always change when an entry is deleted.  
> **username_1**: @nicbent Just out of curiosity, what do you need those sequential IDs for? Seems like a lot of work just to have a "nice-looking" ID, since the IDs aren't really supposed to be visible at all. And the sequentiality is already there since all entries have a timestamp. In case you just want something that is less verbose than the UID (for exported reports or something like that?), elements come with both a UID _and_ a [regular ID](https://docs.craftcms.com/api/v3/craft-base-elementtrait.html#id), which is just an integer. Maybe that't sufficient for your use-case?  
> **username_0**: The functionality is intended for a people database, the 'People ID' would only be invisible in the backend, but visible in the frontend, so that users can search for this value ... I thought about the regular ID, but it is not so elegant, because these are not generated consistently one after the other, but one could possibly overlook this in view of the effort of an extra module  
> **username_1**: @nicbent Why would people search for a random ID? If you need to be able to give people a unique identifier to search for a specific person, wouldn't the entry slug work as well? Also, having a sequential ID and exposing it like this allows for user enumeration (or rather, people enumeration), which will be problematic if you ever want to impose any sort of access restrictions. Still, if you absolutely want to do this, the hooks mentioned in my answers should suffice. Let me know if you run into any problems!  
> **username_2**: @nicbent - is people ID like a customer number or what are you using it for exactly?  As Moritz mentions, if you're exposing it via search, just be careful about what information is exposed unless the users of your front end are already authenticated and trusted with the information...TBH using Craft's ID would probably serve the same purpose and be way easier.  When people are inevitably removed from the database at some future point in time, you're going to get gaps in the sequence regardless.  

---

