本文主要是介绍ERPNext的frappe的js脚本一些方法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
事件demo
注意,有些触发事件不能同时存在,不然会报错,注意一下就好
frappe.ui.form.on('Scripting Test',{// 页面刷新时的方法(保存时也会自动刷新)refresh:function(frm){frappe.msgprint("页面刷新时的方法---Hello D-cod")//弹窗弹出信息frappe.show_alert({message: '这个右下角提示框',indicator: 'yellow'});}refresh:function(frm){frappe.throw("This is an error------抛出异常,保存失败")//抛出异常,保存失败(好像并不会阻止到成功报错只是会弹)}//加载时输出信息onload:function(frm){frappe.msgprint("Hello Word from 'onload' event---加载时输出信息")}//验证时输出信息validate:function(frm){frappe.throw("Hello Word from 'validate' event验证时输出信息---验证时输出信息")}//保存前触发before_save:function(frm){frappe.throw("你好 Ikun 来自---保存前触发 报错信息'before_save' event")}//保存后触发after_save:function(frm){frappe.msgprint("你好 Ikun 来自---保存后触发 信息 'after_save' event")}//提交前触发before_submit:function(frm){frappe.throw("Hello Word from 'before_submit' event")}//提交时触发on_submit:function(frm){frappe.msgprint("Hello Word from 'on_submit' event")}//提交后触发after_submit:function(frm){frappe.msgprint("Hello Word from 'after_submit' event")}//取消前触发before_cancel:function(frm){frappe.throw("Hello Word from 'before_cancel' event")} //有问题,会阻止取消//取消后触发after_cancel:function(frm){frappe.msgprint("Hello Word from 'after_cancel' event")}//字段事件触发enable:function(frm){frappe.msgprint("Hello Word from 'enable' fieldname event")} //勾选“启用”后会弹出//子表事件触发famlly_members_on_form_rendered:function(frm){frappe.msgprint("Hello Word from 'famlly_members' child table fieldname event")} //不懂跳过after_save:function(frm){//保存后输出全名frappe.msgprint(__("The full name is '{0}'",[frm.doc.first_name+" "+frm.doc.middle_name+" "+frm.doc.laste_name]))//拼接打印内容 // //输出子表的关系 for (let row of frm.doc.famlly_members){frappe.msgprint(__("{0},the family member name is '{1}' and relation is '{2}'",[row.idx,row.name1,row.relation]))}} //循环打印子表信息refresh:function(frm){//进入单据时会出现一个蓝色提示框frm.set_intro("你可以进行编辑此单据")//判断这单据是否为新的单据if(frm.is_new()){//处于新单据时,会有以下提示内容frm.set_intro("你现在在创建一个新的单据")}} //进去单据会有一个提示框内容validate:function(frm){//设置全名frm.set_value('full_name',frm.doc.first_name+" "+frm.doc.middle_name+" "+frm.doc.laste_name)//添加一个子表数据let row = frm.add_child('famlly_members',{name1:'tom',relation:'father',age:53,})} //提交后创建了一个全名框,内容为全名,并且子表自动填写了固定的数据//当勾选enable时enable:function(frm){frm.set_df_property('first_name','reqd',1) //设置为必填字段frm.refresh_field("first_name");//刷新frm.set_df_property('middle_name','read_only',1) //设置为只读字段frm.refresh_field("middle_name");//刷新frm.toggle_reqd('age',true)//设置为必填字段} //勾选后姓名和年龄带星号,变成必填,中间名消失refresh:function(frm){frm.add_custom_button("Click Me Button",() =>{frappe.msgprint(__("You clicked me!"));})frm.add_custom_button("Click Me1",() =>{frappe.msgprint(__("You clicked me1!"));},'click me')frm.add_custom_button("Click Me2",() =>{frappe.msgprint(__("哎呦你干嘛点我!!"));},'click me')} //创建按钮,自定义按钮名字和点击按钮后输出的弹框内容});//子表
frappe.ui.form.on('Famlly Members', {name1:function(frm){frappe.msgprint("Hello Word from child table 'name1' fieldname event")}age(frm,cdt,cdn){frappe.msgprint("Hello Word from child table 'age' fieldname event")}}) //点击子表添加字段,在子表name1(名字)字段填写内容,焦点离开后会弹出提示框
frm是要在框架方法里面才能用,如果想框架方法外面赋值可以用cur_frm.set_value('字段名','值');
案例
frappe.ui.form.on('Bill of materials', {one: function(frm) {update_layer_number(frm);},two: function(frm) {update_layer_number(frm);},three: function(frm) {update_layer_number(frm);},four: function(frm) {update_layer_number(frm);}
});function update_layer_number(frm) {const one = frm.doc.one!=undefined?`${frm.doc.one}`:"";const two = frm.doc.two!=undefined?`.${frm.doc.two}`:"";const three = frm.doc.three!=undefined?`.${frm.doc.three}`:"";const four = frm.doc.four!=undefined?`.${frm.doc.four}`:"";const layer_number = `${one}${two}${three}${four}`;frm.set_value('layer_number', layer_number);
}
案例2
// 在'Order Tracking'表单上设置事件处理器
frappe.ui.form.on('Order Tracking',{// 当表单加载时执行的函数onload(frm){// 设置查询条件,只查询类型为"发货公司"的记录frm.set_query("dispatch_company",function(){return {filters:{"type":"发货公司" // 过滤条件:类型为"发货公司"}};});// 设置查询条件,只查询类型为"收货公司"的记录frm.set_query("receiving_company",function(){return {filters:{"type":"收货公司" // 过滤条件:类型为"收货公司"}};});},// 当unit_price字段发生变化时执行的函数unit_price(frm){ // 如果weight和unit_price都有值,则计算amount的值if(frm.doc.unit_price & frm.doc.pcs_all){frm.set_value('amount',frm.doc.unit_price * frm.doc.pcs_all) // 计算amount的值}},// 当unit_price字段发生变化时执行的函数pcs_all(frm){// 如果weight和unit_price都有值,则计算amount的值if(frm.doc.unit_price & frm.doc.pcs_all){frm.set_value('amount',frm.doc.unit_price * frm.doc.pcs_all) // 计算amount的值}},// 当表单刷新时执行的函数refresh(frm) {// 在这里编写你的代码}
})
案例3
通过api填表(((在获取部门方法里))),api在报表里面爬到的,+等等
frappe.ui.form.on('Stock Entry', {refresh(frm) {if (frm.is_new() && frm.doc.purpose == 'Material Transfer for Manufacture'){frm.set_value('inspection_required', 0)}let batch_field = frm.get_docfield("items", "batch_no");batch_field.get_route_options_for_new_doc = function(row) {if (frm.is_new()) return;return {"item": row.doc.item_code,}}//部门输入框为空时自动填部门------------------------------2023.10.10------10.12----------------if(frm.doc.departments===""||frm.doc.departments===null||frm.doc.departments===undefined){console.log('获取部门。。。。。。。。。。。。。。。'+frm.doc.departments)获取部门(frm);}//显示评论let 标签属性 = '[data-page-route="Stock Entry"] [class="comments-count"]';const 评论控制 = setInterval(()=>{//如果出去了就不要显示了if(window.location.href.includes('stock-entry/M')){if (window.location.href!==url) {显示评论(标签属性);}//侧边栏有显示的消息条数if (document.querySelector(标签属性).innerText==0) {显隐元素封装版('隐');}}else{console.log('出去了,隐藏掉');显隐元素封装版('隐');url = "你干嘛 哎呦";clearInterval(评论控制); // 停止定时器}},444);}
})//-------------------------------------------2023.10.10------------------
function 获取部门(frm){// 获取创建人的名字 找不到就 获取当前用户名let userName = document.querySelectorAll('[data-page-route="Stock Entry"] .created-by b')[0]?.innerText ?? frappe.session.user_fullname;userName = userName==='你'? frappe.session.user_fullname: userName;console.log(`获取到的名字为${userName}`)// 构造请求数据const formData = new FormData();formData.append('doctype', 'Employee');formData.append('fields', '["`tabEmployee`.`department`"]');formData.append('filters', `[["Employee","employee_name","like","${userName}"]]`); // 设置请求头const headers = new Headers();headers.append('X-Frappe-CSRF-Token', frappe.csrf_token);headers.append('Content-Type','application/x-www-form-urlencoded');// 构造请求参数 const requestOptions = {method: 'POST',headers,body: new URLSearchParams(formData).toString() };// 发送请求fetch('/api/method/frappe.desk.reportview.get', requestOptions).then(res => res.json()).then(data => {frm.set_value('departments', data.message.values[0][0])if(window.location.href.includes('stock-entry/M')){ //这样子新增的(stock-entry/new)就不会弹出来frappe.show_alert({message: '原本部门为空,自动填写部门成功,保存才生效',indicator: 'green'})}}).catch(error => frappe.show_alert({message: '自动填部门失败,请检查您是否在员工列表或者是否有读取员工列表的权限',indicator: 'yellow'}));
}//-----------------------2023.10.10----------------------------------
// 仅适用于系统过渡期,方便车间人员等其他人员查看评论
//------------------------下面为评论代码------------------------------
var 显评吗 = true;
var url = null;
var 评论s = '';
function 显示评论(标签属性){url = window.location.href;//判断是否初始化了评论元素if (!document.querySelector('#评论')){初始化评论元素();}//先初始化评论2023.10.12document.getElementById('评论').innerHTML = '没有评论<br>没有评论';// 获取所有符合条件的元素let elements = document.querySelectorAll(`[data-page-route="${标签属性.split('"')[1]}"] [data-doctype="Comment"] .content`); if(elements.length>0/* && 显评吗*/){评论s = ' ';// 遍历元素innerTextelements.forEach(e => {评论s += `<div class="indicator-pill whitespace-nowrap red" style="max-width: 400px; height: auto; display: block; white-space: unset;"> ${e.innerText} </div><br>`; });document.getElementById('评论').innerHTML ='评论: ' + 评论s; // 设置的文本内容}else{显隐元素封装版('隐');}//侧边栏有显示的消息条数*************************↓↓↓↓↓↓↓↓↓↓**if (document.querySelector(标签属性).innerText>0) {显隐元素封装版('显');}载入提示库();
}function 显隐元素封装版(显隐){显隐=显隐=='显'?"显示":"隐藏"; //2023.10.12显评吗=显隐=='显'?false:true;显隐元素('评论', 显隐)显隐元素('显评按钮',显隐)
}function 显隐元素(id,显隐){try{document.getElementById(id).style.display = 显隐==="显示"?'block':'none';}catch(err){console.log(id+'还没有加载到页面')}
}function 初始化评论元素(){// 创建一个按钮固定在右下角var btn = document.createElement("div"); // 创建一个元素btn.setAttribute("class", "row form-section card-section visible-section");btn.setAttribute("style", "opacity: 77%;");btn.style.position = "fixed"; // 设置按钮的定位方式为固定btn.style.top = "3px"; // 设置按钮距离底部的距离为10pxbtn.style.left = `${document.querySelector('.navbar-nav').getBoundingClientRect().right}px`; btn.style.zIndex = 1050;btn.style.paddingBottom = 0;btn.setAttribute("title", "点击直接到底部");btn.id="评论";btn.onclick = function() {window.scrollTo(0, document.body.scrollHeight);}; // 滚动到底部document.body.appendChild(btn);let x = document.createElement("div"); //2023.10.9-----点击隐藏评论x.innerHTML="点击隐藏评论"x.style.position = "fixed"; // 设置按钮的定位方式为固定x.style.top = "3px"; // 设置按钮距离底部的距离为10pxx.style.zIndex = 1050;x.style.top = "1px"; // 设置按钮距离底部的距离为10pxx.id="显评按钮";x.style.left = `${document.querySelector('.navbar-nav').getBoundingClientRect().right}px`; x.setAttribute("class", "btn btn-secondary btn-default btn-sm");document.body.appendChild(x);x.onclick = function() {显评吗=!显评吗;x.innerHTML=显评吗?'点击隐藏评论':'点击显示评论';document.getElementById('评论').style.display = 显评吗?'block':'none';};
}function 载入提示库(){// 如果未加载提示库,才动态插入if (!是否加载了脚本('https://unpkg.com/tippy.js@5')) {//导入提示库const script1 = document.createElement('script');script1.src = 'https://unpkg.com/popper.js@1'; const script2 = document.createElement('script');script2.src = 'https://unpkg.com/tippy.js@5';document.head.appendChild(script1); // 在append script2前,确保script1加载完成script1.onload = () => { document.head.appendChild(script2); }script2.onload = () => {// tippy.js 加载完成后,才能用方法tippy('#评论', {content: "点击直接到底部"}); }}else{tippy('#评论', {content: "点击直接到底部"}); }
}function 是否加载了脚本(src) {// 查找头部是否存在该src的scriptconst scripts = document.head.querySelectorAll('script');for (let script of scripts) {if (script.src === src) {return true;}}return false;
}//------------------------上面为评论代码------------------------------
案例4(防呆
两个为空时,两个都非必填,但是填了一个就必须填另外一个(tippy方法要导入库,没就删掉没影响
frappe.ui.form.on('Production Record', {//报废物料编号防呆2023.10.16+++++++++++++++++++++++++++++++++++scrap_item_code(frm){if(frm.doc.scrap_item_code){frm.set_df_property("scrap_warehouse", "reqd", 1);tippy('input[data-fieldname="scrap_warehouse"]', {content: "填了这个要填报废品仓",showOnCreate: true}); }else{frm.set_df_property("scrap_warehouse", "reqd", 0);}},//报废品仓防呆2023.10.16+++++++++++++++++++++++++++++++++++scrap_warehouse(frm){if(frm.doc.scrap_warehouse){frm.set_df_property("scrap_item_code", "reqd", 1);tippy('input[data-fieldname="scrap_item_code"]', {content: "填了这个要填报废物料编号",showOnCreate: true}); }else{frm.set_df_property("scrap_item_code", "reqd", 0);}}
})
案例5(监控url
//监控url是否有变化
frappe.router.on('change', function() {//alert("url有变化了");if(window.location.href.includes('production-record/')){document.getElementById('ikun').style.display = 'block';}else{document.getElementById('ikun').style.display = 'none';}
})
这篇关于ERPNext的frappe的js脚本一些方法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!