<!DOCTYPE html>
<html>
<head>
<link href="style.css" rel="stylesheet">
<link href="//rawgit.com/magnumjs/mag.js/master/src/old/mag.comps.css" rel="stylesheet">
</head>
<body>
<h1>Hello Mag.JS!</h1>
<a target="_tab" href="https://github.com/magnumjs/mag.js">GitHub</a>
<hr/>
<div id="reactExampleGoesHere">
<div class="countryList"></div>
<div class="cityList"></div>
<div class="template hide">
<div id="TabList">
<div class="list">
<a></a>
</div>
</div>
</div>
</div>
<script src="//rawgit.com/magnumjs/mag.js/master/dist/mag.0.15.6.min.js"></script>
<script src="//rawgit.com/magnumjs/mag.js/master/src/old/mag.addons.js"></script>
<script src="//rawgit.com/magnumjs/mag.js/master/src/old/mag.comps.js"></script>
<script src="TabList.js"></script>
<script src="CountriesComponent.js"></script>
<script src="app-init.js"></script>
</body>
</html>
// initialize mag module reference
var citiesPerCountry = [
['New York', 'Detroit'],
['Ontario', 'Toronto']
]
var countries = ['USA', 'CAN']
var props = {
citiesPerCountry: citiesPerCountry,
countries: countries
}
mag.mods.demo.CountriesComponent("reactExampleGoesHere", props)
#Mag.JS Modular namespacing
React2Mag
Hierarchy component dynamic key state
TabList
http://blog.arkency.com/2014/10/react-dot-js-and-dynamic-children-why-the-keys-are-important/
Best practice in creating objects
1. always have one global top level namespace
e.g. var MyCoolApp = MyCoolApp || {};
2. That is included on every page
3.All sub modules are based on that
But they use local vars and return in functions
4. Always have a top parent moduel container
5. components are reusable within modules
(function(namespace) {
// default props to be over ridden
var props = {
active: 0
}
var TabList = {}
TabList.controller = function(props) {
this.active = props.active || 0
}
TabList.view = function(state, props) {
state.list = {
a: props.items.map(function(item, i) {
return {
_className: {
"excited": i == state.active,
"neutral": i != state.active
},
_href: "#",
_text: item,
_onclick: function(a, event) {
state.active = a
props.clickHandler(item, a, event);
}.bind(state, i)
}
})
}
}
namespace.TabList = mag.comp('TabList', TabList, props);
})(mag.namespace('mods.demo'));
(function(namespace) {
var props = {}
var CountriesComponent = {}
CountriesComponent.controller = function(props) {
this['active-country'] = 0
this['active-city'] = 0
this.currentCountry = props.countries[0]
this.handleClick = function(type, item, index, event) {
if (type == 'country') this.currentCountry = item
this['active-' + type] = index
event.preventDefault();
}.bind(this)
}
CountriesComponent.view = function(state, props) {
state.countryList = mag.mods.demo.TabList({
key: "countryList",
active: state['active-country'],
items: props.countries,
clickHandler: state.handleClick.bind(state, 'country')
}, true)
state.cityList = mag.mods.demo.TabList({
key: state.currentCountry,
active: state['active-city'],
items: props.citiesPerCountry[state['active-country']],
clickHandler: state.handleClick.bind(state, 'city')
}, true)
}
namespace.CountriesComponent = mag.comp('', CountriesComponent, props);
})(mag.namespace('mods.demo'));
.hide {
display:none;
}
#reactExampleGoesHere a,
#reactExampleGoesHere a {
border: 1px solid;
margin-right: 10px;
text-decoration: none;
background-color: #2bbb5b;
color: white;
padding: 10px;
}
#reactExampleGoesHere a.excited,
#reactExampleGoesHere a.excited {
background-color: #2bbb5b;
}
#reactExampleGoesHere a.neutral,
#reactExampleGoesHere a.neutral {
background-color: #39a5de;
}
#reactExampleGoesHere div.list,
#reactExampleGoesHere div.list {
height: 70px;
}