From d005c8716965cbfb8d2358a6234d0c52446a111d Mon Sep 17 00:00:00 2001 From: Vladimir Grinenko Date: Wed, 6 May 2015 01:30:23 +0300 Subject: [PATCH 1/2] demo --- .enb/techs/bemtreeToHtml.js | 9 ++++-- common.blocks/main/main.bemhtml | 3 ++ common.blocks/main/main.bemtree | 33 ++++++++++++++++++++++ common.blocks/main/main.css | 9 ++++++ common.blocks/main/main.deps.js | 23 ++++++++++++++++ common.blocks/main/main.js | 49 +++++++++++++++++++++++++++++++++ common.blocks/modal/modal.css | 4 +++ common.blocks/page/page.bemtree | 3 +- common.blocks/root/root.bemtree | 2 ++ data.json | 32 +++++++++++++++++++++ 10 files changed, 163 insertions(+), 4 deletions(-) create mode 100644 common.blocks/main/main.bemhtml create mode 100644 common.blocks/main/main.bemtree create mode 100644 common.blocks/main/main.css create mode 100644 common.blocks/main/main.deps.js create mode 100644 common.blocks/main/main.js create mode 100644 common.blocks/modal/modal.css create mode 100644 data.json diff --git a/.enb/techs/bemtreeToHtml.js b/.enb/techs/bemtreeToHtml.js index 0625d53..4f1afd6 100644 --- a/.enb/techs/bemtreeToHtml.js +++ b/.enb/techs/bemtreeToHtml.js @@ -17,10 +17,12 @@ * ``` */ var vm = require('vm'), + path = require('path'), vow = require('vow'), vfs = require('enb/lib/fs/async-fs'), asyncRequire = require('enb/lib/fs/async-require'), - dropRequireCache = require('enb/lib/fs/drop-require-cache'); + dropRequireCache = require('enb/lib/fs/drop-require-cache'), + dataFilename = path.resolve('data.json'); module.exports = require('enb/lib/build-flow').create() .name('html-from-bemtree') @@ -29,10 +31,11 @@ module.exports = require('enb/lib/build-flow').create() .useSourceFilename('bemhtmlTarget', '?.bemhtml.js') .builder(function(bemtreeFilename, bemhtmlFilename) { dropRequireCache(require, bemhtmlFilename); + dropRequireCache(require, dataFilename); return vow.all([ vfs.read(bemtreeFilename, 'utf-8'), - asyncRequire(bemhtmlFilename) + asyncRequire(bemhtmlFilename), ]) .spread(function(bemtree, bemhtml) { var ctx = vm.createContext({ @@ -46,7 +49,7 @@ module.exports = require('enb/lib/build-flow').create() return [ctx.BEMTREE, bemhtml.BEMHTML]; }) .spread(function(BEMTREE, BEMHTML) { - return BEMTREE.apply({ block: 'root' }) + return BEMTREE.apply({ block: 'root', data: require(dataFilename) }) .then(function(bemjson) { return BEMHTML.apply(bemjson); }); diff --git a/common.blocks/main/main.bemhtml b/common.blocks/main/main.bemhtml new file mode 100644 index 0000000..c7fa476 --- /dev/null +++ b/common.blocks/main/main.bemhtml @@ -0,0 +1,3 @@ +block('main')( + tag()('form') +); diff --git a/common.blocks/main/main.bemtree b/common.blocks/main/main.bemtree new file mode 100644 index 0000000..ba2125d --- /dev/null +++ b/common.blocks/main/main.bemtree @@ -0,0 +1,33 @@ +block('main').content()(function() { + var cars = this.data.cars, + carNames = Object.keys(cars), + firstCar = carNames[0], + firstCarModels = Object.keys(cars[firstCar]); + + return [ + { + block : 'select', + mods : { mode : 'radio', theme : 'islands', size : 'xl' }, + mix : { block: this.block, elem: 'car' }, + name : 'car', + val : firstCar, + options : carNames.map(function(car) { + return { val : car, text : car }; + }) + }, + { + block : 'select', + mods : { mode : 'radio', theme : 'islands', size : 'xl' }, + mix : { block: this.block, elem: 'model' }, + name : 'model', + val : firstCarModels[0], + options : firstCarModels.map(function(model) { + return { val : model, text : model }; + }) + }, + { + block: 'modal', + mods: { theme: 'islands', autoclosable : true } + } + ]; +}); diff --git a/common.blocks/main/main.css b/common.blocks/main/main.css new file mode 100644 index 0000000..160265b --- /dev/null +++ b/common.blocks/main/main.css @@ -0,0 +1,9 @@ +.main +{ + padding: 20px; +} + +.main .select +{ + margin-right: 12px; +} diff --git a/common.blocks/main/main.deps.js b/common.blocks/main/main.deps.js new file mode 100644 index 0000000..35109ac --- /dev/null +++ b/common.blocks/main/main.deps.js @@ -0,0 +1,23 @@ +[ + { + shouldDeps : [ + 'objects', + { + block : 'select', + mods : { mode : 'radio', theme : 'islands', size : 'xl' } + }, + { + block: 'modal', + mods: { theme: 'islands', autoclosable : true } + } + ] + }, + { + tech : 'js', + shouldDeps : { + block : 'select', + mods : { mode : 'radio', theme : 'islands', size : 'xl' }, + tech : 'bemhtml' + } + } +] diff --git a/common.blocks/main/main.js b/common.blocks/main/main.js new file mode 100644 index 0000000..74f5e84 --- /dev/null +++ b/common.blocks/main/main.js @@ -0,0 +1,49 @@ +modules.define('main', ['i-bem__dom', 'BEMHTML', 'objects', 'select'], function(provide, BEMDOM, BEMHTML, Objects, Select) { + +provide(BEMDOM.decl(this.name, { + onSetMod: { + js: { + inited: function() { + var cars = this.params.cars, + modal = this.findBlockInside('modal'), + car = cars[Object.keys(cars)[0]]; + + Select.on(this.elem('car'), 'change', function(e) { + var select = e.target, + val = select.getVal(); + + car = cars[val]; + + if (Objects.isEmpty(car)) { + return BEMDOM.update(this.elem('model'), ''); + } + + BEMDOM.update(this.elem('model'), BEMHTML.apply({ + block : 'select', + mods : { mode : 'radio', theme : 'islands', size : 'xl' }, + mix : { block: this.block, elem: 'model' }, + name : 'model', + val : car[0], + options : Object.keys(car).map(function(model) { + return { val : model, text : model }; + }) + })); + }, this); + + Select.on(this.elem('model'), 'change', function(e) { + var model = e.target.getVal(), + colors = car[model].colors; + + modal + .setContent('

Варианты цветов

' + + (Object.keys(colors).map(function(color) { + return color + ': ' + colors[color]; + }).join('
'))) + .setMod('visible'); + }, this); + } + } + } +})); + +}); diff --git a/common.blocks/modal/modal.css b/common.blocks/modal/modal.css new file mode 100644 index 0000000..97cddc0 --- /dev/null +++ b/common.blocks/modal/modal.css @@ -0,0 +1,4 @@ +.modal__content +{ + padding: 12px; +} diff --git a/common.blocks/page/page.bemtree b/common.blocks/page/page.bemtree index f0e414f..774f1ba 100644 --- a/common.blocks/page/page.bemtree +++ b/common.blocks/page/page.bemtree @@ -4,7 +4,8 @@ block('page').content()(function() { block: 'header' }, { - block: 'main' + block: 'main', + js: this.data }, { block: 'footer' diff --git a/common.blocks/root/root.bemtree b/common.blocks/root/root.bemtree index d92db3b..0e952e9 100644 --- a/common.blocks/root/root.bemtree +++ b/common.blocks/root/root.bemtree @@ -1,4 +1,6 @@ block('root').def()(function() { + this.data = this.ctx.data; + return applyCtx({ block: 'page', title: 'TODO', diff --git a/data.json b/data.json new file mode 100644 index 0000000..12245a4 --- /dev/null +++ b/data.json @@ -0,0 +1,32 @@ +{ + "cars" : { + "toyota" : { + "prius" : { + "colors" : { + "c1" : "qwe", + "c2" : "asd" + } + }, + "camry" : { + "colors" : { + "c1" : "123", + "c2" : "456" + } + } + }, + "mercedes" : { + "benz" : { + "colors" : { + "c1" : "black", + "c2" : "red" + } + }, + "blah" : { + "colors" : { + "c1" : "white", + "c2" : "silver" + } + } + } + } +} From 81b947a7140db1c0262ff401bfe636d5da79e549 Mon Sep 17 00:00:00 2001 From: Vladimir Grinenko Date: Fri, 8 May 2015 21:13:44 +0300 Subject: [PATCH 2/2] next --- common.blocks/main/main.bemtree | 40 ++++++++--------- common.blocks/main/main.js | 59 ++++++++++++++---------- data.json | 80 ++++++++++++++++++++++++++++----- 3 files changed, 123 insertions(+), 56 deletions(-) diff --git a/common.blocks/main/main.bemtree b/common.blocks/main/main.bemtree index ba2125d..5900366 100644 --- a/common.blocks/main/main.bemtree +++ b/common.blocks/main/main.bemtree @@ -2,29 +2,29 @@ block('main').content()(function() { var cars = this.data.cars, carNames = Object.keys(cars), firstCar = carNames[0], - firstCarModels = Object.keys(cars[firstCar]); + firstCarModels = Object.keys(cars[firstCar]), + firstModel = firstCarModels[0], + firstModelYears = Object.keys(cars[firstCar][firstModel]); - return [ - { - block : 'select', - mods : { mode : 'radio', theme : 'islands', size : 'xl' }, - mix : { block: this.block, elem: 'car' }, - name : 'car', - val : firstCar, - options : carNames.map(function(car) { - return { val : car, text : car }; - }) - }, - { + function buildSelectOption(val) { + return { val : val, text : val }; + } + + function buildSelect(name, options) { + return { block : 'select', mods : { mode : 'radio', theme : 'islands', size : 'xl' }, - mix : { block: this.block, elem: 'model' }, - name : 'model', - val : firstCarModels[0], - options : firstCarModels.map(function(model) { - return { val : model, text : model }; - }) - }, + mix : { block: 'main', elem: name }, + name : name, + val : options[0], + options : options.map(buildSelectOption) + }; + } + + return [ + buildSelect('car', carNames), + buildSelect('model', firstCarModels), + buildSelect('year', firstModelYears), { block: 'modal', mods: { theme: 'islands', autoclosable : true } diff --git a/common.blocks/main/main.js b/common.blocks/main/main.js index 74f5e84..d7e20a2 100644 --- a/common.blocks/main/main.js +++ b/common.blocks/main/main.js @@ -4,35 +4,23 @@ provide(BEMDOM.decl(this.name, { onSetMod: { js: { inited: function() { - var cars = this.params.cars, - modal = this.findBlockInside('modal'), - car = cars[Object.keys(cars)[0]]; + var modal = this.findBlockInside('modal'), + cars = this.params.cars, + car = this.car = cars[Object.keys(cars)[0]], + model = this.model = this.car[Object.keys(this.car)[0]]; Select.on(this.elem('car'), 'change', function(e) { - var select = e.target, - val = select.getVal(); - - car = cars[val]; - - if (Objects.isEmpty(car)) { - return BEMDOM.update(this.elem('model'), ''); - } - - BEMDOM.update(this.elem('model'), BEMHTML.apply({ - block : 'select', - mods : { mode : 'radio', theme : 'islands', size : 'xl' }, - mix : { block: this.block, elem: 'model' }, - name : 'model', - val : car[0], - options : Object.keys(car).map(function(model) { - return { val : model, text : model }; - }) - })); + this.onSelectChange(e, 'model', 'car', cars); + this.onSelectChange(e, 'year', 'model', this.car); }, this); Select.on(this.elem('model'), 'change', function(e) { - var model = e.target.getVal(), - colors = car[model].colors; + this.onSelectChange(e, 'year', 'model', this.car); + }, this); + + Select.on(this.elem('year'), 'change', function(e) { + var year = e.target.getVal(), + colors = this.model[year].colors; modal .setContent('

Варианты цветов

' + @@ -43,6 +31,29 @@ provide(BEMDOM.decl(this.name, { }, this); } } + }, + onSelectChange: function(e, name, field, data) { + var select = e.target, + val = select.getVal(), + option = this[field] = data[val]; + + if (Objects.isEmpty(option)) { + return BEMDOM.update(this.elem(name), ''); + } + + BEMDOM.update(this.elem(name), BEMHTML.apply(this.buildSelect(name, option))); + }, + buildSelect: function(name, options) { + return { + block : 'select', + mods : { mode : 'radio', theme : 'islands', size : 'xl' }, + mix : { block: this.block, elem: name }, + name : name, + val : options[0], + options : Object.keys(options).map(function(val) { + return { val : val, text : val }; + }) + }; } })); diff --git a/data.json b/data.json index 12245a4..d234041 100644 --- a/data.json +++ b/data.json @@ -2,29 +2,85 @@ "cars" : { "toyota" : { "prius" : { - "colors" : { - "c1" : "qwe", - "c2" : "asd" + "2001" : { + "colors" : { + "c1" : "1", + "c2" : "2" + } + }, + "2002" : { + "colors" : { + "c1" : "3", + "c2" : "4" + } + }, + "2003" : { + "colors" : { + "c1" : "5", + "c2" : "6" + } } }, "camry" : { - "colors" : { - "c1" : "123", - "c2" : "456" + "2004" : { + "colors" : { + "c1" : "1", + "c2" : "2" + } + }, + "2005" : { + "colors" : { + "c1" : "3", + "c2" : "4" + } + }, + "2006" : { + "colors" : { + "c1" : "5", + "c2" : "6" + } } } }, "mercedes" : { "benz" : { - "colors" : { - "c1" : "black", - "c2" : "red" + "2007" : { + "colors" : { + "c1" : "1", + "c2" : "2" + } + }, + "2008" : { + "colors" : { + "c1" : "3", + "c2" : "4" + } + }, + "2009" : { + "colors" : { + "c1" : "5", + "c2" : "6" + } } }, "blah" : { - "colors" : { - "c1" : "white", - "c2" : "silver" + "2010" : { + "colors" : { + "c1" : "1", + "c2" : "2" + } + }, + "2011" : { + "colors" : { + "c1" : "3", + "c2" : "4" + } + }, + "2012" : { + "colors" : { + "c1" : "5", + "c2" : "6" + } } } }