Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
João Granado committed Jan 23, 2015
1 parent 692b6ac commit c5ab7bf
Show file tree
Hide file tree
Showing 14 changed files with 846 additions and 2 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
bower_components
69 changes: 69 additions & 0 deletions .jshintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
{
// JSHint Configuration File
// See http://jshint.com/docs/ for more details

"maxerr" : 50, // {int} Maximum error before stopping

// Enforcing
"bitwise": true, // true: Prohibit bitwise operators (&, |, ^, etc.)
"camelcase": false, // true: Identifiers must be in camelCase
"curly": true, // true: Require {} for every new block or scope
"eqeqeq": true, // true: Require triple equals (===) for comparison
"forin": true, // true: Require filtering for..in loops with obj.hasOwnProperty()
"freeze": true, // true: prohibits overwriting prototypes of native objects such as Array, Date etc.
"immed": true, // true: Require immediate invocations to be wrapped in parens e.g. `(function () { } ());`
"indent": 2, // {int} Number of spaces to use for indentation
"latedef": false, // true: Require variables/functions to be defined before being used
"newcap": true, // true: Require capitalization of all constructor functions e.g. `new F()`
"noarg": true, // true: Prohibit use of `arguments.caller` and `arguments.callee`
"noempty": true, // true: Prohibit use of empty blocks
"nonbsp": true, // true: Prohibit "non-breaking whitespace" characters.
"nonew": false, // true: Prohibit use of constructors for side-effects (without assignment)
"plusplus": false, // true: Prohibit use of `++` & `--`
"quotmark": "single", // Quotation mark consistency
"undef": true, // true: Require all non-global variables to be declared (prevents global leaks)
"unused": true, // true: Require all defined variables be used
"strict": false, // true: Requires all functions run in ES5 Strict Mode
"maxparams": false, // {int} Max number of formal params allowed per function
"maxdepth": false, // {int} Max depth of nested blocks (within functions)
"maxstatements": false, // {int} Max number statements per function
"maxcomplexity": false, // {int} Max cyclomatic complexity per function
"maxlen": false, // {int} Max number of characters per line

// Relaxing
"asi": false, // true: Tolerate Automatic Semicolon Insertion (no semicolons)
"boss": false, // true: Tolerate assignments where comparisons would be expected
"debug": false, // true: Allow debugger statements e.g. browser breakpoints.
"eqnull": false, // true: Tolerate use of `== null`
"es5": false, // true: Allow ES5 syntax (ex: getters and setters)
"esnext": true, // true: Allow ES.next (ES6) syntax (ex: `const`)
"moz": false, // true: Allow Mozilla specific syntax (extends and overrides esnext features)
"evil": false, // true: Tolerate use of `eval` and `new Function()`
"expr": false, // true: Tolerate `ExpressionStatement` as Programs
"funcscope": false, // true: Tolerate defining variables inside control statements
"globalstrict": false, // true: Allow global "use strict" (also enables 'strict')
"iterator": false, // true: Tolerate using the `__iterator__` property
"lastsemic": false, // true: Tolerate omitting a semicolon for the last statement of a 1-line block
"laxbreak": false, // true: Tolerate possibly unsafe line breakings
"laxcomma": false, // true: Tolerate comma-first style coding
"loopfunc": false, // true: Tolerate functions being defined in loops
"multistr": false, // true: Tolerate multi-line strings
"noyield": false, // true: Tolerate generator functions with no yield statement in them.
"notypeof": false, // true: Tolerate invalid typeof operator values
"proto": false, // true: Tolerate using the `__proto__` property
"scripturl": false, // true: Tolerate script-targeted URLs
"shadow": false, // true: Allows re-define variables later in code e.g. `var x=1; x=2;`
"sub": false, // true: Tolerate using `[]` notation when it can still be expressed in dot notation
"supernew": false, // true: Tolerate `new function () { ... };` and `new Object;`
"validthis": false, // true: Tolerate using this in a non-constructor function

// Environments
"browser": true, // Web Browser (window, document, etc)
"browserify": true, // Browserify (node.js code in the browser)
"node": true, // Node.js

// Custom Globals
"globals": {
"angular": false
}
}
114 changes: 112 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,112 @@
# angular-selective-repeat
Angular selective repeat
# Angular selective repeat
`scRepeat` is a module writen in ES6 which provides an easy way to selectively display a collection of items.

## Installation

Choose your preferred method:

* Bower: `bower install angular-selective-repeat`
* NPM: `npm install --save angular-selective-repeat`
* Download: [angular-selective-repeat](https://raw.githubusercontent.com/seegno/angular-selective-repeat/master/dist/angular-selective-repeat.min.js)

## Usage

1. Include `scRepeat` module and dependencies.

```html
<script src="bower_components/angular/angular.min.js"></script>
<script src="bower_components/angular-selective-repeat/dist/angular-selective-repeat.min.js"></script>
```

2. Inject `scRepeat` module on your angular application:

```js
angular.module('myApp', ['scRepeat'])
.controller('MyController', MyController);
```

3. *./my-controller.js*:

```js
class MyController {
constructor {
this.collection = {
name: 'Doe',
age: 42,
createdAt: 'Thu Jan 22 2015 18:57:12 GMT+0000 (WET)',
city: 'Maryland'
};
}
}
```

4. *./my-view.html*:

```html
<div ng-controller="MyController as myCtrl">
<sc-repeat sc-repeat-collection="myCtrl.collection">
<sc-item sc-item-key="createdAt">
{{ myCtrl.collection.createdAt | date }}
</sc-item>

<div ng-repeat="(key, value) in scRepeat.collection track by $index">
<p>{{ key }}</p>
<h4>{{ value }}</h4>
</div>
</sc-repeat>
</div>
```

## API

### scRepeat directive
`scRepeat` directive creates a wrapper for a custom list and manages its internal elements. Its main purpose is to solve layout problems in a more declarative fashion, without the need for complex filters like, picking properties in a collection that require a different layout structure or a different data format (e.g. links, dates). It exposes an API using `ScRepeatController` that stores the collection in `scRepeat.collection`.

**Usage:**

```html
<!-- using attribute directives -->
<ANY sc-repeat="expression"></ANY>

<!-- using element directives -->
<sc-repeat sc-repeat-collection="expression"></sc-repeat>
```

### scItem directive
`scItem` directive removes an individual property from the collection and so you can include it inside the `scRepeat` directive.
To pick collection items individually, you just need to include `scItem` directive as a child of `scRepeat` element and provide the property.

**Usage:**

```html
<!-- using attribute directives -->
<ANY sc-repeat="expression">
<ANY sc-item="keyValue1"></ANY>
<ANY sc-item="keyValue2"></ANY>
</ANY>

<!-- using element directives -->
<sc-repeat sc-repeat-collection="expression">
<sc-item sc-item-key="keyValue1"></sc-item>
<sc-item sc-item-key="keyValue2"></sc-item>
</sc-repeat>
```

## Contributing & Development

#### Contribute

Found a bug or want to suggest something? Take a look first on the current and closed [issues](https://github.com/seegno/angular-selective-repeat/issues). If it is something new, please [submit an issue](https://github.com/seegno/angular-selective-repeat/issues/new).

#### Develop

It will be awesome if you can help us evolve `angular-selective-repeat`. Want to help?

1. [Fork it](https://github.com/seegno/angular-selective-repeat).
2. `npm install`.
3. Do your magic.
4. Run the tests: `gulp test`.
5. Build: `gulp build`
6. Create a [Pull Request](https://github.com/seegno/angular-selective-repeat/compare).

*The source files are written in ES6.*
28 changes: 28 additions & 0 deletions bower.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "angular-selective-repeat",
"version": "0.0.2",
"description": "AngularJS Selective Repeat",
"main": "./dist/angular-selective-repeat.js",
"authors": [
"Seegno <[email protected]>"
],
"keywords": [
"AngularJS",
"List",
"Selective Repeat"
],
"license": "MIT",
"homepage": "https://github.com/seegno/angular-selective-repeat",
"ignore": [
"**/.*",
"bower_components",
"gulpfile.js",
"karma.conf.js",
"node_modules",
"package.json",
"test"
],
"dependencies": {
"angular": "^1.3.9"
}
}
91 changes: 91 additions & 0 deletions dist/angular-selective-repeat.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/**
* angular-selective-repeat - Angular Selective Repeat
* @version v0.0.2
* @link https://github.com/seegno/angular-selective-repeat
* @license MIT
*/
(function(root, factory) {
if (typeof define === "function" && define.amd) {
define([ "angular" ], factory);
} else if (typeof exports === "object") {
module.exports = factory(require("angular"));
} else {
root.scRepeat = factory(root.angular);
}
})(this, function(angular) {
var _prototypeProperties = function(child, staticProps, instanceProps) {
if (staticProps) Object.defineProperties(child, staticProps);
if (instanceProps) Object.defineProperties(child.prototype, instanceProps);
};
var ScRepeatController = function() {
function ScRepeatController() {
this.removedProperties = [];
}
_prototypeProperties(ScRepeatController, null, {
removeProperty: {
value: function removeProperty(key) {
if (!this.collection) {
return;
}
this.removedProperties.push(key);
},
writable: true,
enumerable: true,
configurable: true
}
});
return ScRepeatController;
}();
function scRepeatDirective($parse) {
return {
restrict: "EA",
scope: true,
controller: "ScRepeatController",
controllerAs: "scRepeat",
require: "scRepeat",
compile: function(element, attrs) {
if (!(attrs.scRepeatCollection || attrs.scRepeat)) {
throw new Error("You need to provide a collection.");
}
var collection = $parse(attrs.scRepeatCollection || attrs.scRepeat);
return {
pre: function(scope, element, attrs, scRepeat) {
scRepeat.collection = angular.copy(collection(scope));
var unwatch = scope.$watchCollection(function() {
return collection(scope);
}, function(collection) {
scRepeat.collection = angular.copy(collection);
if (scRepeat.removedProperties.length) {
angular.forEach(scRepeat.removedProperties, function(property) {
delete scRepeat.collection[property];
});
}
});
scope.$on("$destroy", function() {
unwatch();
});
}
};
}
};
}
scRepeatDirective.$inject = [ "$parse" ];
function scItemDirective() {
return {
restrict: "EA",
require: "^scRepeat",
priority: 601,
link: function(scope, element, attrs, scRepeat) {
if (!scRepeat.collection) {
return;
}
if (!(attrs.scItemKey || attrs.scItem)) {
throw new Error("You need to provide a `key`.");
}
scRepeat.removeProperty(attrs.scItemKey || attrs.scItem);
}
};
}
var ngModule = angular.module("scRepeat", []).controller("ScRepeatController", ScRepeatController).directive("scItem", scItemDirective).directive("scRepeat", scRepeatDirective);
return ngModule;
});
1 change: 1 addition & 0 deletions dist/angular-selective-repeat.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit c5ab7bf

Please sign in to comment.