Alternative to 'options' in backbone.js 1.1.2 - backbone-views

From my view menuitemdetails.js i'am calling options in app.js - itemDetails
My menuitemdetails.js
var MenuItemDetails = Backbone.View.extend({
render: function () {
var markup = '<div>' +
'<h1>' + this.options.name + '</h1>' +
'<p><span class="label">' + this.options.category + '</span></p>' +
'<img src="photos/' + this.options.imagepath + '" class="img-polaroid" />' +
'</div>';
this.$el.html(markup);
return this;
}
});
My app.js
var AppRouter = Backbone.Router.extend({
routes: {
"": "list",
"menu-items/new": "itemForm",
"menu-items/:item": "itemDetails"
},
list: function () {
$('#app').html('List screen');
},
itemDetails: function (item) {
var view = new MenuItemDetails(
{
name: item,
category: 'Entree',
imagepath: 'garden-salad.jpg'
}
);
$('#app').html(view.render().el);
},
itemForm: function () {
$('#app').html('New item form');
}
});
var app = new AppRouter();
$(function () {
Backbone.history.start();
});
Looking forward for an alternative of 'options' because from my view it is not working in backbone.js 1.1.2

Related

Masking Phone in Ember JS

I am trying to mask a Phone number in a input field, can somebody please help me in this regards. Here is my code for the html (or .hbs file)
<label class="control-label">Phone</label>
{{masked-input mask='(999) 999-9999'
value=model.Address.Phone
input-format='regex'
input-filter='\(*[0-9]{3}\) [0-9]{3}-[0-9]{4}'
input-filter-message='Phone number is not valid.'
class='form-control phone masked'
maxlength="14"}}
</div>
And my component definition is as below:
export default () => {
IMS.registerComponent("masked-input", {
tagName: 'input',
attrParams: ['required', 'title', 'name', 'placeholder'],
loaded: false,
prop: Ember.observer(
'required',
'title',
'name',
'placeholder',
'value',
function () {
var scope = this;
$(this.element).val(Ember.get(scope, 'value'));
var stamp = new Date();
if (Ember.get(scope, 'loaded') == true) {
var element = $(this.element);
var attrs = Ember.get(this, 'attrParams');
attrs.forEach(function (attr) {
var value = Ember.get(scope, attr);
if (value == '' | value == null) {
element.removeAttr(attr);
} else {
element.attr(attr, value);
}
})
}
}),
observeMask: Ember.observer('mask', function () {
var scope = this;
$(this.element).inputmask({
mask: Ember.get(scope, 'mask')
});
}),
didInsertElement: function () {
var scope = this;
setTimeout(function () {
var value = Ember.get(scope, 'value');
var element = $(scope.element);
var change = function () { Ember.set(scope, 'value', element.val()); }
element.val(Ember.get(scope, 'value'));
element.attr('type', 'text');
element.change(change);
Ember.set(scope, 'loaded', true);
scope.observeChanges();
element.inputmask({
mask: Ember.get(scope, 'mask')
});
element.attr('input-format', Ember.get(scope, 'input-format'));
element.attr('input-filter', Ember.get(scope, 'input-filter'));
element.attr('input-filter-message', Ember.get(scope, 'input-filter-message'));
}, 250);
}
})
}

The changed value is not reflecting on the input field in ReactJS, TestUtils

