Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancement: Allow custom buttons on toolbar #69

Open
green3g opened this issue Aug 18, 2016 · 12 comments
Open

Enhancement: Allow custom buttons on toolbar #69

green3g opened this issue Aug 18, 2016 · 12 comments

Comments

@green3g
Copy link
Contributor

green3g commented Aug 18, 2016

I'd like to submit a pull request eventually on the attributes table toolbar to allow a configureable menu or buttons to be added to the toolbar. When the button or menu item is clicked, it publishes a topic with the rows in the table and/or the selected rows in the table.

Use cases:

  • I want to select multiple features and then do something with them, like create a workorder
  • I want to update multiple features at a time, the topic might open a form that will iterate through the features and update them with the new attribute (similar to field calculator)

At first glance this seems pretty feasible. What do you think?

@tmcgee
Copy link
Owner

tmcgee commented Aug 18, 2016

thanks @roemhildtg I like the concept and have considered similar functionality for the Export widget.

Conceptually, the ability to add buttons/menus already exists. Another companion widget could subscribe to a existing topic like addTable or addTab. Once the tab is added, the button/menu can be added to the toolbar (tab.attributesTableToolbarDijit).

One advantage I can think of for encapsulating the functionality in the companion widget is that it can be reused easily with any app and multiple tabs in the same app. Just include the widget in the app, and its done. The Export widget is a good example for this. Currently, the Export button is visible on the toolbar but does nothing if the Export widget is not included. You must explicitly hide it within the AttributeTable widget's config. Moving a small amount of code from the AttributesTable widget to the Export widget would remedy this.

One simple enhancement for the AttributesTable widget that might be useful is to add new topics that are subscribed to for add/enable/disable/remove items from the toolbar. This allows you to publish a topic to add a button/menu whenever you like from other widgets or other code. Specifically, I can see this as being useful to enable/disable a button based on whether table rows or features are selected.

Thoughts?

@green3g
Copy link
Contributor Author

green3g commented Aug 18, 2016

I see what you're saying, so if a widget dev wants to use the toolbar, they can simply listen for the tab topic and add a button to the tab. I hadn't really thought about that approach.

That approach would work for me I think.

If I'm correct, the addTab topic has a configurable topicId also, so a custom widget would have to subscribe to topicId + '/addTab' correct? So I guess the user configuring the widget needs to put the same topicID in both the custom widget and the attributes table for this to work correctly. I hadn't looked into this much before but I see now, the export widget has a topicId property to handle this.

@tmcgee
Copy link
Owner

tmcgee commented Aug 19, 2016

yes, you would subscribe to topicID + '/addTab'. One clarification is if you don't change the topicID for the AttributesTable, it will be attributesContainer. You only need to change it if you have more than 1 instance of that widget.

The exportWidget topicID defined in the the Export widget is used to open that widget. That would not be used any longer with the new approach we are discussing - the click event for button can directly call a method in the Export widget. I do use the export's topicID for interaction with another widget via topic publish/subscribe so that approach would remain valid.

@green3g
Copy link
Contributor Author

green3g commented Aug 19, 2016

Right, in the custom widget it could be something like this:

topic.subscribe( this.topicID + '/addTab', function(tab){
    var button = new Button(/*...*/);
    tab.attributesTableToolbarDijit.addChild(button);

    //sudo code...won't work as written but could do stuff like this
    tab.grid.on('selection-clear', function(){
        button.disable();
    });

    button.on('click', function(){
        topic.publish('workorder/createBatch', {
            features: tab.grid.selectedRows
        });
    });

    //etc...
});

@tmcgee
Copy link
Owner

tmcgee commented Aug 19, 2016

something like that should work. Depending on where that code resides, your button.click could call a method directly instead of relaying using the topic.publish. I would go that route if possible.

@green3g
Copy link
Contributor Author

green3g commented Aug 19, 2016

Right, okay like this:

    button.on('click', function(){
        lang.hitch(this, function(){
             this.createWorkorder(tab.grid.selectedRows);
        });
    });

@tmcgee
Copy link
Owner

tmcgee commented Aug 19, 2016

yep

@green3g
Copy link
Contributor Author

green3g commented Oct 5, 2016

So I've got it working with this:

                topic.subscribe('attributesContainer/tableAdded', function(tab) {
                    tab.attributesTableToolbarDijit.addChild(new Button({
                        label: '<i class="fa fa-clipboard"></i> Create Workorder',
                        onClick: function() {
                            console.log(tab.grid.store.data.map(function(row) {
                                return row['cid'];
                            }));
                        }
                    }));
                });

but every time the table is opened, it adds yet another button. So still working that out, but its functional.

@tmcgee
Copy link
Owner

tmcgee commented Oct 5, 2016

how about something like:

var handle = topic.subscribe('attributesContainer/tableAdded', function(tab) {
    tab.attributesTableToolbarDijit.addChild(new Button({
        label: '<i class="fa fa-clipboard"></i> Create Workorder',
        onClick: function() {
            console.log(tab.grid.store.data.map(function(row) {
                return row['cid'];
            }));
        }
    }));

    // add it only once
    handle.remove();
});

@green3g
Copy link
Contributor Author

green3g commented Oct 11, 2016

Okay, so here's my initial solution: https://gist.github.com/roemhildtg/b38e7303e8ee2c0cc2465341f950f7c7

  • I added a buttons property to each layers object, which when the topic is published, it looks up the correct layer and adds its custom buttons
  • Each button can be excluded with a simple boolean switch, this allows certain logged in users to have certain buttons
  • Excluding the workorder button, its pretty simple, each button has an onClick, and a label, and can have any additional properties that a button might have. tab gets mixed in when the button is added
  • I needed to keep the topic subscribed, since I'm using multiple tabs and I want certain buttons to be added to certain tabs

@tmcgee
Copy link
Owner

tmcgee commented Oct 11, 2016

@roemhildtg thanks for sharing your solution.

I would be interested in seeing how you approached the security and roles. Is that something you can share, either in a public repo or directly e-mailed to me?

@green3g
Copy link
Contributor Author

green3g commented Oct 11, 2016

I could share the basics when I get some free time. Basically I'm using Flask and Flask-Login to authenticate with ArcGIS Server, and managing user/roles through AGS. Some simple python requests fetch user roles and print them to a FLASK js variable in the template. So the js app can show hide buttons based on roles, and the AGS won't let a user do anything they don't have the role for. There's some additional workorder views in the Flask app that are also protected using these roles.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants