Try ERPNext Try Frappe Cloud Buy Support Partners Foundation

Action for fieldtype Button

Hi everyone,

In a custom app I have a field with fieldtype button. And I want to add action to it. I want to run a method then return a value to fill a data field and check the checkbox when the button pressed.

To my understanding there are 3 options:

  1. Server script: using the button options I can connect it to a method on doctype_name.py file.
  2. Client script: using doctype_name.js directly add action to the button.
  3. Both: using js to make frappe.call to server method and return the action.

But using #1 I can’t check the box and fill the data field.
Using #2 I can’t run the server method.
Using #3, the frappe.call method path is not recognized because the py file is in the same doctype directory.

What is the best way to do this?
Thank you.

Would the MultiSelectDialog work for you? Not exactly as mentioned in the below link, but may be you can customize this method.

MultiSelectDialog - API (frappeframework.com)

Thanks @hashir,
I’m not doing a dialog. My question is related to the field type of Button in a custom doctype.
And it is also not the button on that top page head next to the Save button.

oops, my bad. i understood initially that you need function to have checkbox to select from it.

i’m not an expert and not sure at all, but i think option 3 is the best way to go, why not copy the same function to a different file like util.py and give its path in the js file?

Because I try to keep the code in the related doctype files :slight_smile:
And I don’t know when not in the same doctype_name.py if I can use self.

I really hope someone can share how to do this :pray:
Or to send value from py to js which is not initially triggered by js (i.e not using frappe.call)

Elaborate please.

#1 using the server script, I don’t know how to change the display of checked checkbox after setting the value to 1.

#3 using the js to catch the button click and send it to py code via frappe call. But since the doctype_name.py file is in the doctype directory (in app/app/doctype/doctype_name.py) I don’t know how to write the path because frappe doesn’t recognize a py file in doctype directory of a custom app.

Use something like

doc = frappe.get_doc(doctype, docname)
doc.check_box = 1
doc.save()
doc.reload()

Frappe does recognize it. You path will be

app.module.doctype.doctype_name.function_name

OK. Will try this.

Yes I use this structure but the error always says there is no function_name in that path.

But let me try again…

Did you whitelist the function?
https://frappeframework.com/docs/user/en/guides/basics/frappe_ajax_call#calling-whitelisted-functions

Add @frappe.whitelist() just above your function.

If I do the code in the doctype_name.py, I don’t have to do this right?
And it is for a new doc.

Tried both whitelisted and not. Still the same.

If you’re in the document class, you can use self. instead of doc.

Can you show your code and a SS of the error?

OK… tried it just now and it is the self.reload() that I need.

I will exercise with the js and frappe.call to see if I made a mistake in the method path.

Thanks @rtdany10

1 Like

Hi @rtdany10,
How to call the method within a class?
If the def is outside the class it can be called (whitelisted or not) using the path, but not if inside a class.

Example:

class Member(Document):
    def button_a(self):
        checkbox_a = 1

def button_b(self):
    checkbox_b = 1

The path app.module.doctype.member.member.button_a returns

AttributeError: module 'app.module.doctype.member.member' has no attribute 'button_a'

While the path app.module.doctype.member.member.button_b is able to run the method.

Let abc be a document of type Member

doc = frappe.get_doc('Member', 'abc')
doc.button_a()

And how to put it as path for use in frappe.call() method ?

You can only call whitelisted functions with frappe.call(), not class.
What is your use case tho?

I have a fieldtype button which I process the method directly in py file of the doctype. Not in js.
But since I want to change the hidden/show of other fields, I need to do it in js, right?
Is there a way to change field property directly from py?

As my initial post, there are 3 ways to link method to button. Each has their own limitation (as I know, and I’m not a developer :pray: )

So the last post of mine was in related to calling a py method from frappe.call(), where that method is inside a class. So it can return a value to js to change the field property.