I am using ReactJs and Mocha and trying few unit tests. I have two mandatory form fields First Name and Last Name. I am trying to test the validation where if only one field is entered, the other field displays the missing value validation error.
Below code simulates the changes to the value and simulates the form submit.
TestUtils.Simulate.change(firstNameElement , {target: {value: 'Joe'}});
TestUtils.Simulate.submit(formElement)
The changed value is reflected in the event handlers on First Name. But, not in the test. So, both the fields display missing value validation failing my test.
What I could be doing wrong here?
Below are code:
//NameForm.jsx
'use strict';
var React=require('react')
var forms = require('newforms')
var NameForm = forms.Form.extend({
firstName: forms.CharField({maxLength: 100, label: "First name(s)"}),
lastName: forms.CharField({maxLength: 100, label: "Last name"}),
cleanFirstName(callback) {
callback(null)
},
render() {
return this.boundFields().map(bf => {
return <div className={'form-group ' + bf.status()}>
<label className="form-label" htmlFor={bf.name}>
<span className="form-label-bold">{bf.label}</span>
</label>
{bf.errors().messages().map(message => <span className="error-message">{message}</span>)}
<input className="form-control" id={bf.name} type="text" name={bf.name} onChange = {this.onChangeHandler}/>
</div>
})
}
, onChangeHandler: function(e){
console.log("onchnage on input is called ----- >> " + e.target.value)
}
})
module.exports = {
NameForm
}
Here is NamePage.jsx:
'use strict';
var React = require('react')
var {ErrorObject} = require('newforms')
var superagent = require('superagent-ls')
var {API_URL} = require('../../constants')
var {NameForm} = require('./NameForm')
var NamePage = React.createClass({
contextTypes: {
router: React.PropTypes.func.isRequired
},
propTypes: {
data: React.PropTypes.object,
errors: React.PropTypes.object
},
statics: {
title: 'Name',
willTransitionTo(transition, params, query, cb, req) {
if (req.method != 'POST') { return cb() }
superagent.post(`${API_URL}/form/NameForm`).send(req.body).withCredentials().end((err, res) => {
if (err || res.serverError) {
return cb(err || new Error(`Server error: ${res.body}`))
}
if (res.clientError) {
transition.redirect('name', {}, {}, {
data: req.body,
errors: res.body
})
}
else {
transition.redirect('summary')
}
cb()
})
}
},
getInitialState() {
return {
client: false,
form: new NameForm({
onChange: this.forceUpdate.bind(this),
data: this.props.data,
errors: this._getErrorObject()
})
}
},
componentDidMount() {
this.setState({client: true})
},
componentWillReceiveProps(nextProps) {
if (nextProps.errors) {
var errorObject = this._getErrorObject(nextProps.errors)
this.refs.nameForm.getForm().setErrors(errorObject)
}
},
_getErrorObject(errors) {
if (!errors) { errors = this.props.errors }
return errors ? ErrorObject.fromJSON(errors) : null
},
_onSubmit(e) {
e.preventDefault()
var form = this.state.form
form.validate(this.refs.form, (err, isValid) => {
if (isValid) {
this.context.router.transitionTo('name', {}, {}, {
method: 'POST',
body: form.data
})
}
})
},
render() {
return <div>
<h1 className="heading-large">Your name</h1>
<form action='name' method="POST" onSubmit={this._onSubmit} ref="form" autoComplete="off" noValidate={this.state.client}>
{this.state.form.render()}
<button type="submit" className="button">Next</button>
</form>
</div>
},
})
module.exports = NamePage
Here is NameTest.js :
//NameTest.js
var React = require('react')
var ReactAddons = require('react/addons')
var TestUtils = React.addons.TestUtils
var InputFieldItem = require('../../src/page/name/NamePage')
describe('Name page component', function(){
var renderedComponent;
before('render element', function() {
console.log("*** in before")
renderedComponent = TestUtils.renderIntoDocument(
<InputFieldItem />
);
});
it('Only First Name entered should display one error message', function() {
renderedComponent = TestUtils.renderIntoDocument(
<InputFieldItem />
);
var formElement = TestUtils.findRenderedDOMComponentWithTag(renderedComponent, 'form').getDOMNode()
var firstNameElement = TestUtils.scryRenderedDOMComponentsWithTag(renderedComponent, 'input')[0].getDOMNode()
var lastNameElement = TestUtils.scryRenderedDOMComponentsWithTag(renderedComponent, 'input')[1].getDOMNode()
var buttonElement = TestUtils.findRenderedDOMComponentWithTag(renderedComponent, 'button').getDOMNode()
TestUtils.Simulate.change(firstNameElement , {target: {value: 'Joe'}});
TestUtils.Simulate.submit(formElement)
var errorSpans = TestUtils.scryRenderedDOMComponentsWithClass(renderedComponent, 'error-message')
console.log("First name value is :|"+ firstNameElement.value + "|")
expect (errorSpans.length).to.equal(1)
})
});

