Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow user to manually input a date #4

Closed
mikaelmello opened this issue Jul 26, 2021 · 10 comments
Closed

Allow user to manually input a date #4

mikaelmello opened this issue Jul 26, 2021 · 10 comments

Comments

@mikaelmello
Copy link
Owner

mikaelmello commented Jul 26, 2021

Is your feature request related to a problem? Please describe.

The user might not want to manually navigate through several days/months/years when trying to input a date. Imagine a birthday for example.

We have shortcuts in place for this, in which ctrl+arrows quickly move by months or years, but it could be better

Describe the solution you'd like

Not sure yet...

Option 0

A new prompt type where instead of a calendar, we display the three date parts (month, date, year) in a customizable order with customizable separators.

The end user can then move around each one of them pressing left or right arrows, and then press up or down to update the values.

Option 1

The user can type a full date in a predefined format, e.g. dd/mm/yyyy and submit. The prompt handler should then try to parse this input and if successful, return the parsed value.

The submit button could be a new shortcut, e.g. Ctrl+Enter, or the same Enter.

Maybe we could do the following:

  • Space for selecting on interactive calendar
  • Enter to submit current input, or current calendar selection if input is empty.

It would be nice if the expected input format was written in grey where the input would be, something like:

? Travel date: 12/0m/yyyy

Option 2

I tried to think of a "filter" approach, like typing a month or year and then the calendar would jump right on that, but didn't get to a reasonable solution.

@VladimirMarkelov
Copy link

Yes, it would be great. E.g, I prefer YYYY-MM-DD format.

We have shortcuts in place for this, in which ctrl+arrows quickly move by months or years, but it could be better

When moving through data parts, are arrow up and down supported? To increase/decrease the currently selected data part? I remember seeing it somewhere and it looked helpful.

@mikaelmello
Copy link
Owner Author

When moving through data parts, are arrow up and down supported? To increase/decrease the currently selected data part? I remember seeing it somewhere and it looked helpful.

Yes, up and down arrows work to move around the candelar (the main demo shows this iirc). It is implemented by simply subtracting/adding a week from the current selected date.

@mikaelmello
Copy link
Owner Author

I prefer YYYY-MM-DD format.

There's going to be an API to customize there for sure. Do you think this would be a good idea for the default format?

On one hand, it is the ISO8601, the standard, etc, which makes it a sensible choice for developers. However, I can't quite see it being the best default option for end users, probably (mostly) developers but I for one would prefer other formats.

I'm considering making dd/mm/yyyy the default.

@VladimirMarkelov
Copy link

I'm considering making dd/mm/yyyy the default.

I'm fine your default. While there is a way to set any format to display a date ;)

Yes, up and down arrows work to move around the candelar

Just a thought: it should be possible to disable automatic displaying calendar(if it is not implemented) when editing a date field.
Sometimes, I do not want calendar and just want to type a date in an edit field with optional special processing of arrows. Possible case: entering a date birth. If the default value is today, using a calendar maybe be tiresome, typing is much faster. Or another case: edit a date and move it two months ahead. I think Ctrl+right to select month part, and pressing arrow up 3 times sometimes is better than using through full-featured calendar.

On the other hand, calendar makes it easier to move by weeks :) I wonder if it is possible to make calendar hidden by default, but to provide a hotkey to open it?

@mikaelmello
Copy link
Owner Author

mikaelmello commented Jul 30, 2021

I think I just now realized what you meant with your first comment, moving around the actual text input (and not the calendar!)

That makes a lot of sense and it is an use-case I hadn't considered before. Making the calendar work alongside text input (with these features), while providing a good UX with hotkeys would be very hard. I also enjoyed the idea of hiding/disabling the calendar, like two "modes" that could be swapped.

Mode A:

  • full-featured calendar, same as it is now
  • normal arrows to move around by day/week
  • ctrl+arrows to move around by month/year
  • some hotkey to change to mode b

Mode B

  • no calendar, text input
  • date always pre-selected to keep things simple at first
    • today by default (customizable)
  • at least one data part "selected" (background in grey)
  • move around data parts by pressing right/left arrows (do we need ctrl?)
  • update a single data part (e.g. month) by pressing up or down. value overflows/underflows without modifying other data parts

wdyt?

@VladimirMarkelov
Copy link

Yes, that what I meant. But I used that type of edit field in GUI application. In TUI it may be harder to implement but should be feasible.

The idea sounds good to me. If edit field always displays cursor (I think in mode B it shows the text cursor always), it is clear what part of the date is selected even without highlighting its background. So, to me changing background is an optional feature. Date edit fields is usable without it as well.

@mikaelmello
Copy link
Owner Author

@VladimirMarkelov what do you think of the following prompt and its API? It uses the newly-added placeholder feature.

From the top of my head, we are missing:

  • Validators once the parsing is successfully executed. In this example, could need to check for holidays or weekends.
  • Dynamic error messages for parsing errors. Not sure why I went with a static one when building CustomType.
  • Enhanced processing of key events, such as moving between date fields. However I'm feeling like that's not strictly necessary for now, as CustomType can handle a lot of our needs.
use chrono::NaiveDate;
use inquire::{formatter::DEFAULT_DATE_FORMATTER, CustomType};

fn main() {
    let amount = CustomType::<NaiveDate>::new("When are you going to visit the office?")
        .with_placeholder("dd/mm/yyyy")
        .with_parser(&|i| NaiveDate::parse_from_str(i, "%d/%m/%Y").map_err(|_| ()))
        .with_formatter(DEFAULT_DATE_FORMATTER)
        .with_error_message("Please type a valid date.")
        .with_help_message("The necessary arrangements will be made")
        .prompt();

    match amount {
        Ok(_) => println!("Thanks! We will be expecting you."),
        Err(_) => println!("We could not process your reservation"),
    }
}

manual_date_input

@VladimirMarkelov
Copy link

It looks great!

Two questions:

  • does it insert date separators automatically? I mean, a user does not have to type / in the example
  • what happens if I type with separators? E.g, what if I type 12/2 - Does / turn a "silent" keypress?

@mikaelmello
Copy link
Owner Author

  • does it insert date separators automatically? I mean, a user does not have to type / in the example
  • what happens if I type with separators? E.g, what if I type 12/2 - Does / turn a "silent" keypress?

Unfortunately nothing was done automatically, I believe I just typed the slashes really quicksly so I'll take that as a compliment ;)

The greyed-out placeholder is just that, a placeholder. There are no masks implemented in the CustomType input or on any prompts with text input for that matter.

What would you think of an API that would allow you to customize the input state before/after a key was pressed? Like this for exmaple: https://stackoverflow.com/questions/12578507/implement-an-input-with-a-mask.

This way, you could hook a couple callbacks that would receive the current InputState (the string, its pre-calculated length and the cursor position, basically) and the pressed key. This callback could then mutate the input state based on the key pressed.

This would allow you to autoamtically insert/remove slashes or implement any custom behavior you might want for your prompts.

@mikaelmello
Copy link
Owner Author

Closing this, I think the last example I showed provides very good building blocks for those that do want to pursue this kind of customization. Additionally, users can also use the Text prompt to parse+validate the input and do all sorts of things with free text input.

@mikaelmello mikaelmello closed this as not planned Won't fix, can't repro, duplicate, stale Aug 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants