Coder Social home page Coder Social logo

jsmodules / angular-material-calendar Goto Github PK

View Code? Open in Web Editor NEW
182.0 16.0 88.0 1.05 MB

A calendar directive for AngularJS and Angular Material Design

Home Page: https://angular-material-calendar.bradb.net/

License: Mozilla Public License 2.0

HTML 50.44% CSS 21.37% JavaScript 27.78% Shell 0.42%

angular-material-calendar's Introduction

AngularJS Material Calendar

Build Status Code Climate Coverage Status Bower NPM Version NPM Downloads License

A calendar directive for AngularJS and Angular Material Design. It's lightweight at ~2.1 kB, and has a lot of configurability.

Screenshot

Installation

RawGit

<script src="https://cdn.rawgit.com/bradberger/angular-material-calendar/master/dist/angular-material-calendar.js"></script>

Bower

Install it via Bower

bower install --save material-calendar

Or add it to your dependencies in your bower.json file:

{
   "dependencies": {
    "material-calendar": "~0.2"
  }
}

NPM

npm install --save angular-material-calendar

Usage

First off, check out the demo.

The documentation still needs to be written. It should be pretty straight forward to figure out if you're brave by using the example/index.html file, which shows a full-fledged instance of the directive in action.

Long story short, though, it's much improved by using dedicated click handlers, setting a ngModel if desired, taking all kinds of labels, and allowing output of HTML into the day blocks. There's also an option to display it with each day taking up full page width, which is great for small mobile screens and displaying content.

By default, the standard CSS and template are included in the single compiled JavaScript file, so if you're just looking to kick the tires, that's all you should need to use. The default template is in src/angular-material-calendar.html for reference, but you can also load a custom template with the template-url attribute of the directive, which should be a url that the $http service will fetch and inject.

<calendar-md flex layout layout-fill
  calendar-direction="direction"
  on-prev-month="prevMonth"
  on-next-month="nextMonth"
  on-day-click="dayClick"
  title-format="'MMMM y'"
  ng-model='selectedDate'
  day-format="'d'"
  day-label-format="'EEE'"
  day-label-tooltip-format="'EEEE'"
  day-tooltip-format="'fullDate'"
  week-starts-on="firstDayOfWeek"
  day-content="setDayContent"></calendar-md>

The related scope looks like this:

angular.module("materialExample").controller("calendarCtrl", function($scope, $filter) {
    $scope.selectedDate = null;
    $scope.firstDayOfWeek = 0;
    $scope.setDirection = function(direction) {
      $scope.direction = direction;
    };
    $scope.dayClick = function(date) {
      $scope.msg = "You clicked " + $filter("date")(date, "MMM d, y h:mm:ss a Z");
    };
    $scope.prevMonth = function(data) {
      $scope.msg = "You clicked (prev) month " + data.month + ", " + data.year;
    };
    $scope.nextMonth = function(data) {
      $scope.msg = "You clicked (next) month " + data.month + ", " + data.year;
    };
    $scope.setDayContent = function(date) {
      // You would inject any HTML you wanted for
      // that particular date here.
        return "<p></p>";
    };
});

Localization

The localization of the calendar is straightforward and follows the standard Angular localization process described in the guide. You can find the list of natively supported locales here.

To translate the calendar, just include the correct localization file in your web page, right after the inclusion of angular.js. You can install it by downloading the file manually or using either npm or bower to automate the download.

npm install angular-i18n

or

bower install angular-i18n

Then use the script tag to include the translations (for example, for spanish locale):

<script src="bower_components/angular-i18n/angular-locale_es-es.js"></script>

Another option is to use directly a CDN like cdnjs:

<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/angular-i18n/1.5.7/angular-locale_es-es.js"></script>

That's all, now the calendar will be automatically translated in the language of you choice.

Hacking On It

Use gulp to spin up the server and re-compile resources on the fly. The gulp default task does all that for you. Just make sure to Selenium is up and running:

./node_modules/protractor/bin/webdriver-manager update
# In one terminal
webdriver-manager start
# In separate terminal
gulp

Protractor is set up to run all the tests during development. JavaScript code is linted with eslint, too, so make sure that's not complaining about code styling or other issues.

Unit tests are thanks to Karma, so run those at the same time while developing. They'll detect code changes and run automatically in the background:

# In another terminal
karma start

Contributing

Pull requests are most welcomed! The build process requires strict linting of code, so please follow the established ESLint style guide.

Also, the first round of the directive was just a proof-of-concept and test coverage is not complete, please do add tests for all new features and bug-fixes, too! Most submissions won't be merged without a test.

Also, if you could kindly add an extra test that's not related to your submission just to help us get to 100% coverage, that would be very much appreciated!

To Do

  • Unit tests (the basic setup is there, need to fill them out)
  • Verify the correct handling of timezones (tests?)
  • Write documentation
  • Spread the work
  • Add to cdnjs, jsdelivr, etc.
  • Automate the website update process after successful CI build

angular-material-calendar's People

Contributors

dgavigan avatar diegodalbosco avatar f481 avatar fbertone avatar gavinbarron avatar ideahunter avatar leocaseiro avatar lohithanand avatar rossie avatar sendilkumarn avatar stefannegrea 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

angular-material-calendar's Issues

Missing support for $templateCache

Using $http.get($scope.templateUrl) disables things like gulp-angular-templatecache and inlined templates like <script type="text/ng-template" id="templateId.html">.

Here is proposal: https://gist.github.com/darosh/f6dbf2be5363f37a9558/revisions

The trick is based on using directive templateUrl property directly in functional form:

  templateUrl: function (element, attrs) {
    return attrs.templateUrl || defaultTemplateUrl;
  },

and putting defaultTemplate into cache:

  $templateCache.put(defaultTemplateUrl, defaultTemplate);

More intuitive selection of month/year

Want to come up with a method for a quicker/more intuitive selection of month and year. Right now the previous/next links work fine, but if there's a need to select a date which is far in the future or past, it requires a lot of clicking.

This is very much open to suggestions, so if you've seen a calendar that has a good implementation of that type of navigation let me know. PR's always welcomed, too!

css class or style for days with events.

Hello,
It would be great to change the style of the days with events, so you can distinguish them better.

It happens that when you are using the calendar on mobile devices is difficult to display text in days, that would be nice to be able to distinguish a css class.

Thank you.

Get $templateUrl from $http

I think, that parameter in $http.get() function should be "$scope.templateUrl", as we have it in condition above.

Line 257 at source code:
if ($scope.templateUrl) {
$http
.get($scope.template)
.success(deferred.resolve)
.error(deferred.reject);
}

Binding data to a date.

Right now, the only way to associate external data with a specific day in the calendar is via setDayContent(), and this is mostly presentational. I didn't see anything in the demo that indicates that it's possible to do what I'm suggesting. Is this feature in the pipeline?

Edit: Also, is there an existing, preferred hack that makes this possible?

Bad days

I noticed there is an issue with day of the calendarbfir October and other months near the end.
There are two "25" days. You can see it on the demo page too.

NPM install

Error while installing with command:

npm install angular-material-calendar --save
npm ERR! [email protected] postinstall: `./node_modules/protractor/bin/webdriver-manager update`
npm ERR! spawn ENOENT
npm ERR! 
npm ERR! Failed at the [email protected] postinstall script './node_modules/protractor/bin/webdriver-manager update'.
npm ERR! This is most likely a problem with the angular-material-calendar package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     ./node_modules/protractor/bin/webdriver-manager update
npm ERR! You can get their info via:
npm ERR!     npm owner ls angular-material-calendar
npm ERR! There is likely additional logging output above.

Calendar is not auto-updating when new event is being created.

How can I refresh / reload calendar when I update setDayContent?

self.diary.setDayContent = function(date) {

        var deferred = $q.defer();
        $timeout(function () {
            var ReminderNum = 0;
            var reminderPromise = ReminderAPI.get({ userID: UserID, RosterDate: date }).$promise.then(function (reminders) {
                angular.forEach(reminders, function (val, key) {    
                    ReminderNum++;
                });
                var promise = RosterAPI.daily({ userID: UserID, daily: date }).$promise.then(function (rosters) {
                    var workTime = "<p></p>";
                    var displayRoster = [];
                    var reminderTxtNum = '';

                    if (ReminderNum > 1) {
                        reminderTxtNum = "<p><i class=\"fa fa-bell-o\"></i> You have " + ReminderNum + " reminders.</p>";
                    }
                    if (ReminderNum == 1) {
                        reminderTxtNum = "<p><i class=\"fa fa-bell-o\"></i> You have " + ReminderNum + " reminder.</p>";
                    }

                    angular.forEach(rosters, function (val, key) {
                        if (angular.equals(val.RosterDate, date)) {
                            var startTime = val.StartTime;
                            var endTime = val.EndTime;

                            val.StartTime.split(':').map(Number).reduce(function (pUnit, cUnit, index) {
                                if (cUnit == 0) cUnit = '00';
                                if (index == 1) startTime = pUnit + ':' + cUnit + 'am';
                            });
                            val.EndTime.split(':').map(Number).reduce(function (pUnit, cUnit, index) {
                                if (cUnit == 0) cUnit = '00';
                                if (index == 1) endTime = pUnit + ':' + cUnit + 'pm';
                            });

                            workTime = "<p>" + startTime + " - " + endTime + "</p>" + reminderTxtNum;
                            displayRoster.push({ html: workTime, holidays: holiday });
                            deferred.resolve(displayRoster, date);
                        } else {
                            if (self.diary.isPublicHoliday)
                                workTime = self.diary.publicHolidayName;
                            // console.log('workTime=' + workTime);
                            deferred.resolve(workTime, null);
                        }
                    });
                });
            });

        }, 1000);
        return deferred.promise;
    };

Directive runs before JSON data is fetched.

This may be due to my inexperience, but when I run the directive with JSON holiday data from a server it shows the holidays as undefined. When I use the same exact data hard-coded it runs just fine.

<calendar-md day-content=holiday.setDayContent></calendar-md>

So, essentially this is running just before the HolidayService get function. Is there a way to wait to run the directive until the JSON data is defined?

Need ability to disable click event

I have a need to use this calendar in a read-only fashion. It would be really helpful to add a disable-click or a read-only attribute.

It seems like an easy fix. The handle click function could just be wrapped in an if.

reload data

Hi, is possible to reload all the calendar component after it was rendered?
thanks in advance

Localization advise

Hi!

I'd just like to notice it would be fine to advise everyone that wants to use a different locale for the calendar, they only need to use the correct angular-i18n file.

Two different ways to install:

bower install angular-i18n

or

npm install angular-i18n

then use the script tag to include the translations (for example, for spanish locale):

<script src="bower_components/angular-i18n/angular-locale_es-es.js"></script>

or you may use a CDN like cdnjs:

https://cdnjs.com/libraries/angular-i18n

Please consider including some related information at README.md

Have a nice day

Unable to update displayed data without re-loading the directive

At present the HTML shown can only be set once per date per load. This makes it necessary to re-load the view containing the control to change the data displayed.

Suggest that we implement a data service to hold the data object currently on the directive scope and expose get/set methods to allow another component to alter the data to be shown after loading has completed.

March is doubled and October does not appear while navigating prev / next month

Hi,

Before starting explaining my issue, let me congratulate you for this super nice work ๐Ÿ‘

I encounter this issue :

  • March month is doubled (I navigate February to March then March again then April).
  • October does not appear (I navigate from September to November) โ€” should a consequence of March bug โ€”.
  • occurs both calendar and agenda views
  • not sure it is relevant but I'm in GMT+2 zone
  • it is not related to date event binding since it occurs even if no data are bound
  • I updated to latest release and it did not fix this issue

It is 99% chance related to leap year but I had a fast check on your Calendar service and I don't see what is wrong.

UPDATE :

It seems like it is month label issue since if I check previous and next month data while navigating all seems correct :

    prevMonth(data) {
        console.info(`you clicked (prev) month ${data.month} ${data.year}`);
  }

    nextMonth(data) {
        console.info(`you clicked (next) month ${data.month} ${data.year}`);
    }   

When september label next/prev tells me :

 you clicked (next) month 10 2015

Thank you in advance for your help / advices.

IE needs fixed height container

The only way I can seem to get the main content of the calendar to appear in IE is to use layout-fill and force the parent container to a fixed height (otherwise, just the md-toolbar header section is visible). This appears to be what is done on the demo page also. A fixed height calendar is not great when the day content is too big for the fixed cell heights though.

Other browsers (tested on Chrome, Firefox and Opera) have no problem with the parent container not specifying a height and/or using layout-fill and all render it with cell heights adjusting to content.

Can this be fixed in IE11?

Next Month Function

The Next month function doesn't work. In the angular-material-calendar.js file, the month is increased by 2, which actually displays the current month.

Custom interpolation symbols support

Currently the default interpolation symbols {{ and }} and hard-coded in the templates. This makes it that configuring custom ones (e.g. $interpolateProvider.startSymbol('{$'); $interpolateProvider.endSymbol('$}');) will break angular-material-calendar .
Is there an easy way to work around this or will this be fixed?

Fill $scope variable with events from json on calendar init display

Iโ€™m trying to get a $scope variable feeded at first because I need his content for displaying the calendar but also for clicks on day:

Here is my code:

