Angular Formly Model with complex object - angularjs

I'm using Angular Formly and works very well if the model is a value of the scope, like a string:
{
key: 'name',
type: 'input'
}
The problem is that I'm using a more elaborated object to handle the model, with "controller as" syntax and the name as part of the user object:
vm.user = {name: 'john', lastname: 'doe'}
And then of course, the key would be:
{
key: 'user.name',
type: 'input'
}
(Usually the vm is taken out of the key in formly notation).
The problem is that Formly uses a bracketed notation to handle the model:
template = '<input ng-model=\"model[options.key]\">'
That when processed, spits out this output:
<input name="bd.form_input_user.name_1" type="text" ng-model="model.user.name">
Of course, the model doesn't have the user object and empty fields show.
So, my question is: How can I pass or link the appropriate object to the formly model when it's a more complex object?
Thanks in advance.

The model can be defined both at the form and the field level, so it is easy to use any property in an object graph as a form field. An example:
Markup:
<div ng-controller="MyCtrl as vm">
<formly-form model="vm.data" fields="vm.userFields">
<button type="submit" class="btn btn-default" ng-click="vm.submit(vm.user)">Submit</button>
</formly-form>
</div>
JavaScript:
angular
.module('myApp', ['formly', 'formlyBootstrap'])
.controller('MyCtrl', ['$scope', function($scope) {
var vm = this;
vm.data = {
user: {
name: 'john',
lastname: 'doe'
},
extra: 'extra'
};
vm.userFields = [
{
model: vm.data.user,
key: 'name',
type: 'input',
templateOptions: {
type: 'text',
label: 'Name',
placeholder: 'Enter name'
}
},
{
model: vm.data.user,
key: 'lastname',
type: 'input',
templateOptions: {
type: 'text',
label: 'Lastname',
placeholder: 'Enter lastname'
}
},
{
key: 'extra',
type: 'input',
templateOptions: {
type: 'text',
label: 'Extra',
placeholder: 'Enter extra'
}}
];
}]);
A fiddle: http://jsfiddle.net/masa671/c37gxg3h/

Related

Add directive dynamically when using angular-formly

What would be the best way to add some directive, e.g. ng-focus-if conditionally to the form's input element when using angular-formly with custom templates?
I would like to use it like this:
$scope.formFields = [
{
key: 'email',
type: 'input',
templateOptions: {
type: 'email',
placeholder: 'Your E-Mail address',
required: true,
focusIf: 'some-expression' // <--- optional directive configuration here
}
}
];
The idea is to apply the directive only when configuration option is actually provided.
You can combining angular-formly attributes with ng-focus-if attributes or any others custom attributes by using ngModelAttrs.
in your case your code should be like:
$scope.formFields = [ {
key: 'email',
type: 'input',
ngModelAttrs: {
focusIf: {
attribute: 'focus-if' //directive declaration
}
},
templateOptions: {
type: 'email',
placeholder: 'Your E-Mail address',
focusIf: '', //directive default value
required: true
}
}]
this is a working demo that can help you:
I've managed to figure out how to achieve the desired behavior, thanks to #kentcdodds and #aitnasser.
Just wanted to share the extended version here.
The idea is to use ngModelAttrs property when defining your type:
formlyConfigProvider.setType({
name: 'input',
template: '<input ng-model="model[options.key]">',
defaultOptions: {
ngModelAttrs: {
focusIf: {
attribute: 'focus-if'
}
}
}
});
Make sure not to provide the default value for the focusIf. This will prevent addition of the directive on the input element by default.
And then set the required expression on your field:
$scope.formFields = [
{
key: 'email',
type: 'input',
templateOptions: {
type: 'email',
required: true,
placeholder: 'E-Mail',
focusIf: 'true' // Or any other Angular expression
}
}
];
Feel free to play with this JSBin.

Select option in Angular xeditable and Angular Formly

I don't know how to give e-ng-options of xeditable in angular Formly.
Here is the formly Config:
formlyConfig.setType({
extends: 'select',
template: '<div><span editable-select="model[options.key]" e-ng-options="" e-name="{{::id}}">{{ model[options.key] || "empty" }}</span></div>',
name: 'editableSelect'
});
Here is the select value:
{
className: 'col-xs-12 col-sm-6',
type: 'editableSelect',
key: 'gender',
templateOptions: {
label: 'Gender',
options: [
{name: 'Male', value: 'male'},
{name: 'Female', value: 'female'}]
}
}
Pls look at JSBIN
I just figured it out.
formlyConfig.setType({
extends: 'select',
template: '<div><span editable-select="model[options.key]" e-ng-options="s.value as s.name for s in {{options.templateOptions.options}}" e-name="{{::id}}" e-placeholder="{{options.templateOptions.placeholder}}">{{ model[options.key] || "empty" }}</span></div>',
name: 'editableSelect'
});
Refered xeditable

smart table +Angular js

I am using Smart-table to show reports to the user with Angular js.
Now,I want to customize table header and want a colspan in smart table 's header.
Does anyone know about this?Is it possible?
Please share example,plunker if anyone have achieved this
You can have whatever template you want in cellTemplate attr, where I have concatenated both first name and last name.
Like I have used,
scope.columnCollection = [
{ label: 'Name', map: 'FirstName', validationAttrs: 'required', validationMsgs: '<span class="error" ng-show="smartTableValidForm.FirstName.$error.required">Required!</span>',cellTemplate:'<div class="name"><span>{{dataRow.FirstName +" "+dataRow.LastName}}</span><div>'}, //have whatever template you want and your custom css
//{ label: 'Last Name', map: 'LastName' },
{ label: 'User Name', map: 'UserName', validationAttrs: 'required' },
{ label: 'Password', map: 'Password', noList: true, editType: 'password' },
{ label: 'Customer', map: 'CustId', optionsUrl: '/GetCusts', editType: 'radio' },
{ label: 'Role', map: 'RoleId', optionsUrl: '/GetRoles', editType: 'select', defaultTemplate: '<option value="" ng-hide="dataRow[column.map]">---</option>', validationAttrs: 'required', validationMsgs: '<span class="error" ng-show="smartTableValidForm.RoleId.$error.required">Required!</span>' }, // NOTE: small hack which enables defaultTemplate option :)
{ label: 'E-mail', editType: 'email', map: 'Email' },
{ label: 'Cell Phone', map: 'Mobilephone', noEdit: true, validationAttrs: 'required' },
{ label: 'Locked', map: 'IsLocked', cellTemplate: '<input disabled type="checkbox" name="{{column.map}}" ng-model="dataRow[column.map]">', editType: 'checkbox', noAdd: true }
];
In css you can have your custom Css.
Please have a look at this
plunker
Hope this solves your problem :)
Based on the documentation you need to add something like this:
app.controller('basicsCtrl', ['$scope', function (scope) {
scope.rowCollection = [
{firstName: 'Laurent', lastName: 'Renard', birthDate: new Date('1987-05-21'), balance: 102, email: 'whatever#gmail.com'},
{firstName: 'Blandine', lastName: 'Faivre', birthDate: new Date('1987-04-25'), balance: -2323.22, email: 'oufblandou#gmail.com'},
{firstName: 'Francoise', lastName: 'Frere', birthDate: new Date('1955-08-27'), balance: 42343, email: 'raymondef#gmail.com'}
];
scope.columnCollection = [
{label: 'First Name', map: 'firstName'},
{label: 'same same but different', map: 'firstName'},
{label: 'Last Name', map: 'lastName'}
];
}]);
Your columnCollection will adjust the labels based on the mappings.

How to get parent node in angular

I loop an array inside another array in angular.
fields:
[
{
label: 'First Name',
name: 'firstname',
key: '',
type: 'text',
//fixa requierd i templatesen
required: true
},
{
label: 'Last Name',
name: 'lastname',
key: '',
required: true,
},
{
label: 'Email',
name: 'email',
key: '',
required: true,
type: 'email',
},
{
key: 'test',
type: 'radio',
labels:
[
{
name: 'media',
label: 'Media'
},
{
name: 'frilans',
label: 'Frilans'
}
],
}
],
Whilst looping through field.labels, I want to access it's sibling "key". I tried using $parent scope, but that will include the entire scope. Then angular doesn't know what key it should use.
<div ng-repeat="field in fields">
<div ng-repeat="subfield in field.labels">
<!-- gets you parent's key -->
{{field['key']}}
<!-- you can play around with $index to reach the parent's siblings -->
<!-- just make sure index is in the range though -->
{{fields[$parent.$index - 1]['key']}}
{{fields[$parent.$index + 1]['key']}}
</div>
</div>

Validation data in Ext.Model

Help me please.
Models have built-in support for validations, which are executed against the validator functions in Ext.data.validations.
My code:
Ext.define('User', {
extend: 'Ext.data.Model',
fields: [{
name: 'name',
type: 'string'
},{
name: 'age',
type: 'int'
},{
name: 'phone',
type: 'string'
},{
name: 'gender',
type: 'string'
},{
name: 'username',
type: 'string'
}],
validations: [
{
type: 'length',
field: 'name',
min: 2
},{
type: 'format',
field: 'username',
matcher: /([a-z]+)[0-9]{2,3}/
}]
});
var person = Ext.create('User', {
name: 'Eugene',
username: 'Popov',
gender: 'F',
age: 300,
Married: false
});
console.log(person.get('name'))
person.set('name','U');
console.log(person.get('name'))//U
});
I've read that the model can filter data .
What is the principle of their work?
Why I can write wrong values in my example?
Thanks!
Model validations don't reject changes by themselves. Editing a model through some other component (like stores or grid editors) may provide this feature. Validations only come into play when calling the validate or isValid methods on a model.
If your models are part of a store, you can listen for the store's update event (link to docs). From within the event handler, you can validate the model and reject any changes you want.
// Simple demonstration
store.on('update', function (store, model, operation) {
if (operation === Ext.data.Model.EDIT && !model.isValid()) {
model.reject();
}
});

Resources