Jump to content

DxGrid - Remove row


Recommended Posts

Posted

Whats the magic to add the delete row button and to remove the row from the collection on the grid?

This will add the button, but where am I supposed to wire up the onClick, right now it takes me away from the plugin page.

options.columns.Add(new DxGridColumn()
                    {
                        type = "buttons",
                        buttons = new []
                                  {
                                      new DxGridButton{text = "Delete", onClick = "deleteConfiguration", icon = "trash"} 
                                  }
                    });


This doesnt add the column, and it doesnt look like there is a way to add the DxGridCommandColumn that you would normally add for DxGrids and have it auto populate.

options.editing = new DxGridEditing
{
    allowAdding = false,
    allowDeleting = true,
    allowUpdating = false,
    mode = DxGridEditing.GridEditMode.row,
    useIcons = true
};

 

Posted

Please hold on, I'll dig up a sample for this tomorrow.

Posted
1 hour ago, softworkz said:

Please hold on, I'll dig up a sample for this tomorrow.

An example that also write back data from wizard to plugin options would also be great, I think it follows the pattern for dialog using the OnDialogResponse, or if there was just a database plugin store would probably also make life simpler than having to hold json around thru multiple views. Why not make a generic KVP store that stores thing by pluginId and a KVP?

Posted (edited)
3 hours ago, bakes82 said:

An example that also write back data from wizard to plugin options would also be great, I think it follows the pattern for dialog using the OnDialogResponse, or if there was just a database plugin store would probably also make life simpler than having to hold json around thru multiple views. Why not make a generic KVP store that stores thing by pluginId and a KVP?

Alright, good questions!