angular.module(โ€˜myApp')
.controller('agendaController', function ($scope, $mdSidenav, $rootScope, $state, $filter, $http) {

    $scope.events = [];
    $scope.showevent = false;

    $scope.dayevents = [];

    $scope.daytitle = '';

    $scope.dayFormat = "d";
    $scope.selectedDate = null;
    $scope.firstDayOfWeek = 1; // First day of the week, 0 for Sunday, 1 for Monday, etc.

    $http.get('./data/agenda.json')

    .success(function (data) {

            $scope.events = data;

        })
        .error(function (data, status, headers, config) {
            //  Do some error handling here
        });

    $scope.dayClick = function (date) {

        var numFmt = function (num) {
            num = num.toString();
            if (num.length < 2) {
                num = "0" + num;
            }
            return num;
        };

        var key = [date.getFullYear(), numFmt(date.getMonth() + 1), numFmt(date.getDate())].join("-");

        //get events for the clicked date

        $scope.dayevents = $scope.events[key];

        $scope.daytitle = $filter("date")(date, "fullDate");

        if ($scope.dayevents) $scope.showevent = true;
        else $scope.showevent = false;

    };

    $scope.prevMonth = function (data) {
        $scope.msg = "You clicked (prev) month " + data.month + ", " + data.year;
        $scope.showevent = false;
    };

    $scope.nextMonth = function (data) {
        $scope.msg = "You clicked (next) month " + data.month + ", " + data.year;
        $scope.showevent = false;
    };

    $scope.setDayContent = function (date) {

        var numFmt = function (num) {
            num = num.toString();
            if (num.length < 2) {
                num = "0" + num;
            }
            return num;
        };

        var key = [date.getFullYear(), numFmt(date.getMonth() + 1), numFmt(date.getDate())].join("-");

        var result = '';
        var disp_result = '';

        if ($scope.events[key]) {

            if ($scope.events[key].length > 1) {

                for (i = 0; i < $scope.events[key].length; i++) {
                    result += '<span class="icon-hexagon event_category_' + $scope.events[key][i].category + '"></span>';
                }
            } else {
                result = '<span class="icon-hexagon event_category_' + $scope.events[key][0].category + '"></span>';
            }


        }

        if (result != '') disp_result = '<div class="events_result">' + result + '</div>';

        return $scope.events[key] ? disp_result : "";


    };

})

and agenda.json example:

{
"2015-09-07": [{
"name": "Labor Day",
"category": 1,
"date": "2015-09-07",
"start": "13h15"
}],
"2015-09-11": [{
"name": "Patriot Day",
"category": 1,
"date": "2015-09-11",
"start": "09h15"
}],
"2015-09-13": [{
"name": "Grandparent's Day",
"category": 1,
"date": "2015-09-13",
"start": "08h15"
}],
"2015-09-17": [{
"name": "Constitution Day",
"category": 1,
"date": "2015-09-17",
"start": "13h35"
}],
"2015-10-06": [{
"name": "German-American Day",
"category": 1,
"date": "2015-10-06",
"start": "15h45"
}],
"2015-10-09": [{
"name": "Leif Erkson Day",
"category": 1,
"date": "2015-10-09",
"start": "11h00"
}]
}

For the moment it's working only by clicking next/previous month but but not on the initial displayed month.

Thanx to help.

Apply classes on click and current date

This is more of feature request.

I see there is no way to Add a class to a date.
For Example, Instead of injecting HTML It is easy to change the background color (By applying the class) in case of an event.

Start day/week is off.

Really like this app you created and looks to be exactly what I am looking for. However I thought I should point an issue I noticed after cloning/building. Your start day is on a row by itself and the last week is a day short. See attached screenshot for explanation.

angular-material_screenshot

Error when tap to change the month

Hi, I am trying to use the calendar in my ionic app.
The calendar is run, but with a little problem. For example suppose the calendar is on March,
when I tap to change the month it skip the April, and go to May.

When I tap newly, it change to July. Ever swicthing from 2. Sorry for my english.
This occur when deploy to my device and run as an android app.

Do you have any idea!?
Regards,
Marcelo

Open Calendar on specific date on init

Please could document how to open the calendar on a specific date (as it was clicked) on init ?

I tried using variables in data-start-month and data-start-year but not working.

Giving a value to $scope.selectedDate not working too.

Thanx for your help.

Disabled global $log.debug() on localhost

This code:

angular.module("materialCalendar").constant("materialCalendar.config", {
     version: "0.2.13",
     debug: document.domain.indexOf("localhost") > -1
});

angular.module("materialCalendar").config(["materialCalendar.config", "$logProvider", "$compileProvider", function (config, $logProvider, $compileProvider) {
    if (config.debug) {
        $logProvider.debugEnabled(false);
        $compileProvider.debugInfoEnabled(false);
    }
}]);
  • leads to disabled $log.debug in whole app on localhost (which is probably opposite of intended goal as we usually debug on localhost only)
  • disabling global $log.debug by directive is sort of unexpected and unwanted behaviour (I thought my browser console is broken ๐Ÿ˜„)
  • $log.debug is not used at all in the calendar directive so the $logProvider.debugEnabled(false); can be removed anyway

Problem cdn.rawgit.com

Hello,
Was using the library without problems, but a few days ago stopped working calendar, showing me the error console is:
TypeError: $ q.resolve is not a function
ย ย ย ย  at init (angular-materials-calendar.min.js: 320)

md-calendar collides with md-calendar in angular-material 0.11.0

0.11.0 introduces an md-calendar directive, this collides with this directive.

Technically we (the wider community) should not be using the md- namespace in much the same way that we're not supposed to use the ng namespace, they're reserved (in theory) for those projects.

Anyway I really like your project and and like the ability to inject content into the calendar easily. So I propose a simple change from md-calendar to calendar-md as seen in my PR.

Cheers

Localization

Hi all,
I'm testing this component but I need a different localization,there's a way to do that?
I haven't find any way in the documentation, i've missed something?

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.