hsuanxyz / ion2-calendar

📅 A date picker components for ionic2 /ionic3 / ionic4
https://hsuanxyz.github.io/demo/ion2-calendar/
MIT License
555 stars 278 forks source link

Is it possible in multiple choice, a readonly ? #187

Open Dudusk opened 6 years ago

Dudusk commented 6 years ago

Ionic version: (check one with "x") [ ] 2.x [x] 3.x [ ] 4.x

Ion2-calendar mode: (check one with "x") [x] components mode [ ] modal mode

I'm submitting a ... (check one with "x") [ ] bug report [ ] feature request [x] help me

Hi,

I use ion2-calendar and i'd like when a user tap the date, a modal with 2 input boxes comes with some informations which he have to enter. After, the user can't unselect the day, but when he click on the day, it show what he entered before.

Other information:

cli packages: (...\npm\node_modules)

    @ionic/cli-utils  : 1.19.2
    ionic (Ionic CLI) : 3.20.0

global packages:

    cordova (Cordova CLI) : 7.0.1

local packages:

    @ionic/app-scripts : 3.1.2
    Cordova Platforms  : none
    Ionic Framework    : ionic-angular 3.9.2

System:

    Android SDK Tools : 26.1.1
    Node              : v8.11.3
    npm               : 5.6.0
    OS                : Windows 10

Environment Variables:

    ANDROID_HOME : C:\Android\android-sdk

Misc:

    backend : pro

Thanks a lot if someone can help me :) Kind regards.

waleman commented 6 years ago

Hi im trying this too

i load the dates from my webservice and I would like that you can only click on those dates

try to readonly = true but that disables all dates

Dudusk commented 6 years ago

Hi !

In fact, For me, if i try to put readonly=true, i can't select an other one..

Let's continue to search haha

jcmendes9898 commented 4 years ago

Did you have success? I'm trying to make modal to be readonly to. Without any success so far.

germangc125 commented 3 years ago

I modified the month.component.js file (compiled) in the function that is below and add an if and the emit for when the day is clicked, with this the selected day would be obtained and already in your ts in the select = "selectDay" you can do whatever you want. The file compiled is : node_modules/ion2-calendar/__ivy_ngcc__/dist/components/month.component.js

MonthComponent.prototype.onSelected = function (item) { debugger; if (this.readonly) { item.selected = true; this.select.emit(item); } else { item.selected = true; this.select.emit(item); if (this.pickMode === config_1.pickModes.SINGLE) .....

gbrits commented 2 years ago

Hi there, I'm using this package to show calendar events for an app, I am using the modal view, the best I could do to get events emitted was to use onChange in the componentProps, which does return the events when selected or deselected, as an array of dates. The readonly attribute in my code below is not being utilised, I can still select & unselect all dates. I'm hoping to be able to click on a date & just show its information - to then utilise it to show information about that date, rather than deselect a selected date.

Would any bright spark out there have the solution? :) Thanks. If I figure it out I'll post it here too to hopefully help others.

async openCalendar() {
    var dates = [];
    this.open$.subscribe(async (data) => {

      dates = data.map( (d: any) => {
          let day_var = new Date( d.bookedFor );
          return {
            date: day_var.getDate(),
            dateObj: 1,
            months: day_var.getMonth(),
            string: (typeof d.bookedFor === 'string' || d.bookedFor instanceof String) ? d.bookedFor.split('T')[0] : day_var.toLocaleTimeString("en-US"),
            time: Math.round(day_var.getTime()),
            unix: Math.round(day_var.getTime()/1000),
            years: day_var.getFullYear()
          };
      } );

      const options: CalendarModalOptions = {
        pickMode: 'multi',
        title: 'Active Orders',
        defaultDates: dates,
        closeLabel: 'Close',
        cssClass: 'order-calendar'
      };
        const myCalendar = await this.modalCtrl.create({
            component: CalendarModal,
            componentProps: { 
                options, 
                readonly: true, // Does not work
                onChange: function(sel) { console.log('onChange', sel) } 
            }
        });
        myCalendar.present();
        });
    });
  }

So I have found a workaround, it's hacky, and it requires jQuery, but it works -- and I don't see any other viable solutions.

You start by disabling everything with the disableWeeks option property.

    const options: CalendarModalOptions = {
        pickMode: 'multi',
        title: 'Active Orders',
        defaultDates: dates,
        closeLabel: 'Close',
        disableWeeks: [0,1,2,3,4,5,6], // Add this
        cssClass: 'order-calendar'
    };

Then, using a short setTimeout, each through the days & remove the disabled prop.

    myCalendar.present();
    setTimeout(() => {
        jQuery(function($) {
            $('.ion-page .days-btn').each(function() {
                $(this).prop('disabled', false);
            });
        });
    }, 1000);

Now, over in your parent component, in the ngOnInit you can utilise the event's aria label:

jQuery(function($) {
      $('.ion-page').on('touchstart', '.days-btn', function(e) {
        if($(this).hasClass('on-selected')){
          $(this).addClass('was-selected');
        }
      });
      $('.ion-page').on('touchend', '.days-btn', function(e) {
        if($(this).hasClass('was-selected')) {
          console.log('Which date?', $(this).attr('aria-label'));
        } else {
          $(this).removeClass('on-selected');
        }
        return false; // Important to stop usual function.
      });
    });