Currently, the Select field in Frappe only supports a simple list of values. This means that the value stored in the database is the same as the text displayed to the user. Many use cases require storing a machine-readable key in the database while showing a human-readable label in the UI, similar to HTML Open behavior.
Proposed Feature:
Allow Select fields to accept key-value pairs.
The key is stored in the database, while the label is displayed to the user.
Maintain backward compatibility so that existing Select fields (with simple lists) continue to work.
Optionally, support defining these key-value pairs either via newline-separated strings or via a JSON/dictionary format in the field definition.
Example Use Case:
1: Open
2: Closed
3: Pending
Database: stores 1, 2, or 3.
UI: displays Open, Closed, or Pending to the user.
Reduces the need for Client Scripts or extra Read-Only fields.
Makes Select fields more versatile and suitable for ERP use cases.
Benefits:
Cleaner and more maintainable DocTypes.
Improves UX for end-users.
Aligns Frappe Select fields with standard HTML behavior.
Additional Notes:
Ideally, the feature would be compatible with both server-side and client-side forms.
Could also support dynamic fetching of key-value pairs from linked DocTypes for more advanced use cases.
I implemented this via a Client Script ![]()
frappe.ui.form.on('Doctype name', {
onload: function(frm) {
const options = {
draft: "Draft mode (show to user)",
submitted: "submitted mode (show to user)",
approved: "approved mode (show to user)",
};
const formatted = Object.entries(options).map(([value, label]) => ({
value,
label,
}));
frm.set_df_property('status(field name )', 'options', formatted);
}
});