GithubHelp home page GithubHelp logo

angularagility / angularagility Goto Github PK

View Code? Open in Web Editor NEW
279.0 23.0 49.0 1.37 MB

A set of useful Angular.js extensions implementing common UX patterns to improve productivity from @JohnCulviner

Home Page: http://angularagility.herokuapp.com/

License: MIT License

JavaScript 74.74% HTML 20.42% CSS 4.83%

angularagility's Introduction

AngularAgility

[![Build Status][2]][1] [1]: https://travis-ci.org/AngularAgility/AngularAgility [2]: https://travis-ci.org/AngularAgility/AngularAgility.png (Build Status)

A set of useful Angular extensions to improve productivity.

Installation

Note all JavaScript/CSS that you might want to use is located in /src/**/*.

Or install with:

npm install -S angular-agility

or:

bower install -S angular-agility

For TypeScript 2.0+ type definitions, use:

npm install -D @types/angular-agility

AngularJS is the only dependency.

For example for FormExtensions add the following dependencies to your Angular module definition. (aaNotify is baked in and allows for notifications. Disableable, see provider.js)

angular.module('myModule', ['aa.formExtensions', 'aa.notify']);

Form Extensions

Blog Posts | Source | API Docs | Live Demo

AngularJS form validation is likely one of the best takes on form validation out there. Unfortunately it can often be a little TOO flexible for many applications where you want basic error message display and generation without having to dive into the form object model and manually construct basic messages for each field.

This is where Form Extensions comes in. It works with built in AngularJS validation and TBS3 (by default) to:

  • Drastically reduce the amount of boilerplate, repetitive, error-prone HTML required to produce forms, labels and validation messages. Comes with support for Twitter Bootstrap 3 baked in but free to do whatever you want (see last bullet).
  • Automatically generate AngularJS fields for use in form validation, their error messages AND labels.
  • On blur and on invalid submit attempt showing of validation messages.
  • Form extensions programatically extends forms at myForm.$aaFormExtensions = {...}.
  • Code is cleaner and easier to read. Form Extensions is DSL that distills your HTML down to only what is required.
  • Feel free to use full blown markup whenever you want complete control.
  • Mix and match the directive components of Form Extensions to get exactly what you'd like for each situation.
  • It does exactly what you want: EVERYTHING is overridable on a global and per-instance basis through a rich provider model. AKA if you don't like how it looks right now you can change it. Heck you don't even need to use Twitter Bootstrap even.
myApp.config(function(aaFormExtensionsProvider) {
    aaFormExtensionsProvider.onNavigateAwayStrategies.myCustomStrategy = function(rootFormScope, rootForm, $injector){/*...*/};
    aaFormExtensionsProvider.defaultOnNavigateAwayStrategy = 'myCustomStrategy';
    //etc, look at provider.js to see what is available
})

Note all of the strategies include an $injector as the last argument so that you can bring in your own Angular dependencies (or perhaps even do a $compile if you wanted inside).

Demo

In a nutshell

With Form Extensions:

<div ng-form="exampleForm" class="form-horizontal">
    <input type="number" aa-field-group="person.age" min="0" max="140" required>
</div>

Without Form Extensions:

<div ng-form="exampleForm" class="form-horizontal">
    <div class="form-group">
        <label for="age" class="col-sm-2 control-label">
            Age *
        </label>
        <div class="col-sm-3">
            <input type="number" class="form-control" ng-model="person.age"
            name="age" id="age" min="0" max="140" required />

            <div class="validation-error" ng-show="(exampleForm.age.$dirty || invalidSubmitAttempt) && exampleForm.age.$error.number">
                Age must be a number
            </div>
            <div class="validation-error" ng-show="(exampleForm.age.$dirty || invalidSubmitAttempt) && exampleForm.age.$error.min">
                Age must be at least 0.
            </div>
            <div class="validation-error" ng-show="(exampleForm.age.$dirty || invalidSubmitAttempt) && exampleForm.age.$error.max">
                Age must be at most 140.
            </div>
            <div class="validation-error" ng-show="(exampleForm.age.$dirty || invalidSubmitAttempt) && exampleForm.age.$error.required">
                Age is required.
            </div>
        </div>
    </div>
</div>

Or configure it from your code:

var app = angular.module('app', ['aa.formExternalConfiguration', 'aa.notify'])
    .controller('main', ['$scope', function(scope) {
       scope.user = {
           name:'Test1',
       };
       scope.formconfig = {
           validations: {
               user:{
                   name: {
                       'ng-minlength':8,
                       required:true
                   },
               }
           }
       };
    }]);
<div ng-controller="main">
    <div aa-configured-form validation-config="formconfig" ng-form="exampleForm">
        <input type="text" ng-model="user.name" />
    </div>
</div>

Advanced Form Extensions

Blog Posts | Source | API Docs | Live Demo

Form changed tracking

Form changed tracking means deviation from the initial state of the form† indicates that a form changed. You can change a field and set it back to it's initial state and aaFormExtensions considers the field AND the form no longer changed (all values are equal to their init state†).

Angular considers the field/form dirty still since it was touched (yet changed back to initial state).

Form reset

Sets the state of the form back to it's original state†:

personForm.$aaFormExtensions.$reset(/*optional shouldNotConfirmReset*/);

†AFTER AJAX. All native Angular AJAX requests are counted by aaLoadingWatcher and a form isn't considered loaded until pending AJAX requests have completed. If you have other types of loading to account for simply use aaLoadingWatcher.increment()/.decrement() API to count them.

Reset initial form state

The current state of the form will be considered it's initial state (any changes from here are now $changed):

personForm.$aaFormExtensions.$resetChanged();

Loading indicators

isLoading boolean is available from aaLoadingWatcher.isLoading factory or: $rootScope.aaIsLoading = false

On-navigate away handling

Includes (by default, overridable) detection of AngularUI Router $stateChangeStart. If the root form in the view is myForm.$aaFormExtensions.$changed it will block with a JavaScript confirm. Please customize this with however you are doing modals. I would recommend AngularUI Modal. Then register your own custom strategy:

myApp.config(function(aaFormExtensionsProvider) {
    aaFormExtensionsProvider.onNavigateAwayStrategies.myCustomStrategy = function(rootFormScope, rootForm, $injector){/*...*/};
    aaFormExtensionsProvider.defaultOnNavigateAwayStrategy = 'myCustomStrategy';
    //etc, look at provider.js to see what is available
})

Use to ignore on a per form basis (if you registered a global default):

<div ng-form="myForm" on-navigate-away-strategy="none">...</div>

Notify

Fully customizable/configurable growl, toastr style notifications done right

Blog Posts | Source | API Docs | Live Demo

1. Put a notification directive somewhere in the DOM with the markup for how you want it positioned

<!-- probably use a CSS class IRL but you get the point-->
<div aa-notify style="position: fixed; bottom: 25px; right: 25px;"></div>

2. Call it from your code!

angular.module('myApp')
.controller('myController', function($scope, aaNotify, $timeout) {

    $scope.trySuccess = function() {
        //the default notifyConfig sets the life to 4 seconds
        //you can tweak this globally or add your own default notifyConfig
        aaNotify.success('Example success message!');
    };

    $scope.tryInfo = function() {
        //configure to 1 second life here only
        aaNotify.info('Example info message!', { ttl: 1000 });
    };

    $scope.tryWarning = function() {
        var handle = aaNotify.warning('Example warning message!', { ttl: 999999999 });

        //whoops that message is going to be around a little *too* long with that ttl.
        //use the handle to remove it after only 4 seconds
        $timeout(function() { aaNotify.remove(handle); }, 4000);

    };

    $scope.tryDanger = function() {
        aaNotify.danger('Example danger message!<br/><br/><br/>This text after some <br/>s',
            {
                //You can register many different templates and
                //*do whatever you want* for a notification, wherever/however you want!
                //(you aren't bound by this dev's idea of what a notification should look like)
                //if you like the sound of this keep scrolling to Advanced Mode below...

                //the default template has these options
                //*if you don't like them *easily* make your own template!*
                showClose: true,                            //close button
                iconClass: 'fa fa-exclamation-triangle',    //iconClass for a <i></i> style icon to use
                allowHtml: true,                            //allows HTML in the message to render as HTML

                //common to the framework as a whole
                ttl: 0  //time to live in ms
            });
})

It does much more than this, advanced demos coming soon!

Select 2

Blog Posts | Source | API Docs | Live Demo

Headache free use of Select2 with Angular for most common tasks

First off, there are a few other Select2 directives out there. This one is different in that it is specifically designed to easily work with binding ids, objects, arrays, AJAX queries, etc. for some pretty common use cases (see examples!).

It abstracts away the complicated Select2 API (lots of examples below!) and should make it pretty easy to do a lot of things without writing a bunch of hacks. You can still always call the select2 API directly if you want. See examples below!

It offers no support for the basic 'replace a <select> list and <option>' functionality: This is designed for working with JavaScript object data (as you generally do with Angular). Not what you want? Take a look at the AngularUI one.

Interactive demos here: Demos

angularagility's People

Contributors

andersdjohnson avatar benjaminkitt avatar cliechty avatar cthrax avatar dalelotts avatar deividfortuna avatar domderen avatar dzcpy avatar gorbach avatar jasonmore avatar jdkrebs avatar jglinsek avatar johnculviner avatar maxthyen avatar meligy avatar mgibas avatar michaelpmaddox avatar milosmosovsky avatar nancoder avatar pkelbern avatar randallmeeker avatar ryanmelenanoesis avatar sfguru avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

angularagility's Issues

Correct use of on-navigate away handling

Hey John, nice toolset you've put together here. We are starting to use it but can't seem to get the on-navigate away stuff working correctly. We have a directive that we use to wrap up some of our form handling stuff. In that directive, we have a save function where we save our object to our REST API and then call an onSave handler that would exist on the controller scope (where things happen after a successful save). In the onSave in the controller we do the redirect (we are using UI-Router).

So, after a successful save, but before the call to onSave, I've tried calling:

myForm.$aaFormExtensions.$resetChanged();

But that doesn't seem to clear the $changed flag and when the redirect happens I still get the message that there are unsaved changes.

I looked at the source on your demo (http://angularagility.herokuapp.com/#/formExtensions/formExtensions/advanced) and it seems to inject $aaFormExtensions into the controller. But, when I try to inject that into my directive, I get an angular error:

Error: [$injector:unpr] Unknown provider: $aaFormExtensionsProvider <- $aaFormExtensions <- myDirective

Your docs are a little light on this stuff so maybe I'm just doing something wrong?

ng-minlength has weird behavior when used with ext-configured form

Hey there,

I've re-worked the aa.formExternalConfiguration slightly because we ran into some issues while implementing it.
I was using transclusion in my directive, which turns out I didn't need, so I threw that out.
Currently things work ALMOST as they're supposed to but I'm experiencing one weird issue:
When adding ng-minlength to an input element using the external validation configuration the model value doesn't get displayed by the element. ng-maxlength has no problems (or any other directives I've tried), but once you add ng-minlength it breaks. No errors, but the bound value doesn't display...
You can see what the directive does here:

https://github.com/rolandzwaga/AngularAgility/blob/master/src/aa.formExternalConfiguration.js#L222

I've set my priority to 500 and terminal to true to prevent directives from compiling too early, then I loop through all the child elements, check if an element has an ngModel directive attached and then add the directives that are defined in the external configuration.
Then lastly, I call $compile() on the root element.

I see nothing weird going on here, aaField, for instance, does something similar. So, I'm currently rather stumped as to what causes this issue. I'm hoping you might have an idea?

thanks in advance.

$aaFormExtensions in angularjs controller

i can not get object of $aaFormExtensions in angularjs controller.
its working only on html page.
i dont want reset button but just want reset it when form is successfully submitted.

Feature Request Customizable Templates

I sort of asked this in #58 about template customization. I'm not sure about the response.

But I thought it would be nice if the templates could be extracted from the code, such as they are in UI Bootstrap. That way they could be easily modified.

Or placing the templates in variables that could be set in a config. Or maybe all the classes that are applied could be set in a config.

There seems to be many different ways. But as of now If I'm reading the docs and the code correctly (and I may not be), in order to change the width of my bootstrap column I would need to add aa-col="X" to every input. Was hoping to that I could just adjust this once and have it affect my app wide.

Like I said, many ways to skin this cat, so I figured I would post before I started hacking away.

Form mode profiles

Wishlist item:

I saw reading the code at AngularAgility/AngularAgility/blob/master/demo/app/app.js there is an example of setting the default label strategy to bootstrap3InlineForm.

My thought for profile is that it would set both the LabelStrategy and the MsgPlacementStrategy in one go.

To make this really useful having several of them already packaged (or easily available as a plugin lib) such as the existing bootstrap3inline as well as new bootstrap3basic and the other one or two demoed at http://getbootstrap.com/css/#forms-example

You would then do a single

 aaFormExtensionsProvider.setDefaultFormProfile('bootstrap3basic');

or

 <input aa-profile="bootstrap3inline" ...>

That would set the DefaultLabelStrategy and the DefaultValMsgPlacementStrategy (and perhaps make it add the 'has-error' class to the parent .form-group)

Perhaps similarly a directive that goes with aa-auto-field such as aa-profile or somesuch that would take the same bootstrap3basic, bootstrap3Inline.

Can you please provide example for 2 column layout

I would love to get example how to get 2 column form layout with aa-field-group.

Example output

<div class="form-group">
  <label class="col-sm-2 control-label">{{ 'user.PASSWORD' | translate}}</label>
  <div class="col-sm-4">
    <input type="password" class="form-control" placeholder="{{ 'user.PASSWORD' | translate}}" ng-model='user.password'>
  </div>
  <label class="col-sm-2 control-label">{{ 'user.PASSWORD_CONFIRM' | translate}}</label>
  <div class="col-sm-4">
    <input type="password" class="form-control" placeholder="{{ 'user.PASSWORD_CONFIRM' | translate}}" ng-model='user.password_confirm'>
  </div>
</div>

hidden required field

When an required input field is hidden using ng-show, aa-form-submit still fails and say's that the field is required.

Is there anyway to disable the required property automatically if the input is hidden?

Update bower.json

I see the latest version for the bower download is currently 0.1.0, could you update this so a bower install will download the latest versions of the code?
(I'm not too familiar with setting up bower, so that's why I'm asking here)

Bower installable

Wishlist item:

My (probably naive) understanding of the bower/npm ecosystem is that npm is more for stuff running on the server side, or development; bower is for stuff loaded by the client. grunt-bower-install is one of the big things that helps that along which is setup by the yeoman generator for example.

Having this lib be bower installable would be nice for testing it out.

ng-include html file with form fields not working

I came across following bug:
I defined a form, and within it I call to ng-include to a file containing some fields being validated.
As a result Angular complains during compile time:
Controller 'form', required by directive 'aaValMsg', can't be found!

Seems like require: ['^form'] does not really work as it supposed to.
Plunker:
http://plnkr.co/edit/ZqENgh?p=preview (see console output)

Not work with html file control (Need ngModelBehaviors for this)

Its not work when i put file control in form when i click to browse file it will fire validation because of field is unfocused. but actually its not unfocus just open a dialog for selecting file.
Expected result is When i am clicking on browse button it will not fire validation.

Can u please explain me how can i achieve that??

ngInclude without root element in template causes aa-field-group to error

Some of my common form elements. Such as an address grouping (street, city, state, zip), I put into a template and then ngInclude it in the form. However, it seems that the aa-field-group directive does not like this and requires that the inputs inside my template be wrapped in a ngForm despite the fact that their being included into an ngForm.

Thoughts, suggestions on how to template out my forms and still use?

Produce independent module builds

Could you produce independently built modules? e.g. so that we can source aaFormExtensions in isolation instead of the current monolithic dist.

AngularStrap is a good example of this. Their build chain includes a step to produce the modules directory in dist.

Not getting the same output on the demo site

Check out this basic plunkr. its the current release of agility and 2.17 of angular
http://plnkr.co/edit/WVgDZBx0RudzjjAO5pp1

The resulting HTML is below, clearly it does not match the demo

<div class="form-group ng-scope">
    <div class="col-sm-3"></div>
    <label for="6869a5bb-1ba2-4499-b5a3-7936c4583510">Name *</label>
    <input type="text" required="" class="form-control ng-scope ng-pristine ng-valid ng-valid-required" ng-model="name" name="name" aa-label="Name" aa-val-msg="" id="6869a5bb-1ba2-4499-b5a3-7936c4583510">
    <div class="validation-errors ng-scope" aa-val-msg-for="bob.name">
        <div class="notch notch-border"></div>
        <div class="notch"></div>
    </div>
</div>

Want show notification again after submit even one time close it.

I have a form when i click on submit it fires notification alert using aanotify just like toster.
And there is a close button in that pop up after close and then submit again now notification toster will not occur.
I want to saw it again when user click submit.

Bootstrap 2 support

We've a legacy application that's coupled to Bootstrap 2. Do form extensions have support for it or any pointers on how to add it?

Bower install doesn't work correctly

After doing a 'bower install angular-agility', only the files in the root are actually downloaded. The rest of the package only consists of an empty directory tree.

Few questions

Hi,

Been playing with using AA for the past few days.

1 - Seem to be causing a few JS errors:

"Cannot read property '$name' of undefined"

On this line: https://github.com/AngularAgility/AngularAgility/blob/master/src/aa.formExtensions.js#L625

2 - would be cool to have a "hide"/"show" aa directive. E.g. if you want to hide the whole group:

<input type="email" aa-field-group="customer.email" aa-hide="customer.isTelephoneOnly" />

Currently have to do something like:

<div ng-hide="customer.isTelephoneOnly">
<input type="email" aa-field-group="customer.email" />
</div>

To get it to hide the whole control group.

3 - Using aa-field-group on a checkbox results in the checkbox getting the "form-control" style which leads to it being huge.
I manually fixed this by changing:

https://github.com/AngularAgility/AngularAgility/blob/master/src/aa.formExtensions.js#L906

To be

if(!element.prop('class') && element.prop('type') != 'checkbox') {

Not pretty but means it's not applied to checkboxes and they are normal size.

4 - Is there any documentation on making custom strategies and how to use them? I see in the code/sample site a few references to strategies but nothing I can read.

5 - Is there any documentation on how to make AA play nicely with existing directives? I've about got it working with AngularUI's Typeahead via my own custom directive but it's not very clean.

Enhancement: Date field/validation or integration with angular-ui bootstrap's datepicker

I didn't find a datetime validation in aa.formExtensions and so I'm currently doing it separately with the following html in order to choose and validate date inputs.

<div class='form-group'>
     <div class='col-sm-3'>
        <label>Creation Date *</label>
        <input ng-model='item.CreationDate' type='text' datepicker-popup required class='form-control'>
     </div>
</div>

Maybe there is a better way that I'm just not seeing.

http://angular-ui.github.io/bootstrap/#/datepicker

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.