Presenting a Date picker

I am trying to see if I can present a Date picker to choose random days in a month to assign specific calendar events without having to input events every time. Is this possible?

let calendarrName = “Calendar”
let cal = await Calendar.forEventsByTitle(calendarrName)
let addEvent = new CalendarEvent()
let d = new Date()
let weekDay = d.getDay()

if(weekDay == 2 || weekDay == 4)
{
Speech.speak(“Ivan today is not a day to go to work”)
addEvent.title= “No work day”
addEvent.save()
}else{
var lastDayOfMonth = new Date(d.getFullYear(), d.getMonth()+1, 1);
let rule = RecurrenceRule.complexWeeklyEndDate(1, [2,4,6],null, lastDayOfMonth)
addEvent.addRecurrenceRule(rule)
addEvent.title = “Burlington Coat Factory”
addEvent.notes = “Hi Ivan, your work schedule for today is between 2.00 PM & 8.00 PM”
addEvent.location = “1640 Charles Road, Albania”
addEvent.save()
}

let uiTable = new UITable()
let uiTablerow = new UITableRow()
let event = Calendar.forEventsByTitle(calendarrName)
let titleCell = uiTablerow.addText(addEvent.title)
uiTablerow.addText(formatTime(addEvent.startDate))
uiTablerow.addText(formatTime(addEvent.endDate))
uiTablerow.height = 40; uiTablerow.cellSpacing = 40;
uiTable.addRow(uiTablerow)
let addressTableRow = new UITableRow()
let addressTitle = addressTableRow.addText(“Location”)
addressTableRow.addText(addEvent.location)
addressTableRow.height=40;
uiTable.addRow(addressTableRow)

function formatTime(date) {
let hours = date.getHours()
let minutes = date.getMinutes()
let time = ‘’;
if(hours < 10){
time+=‘0’
}
time+=hours;
time+=’:’
if(minutes< 10){
time+=‘0’;
}
time+=minutes;
return time;
}
Pasteboard.pasteString(addEvent.location.toString())
if(config.runsWithSiri){Speech.speak(addEvent.notes)
QuickLook.present(addEvent.location.toString())
QuickLook.present(addEvent.notes.toString())
QuickLook.present(uiTable)
}

Can you clarify your request. Presnting a date picker to pick a date isn’t the same thing as choosing a random day of the month … unless you are assuming yourself to be random.

Are you looking to display something to let you pick a date, or are you looking to generate one (or more) random days in a month?

Also, I have questions regarding passing a PasteBoard input (copied text) into a Shortcuts Clipboard input to pass on to the next action ? Any help would be much appreciated

You might want to post that second, different question, as a new topic with more detail about what your questions are. It’s a bit tricky to see what the issue is given you are talking about the pasteboard/clipboard that is available in both Scriptable and Shortcuts just by it being an OS feature.

I have shared my code above for trying to create a specific event that would occur on specific days of a month (for example, an assigned work schedule). Instead of inputting the schedule on those days individually, I am trying to automate the entries for which I need to be able to choose the days of the month.

If I understand correctly, you want to have a way to specify a set of days in the month an then generate an event that occurs on each of those dates, and it is the capture of those dates that you have the issue with.

I’d start by using Scriptable’s Alert to capture a comma separated string of dates and parsing that string into an array you can iterate through and create your events for.

Once that was working, I’d perhaps look at writing a little HTML based calendar UI I could display in a web view and then multi-select entries to fnally return a string of days I could slot into the script.

An alternative might be, that if you were working with more predictable patterns such as ‘every Monday and Wednesday’, or ‘every three days startng tomorrow’, a menu based approach using button cells in a table may be an option.

Hope that’s something like what you’re looking for.


Quick Tip
If you wrap your code in backticks…

```

let foo = “bar”;

```

… it’ll get formatted :sunglasses:

let foo = "bar";

2 Likes

I was able to work on the lead and get a webview to load a jQuery Date picker and store an array of Dates from the calender UI. How can I pass the stored dates array into the scriptable for use with the script

1 Like

I’m not conceniced that a web view is the right solution here. In theory, you can use a web view and run the script when pressing a link in the web view using Scriptables URL scheme but that will cause the script to be run again, potentially with a query parameter that allows you to differentiate the behavior. It’s a powerful feature but probably not ideal for your solution.

Instead I would try to present the dates in a UITable with UITableCells containing buttons. You can assign an action to these buttons.
For a quick introduction to this, take a look at the Watchlist example script located in the apps settings. Don’t hesitate to ask if you have any questions about this.

I would like to know if there is a native IOS Datepicker that I can present to a user from within Scriptable ? Is this in the works or Am I missing something?

In the meantime I can work on the approach you suggested of creating a UI Table to display the calendar

iOS does have a date picker and I do have on my todo to bridge it to Scriptable for a future update. In the mean time, I think you’ll find that the UITable approach fulfill your needs :blush:

///

let d = new Date();
    var days = ["Sun","Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
    var months = ["Jan", "Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]
    var month = months[d.getMonth()]
    var date = d.getDate()
    var year = d.getFullYear()

// Creating the UITable with rows and cells    
let table = new UITable()
table.showSeparators = true;
let row = new UITableRow()
let titleRow = new UITableRow()
row.height = 100
row.cellSpacing=40

let cell = UITableCell.text(month+"", year+"")
titleRow.addCell(cell)
cell.centerAligned()


table.addRow(titleRow)

row.addCell(UITableCell.text("Sunday",null))
row.addCell(UITableCell.text("Monday",null))
row.addCell(UITableCell.text("Tuesday",null))
row.addCell(UITableCell.text("Wednesday",null))
row.addCell(UITableCell.text("Thursday",null))
row.addCell(UITableCell.text("Friday",null))
row.addCell(UITableCell.text("Saturday",null))



table.addRow(row)

loadDatePicker()

getbtnvalue()



// function to show the dates and populate them

function populateDates() {
	table.removeAllRows()
	
}

// function to open the date picker UI
function loadDatePicker(){
	
    
   
   let firstDay = firstDayofMonth(d.getMonth(), d.getFullYear())
  
   let maxdaysInMonth = daysInMonth(d.getMonth(), d.getYear())
  
   
    let dater =1;
    
    
    

      for( let i=0; i <6 ; i++) {
      
        let dateRo = new UITableRow()          
        
            for( let j =0; j < 7; j++) {
              
              
          
            if(i === 0 && j < firstDay) {
            
           
            let btn = dateRo.addButton((""))
            
            } else if(dater > maxdaysInMonth){
              break;
              
          } else {
                            
              
              dateRo.addButton((dater+ "") )
         
                dater++

      }
      }
            
        table.addRow(dateRo)
       }

      
      table.present()
     
      
}

//function to get the clicked date
function getbtnvalue(){
      let btn = table.
      btn.onTap = (idx) => {
      
}
  }


// function to get first day of the month
  
 function firstDayofMonth(month, year) {
    
    let firstDay = (new Date(year, month)).getDay()
    
    return firstDay
  
  }
  
// function to get number of days in a month  
  
  function daysInMonth(month, year) {
    
    let daysInMonth = 32- new Date(year, month, 32).getDate()
    
    return daysInMonth
    
    }
  /
///

Currently this is how the calendar looks. I am still working on it to make it fully usable.
My current question would be to capture a particular date on button tap. Are there ways to get to a particular cell in a particular row of the table programmatically? or Can this be done only by relying on capturing the onSelected/onTap action on a cell?

Date maths is awful, @simonbs. Anything you can do to ease the burden would be great.

Three examples:

  1. A date picker as we’re doing here.
  2. A function to return the number of days between two dates.
  3. A function to return the date formed by adding (or subtracting) a number of days from a date.

2 and 3 might already be in javascript. 1 is the item I’d encourage you to add.