Run script inside hmtl of field formatter

I have a fieldformatter that in its _convert method needs to do a HTTP (POST/PUT) request to a url using one of two different buttons (or allow user to input a value and post that). I have created an html <button> and for the onClick= I simply reference an imported javascript that makes the call, but also tried doing a POST request with . Both options gets refused to execute inline script because it violates the following Content Security Policy directive: .....

How can I make this call? I would rather not force to allow inline scripts, and I have read how to fix it using event listeners etc., but I cannot figure out how to make it work in my _convert method.

Hi @Elaak,

thanks for your interesting question.

To make sure I understand correctly - you are using a field formatter to render a field as a button (or even a form) that should submit a request? That's a pretty cool idea to get custom UI into Kibana, although a bit hacky :slight_smile: .

I can see how the event listener workaround could work, you could add a custom data attribute like data-trigger-post-action="<the value of the field>" to your rendered html button. In your imported javascript you would have to install a click handler on the document that checks the target element on each click and whether it contains the data attribute and trigger the request if it's the case. The you don't need inline scripts.

Another possibility which is probably simpler is getting rid of javascript in the first place. You could use a regular html form with a nested submit button using <form target="_blank". Post requests shouldn't be a problem and it will open in a new tab so the current page is not lost.

If your use case is to add functionality to Discover in particular, you can also consider providing a separate "doc view" which will render as a tab (like the table and json view) for each row of discover: Inject front end code into Discover from custom plugin
This is the recommended way, as you have full control over the rendered html and attached event listeners. Plus this is an official API so we will support it and make sure it doesn't break because of an unrelated change which could always happen with the more hacky solutions.
The location in the code changed, its now https://github.com/elastic/kibana/tree/master/src/legacy/core_plugins/kbn_doc_views/public

Hi @flash1293,
Thank you for your suggestions!

Yes that is correct. It is indeed hacky, but it was the simplest solution to a critical issue :slight_smile:

I tried the form workaround with the target=_blank property, but my controller does not appear to accept it due to the charset:

Content type 'text/plain;charset=UTF-8' not supported

I think I will try the event listener workaround, but I am unsure how I access the document in my javascript. How would the javascript find it?

I tried the form workaround with the target=_blank property, but my controller does not appear to accept it due to the charset:

With controller you mean the code handling the POSTed form data? A regular form won't send the request as JSON so you would have to adjust the receiving end to handle this case. If thats out of question, trying the event listener approach is probably not too bad.

The document is a global variable, so you just have to do

document.addEventListener('click', (e) => console.log(e))

This will log the event for every single click event on the page. Now you just have to replace the console.log with a function checking whether the clicked element is one of your buttons and trigger the request if it's the case.

Thank you, I didn't realize that it was so easy actually. I was trying out with an id=btn on my <button> and then document.getElementById("btn") .... but it does not work. I got it working in the end with the custom data attribute, but just out of curiosity why does it not appear to work using the id and getElementById() ?

The consuming format is text/plain for both the form and my java spring controller. The issue is that I cannot make my controller to accept this Content-Type: text/plain;charset=utf-8 (or accept any charset). This issue is still there now that I have implemented the EventListener.

I got it working in the end with the custom data attribute, but just out of curiosity why does it not appear to work using the id and getElementById() ?

It's about the order of execution - your getElementById() code is probably running before Kibana is able to render the button. For catching the event on document level it doesn't matter because the document is always there.

The consuming format is text/plain for both the form and my java spring controller. The issue is that I cannot make my controller to accept this Content-Type: text/plain;charset=utf-8 (or accept any charset)

If you are using the fetch api to trigger the request you should be able to set the header to any value you want as in this example: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#Supplying_request_options

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.