Backbone - How to create a nested list with subview list items?

I'm a Backbone noob and I've been at a standstill for 2 days now and can't figure out where I'm going wrong. Could anyone help me out?
My app is retrieving a JSON file with a list of components in it. Each component has a category it belongs to. I create a view called "Components" that is a collapsible list. When a component category is clicked, it should open up to show the components in that category. Each of these components (list items) a separate view called "Component".
I'm using a lot of append()'s in the parent view and I don't think this is efficient. I tried to compile a string of html and then append it to the view in one statement but the events of the subviews weren't triggering.
There are probably a few errors going on here. Even though my sublist items should be wrapped in ul's they aren't being. If someone can put me on the path to enlightenment I'd be really grateful!
Here's my code
/* ----------------- PARENT VIEW ---------------------- */
var ComponentsView = Backbone.View.extend({
id: 'components-view',
className: 'components-view',
html: [
'<div class="panel panel--components">',
'<h3 class="panel__heading">add an item</h3>',
'<ul class="component-list"></ul>',
'</div>'
].join(''),
initialize: function(){
var types = [];
var currentTypeSelected = 1;
this.getTypes = function(){
return types;
}
this.getCurrentTypeSelected = function(){
return currentTypeSelected;
}
this.setCurrentTypeSelected = function(value){
currentTypeSelected = value;
}
if(this.collection.length){
this.collection.each(function(model){
var thisItemType = model.attributes.type;
if(types.indexOf(thisItemType)==-1){
types.push(thisItemType);
}
});
}
this.$el.html(this.html);
this.$componentList = this.$('.component-list');
this.render();
},
render: function(){
var that = this;
this.getTypes().forEach(function(type){
that.$('.component-list').append('<li class="component-type">' + type + '');
// now cycle through all the componenets of this type
that.$('.component-list').append('<ul>');
that.collection.byType(type).each(function(model){
that.$('.component-list').append('<li class="component">');
that.$('.component-list').append(that.renderIndividualComponent(model));
that.$('.component-list').append('</li>');
});
that.$('.component-list').append('</ul>');
});
},
renderIndividualComponent: function(model){
var componentView = new ComponentView({model: model});
return componentView.$el;
},
events: {
'click .component-type': 'onOpenSubList'
},
onOpenSubList: function (e) {
alert('open sub list');
}
});
/* ----------------- SUB (list item) VIEW ---------------------- */
var ComponentView = Backbone.View.extend({
tagName: "li",
className: "component",
initialize: function(model){
this.render();
},
render: function(){
var html = '' + this.model.attributes.description + ''//template(this.model.attributes);
$(this.el).append(html);
return this;
},
events: {
'click a': 'onAddComponent'
},
onAddComponent: function (e) {
e.preventDefault();
alert('add component');
}
});

Implementation of displaying breadcrumb path in ember with sample code or may be direct me to some repository

