Thursday, December 25, 2014

Implementing Drag and Drop functionality in ADF Calendar

To achieve Drag and Drop functionality for activities within the adf Calendar:

- Add 'Calendar Drop Target' as a child to Calendar:

<af:calendarDropTarget dropListener="#{pageFlowScope.calendarBean.calendarDropListener}" actions="MOVE">
    <af:dataFlavor flavorClass="org.apache.myfaces.trinidad.model.RowKeySet" discriminant="DnDAcivityModel"/>
</af:calendarDropTarget>

- Add the code below in calendarDropListener

  public DnDAction calendarDropListener(DropEvent dropEvent)
  {
    TimeZone timeZone1 = TimeZone.getDefault();
    Transferable transferable = dropEvent.getTransferable();
    CalendarActivity activity =
      (CalendarActivity) transferable.getData(DataFlavor.getDataFlavor(CalendarActivity.class));

    CalendarDropSite dropSite = (CalendarDropSite) dropEvent.getDropSite();
    Date dropTargetDate = dropSite.getDate(); //Date at drop target, time is defaulted at 00:00:00 in month view.
    System.out.println("Drop Date:"+ dropTargetDate);       
    
    Date sourceStartDate = activity.getStartDate(timeZone1); // Start date of dragged activity
    Date sourceEndDate = activity.getEndDate(timeZone1); // End date of dragged activity
    System.out.println("Old start date:" + sourceStartDate);
    System.out.println("Old end date:" + sourceEndDate); 

    // Calculate new start date for dragged activity
    Date targetStartDate = null;   
    // In day and week view
    if (calendarBinding.getView().equals("day") || calendarBinding.getView().equals("week"))
    {
      // Start date will be same as target date
      targetStartDate = dropTargetDate;
    }
    else // In month view
    {
        // New start date will be target date with start date time component
        // If  start date is 12/23/2014 07:38:16 and target date is 12/24/2014 00:00:00
        // then the new start date will be 12/24/2014 07:38:16
        targetStartDate = setStartDate(sourceStartDate, dropTargetDate);
    }
    
    // Calculate new end date by adding the difference of start and end date to new start date.
    Date targetEndDate =
      setEndDate(sourceStartDate, sourceEndDate, targetStartDate); 

    System.out.println("New start Date:" + targetStartDate);
    System.out.println("New end Date:" + targetEndDate);
  
    //Update Calendar Model with new start and end dates for dragged activity
    activity.setStartDate(targetStartDate, timeZone1);
    activity.setEndDate(targetEndDate, timeZone1);
  
    OperationBinding op =  ADFUtils.findOperation("Commit");
    op.execute();

    return dropEvent.getProposedAction();
  }

  public Date setStartDate(Date sourceStartDate, Date targetDate)
  {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(sourceStartDate);
    int hour = calendar.get(Calendar.HOUR);
    int minute = calendar.get(Calendar.MINUTE);
    int second = calendar.get(Calendar.SECOND);
    calendar.setTime(targetDate);
    int year = calendar.get(Calendar.YEAR); 
    int month = calendar.get(Calendar.MONTH);
    int day = calendar.get(Calendar.DATE);
    calendar.set(year, month, day, hour, minute, second);    
    Date newStartDate = calendar.getTime();
    return newStartDate;
  }

  public Date setEndDate(Date sourceStartDate, Date sourceEndDate,
                         Date targetStartDate)
  {
    long diff = sourceEndDate.getTime() - sourceStartDate.getTime();
    int diffDays = (int) ((diff) / (1000 * 60 * 60 * 24));
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(sourceEndDate);   
    int tHour = calendar.get(Calendar.HOUR);
    int tMinute = calendar.get(Calendar.MINUTE);
    int tSecond = calendar.get(Calendar.SECOND);
    calendar.setTime(sourceStartDate);
    int sHour = calendar.get(Calendar.HOUR);
    int sMinute = calendar.get(Calendar.MINUTE);
    int sSecond = calendar.get(Calendar.SECOND);
    calendar.setTime(targetStartDate);
    calendar.add(Calendar.DATE, diffDays);
    calendar.add(Calendar.HOUR, tHour - sHour);
    calendar.add(Calendar.MINUTE, tMinute - sMinute);
    calendar.add(Calendar.SECOND, tSecond - sSecond);
    Date newEndDate = calendar.getTime();  
    return newEndDate;
  } 


For more details on adding Drag and Drop functionality to adf Calendar refer to Oracle docs

1 comment:

  1. Modified calendarDropListener code to make Drag and Drop work for the movement of activities with in the same day

    ReplyDelete