This is what you can end up with, managing all possible state changes manually. I've done this myself with jQuery, show/hide, enable/disable elements. Turns into a game of Whac-A-Mole and full-time job for testers. Now imagine adding/removing elements and having to update this monster. No thank you.
https://github.com/bradwoods/7guis-html-css-js/blob/19279899...
I like it, and it's also a good example of why a framework will start to be useful if you get more complex code.
When we arrive at the CRUD widget,a simple <script> dep on petite-vue (6ko: https://github.com/vuejs/petite-vue) would half the implementation by half.
Of course it would still count as more lines of code in total, but not sure that matters.
Anyway, when I teach react/vue, I always start with the vanilla example because just like with ORM, people need to know the benefit and cost of the abstraction.
I think this is a good teaching example of doing GUIs with the DOM and the MVC approach. It builds up step by step to introduce all the concepts.
A few years back I stumbled into something a bit more complex, still done in pure js, just for the hell of it: https://github.com/morris/vanilla-todo
And then wrote my own version, with code a lot closer to modern react, with undo/redo and other niceties - https://github.com/ivank/vanilla-teuxdeux
And what I leaned is that is astonishingly easy to write code that would be understandable to people coming from the redux crowd. Maybe that’s because redux is just such a simple concept in and off itself - a glorified switch on a big object. And it’s also quite easy to hack a simple version of vdom to make it all work.
What’s missing from all those vanilla js efforts though turned out to be testability. There is a ton of code in the modern js world just to allow you to mock/test your components, and thats for me the real tragedy of vanilla js.
I have no idea why W3C crowd have not invested into standardizing js tests in all these years…
The Cells example is super interesting to me, because I've longed for an open source, liberally licensed, spreadsheet component for the web, similar to what exists for rich editing (ProseMirror, Slate, Quill). Some UI frameworks like Material UI have a neat table component, but the pro version gets the fancy data grid, and it isn't designed to be able to function as a spreadsheet anyway.
Besides lacking an open source version, spreadsheets and data grids haven't been studied as well as they should be.
It is also difficult to build one using just the DOM. For instance, you can't have a table be horizontally scrollable with the scrollbar fixed at the bottom and also have a fixed header.
Here's something I played around with a while back that has keyboard navigation between cells. Going between pages isn't great. The default focus scrolling in Chrome skips a few rows, and it doesn't respect the fixed header when scrolling up to the top after scrolling down. https://table-edit-20210409.vercel.app/ https://gitlab.com/ResourcesCo/table-edit-20210409 I tried making it with CSS Grid just to see if it could be done, and it turns out, only with Firefox. https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_La... I'm thinking of drawing it with JavaScript, perhaps with a combination of canvas and DOM elements.
Back to the 7 GUIs - what's great about it is trying to build stuff from scratch. So much of web development is just putting components together and customizing them, but there is a lot of lower level work to do, and the more developers that attempt it, the more progress will be made.
Edit: found this, pretty interesting: https://github.com/TonyGermaneri/canvas-datagrid
> For instance, you can't have a table be horizontally scrollable with the scrollbar fixed at the bottom and also have a fixed header.
You might actually be able to do that with position:sticky now: https://jsfiddle.net/0ydsve3x/1/
I couldn't get it to work with a table - only with having to scroll all the way to the bottom to find the horizontal scrollbar.
Edit: hmm, it's working in the CodePen here: https://css-tricks.com/a-table-with-both-a-sticky-header-and... I'll have to fully revisit what I was trying to do and see if I can get it working.
Edit 2: Oh, I realized that I wanted the horizontal scrollbar to be sticky when it is an element taking part of the vertical space of a page, but more than a screenful. I found this that solves it but not for a table with a fixed header: https://amphiluke.github.io/handy-scroll/ To see what I'm talking about, go to the top of the demo, horizontally scroll, and note that horizontal scrollbar is shown when scrolling horizontally. Then click disable, and note that it isn't shown when scrolling horizontally, unless you go all the way to the bottom. Or, if you don't have a trackpad, you actually have to go all the way to the bottom to scroll it horizontally.
Have you tried holding shift while scrolling?
Yeah, it doesn't make a difference, and my use case is scrolling with just a mouse.
> because I've longed for an open source, liberally licensed, spreadsheet component for the web
I assume SlickGrid (https://github.com/6pac/SlickGrid/wiki/Examples) didn't satisfy your requirements?
I hadn't checked it out in a while. Thanks. It satisfies some but not others, and is a bit more monolithic. I found a project called slickgrid-universal by one of the recent contributors. This looks neat except it takes a while to scroll: https://ghiscoding.github.io/slickgrid-universal/#/example11
These examples are very reassuring to me. Sometimes, after a long day of fighting whatever trendy JS framework my current project uses, I may be tempted to advocate for a "back to the basics" approach with vanilla JS or even jQuery.
Anything after the temperature converter example makes it painfully obvious that it would not be a pleasant experience.
The whole environment around JS frameworks had got to be especially intimidating for new developers. There's this false sense that you can't do "anything" these days in JS without a package manager, a build pipeline, a local server, a view library, a state management library, etc...
Meanwhile all the functionality of vanilla JS is still there, and the language and runtime are arguably much better than they ever were.
It's worth experimenting with these things every now and then on your own, even if you don't have a simple setup at work.
Not arguing your point, because I believe its really valid.
However, the issue is, any moderately complex application will soon develop its own in-house Framework. Its the natural progression, very soon the head Dev will say "lets create a library to handle all our form validation requirements....lets create library separate UI from business logic...etc"
That's the real "slippery slope" from a management perspective.
Do we wind up developing our own in-house Framework which our current developers are very productive in (but new hires don't understand)? Or do we bite the bullet and opt for an already existing Framework that already has a dev community? I'm not suggesting its an easy answer as there are pros/cons to each. In the end for 90% of cases I think starting with an existing Framework (or at least "Framework-lite") is best approach.
> intimidating for new developers
Or in my case seasoned developers who have been away from that front (concentrating on database/infrastructure/security matters) for some time and might like to catch up a bit. I can still do things the vanilla (or jquery/similar) way but that might not be ideal, but beyond that the sea of choice is daunting to think about navigating.
Or maybe I've been away so long I should consider myself to be a newbie in a new environment, instead of just a bit out-of-date in one that has moved forwards rapidly in my absence!
It works well until you need to manage many states in one page. Even with knockout js, when an application become a little complex, it become hard to develop.
Alas, the common thing I see this days is devs fighting infrastructure instead of developing product.
Yep,it has become popularity contest for frameworks, and in the end they make developing even harder.
That's simply not true. You know better than thousands of developers who are using React or Vue in their projects, and they are just making their life harder?
So let's look at the data: According to stateofjs survey: 100% of JS developers know what React is, 80% are using it, 88% are satisfied. There is no "one size fits all" but saying that
> they make developing even harder
is saying
> These people are stupid and make their jobs more difficult
I'm not saying that majority is always right, but I think these devs might be onto something. I'm also trying to show how idiotic is the logic of tonis2 who throws such a slogan around without giving a single argument WHY these frameworks make development more difficult.
nodemon was my build tool.
The trick to write vanilla HTML is to make it static (no dynamic changes except layout/mobile responsiveness) Meanwhile the trick to writing a statefull app in vanilla JS is to not use HTML instead create the DOM tree using JS functions which gives you the ability to use higher abstractions, local/private state management and automatic UX tests.
Now get that list of different implementations going.
I’ve been thinking of something similar, and this is a good list, but is it “exhaustive”? What would such a list look like? Is there an objective way to explore all the various challenges of building UI?
Here’s one example: Very large forms. This is not covered, and can be quite challenging, especially when different parts of the form show up at different times. Even vanilla React fits this poorly (this is where Flux came into being, which ultimately spurred Redux, Recoil etc).
But also a CLI. A flow chart. Notebooks (Jupyter). So many types of UI to cover.
The cells example would be improved by keeping the top left corner clear by making that cell stick in place and on top:
#colHeadings .rowHeading {
z-index: 3;
top: 0;
}
I also believe keyboard navigability is essential for the cells example, although the task specification neglected to mention it. (But then, the spec doesn’t specify anything about the formulas either—though it does include a picture depicting something like =SUM(B1:C4).) Tab and Shift+Tab work to shift cell focus, but that’s all; at the very least, Up/Down/Left/Right should work for cell navigation, and some way of entering edit mode without needing the mouse (start with F2, which is standard across spreadsheet apps that I know; perhaps Enter too, though they don’t).This also doesn't have that issue, and it's also using a z-index: https://css-tricks.com/a-table-with-both-a-sticky-header-and...
Good points.
Regarding the author's content online - great work! Nice minimal design with clean and bold lines, right alongside a fantasy and whimsical design from the early days. Love the education background - keep up the good work and output!
Very cool. I had to code a Cells app in Java back in university, too.
One thing though: add undo/redo to the Cell task as a requirement. After all, "a good paradigm should give you this functionality for free" :)
Imagine if a GUI programming benchmark had GUI specifications with reasonable UX? The 7GUIs designs are criminally bad, especially CRUD and Circle drawer.
Then you'd need more complex implementations, which would be more difficult to compare, muddying up the point of the exercise: to produce various comparible implementations.
I don’t believe that the UX problems here are motivated by reducing complexity. Perhaps the circle drawer one, where any reasonable redesign would turn it into a direct manipulation GUI, but honestly direct manipulation is table stakes and something that you must be able to implement, and not really that complex in most cases.
The CRUD example is just bad for no reason. It looks like a typical master-detail view, but the detail view doesn’t give any feedback when the selection in the list changes.
Hmm. Well, that circle-drawer is indeed atrocious. But its atrocity is according to the design spec. It says to use a modal window with a slider. Everyone's supposed to build the same thing. Your criticisms should go 'upstream' to the original 7GUIs task specifier, eugenkiss (whose domain has been hijacked by some gambling operation, onoes!)
eta: Bad UX granted, I gather that the task is meant to compare DX. (And it'd be useful for comparing coding approaches by individuals, for evaluating interview candidates. For that purpose, it'd perhaps be useful to be able to test a person's particular design choices, and how they interpret the spec, perhaps to see if they are justified in building something not-quite-to-spec.)
eta2: https://eugenkiss.github.io/7guis/tasks#circle
Man, look how detailed this is. I suppose some people's job as developers is to literally implement specs exactly. Glad that's not my job. But maybe some folks would prefer not to have to deal with ambiguity.
Yes, my criticism is about 7GUIs as benchmark, that’s right there in my first post.
Yeah, this benchmark is way too specific. Would be much more interesting to see how different implementations could take advantage of their frameworks. Eg. some frameworks may make it easy to use animations, or they may have reusable components like date pickers. And of course they should take the target device in account - phone apps should look different from desktop apps, and they would probably also look different from control interfaces on industrial equipment.
They are pretty windows 95ish.
I just read some more of Brad's stuff. His piece on problem solving is worth a read.
Can you supply a link please, could not find it. His page is worth looking at, even if it takes a while to load.
(edit) nevermind, found it: https://garden.bradwoods.io/notes/problem-solving
The Cells example doesn't seem to work properly on my Mac in Safari:
Classic Safari, I'll get right onto that.
Was the problem an error on your part (that other browsers let you get away with) or something that should be OK but Safari doesn't support properly that you had to work around?
Hmm... Worked fine for me (unless you fixed something since your comment) :)
The only "issue" I see: visually it's hard to see whether a cell is just focused, or is in edit mode.
I thought about making the blinking cursor a lot fatter to differentiate the 2 different states.
Thanks it works now. I ain't a web dev but it seems like some nice examples. I also like the black-on-white UI, reminds me of classic Macintosh systems :)
Cells and Circle do not work on iOS
smart approach, but a framework would be needed for complex stuff
Fun Fact: 999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999°C = 32.00°F
That is a fun fact
Monster? It's very straightforward, functional and easy to follow. You could easily refactor that and break it up without fuss. Not sure what the big deal is here. The fact that it operates on a state machine makes it even easier. You can see all the different ways the UI will render by stubbing the state value.
The problem is when you have a large app with multiple components and plenty of state to manage. These things always look easy when they are small toy isolated projects.
This sort of thing in a production app would be littered with global state, it would be difficult to change anything / refactor without serious anxiety, if you have multiple developers good luck getting them to program the same predictable way, importing libraries see previous point, etc, etc.
Yes it's okay for this example. I think it can get out of hand.
Not the worst. Seems acceptable imo, yes its a long function with giant switch statement but its pretty clear what it does and easy to read.
Adding a few more fields would require me to update every case plus add some more, no? Resulting in an hard to maintain explosion of state? Or am I missing something.
https://statecharts.dev/state-machine-state-explosion.html
What are the other options here then? Not trolling just wondering. If an app has state it has to be dealt with somewhere...
You can dispense with the whole intermediate state variable and just do everything directly
This follows the problem description quite closely, eg. "The return textfield is enabled if the combobox’s value is return flight" is implemented by one line, and not spread across seven different enable/disable calls.https://github.com/eugenkiss/7guis-React-TypeScript-MobX/blo...