Can some one redirect me to some project code or some working example of displaying crumble path in ember?
This code doesn't work for some reason.
ApplicationController = Ember.Controller.extend({
needs: ['breadcrumbs'],
hashChangeOccured: function(context) {
var loc = context.split('/');
var path = [];
var prev;
loc.forEach(function(it) {
if (typeof prev === 'undefined') prev = it;
else prev += ('/'+it)
path.push(Em.Object.create({ href: prev, name: it }));
});
this.get('controllers.breadcrumbs').set('content',path)
}
});
ready : function() {
$(window).on('hashchange',function() {
Ember.Instrumentation.instrument("hash.changeOccured", location.hash);
});
$(window).trigger('hashchange');
}
App.ApplicationRoute = Ember.Route.extend({
setupController: function(controller, model) {
Ember.Instrumentation.subscribe("hash.changeOccured", {
before: function(name, timestamp, payload) {
controller.send('hashChangeOccured', payload);
},
after: function() {}
});
}
});
Here you have a starting point:
APP.Breadcrumb = Em.View.extend({
classNames: ['breadcrumb'],
tagName: 'ul',
activeChanged: function () {
var self = this;
Em.run.next(this, function () {
self.set('active', self.get('childViews.firstObject.active'));
});
}.observes('childViews.firstObject.active'),
disabled: function () {
var role = this.get('role');
if (!Em.isEmpty(role)) {
return !this.get('controller.controllers.login').hasRole(role);
}
return false;
}.property("controller.controllers.login.authenticationMediator.roles.#each"),
currentPathChanged: function() {
this.rerender();
}.observes('controller.currentPath'),
template: function () {
var template = [],
controller = this.get('controller'),
router = controller.container.lookup('router:main'),
currentHandlerInfos = router.get('router.currentHandlerInfos');
for (var i = 0; i < currentHandlerInfos.length; i++) {
var name = Em.get(currentHandlerInfos[i], 'name');
if (!(router.hasRoute(name) || router.hasRoute(name + '.index')) || name.endsWith('.index')) {
continue;
}
var notLast = i < currentHandlerInfos.length - 1 && !Em.get(currentHandlerInfos[i + 1], 'name').endsWith('.index');
template.push('<li' + (notLast ? '>' : ' class="active">'));
if (notLast) {
template.push('{{#linkTo "' + name + '"}}');
}
template.push(name);
if (notLast) {
template.push('{{/linkTo}}');
}
if (notLast) {
template.push('<span class="divider">/</span>');
}
template.push('</li>');
}
return Em.Handlebars.compile(template.join("\n"));
}.property('controller.currentPath')
});

Can't get data from model to appear in template Ember.js

My code is here: http://jsfiddle.net/FNn4R/4/ I can't get the outgoings model (a model with messages outbound) to display in the template.
HTML
<script type="text/x-handlebars" data-template-name="messages">
Hello <b>{{App.username}}</b><br />
{{#each outgoings in model}}
<h4>{{outgoings.vehicle_reg}}</h4>
<p>{{outgoings.message_subject}}</p>
{{/each}}
</script>
JS
App.MessagesRoute = Ember.Route.extend({
model: function() {
return App.Outgoings.all();
},
renderTemplate: function() {
this.render('header-messages', {
into: 'application',
outlet: 'header'
});
this.render('messages', {
into: 'application',
outlet: 'content'
});
}
});
App.Outgoings = Ember.Object.extend();
App.Outgoings.reopenClass({
all: function() {
var outgoings = [];
var apiPage = "messages";
var parameters_string = "action=outgoing";
var url = "http://do-web-design.com/clients/carbuddy/index.php/api/";
var url = url + apiPage + "?" + parameters_string + "&username=" + "will" + "&password=" + "1234";
// console.log(url);
var response = $.ajax({
type: "GET",
url: url,
dataType: "text json",
success: function(data){
return data;
// return JSON.parse(data)
alert('Its working'); //It will alert when you ajax call returns successfully.
},
error: function(jqXHR, textStatus, errorThrown) {
console.log(JSON.stringify(jqXHR));
console.log("AJAX error: " + textStatus + ' | ' + errorThrown);
}
}).done(function(response) {
response.forEach( function (outgoing) {
outgoings.push( App.Outgoings.create(outgoing) );
});
});
return outgoings;
}
});
My Ajax call is getting data but its just not copying it into the model and or sending it to the template.