Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
22 changes: 22 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module.exports = {
extends: [
'eslint:recommended'
],
env: {
es6: true,
node: true
},
overrides: [
{
files: ['test-dialog-node.js', 'example.js'],
rules: {
'no-console': 'off'
}
}
],
parserOptions: {
ecmaVersion: 2017
},
rules: {
}
};
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
.idea
54 changes: 33 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ dialog-node is providing developers an easy cross platform way to use interactiv

* no external dependencies since dialog-node does all the UI dialogs with onboard tools
* low memory foot print, important for IoT platforms like Raspberry
* low CPU consumption
* low CPU consumption

## Installation

Expand All @@ -31,23 +31,36 @@ This test will run through all available dialogs with some example settings

### Example (see also example.js)

```
var dialog = require('dialog-node');
```js
const dialog = require('dialog-node');

//will be called after user closes the dialog
var callback = function(code, retVal, stderr)
const callback = function(code, retVal, stderr)
{
console.log("return value = <" + retVal + ">");
console.log('return value = <' + retVal + '>');
}

dialog.entry('Type some text', "entry prompt", 0, callback);
dialog.entry('Type some text', 'entry prompt', 0, callback);

// OR:

try {
const {response, stderr} = await dialog.entry({
message: 'Type some text',
title: 'entry prompt',
timeout: 0
});
} catch ({code, stderr}) {
// ... Handle any errors
}
```

in order to run example.js:

```
npm start
```

## Usage

### setCwd(directory) (optional)
Expand All @@ -64,42 +77,43 @@ directory = location of mode_modules folder that includes dialog-node

### Parameter for all dialogs
```
dialog-node.<dialog>(msg, title, timeout, callback);
promise = dialog-node.<dialog>(message, title, timeout, callback);

msg = string containing specific dialog message
message = string containing specific dialog message
title = string containing title of dialog (this parameter is not observed for all dialogs)
timeout = dialog is timing out after <timeout> seconds, if parameter is 0 dialog does not time out
callback = to be called after user closes dialog, for further description see further below
promise = resolves to the return value or an Error object with "stderr" as the message and any exit code as its `code` property
```

### info

Information dialog with text and title and an OK button
```
dialog-node.info(msg, title, timeout, callback);
dialog-node.info(message, title, timeout, callback);
```

### warn

Warning dialog with text and title and an OK button

```
dialog-node.warn(msg, title, timeout, callback);
dialog-node.warn(message, title, timeout, callback);
```

### error

Error dialog with text and title and an OK button
```
dialog-node.error(msg, title, timeout, callback);
dialog-node.error(message, title, timeout, callback);
```

### question

A dialog that displays text and title and that prompts user to click a Cancel or an OK button. OK is the default answer.
A dialog that displays text and title and that prompts user to click a Cancel or an OK button. OK is the default answer.

```
dialog-node.question(msg, title, timeout, callback);
dialog-node.question(message, title, timeout, callback);
```

Returns the result of the user action as a string handed into the callback function (see also callback mechanism):
Expand All @@ -112,7 +126,7 @@ Returns the result of the user action as a string handed into the callback funct
Dialog querying user to type in some text.

```
dialog-node.entry(msg, title, timeout, callback);
dialog-node.entry(message, title, timeout, callback);
```

Returns the text the user typed as a string handed into the callback function (see also callback mechanism):
Expand All @@ -124,7 +138,7 @@ Returns the text the user typed as a string handed into the callback function (s
Prompts user to select or type a date. This one varies quite a bit across the different OSes.

```
dialog-node.calendar(msg, title, timeout, callback);
dialog-node.calendar(message, title, timeout, callback);
```

Returns the date the user selected as a string handed into the callback function (see also callback mechanism):
Expand All @@ -134,10 +148,10 @@ Returns the date the user selected as a string handed into the callback function

### file select

Prompts user to select a file.
Prompts user to select a file.

```
dialog-node.fileselect(msg, title, timeout, callback);
dialog-node.fileselect(message, title, timeout, callback);
```

Returns the path of a selected file as a string handed into the callback function (see also callback mechanism):
Expand All @@ -152,7 +166,7 @@ dialog-nodes are non-blocking and call a callback function after the user action
```
function(code, retVal, stderr)

code = return code from dialog
code = return code from dialog
retVal = user's response as a string
stderr = any error information that the dialog created
```
Expand All @@ -161,7 +175,7 @@ stderr = any error information that the dialog created

## Known Bugs / Issues

* timeout not a functional parameter for some dialogs (i.e. file select)
* timeout not a functional parameter for some dialogs (i.e. file select)

## Authors

Expand All @@ -175,5 +189,3 @@ This project is licensed under the MIT License -

* Tomás Pollak for the inspiration and elegant but short dialog code, see also https://github.com/tomas/dialog
* OSX date picker from Shane Stanley, modified by Christopher Stone, see also https://forum.keyboardmaestro.com/t/feature-request-date-picker-in-prompt-for-user-action/3281


144 changes: 65 additions & 79 deletions datepicker.osa
Original file line number Diff line number Diff line change
@@ -1,85 +1,71 @@
# 06/04/16 09:35:02
# Author: Shane Stanley
# Adapted by Christopher Stone

#use AppleScript version "2.3.1"
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
# Fixed & Rewritten by CJK
# Permission obtained for MIT license per https://stackoverflow.com/questions/56216434/problem-with-date-picker-showing-main-thread-issue/56217976?noredirect=1#comment99061871_56217976
--------------------------------------------------------------------------------
use framework "AppKit"
use scripting additions

property this : a reference to the current application
property nil : a reference to missing value
property _1 : a reference to reference

property NSAlert : a reference to NSAlert of this
property NSDatePicker : a reference to NSDatePicker of this
property NSView : a reference to NSView of this

property NSAlertSecondButtonReturn : 1001
property NSHourMinuteSecondDatePickerElementFlag : 14
property NSTextFieldAndStepperDatePickerStyle : 0
property NSYearMonthDayDatePickerElementFlag : 224
--------------------------------------------------------------------------------
property date : missing value
--------------------------------------------------------------------------------
on run
its performSelectorOnMainThread:("showDatePicker:") withObject:{¬
NSTextFieldAndStepperDatePickerStyle, ¬
NSYearMonthDayDatePickerElementFlag + ¬
NSHourMinuteSecondDatePickerElementFlag} ¬
waitUntilDone:true

return my date
end run

on showDatePicker:params
local params

set {PickerStyle, PickerElements} to params

tell (current date) to set ¬
[dateFrom, day, its month, day, year, time] to ¬
[it, 1, 4, 1, 2015, 12 * hours + 0 * minutes]

tell NSDatePicker's alloc()
initWithFrame_({{0, 0}, {100, 100}})
setDatePickerStyle_(PickerStyle)
setDatePickerElements_(PickerElements)
setDateValue_(dateFrom)
set fittingSize to fittingSize()
setFrameSize_(fittingSize)

set View to NSView's alloc()
View's initWithFrame:{{0, 0}, {100, 175}}
View's setFrameSize:fittingSize
View's addSubview:it

tell NSAlert's alloc()
init()
setMessageText_("Pick a date and time")
setInformativeText_("Any date")
addButtonWithTitle_("OK")
addButtonWithTitle_("Cancel")
setAccessoryView_(View)

my datePicker()
runModal()
end tell

on datePicker()
set theApp to path to frontmost application as text

if not (current application's NSThread's isMainThread()) as boolean then
display alert "This script must be run from the main thread." buttons {"Cancel"} as critical
error number -128
end if
-- create a view
set theView to current application's NSView's alloc()'s initWithFrame:(current application's NSMakeRect(0, 0, 100, 175))
-- create date picker
set datePicker to current application's NSDatePicker's alloc()'s initWithFrame:(current application's NSMakeRect(0, 0, 100, 100))
-- set style: choices are NSTextFieldAndStepperDatePickerStyle, NSClockAndCalendarDatePickerStyle, or NSTextFieldDatePickerStyle
#datePicker's setDatePickerStyle:(current application's NSClockAndCalendarDatePickerStyle)
datePicker's setDatePickerStyle:(current application's NSTextFieldAndStepperDatePickerStyle)
#datePicker's setDatePickerStyle:(current application's NSTextFieldDatePickerStyle)
-- set elements: choices include NSHourMinuteDatePickerElementFlag, NSHourMinuteSecondDatePickerElementFlag, NSTimeZoneDatePickerElementFlag, NSYearMonthDatePickerElementFlag, and NSEraDatePickerElementFlag
datePicker's setDatePickerElements:((current application's NSYearMonthDayDatePickerElementFlag) + (current application's NSHourMinuteSecondDatePickerElementFlag as integer))

-- set initial date
#datePicker's setDateValue:(current application's NSDate's |date|())
--set theCal var to a new(empty) instance of the calendar
set theCal to current application's class "NSCalendar"'s currentCalendar()
-- unpack the components of theCal to a variable
set theComponents to theCal's components:254 fromDate:(current application's NSDate's |date|())
theComponents's setSecond:0
theComponents's setMinute:0
theComponents's setHour:12
theComponents's setYear:2015
theComponents's setMonth:4
theComponents's setDay:1
datePicker's setDateValue:(theCal's dateFromComponents:theComponents)

-- get the size it needs
set theSize to datePicker's fittingSize()
--resize the picker and view accordingly
theView's setFrameSize:theSize
datePicker's setFrameSize:theSize
-- add the picker to the view
theView's setSubviews:{datePicker}
-- create an alert
set theAlert to current application's NSAlert's alloc()'s init()
-- set up alert
tell theAlert
its setMessageText:"Pick a date and time"
its setInformativeText:"Any date"
its addButtonWithTitle:"OK"
its addButtonWithTitle:"Cancel"
its setAccessoryView:theView
end tell

-- show alert in modal loop
set returnCode to theAlert's runModal()
if returnCode = (current application's NSAlertSecondButtonReturn) then error number -128
-- retrieve date
#set theDate to datePicker's dateValue() as date
# Shane Stanley
# http://macscripter.net/viewtopic.php?pid=119633#p119633
set theDate to datePicker's dateValue()
#set theCal to current application's class "NSCalendar"'s currentCalendar()
-- unpack the components of theDate to a variable
set theComponents to theCal's components:254 fromDate:theDate
set theDate to current date
set day of theDate to 1 -- important
set seconds of theDate to theComponents's |second|()
set year of theDate to theComponents's |year|()
set month of theDate to theComponents's |month|()
set day of theDate to theComponents's |day|()
set hours of theDate to theComponents's hour()
set minutes of theDate to theComponents's minute()

return (theDate as text)
#return (theDate)
end datePicker
set my date to dateValue() as date
end tell
end showDatePicker:
---------------------------------------------------------------------------❮END❯
8 changes: 8 additions & 0 deletions datepicker.workflow/Contents/Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleName</key>
<string>datepicker</string>
</dict>
</plist>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading