Skip to content

Instantly share code, notes, and snippets.

@emrahtoy
Last active August 29, 2015 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save emrahtoy/98fd5fe207db02614223 to your computer and use it in GitHub Desktop.
Save emrahtoy/98fd5fe207db02614223 to your computer and use it in GitHub Desktop.
Two way binding for marionette with marionette.behavior like angularjs directives approach
var focus = new Marionette.Application();
Marionette.Behaviors.behaviorsLookup = function() {
return focus.behaviors;
};
focus.router = new Marionette.AppRouter();
focus.addRegions({
mainRegion: '#mainRegion'
});
$(document).ready(function () {
focus.start();
});
focus.module('test', function (test, focus, Backbone, Marionette, $, _) {
test.controller={
init:function(){
$view=new focus.test.view({model:focus.test.model});
focus.mainRegion.show($view);
}
};
});
<form mrmodel="focus.test">
<input name='name' type='text' mrfield="name" required />
<input name='surname' type='text' mrfield="surname" />
<input name='birthday' type='date' mrfield="birthday" />
<input name='phone' type='text' mrfield="phone" />
<input name='age' type='number' mrfield="age" />
<input type="checkbox" name="testCheck1w" value="test1" mrfield="testCheck1" />
<input type="checkbox" name="testCheck2f" value="test2" mrfield="testCheck2" />
<input type="checkbox" name="testCheckGroup[]" value="test3" mrfield="checkGroup" />
<input type="checkbox" name="testCheckGroup[]" value="test4" mrfield="checkGroup" />
<label>
<input type="radio" name="testRadiof" value="radio1" mrfield="testRadio" />
Radio</label>
<input type="radio" name="testRadiof" value="radio2" mrfield="testRadio" />
<input type="radio" name="testRadiof" value="radio3" mrfield="testRadio" />
<select multiple name="multiSelect" mrfield="testMultiSelect">
<option value="select1">Select1</option>
<option value="select2">Select2</option>
<option value="select3">Select3</option>
<option value="select4">Select4</option>
</select>
<select name="onlySelect" mrfield="testSelect">
<option value="select1">Select1</option>
<option value="select2">Select2</option>
<option value="select3">Select3</option>
<option value="select4">Select4</option>
</select>
<input type="submit" name="formSubmit" value="send" />
<input type="reset" name="formReset" value="reset" />
</form>
<!DOCTYPE html>
<html>
<head>
<title>Focus</title>
</head>
<body id="mainRegion">
<div>Content</div>
</body>
</html>
focus.module('test', function (test, focus, Backbone, Marionette, $, _) {
test.modelClass = Backbone.Model.extend({
defaults: {
name: 'Emrah',
surname: 'TOY',
birthday: '2014-09-29',
phone: '0 532 234',
age: 32,
checkGroup:['test3','test4'],
testMultiSelect:['select1','select4'],
testSelect:'select3',
testRadio:'radio2',
testCheck2:'test2'
}
});
test.model = new test.modelClass();
});
// focus is applications name. Behaviors lookup also set to lookup at focus.behavours
focus.module('behaviors', function (behaviors, focus, Backbone, Marionette, $, _) {
behaviors.modelBind = Marionette.Behavior.extend({
events: {
'change [mrfield]': 'onViewChange',
'click input[type="reset"]': 'onReset'
},
modelEvents: {
'change': 'onModelChange'
},
onShow: function () {
this.updateView(this.view.model.attributes);
},
onReset: function (e) {
e.preventDefault();
this.view.model.clear();
this.view.model.set(this.view.model.defaults);
},
onModelChange: function (model) {
this.updateView(model.changed);
},
onViewChange: function (element) {
var value = this.getValueByType($(element.currentTarget));
var attributeName = element.currentTarget.attributes['mrfield'].value;
this.updateModel(attributeName, value, {silent: true});
},
updateView: function (model) {
var self = this;
if (!_.isEmpty(model)) {
_.forEach(model, function (value, name, object) {
this.updateViewByType(this.$('[mrfield=' + name + ']'), value);
}, this);
}
},
updateModel: function (name, value, options) {
if (_.isBoolean(value) || (_.isString(value) && value.length > 0) || (_.isArray(value) && value.length > 0)) {
if (value === parseInt(value, 10)) {
value = parseInt(value, 10);
}
this.view.model.set(name, value, options);
} else {
this.view.model.unset(name, options);
}
},
getValueByType: function ($element) {
var value;
if ($element.prop('tagName') === 'INPUT' && $element.attr('type') === 'checkbox' && $element.attr('name').indexOf('[]') !== -1) {
value = [];
this.$("input[name='" + $element.attr('name') + "']:checked").each(
function () {
value.push($(this).val());
}
);
} else {
value = $element.val();
}
return value;
},
updateViewByType: function ($element, value) {
if ($element.prop('tagName') === 'INPUT' && ($element.attr('type') === 'checkbox' || $element.attr('type') === 'radio')) {
if ($element.attr('name').indexOf('[]') !== -1) {
$element.prop('checked', false);
if(value!==undefined) $element.val(value);
} else {
$element.prop('checked', false);
$element.filter('[value="' + value + '"]').prop('checked', true).trigger('change');
}
}
else {
$element.val(value);
}
}
});
});
focus.module('test', function (test, focus, Backbone, Marionette, $, _) {
test.router={
"test": "init"
};
focus.router.processAppRoutes(test.controller, test.router);
});
focus.module('test', function (test, focus, Backbone, Marionette, $, _) {
test.view = Marionette.ItemView.extend({
behaviors:{
modelBind:'' // model bind doesnt take any variable but we could send the model.
},
template: templates['items.form'] // compiled template
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment