ERPNext的frappe的js脚本一些方法

2023-10-30 23:20
文章标签 方法 js 脚本 frappe erpnext

本文主要是介绍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脚本一些方法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/311225

相关文章

Spring Security方法级安全控制@PreAuthorize注解的灵活运用小结

《SpringSecurity方法级安全控制@PreAuthorize注解的灵活运用小结》本文将带着大家讲解@PreAuthorize注解的核心原理、SpEL表达式机制,并通过的示例代码演示如... 目录1. 前言2. @PreAuthorize 注解简介3. @PreAuthorize 核心原理解析拦截与

一文详解JavaScript中的fetch方法

《一文详解JavaScript中的fetch方法》fetch函数是一个用于在JavaScript中执行HTTP请求的现代API,它提供了一种更简洁、更强大的方式来处理网络请求,:本文主要介绍Jav... 目录前言什么是 fetch 方法基本语法简单的 GET 请求示例代码解释发送 POST 请求示例代码解释

Feign Client超时时间设置不生效的解决方法

《FeignClient超时时间设置不生效的解决方法》这篇文章主要为大家详细介绍了FeignClient超时时间设置不生效的原因与解决方法,具有一定的的参考价值,希望对大家有一定的帮助... 在使用Feign Client时,可以通过两种方式来设置超时时间:1.针对整个Feign Client设置超时时间

C/C++错误信息处理的常见方法及函数

《C/C++错误信息处理的常见方法及函数》C/C++是两种广泛使用的编程语言,特别是在系统编程、嵌入式开发以及高性能计算领域,:本文主要介绍C/C++错误信息处理的常见方法及函数,文中通过代码介绍... 目录前言1. errno 和 perror()示例:2. strerror()示例:3. perror(

CSS去除a标签的下划线的几种方法

《CSS去除a标签的下划线的几种方法》本文给大家分享在CSS中,去除a标签(超链接)的下划线的几种方法,本文给大家介绍的非常详细,感兴趣的朋友一起看看吧... 在 css 中,去除a标签(超链接)的下划线主要有以下几种方法:使用text-decoration属性通用选择器设置:使用a标签选择器,将tex

C++变换迭代器使用方法小结

《C++变换迭代器使用方法小结》本文主要介绍了C++变换迭代器使用方法小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1、源码2、代码解析代码解析:transform_iterator1. transform_iterat

C++中std::distance使用方法示例

《C++中std::distance使用方法示例》std::distance是C++标准库中的一个函数,用于计算两个迭代器之间的距离,本文主要介绍了C++中std::distance使用方法示例,具... 目录语法使用方式解释示例输出:其他说明:总结std::distance&n编程bsp;是 C++ 标准

微信公众号脚本-获取热搜自动新建草稿并发布文章

《微信公众号脚本-获取热搜自动新建草稿并发布文章》本来想写一个自动化发布微信公众号的小绿书的脚本,但是微信公众号官网没有小绿书的接口,那就写一个获取热搜微信普通文章的脚本吧,:本文主要介绍微信公众... 目录介绍思路前期准备环境要求获取接口token获取热搜获取热搜数据下载热搜图片给图片加上标题文字上传图片

Linux换行符的使用方法详解

《Linux换行符的使用方法详解》本文介绍了Linux中常用的换行符LF及其在文件中的表示,展示了如何使用sed命令替换换行符,并列举了与换行符处理相关的Linux命令,通过代码讲解的非常详细,需要的... 目录简介检测文件中的换行符使用 cat -A 查看换行符使用 od -c 检查字符换行符格式转换将

SpringBoot实现数据库读写分离的3种方法小结

《SpringBoot实现数据库读写分离的3种方法小结》为了提高系统的读写性能和可用性,读写分离是一种经典的数据库架构模式,在SpringBoot应用中,有多种方式可以实现数据库读写分离,本文将介绍三... 目录一、数据库读写分离概述二、方案一:基于AbstractRoutingDataSource实现动态