-
-
Save Inviz/1344185 to your computer and use it in GitHub Desktop.
// Does this look familiar? A grid of dependent checkboxes. | |
// [ ] Select all | |
// [ ] Option 1 | |
// [ ] Option 2 | |
// [ ] Option 3 | |
// [ ] Option 4 | |
// [ ] Select all | |
// But how do i declare their relations? Usually, it's pretty hard | |
// Not with LSD.Script | |
// Just code it like you mean it, and it will just work. | |
// It will pick up new checkboxes, and set them into the correct state. | |
// Will check "Select all" when every option is checked one by one | |
it ("should execute scenarios", function() { | |
var scope = new LSD.Script.Scope; | |
var script = new LSD.Script(' \n\ | |
each (masters) |input| \n\ | |
if (input.checked) \n\ | |
each(slaves) |checkbox| \n\ | |
checkbox.check() \n\ | |
if (every(slaves) {|c| c.checked}) \n\ | |
input.check() \n\ | |
', scope) | |
$script = script | |
var checks = 0, unchecks = 0; | |
scope.methods.set('check', function(object) { | |
console.error('checked', object.title); | |
checks++; | |
return object.set('checked', true) | |
}); | |
scope.methods.set('uncheck', function(object, force) { | |
console.error('unchecked', object.title); | |
unchecks++; | |
return object.set('checked', false) | |
}); | |
var masters = new LSD.Array(new LSD.Object.Stack({title: 'A'}), new LSD.Object.Stack({title: 'B'})) | |
var slaves = new LSD.Array(new LSD.Object.Stack({title: 'a'}), new LSD.Object.Stack({title: 'b'}), new LSD.Object.Stack({title: 'c'}), new LSD.Object.Stack({title: 'd'})); | |
scope.variables.merge({'masters': masters, slaves: slaves}); | |
expect(checks).toEqual(0); | |
expect(unchecks).toEqual(0); | |
scope.methods.check(masters[0]); | |
expect(checks).toEqual(7); | |
expect(unchecks).toEqual(0); | |
expect(masters[0].checked).toBeTruthy(); | |
expect(masters[1].checked).toBeTruthy(); | |
expect(slaves[0].checked).toBeTruthy(); | |
expect(slaves[1].checked).toBeTruthy(); | |
expect(slaves[2].checked).toBeTruthy(); | |
expect(slaves[3].checked).toBeTruthy(); | |
scope.methods.uncheck(masters[0], true); | |
expect(masters[0].checked).toBeFalsy(); | |
expect(masters[1].checked).toBeFalsy(); | |
expect(slaves[0].checked).toBeFalsy(); | |
expect(slaves[1].checked).toBeFalsy(); | |
expect(slaves[2].checked).toBeFalsy(); | |
expect(slaves[3].checked).toBeFalsy(); | |
expect(unchecks).toEqual(7); | |
expect(checks).toEqual(7); | |
scope.methods.check(masters[1]); | |
$slaves = slaves | |
$masters = masters | |
expect(masters[0].checked).toBeTruthy(); | |
expect(masters[1].checked).toBeTruthy(); | |
expect(slaves[0].checked).toBeTruthy(); | |
expect(slaves[1].checked).toBeTruthy(); | |
expect(slaves[2].checked).toBeTruthy(); | |
expect(slaves[3].checked).toBeTruthy(); | |
expect(checks).toEqual(14); | |
expect(unchecks).toEqual(7); | |
scope.methods.uncheck(slaves[0], true); | |
expect(masters[0].checked).toBeFalsy(); | |
expect(masters[1].checked).toBeFalsy(); | |
expect(slaves[0].checked).toBeFalsy(); | |
expect(slaves[1].checked).toBeFalsy(); | |
expect(slaves[2].checked).toBeFalsy(); | |
expect(slaves[3].checked).toBeFalsy(); | |
expect(checks).toEqual(14); | |
expect(unchecks).toEqual(14); | |
scope.methods.check(slaves[0]); | |
expect(checks).toEqual(15); | |
expect(unchecks).toEqual(14); | |
scope.methods.check(slaves[1]); | |
expect(checks).toEqual(16); | |
expect(unchecks).toEqual(14); | |
scope.methods.check(slaves[2]); | |
expect(checks).toEqual(17); | |
expect(unchecks).toEqual(14); | |
scope.methods.check(slaves[3]); | |
expect(checks).toEqual(24); | |
expect(unchecks).toEqual(14); | |
expect(masters[0].checked).toBeTruthy(); | |
expect(masters[1].checked).toBeTruthy(); | |
expect(slaves[0].checked).toBeTruthy(); | |
expect(slaves[1].checked).toBeTruthy(); | |
expect(slaves[2].checked).toBeTruthy(); | |
expect(slaves[3].checked).toBeTruthy(); | |
scope.methods.uncheck(slaves[3], true); | |
expect(masters[0].checked).toBeFalsy(); | |
expect(masters[1].checked).toBeFalsy(); | |
expect(slaves[0].checked).toBeFalsy(); | |
expect(slaves[1].checked).toBeFalsy(); | |
expect(slaves[2].checked).toBeFalsy(); | |
expect(slaves[3].checked).toBeFalsy(); | |
expect(checks).toEqual(24); | |
expect(unchecks).toEqual(21); | |
}); |
Yes! Straight to the point. It makes life easier: memoizes and reuses lazy calculations, takes out the "flow control" with callbacks, and makes it easy to set context in the script by adding or removing variables.
There're other parts, that are observable objects and arrays, but the essense is this - code that does not execute from top to bottom, but rather make everything a rule. And those rules dont overwrite each other, as in regular code, but they are stacked and remembered, throughout the script and UI framework.
very interesting!
Could you use this to implement a constraint based UI layout system?
Cf. https://developer.apple.com/videos/wwdc/2011/#cocoa-autolayout
That is actually a great idea. Looking at http://developer.apple.com/library/mac/#documentation/UserExperience/Conceptual/AutolayoutPG/Articles/formatLanguage.html it seems to be very doable and fun, considering the fact that I have selectors as first-class objects in LSD.Script.
Thanks for heads up, if you'll have any more ideas or feedback, or if you'll be interested to see some more of my cool stuff, drop me a email some time.
Thanks.
This seems like some sort of declarative programming. You create rules instead of all the specific steps and glue code over and over.