marat-gainullin / platypus-js

Apache License 2.0
9 stars 9 forks source link

Custom Widgets API #87

Open AlexeyKashintsev opened 8 years ago

AlexeyKashintsev commented 8 years ago

Add API for custom UI widgets

marat-gainullin commented 8 years ago

Is NativeAPI widget.element insufficient?

valeriy-maslov commented 8 years ago

Here some elaboration. Sometimes (really often actually) developer must provide modern usable and reaaaaly beautyfull GUI for the best user experience. Especially in HTML5 clients. It's obvious that we can use any libs or GUI frameworks to rich this. But stills it gets really bad because:

  1. this 3rd side frameworks have not any bonds with PlatypusJS, so there is only one possible solution - making adapter which is not good at all 'cause mixing GUI low-level code with bussiness logic conflicts with PlatypusJS GUI concepts. Also it's not available in Platypus Designer, so development slows down.
  2. this components have not connection with ORM. For example: I need to create widget showing image loaded from destination stored somewhere in database and also this must refresh every time I choose some string from ModelGrid placed in the same form. There is no such widget in PlatypusJS right now. But if there was API I could create widget representation for img tag working PlatypusJS ORM, working with PlatypusJS events like onActionPerformed etc. May be this is not really the best example, but the point should be clear - GUI flexibility without harming general coding style in application and also availability of widgets in Designer.
  3. I've already said that - custom widgets must be available in designer, cause it's not right if you see one picture in Designer and completely different in browser.

widget.element is good to make some grooming, but still it's not the right way to make completely different widget. I totaly can say that 'cause I passed through working with it in past year in CBSM project with Cordova. I also used Onsen wich is based on AngularJS btw. So both ways are complete mess.

Also this API will be reaaaally usefull in new Corvus. I think we need to determine this API task more precisely.

marat-gainullin commented 8 years ago
  1. 3rd side frameworks don't need any bounds to Platypus.js. What for? The point about adapters is unclear. What kind of adapter an application developer should build and what for? Why and how adapters development should lead to mixing of low-level GUI code and business logic of an application?
  2. 3rd side widgets doesn't need any bounds with Platypus.js ORM. ORM has its own events and widgets have theirs own events (regardless of are they Platypus UI widgets or not). Platypus UI widgets know about how to bound to Platypus ORM entities, but it is not general behaviour of widgets. May be it will be more clear, when new branch "manual-binding" will be merged into master and then into production. There are some changes in Platypus UI API in this branch, enabling application code to bind them to any JavaScript object, regardless of binding technique (Es6, O.o, defineProperty, ko.observables and so on).
  3. Custom widgets can't be represented in the designer easily. This is very complicated question. It should be reviewed more precisely. May be there is a way of custom widgets templating.

widget.element is much more powerfull. It allows to build composite UI in browser and thus to combine widgets of different nature in one UI.

valeriy-maslov commented 8 years ago
  1. I explained it not so good. Let me do this again. By 3rd side bounds with PlatypusJS I meant that any time you need to mix it with some Platypus features you need data convertion from Platypus state into another understandable for this 3rd side lib or whatever it is. It's usual thing in this kind situations and may be not so bad at first sight, but only until this 3rd side lib or framework provide it's own features similar to PlatypusJS's. Great example is my Onsen experience: as I said before it's based on Angular which is heavy by itself. And it's really sad that I used this only because there is not custom widgets in PlatypusJS, so I wrote platypus module to retrieve data from database and convertion to objects with another, after this I wrote platypus module to render Onsen template with data retrieved with PlatypusJS ORM into objects which is understandable for Angular which is re-render whole GUI after any change was done. This is huuuge overhead for displaying simple pleasant list of a few items. In this case Onsen could be replaced for another faster UI tool, but still it needs adaptor module. So there is a bit of useful code and many code for convertion. And it's also have it's own renderer, so why I must use this if Platypus has it's own and can just grab this data show it?
  2. I understand that. But as you just said: Platypus UI widgets know about how to bound to ORM ;) So 3rd side frameworks doesn't which is sad. And I guess ORM not the only thing to bound to. And as far as I can undestand if widgets has it's own events and stuff so the difference between platypus widget and 3rd side widget is that first implements something platypus relating (like java interface or class or something, don't know how it works inside exactly). So if this is the only defference so it could be the path to make custom widget by implementing this things. May be there is nothing to develop at all for this and the only thing is to describe it in documentation, isn't it? Can you provide more information about this difference? Btw I didn't catch the point about "manual-binding" branch. What exactly was meant by binding UI widgets to any object? Can you provide an example?
  3. Obviously it is. And may be there is no urgent need in displaying it in designer as they are. But if we will have ability to make custom UI so it make sense to append it in layout files as XML tags passing parameters via attributes like all platypus UI widgets do to render it in HTML5 client in their all beauty.

PS: I also wanna say that this API feature can make PlatypusJS more attractive tool for many people. Some custom widgets developed by community could bring more interest to platform. PPS: Folks are supporting this feature :)

valeriy-maslov commented 8 years ago

Update commentary.

  1. Any 3rd side framework adaptation causes mix of logic to rich needed data state so it can be used in this 3rd side framework. In my opinion it usually happens before UI rendering, but after any bussiness logic happens. So this is not complete mix, cause you can separate this into another module. But still you need to get it into your own hands while there is no other way to delegate, 'cause PlatypusJS don't know anything about 3rd side and vice versa. So this convertional module (or code) - this what I call adapter, like java adapter pattern, you know what Im saying =) And usually that's not so scary at all and it works, but the question is: why I can not just do the same without any adaptation? That's my point, may be I'm wrong, so correct me, but in my past experience that's how it was. So by mixing I meant that with bussiness logic you also must look after this adaptation logic for UI building. Any structural changes in one half cause refactoring of this adaptation slowing down. As PlatypusJS platform developer I wanna concern only about bussiness logic.

Still I used widget.element only as way to rich DOM element to make some grooming. Do you mean that any other DOM element can be assigned and this will work?

marat-gainullin commented 8 years ago

For better understanding of each other, we need concrete examples of adaptors code. Let's discuss them and thus we will reach a clear point.

I believe, that there is no need to develop adapter layers in an application at all, because any framework or UI library should be able to accept JavaScript objects regardless of theirs source. At this moment, Platypus UI is such UI library.

On the other hand, since Object.observe was eliminated, and ES6 proxies were added, we should consider data binding layer in any our browser application, wichever UI library we will use. Otherwise we are pushed to use framework-specific ways of data binding.

There are widgets in Platypus UI library without internal structure of widget.element. So, an application developer is able o add an any widget from any library to Platypus UI widget and vice versa. See web socket example for details.

Also, i want to make the point about desginer clear. Do you want Platypus.js to support third party widgets in its UI Factory at runtime and in palette and layout in designer? I think this feature is completely separate from Platypus UI library itself. Am i right?

valeriy-maslov commented 8 years ago

Recently @jskonst provided this good example of using placeholders as an alternative way of widgets customization. At first sight this thing is looks like much closer to the things I was talking about: platypus style events, custom markup etc. But after closer look I found out two things.

I guess if second bullet is correct, so this exact issue is 80% solved. Another 20% is the first bullet which is still would be a great feature anyway if it will be done. But right now I am extremely interested in second bullet. So am I right about manual binding?

marat-gainullin commented 8 years ago

Yes. You are absolutely right. The new branch manual-binding will be merged to master after tests transferring to Travis CI.

valeriy-maslov commented 8 years ago

UPD: Marat, about UI Factory and palette and stuff in designer: yes, that is exactly I was talking about. And I understand that it's complicated. But this would be great anyway. Just to be more clear I wanna say that by 3rd party widgets I meant not only exact 3rd party frameworks and libs, but also widgets made for platypus such as widget in example which @jskonst made. In this case 3rd party widget for me is any custom UI element with it's own markup and styles (and sometimes with behaviour) which can be plugged and used inside application. So this is first bullet in my recent comment.

marat-gainullin commented 8 years ago

I believe that placeholders can cover needs of application UI developer in case of using third-party and external widgets.

valeriy-maslov commented 8 years ago

For long enough, yes.