Let me start from here: The Plugin UI model doesn't prescribe any way for how to store and persist settings. That's essentially all up to you and your own judgement about which way you think would be the most suitable for your use case.
The largest amount of views/dialogs/wizards we have on our side are for TVnext (yet unreleased) where storage is mostly done in a database model (typed, multi-layered).
Then we have an upcoming plugin to supersede two existing plugins where settings are persisted as an XML file (to match the predecessors' persistence model).
Other new plugins are persisting settings to JSON files due to better flexibility and cross-version behavior.
That means: you can do it in whichever way you prefer, just that is should ideally land in the designated folder which is. Emby SDK Reference: IApplicationPaths.PluginConfigurationsPath.

On top of all this, we had thought about how we could make life easier for plugin developers and we got two answers for this

  1. The PluginSimpleUI template
    This is meant for plugins where you have just a few simple values to configure.
    Developers don't need to care about anything here because the UI class is also used as the storage class, so you just need to add your values as properties and you're done
  2. The storage implementation in the PluginUI Demo project
    This is just meant to be an example for how you can do it. You can copy it and adjust it to your specific needs or you can run your own implementation - it's all up to you.

If you prefer a key-value store, you are free to implement that and you're again free to choose a persistence mode for it.

 

 

Besides that above, general drawbacks of using KV stores are:

  • Typing gets lost: all values are just string
  • It doesn't obsolete the need for serialization/deserialization (or at least some kind of "value conversion")
  • You need to perform serialization/deserialization on every single value (rather than once for the whole storage class
  • This pattern doesn't naturally provide atomicity on save (save all or nothing, depending on whether all settings are consistent)

In many cases, these bullets might not matter, but I still avoid it usually because requirements can change and then you're sitting on a pattern which doesn't match the (new) requirements anymore.

But any way, it's all up to you!

Edited by softworkz
Posted

Im saying the SDK should provide a simple KVP repo for saving the plugin values in the default emby db. I understand I could create another db for this, just as I could create a whole API and store everything in the cloud, but the KVP repo would make life so much easier than passing the JSON around to maintain one "plugin" json configuration file, all the controls seem to already be designed around the "onSave" events, let me inject the IPluginDBSaveRepo, do repo.GetValue("MyConfigOption", pluginInfo.Id), and then a repo.SaveValue or UpsertValue in the onSave and boom Im on my way and I just removed a bunch of boilerplate code in every plugin you create. I suppose you could make a nuget for this, you could do it for JSON also, also couldnt the "View" files PluginWizardView etc be tossed into another nuget to avoid all this extra boilerplate?


This is all boilerplate for most people Id think.

image.png.c61cb3e8165264469430d4155a06898d.png

Posted (edited)

Sorry, but there are no intentions for creating a DB storage for plugin settings. You have plenty of ways to do this, and it's all up to you to do it in whichever way you prefer.

The purpose of the "boilerplate code" is to protect or "isolate" your work from changes to the API at the server side. It allows you to adapt to future API changes of the server API by making simple changes to the "boilerplate code" only, rather than having to make changes to every single page/dialog/wizard class you have created.
You could also drop this entirely and directly use the server APIs for plugin ui without this intermediate layer, but being more "vulnerable" to server-API changes then.
Since this layer is meant for adaption, there's no point in publishing it as a nuget package, because then it would no longer be able to fulfill its purpose.

 

Edited by softworkz
Posted

Now for the grid interaction. There are generally two ways for interaction:

  1. Client-Side grid interaction
    In that case, the user is editing grid-data at the client side. This includes editing (of grid cell values), adding rows and deleting rows.
    Once editing is complete the users presses some kind of button which causes the edited grid data to be round-tripped back to the server and at the server side you then need to figure out which rowss have been deleted, added and/or changed, then pplying the ose changes to your data stored.
    The code you've shown which adds a delete button to every grid row is for client-side editing. Unfortunately that's not properly working in the current version, it's on my list to get this fixed.
    In addition to the in-grid buttons it's also possible to add custom buttons to perform client-side grid actions (needs to be documented, in that case, the Emby SDK Reference: ButtonItem.Data1 value is set to "GridCommand" and Data2 is set to the desired action
     
  2. Server-Side  grid interaction
    This means using buttons just like in case of any other plugin ui view.
     But what you need now is to knw which row(s) in the grid are currently selected. A grid can be single-selection or multi-selection depending on Emby SDK Reference: DxGridSelection.mode. You can also set Emby SDK Reference: DxGridSelection.ShowCheckBoxesMode  to add a checkbox column.
    In all those cases, the grid options need to specify a unique key (column), and then you also need roundtrip the row selection state between server and client-side. For this, you just need to create a hidden property of type string list, e.g.:
     
            [Browsable(false)]
            public IList<string> SelectedItemsIds { get; set; }

    and then you specify that via this attribute: Emby SDK Reference: GridSelectionSourceAttribute.GridSelectionSourceAttribute on the gird property, i.e.:
            [DisplayName("Available Rows")]
            [Description("Please select a row")]
            [GridDataSource(nameof(GridRows))]
            [GridSelectionSource(nameof(SelectedItemsIds))]
            public DxDataGrid TestGrid
            {

    GridSelectionsource works in both directions, so you can also set your desired selections in code

  3. Now in casee of a button event, you can check the p p SelectedItemsIds property and perform the desired actions.


  4.  
Posted

So basically the grid is just a table with a filter, any of the advanced usage like buttons per row etc arent supported and I should just keep using the list view instead.

Posted

No, it's a very capable high-performance grid with loads of features, but inline buttons aren't working right now. What you use is up to your own choosing.

Posted
1 hour ago, softworkz said:

No, it's a very capable high-performance grid with loads of features, but inline buttons aren't working right now. What you use is up to your own choosing.

Im very familiar with DevExpress grids, you have an entire abstraction on top of it with 0 documentation and stuff not working lol, so saying it has loads of features means nothing, it took over a year to get an example of how to use the "wizard" and even still there is no documentation on how to pass the data from the finished wizard back to the calling page. Like it seem so poor that you arent pushing best practices and defined patterns but instead say oh we dont care how you do it, its just lazy, most of the people that have developed plugins are hobbyist at the best youd think you would want clear easy to use framework but no youre like just do it however and copy/pasta over all this generic boilerplate every time, sure makes managing multiple plugins so easy especial on updates ...... Im not sure why its so complicated to build a simple plugin that has a few global fields IE API key etc, and then a user defined collection of items, I know the devexpress grid can have this all built in and just pass it a model for the collection piece.

Posted (edited)

LOL yourself! If you would _really_ know the Dx Grid, then you would have realized that we don't have any "abstraction on top". The config classes are implementing the original dx grid configuration without anything in-betwen.

Besides that, please decide whether you are interested in help or just up to arguing and complaining. I got no time for the latter.

Thanks

Edited by softworkz

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...