Two way binding for marionette with marionette.behavior like angularjs directives approach
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); | |
} | |
} | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment