Plug me to your RESTFul API to get a complete administration tool (CRUD, multi-model relationships, dashboard, complex form widgets) in no time!
Check out the online demo (source), and the launch post.
Retrieve the module from bower:
bower install ng-admin --save
Include it:
<link rel="stylesheet" href="/path/to/bower_components/ng-admin/build/ng-admin.min.css">
<script src="/path/to/bower_components/ng-admin/build/ng-admin.min.js" type="text/javascript"></script>
Make your application depend on it:
var app = angular.module('myApp', ['ng-admin']);
Configure ng-admin:
app.config(function(NgAdminConfigurationProvider, Application, Entity, Field, Reference, ReferencedList, ReferenceMany) {
// See below for more information about the configuration
var app = new Application('My backend')
.baseApiUrl('http://localhost:3000/')
.addEntity(/* ... */)
NgAdminConfigurationProvider.configure(app);
});
Your application should use a ui-view
:
<div ui-view></div>
We chose to define the entities directly into a Javascript file to allow greater freedom in the configuration. For some part of the configuration, you'll be able to directly define the function that matches your specific needs to fit your API.
Here is a full example for a backend that will let you create, update, and delete some posts (posts
entity).
Those posts can be tagged (tags
entity) and commented (comments
entity).
app.config(function(NgAdminConfigurationProvider, Application, Entity,
Field, Reference, ReferencedList, ReferenceMany) {
var postBody, postId;
// Declare a new entity
var tag = new Entity('tags')
.label('Tags')
// how many element should be displayed in dashboard ?
.dashboard(10)
// define your specific pagination function returning GET parameters
.pagination(function(page, maxPerPage) {
return {
offset: (page - 1) * maxPerPage,
limit: maxPerPage
}
})
// enable lazyload pagination
.infinitePagination(true)
// Set specific parameter for search
.filterQuery(function(query) {
return {
filter: query
};
})
.addField(new Field('id')
.order(1)
.label('ID')
.type('number')
.identifier(true)
.edition('read-only')
)
.addField(new Field('name')
.order(2)
.label('Name')
.edition('editable')
.validation({
"required": true,
"max-length" : 150
})
);
var comment = new Entity('comments')
.label('Comments')
.dashboard(10)
.infinitePagination(true)
.filterQuery(false)
.sortParams(function(field, dir) {
return {
// Change sorting params
params: {
sort: field,
sortDir: dir
},
// You can also want to sort via headers
headers: {
}
}
})
.addField(postId = new Field('id')
.order(1)
.label('ID')
.type('number')
.identifier(true)
.edition('read-only')
)
.addField(postBody = new Field('body')
.order(2)
.label('Comment')
.edition('editable')
.validation({
"required": true,
"max-length" : 150,
// define your custom validation function
"validator" : function(value) {
return value.indexOf('cat') > -1;
}
})
)
.filterParams(function(params) {
// Allows to return custom specific search params
return params;
})
.addField(new Field('created_at')
.order(3)
.label('Creation Date')
.type('date')
.edition('editable')
.validation({
"required": true
})
).addQuickFilter('Today', function() {
var now = new Date(),
year = now.getFullYear(),
month = now.getMonth() + 1,
day = now.getDate();
month = month < 10 ? '0' + month : month;
day = day < 10 ? '0' + day : day;
return {
created_at: [year, month, day].join('-')
}
})
.addField(new Field('actions')
.type('callback')
.list(true)
.label('Big value')
// Disable default link on the list view
.isEditLink(false)
// Add a new link to the post thanks to callback
.callback(function(entity) {
// Directive can also be included
return '{{ entity.getField("name").value.toUpperCase() }}';
})
);
var post = new Entity('posts')
.label('Posts')
.dashboard(null)
.pagination(false)
.addField(new Field('id')
.label('ID')
.type('number')
.identifier(true)
.edition('read-only')
)
.addField(new Field('body')
.label('Body')
.type('wysiwyg')
.edition('editable')
)
.addField(new ReferencedList('comments')
.label('Comments')
.targetEntity(comment)
.targetField('post_id')
.targetFields([postId, postBody])
)
.addField(new ReferenceMany('tags')
.label('Tags')
.targetEntity(tag)
.targetLabel('name')
);
var app = new Application('My backend')
// Add extra headers for each actions
.headers(function(entityName, action) {
return {
'X-User': entityName === 'post' ? 'username' : 'user2',
'X-Password': 'pwd'
}
})
.baseApiUrl('http://localhost:3000/')
.addEntity(post)
.addEntity(comment)
.addEntity(tag);
NgAdminConfigurationProvider.configure(app);
});
Field
: simple fieldReference
: association 1-N with another entityReferenceList
: association N-1ReferenceMany
: association N-N
-
type(string ['number'|'string'|'text'|'wysiwyg'|'email'|'date'|'choice'])
Define the field type. -
label(string label)
Define the label of the field. -
defaultValue(v)
Define the default value of the field. -
edition(string ['read-only'|'editable'])
Define if the field is editable in the edition form. -
order(number|null)
Define the position of the field in the form. -
identifier(boolean [true|false])
Define if this field is the entity's identifier (to build the REST requests). -
format(string ['yyyy-MM-dd' by default])
Define the format fordate
type. -
choices([{value: '', label: ''}, ...]) Define array of choices for
choice` type. A choice has both a value and a label. -
valueTransformer(function)
Define a custom function to transform the value.
.addField(new Field('characters')
.valueTransformer(function(value) {
return value && value.items ? value.items[0] : value;
})
)
-
list(boolean)
Define if the field should be displayed in the list. -
dashboard(number|false)
Number of elements displayed in dashboard. -
validation(function)
Define a custom validation function.
The Reference
type also defines label
, order
, valueTransformer
, list
& validation
options like the Field
type.
-
targetEntity(Entity)
Define the referenced entity. -
targetLabel(string)
Define the target field name used to retrieve the label of the referenced element.
The ReferencedList
type also defines label
, order
, valueTransformer
, list
& validation
options like the Field
type.
-
targetEntity(Entity)
Define the referenced entity. -
targetField(string)
Define the field name used to link the referenced entity. -
targetFields(Array(Field))
Define an array of fields that will be displayed in the list of the form.
The ReferencedMany
type also defines label
, order
, valueTransformer
, list
& validation
options like the Field
type.
-
targetEntity(Entity)
Define the referenced entity. -
targetField(string)
Define the field name used to link the referenced entity. -
targetLabel(string)
Define the target field name used to retrieve the label of the referenced element.
Concatenate and minify the app with:
grunt build
Tests are launched with karma by grunt:
grunt test
A new build/ng-admin.min.js
file will be created.
Your feedback about the usage of ng-admin in your specific context is valuable, don't hesitate to open GitHub Issues for any problem or question you may have.
All contributions are welcome. New applications or options should be tested with go unit test tool.
ng-admin is licensed under the MIT Licence, courtesy of marmelab.