Loading...
Loading...
Compare original and translation side by side
public/js/public/js/frappe.ui.form.on('DocType Name', {
// Form-level events
setup(frm) { },
refresh(frm) { },
validate(frm) { },
// Field change events
fieldname(frm) { }
});frappe.ui.form.on('DocType Name', {
// 表单级事件
setup(frm) { },
refresh(frm) { },
validate(frm) { },
// 字段变更事件
fieldname(frm) { }
});| Action | Code |
|---|---|
| Set value | |
| Hide field | |
| Make field mandatory | |
| Call server | |
| Prevent save | |
| 操作 | 代码 |
|---|---|
| 设置字段值 | |
| 隐藏字段 | |
| 设置字段为必填 | |
| 调用服务器方法 | |
| 阻止保存 | |
One-time setup (queries, defaults)?
└── setup
Show/hide UI, add buttons?
└── refresh
Validation before save?
└── validate
Do something right after save?
└── after_save
React to field change?
└── {fieldname}一次性初始化(查询、默认值设置)?
└── setup
显示/隐藏UI、添加按钮?
└── refresh
保存前验证?
└── validate
保存后执行操作?
└── after_save
响应字段变更?
└── {fieldname}// Set single value (async, returns Promise)
frm.set_value('status', 'Approved');
// Set multiple values at once
frm.set_value({
status: 'Approved',
priority: 'High'
});
// Get value
let value = frm.doc.fieldname;// 设置单个值(异步,返回Promise)
frm.set_value('status', 'Approved');
// 批量设置多个值
frm.set_value({
status: 'Approved',
priority: 'High'
});
// 获取值
let value = frm.doc.fieldname;// Show/hide
frm.toggle_display('priority', condition);
// Make mandatory
frm.toggle_reqd('due_date', true);
// Make read-only
frm.toggle_enable('amount', false);
// Advanced property change
frm.set_df_property('status', 'options', ['New', 'Open', 'Closed']);
frm.set_df_property('amount', 'read_only', 1);// 显示/隐藏字段
frm.toggle_display('priority', condition);
// 设置为必填字段
frm.toggle_reqd('due_date', true);
// 设置为只读
frm.toggle_enable('amount', false);
// 高级属性修改
frm.set_df_property('status', 'options', ['New', 'Open', 'Closed']);
frm.set_df_property('amount', 'read_only', 1);// Simple filter
frm.set_query('customer', () => ({
filters: { disabled: 0 }
}));
// Filter in child table
frm.set_query('item_code', 'items', (doc, cdt, cdn) => ({
filters: { is_sales_item: 1 }
}));// 简单筛选
frm.set_query('customer', () => ({
filters: { disabled: 0 }
}));
// 子表格中的字段筛选
frm.set_query('item_code', 'items', (doc, cdt, cdn) => ({
filters: { is_sales_item: 1 }
}));frappe.call({
method: 'myapp.api.process_data',
args: { customer: frm.doc.customer },
freeze: true,
freeze_message: __('Processing...'),
callback: (r) => {
if (r.message) {
frm.set_value('result', r.message);
}
}
});frappe.call({
method: 'myapp.api.process_data',
args: { customer: frm.doc.customer },
freeze: true,
freeze_message: __('Processing...'),
callback: (r) => {
if (r.message) {
frm.set_value('result', r.message);
}
}
});// Calls method on document controller
frm.call('calculate_taxes', { include_shipping: true })
.then(r => frm.reload_doc());// 调用文档控制器中的方法
frm.call('calculate_taxes', { include_shipping: true })
.then(r => frm.reload_doc());async function fetchData(frm) {
let r = await frappe.call({
method: 'frappe.client.get_value',
args: {
doctype: 'Customer',
filters: { name: frm.doc.customer },
fieldname: 'credit_limit'
}
});
return r.message.credit_limit;
}async function fetchData(frm) {
let r = await frappe.call({
method: 'frappe.client.get_value',
args: {
doctype: 'Customer',
filters: { name: frm.doc.customer },
fieldname: 'credit_limit'
}
});
return r.message.credit_limit;
}let row = frm.add_child('items', {
item_code: 'ITEM-001',
qty: 5,
rate: 100
});
frm.refresh_field('items'); // REQUIRED after modificationlet row = frm.add_child('items', {
item_code: 'ITEM-001',
qty: 5,
rate: 100
});
frm.refresh_field('items'); // 修改后必须调用此方法frm.doc.items.forEach((row) => {
if (row.qty > 10) {
row.discount_percentage = 5;
}
});
frm.refresh_field('items');frm.doc.items.forEach((row) => {
if (row.qty > 10) {
row.discount_percentage = 5;
}
});
frm.refresh_field('items');frappe.ui.form.on('Sales Invoice Item', {
qty(frm, cdt, cdn) {
let row = frappe.get_doc(cdt, cdn);
frappe.model.set_value(cdt, cdn, 'amount', row.qty * row.rate);
},
items_add(frm, cdt, cdn) {
// New row added
},
items_remove(frm) {
// Row removed
}
});frappe.ui.form.on('Sales Invoice Item', {
qty(frm, cdt, cdn) {
let row = frappe.get_doc(cdt, cdn);
frappe.model.set_value(cdt, cdn, 'amount', row.qty * row.rate);
},
items_add(frm, cdt, cdn) {
// 新增行时触发
},
items_remove(frm) {
// 删除行时触发
}
});frappe.ui.form.on('Sales Order', {
refresh(frm) {
if (frm.doc.docstatus === 1) {
// Grouped buttons
frm.add_custom_button(__('Invoice'), () => {
// action
}, __('Create'));
// Primary action
frm.page.set_primary_action(__('Process'), () => {
frm.call('process').then(() => frm.reload_doc());
});
}
}
});frappe.ui.form.on('Sales Order', {
refresh(frm) {
if (frm.doc.docstatus === 1) {
// 分组按钮
frm.add_custom_button(__('Invoice'), () => {
// 执行操作
}, __('Create'));
// 主要操作按钮
frm.page.set_primary_action(__('Process'), () => {
frm.call('process').then(() => frm.reload_doc());
});
}
}
});frm.refresh_field('table')frm.doc.field = valuefrm.set_value()__('text')frappe.throw()frm.refresh_field('table')frm.doc.field = valuefrm.set_value()__('text')frappe.throw()erpnext-impl-clientscriptserpnext-errors-clientscriptserpnext-syntax-whitelistederpnext-impl-clientscriptserpnext-errors-clientscriptserpnext-syntax-whitelisted