Get text box data after pressing button in plugin

I’m working on my first plugin, and I want to be able to get the text content of a text box in the admin panel (part of the plugin) after pressing a button. Then, I want to do some stuff with the content in Ruby. Is there a way for the Ember frontend to send data back to the Ruby backend?
My plugin.rb:

# name: Discourse Sample Plugin
# about: A simple plugin to play around with
# version: 1.0.0
# authors: NateDhaliwal 
# url: https://google.com

enabled_site_setting :plugin_enabled

add_admin_route 'sample_page.title', 'sample-page'

Discourse::Application.routes.append do
  get '/admin/plugins/sample-page' => 'admin/plugins#index', constraints: StaffConstraint.new
end

My assets/javascripts/discourse/templates/admin/plugin-sample-plugin.hbs:

<div class="textbox">
  <input id="textbox-data" type="text" />
</div>

<div class="buttons">
  <DButton
    @label="sample_page.send"
    @action={{action "sendTextboxData"}}
    @icon"arrow-right"
    @id="send-textbox-data"
  />
</div>

Not sure what by sendTextboxData should do.
My assets/javascripts/discourse/sample-page-route-map.js:

export default {
  resource: 'admin.adminPlugins',
  path: '/plugins',
  map() {
    this.route('sample-page');
  }
};

My assets/javascripts/discourse/controllers/admin-plugins-sample-plugin.js.es6:

import Controller from "@ember/controller";
import { action } from "@ember/object";

export default class AdminPluginsSamplePlugin extends Controller {

  @action
  sendTextboxData() {
    // How do I send the data?
  }
}

If I do manage to get the data to the Ruby backend, where do I put the logic for dealing with the data? In plugin.rb? Or some other file?

Or would a setting be more ideal? However, my use case is that the textbox won’t be needing to retain values each time. Does yml provide this functionality? Can I change Site Settings through Ruby?

It sounds like what you’re looking for is to make an API in Ruby that the JS can call. An example is the Data Explorer plugin, which implements a user input API with admin permission scope on the ruby side.

The JS for the data explorer is on the beefier side of things, so I’ll just give a simplified example of what you’d probably need.

import { ajax } from "discourse/lib/ajax";

...
  @action
  sendTextboxData() {
    ajax("/endpoint", {
        type: "POST",
        data: {
          key: "value"
        },
    }).then((result) => {
        // do something with the result
    };
  }

You can do the same thing with a native JS fetch() but it seems that the ajax() function that discourse provides handles a few minor things under the hood.

If your ruby code is light enough, you can probably fit it entirely within a single file for the controller. Otherwise you can organize it however you need.

2 Likes