{ "version": "https://jsonfeed.org/version/1.1", "user_comment": "This feed allows you to read the posts from this site in any feed reader that supports the JSON Feed format. To add this feed to your reader, copy the following URL -- https://decoding.io/tag/javascript/feed/json -- and add it your reader.", "home_page_url": "https://decoding.io/tag/javascript", "feed_url": "https://decoding.io/tag/javascript/feed/json", "language": "en-US", "title": "JavaScript – Decoding", "description": "Articles about productivity and technology.", "items": [ { "id": "https://decoding.io/?p=2595", "url": "https://decoding.io/2023/12/read-web-apps-are-better-than-no-apps/", "title": "Read \u201cWeb Apps Are Better Than No Apps\u201d", "content_html": "
\n

Since web apps can\u2019t just use the components provided by the operating system, they have to recreate everything from scratch. And this creates a lot of burden for developers and, I think, lowers the quality floor. Creating beautiful, compelling apps is possible, but it requires so much work. People building native apps get it all \u201cfor free\u201d. In fact, this could be one of the reasons Apple still has such a vibrant ecosystem of great artisanal apps since developers can build most things out of nice ready-made components.

\n
\n

Well, yeah!

\n
", "content_text": "Since web apps can\u2019t just use the components provided by the operating system, they have to recreate everything from scratch. And this creates a lot of burden for developers and, I think, lowers the quality floor. Creating beautiful, compelling apps is possible, but it requires so much work. People building native apps get it all \u201cfor free\u201d. In fact, this could be one of the reasons Apple still has such a vibrant ecosystem of great artisanal apps since developers can build most things out of nice ready-made components.\n\nWell, yeah!", "date_published": "2023-12-06T20:01:08+01:00", "date_modified": "2023-12-08T23:09:58+01:00", "authors": [ { "name": "Zsolt Benke", "url": "https://decoding.io/author/zsbenke/", "avatar": "https://secure.gravatar.com/avatar/d2f7385024c21eb525b487cf362987f5?s=512&d=mm&r=g" } ], "author": { "name": "Zsolt Benke", "url": "https://decoding.io/author/zsbenke/", "avatar": "https://secure.gravatar.com/avatar/d2f7385024c21eb525b487cf362987f5?s=512&d=mm&r=g" }, "tags": [ "Application", "electron", "JavaScript", "macOS", "Open Web", "Comments" ] }, { "id": "https://decoding.io/?p=2567", "url": "https://decoding.io/2023/12/bookmarked-you-dont-need-javascript-for-that-htmhell/", "title": "Bookmarked \u201cYou don\u2019t need JavaScript for that \u2013 HTMHell\u201d", "content_html": "
\n

Just because you know something needs JavaScript, doesn’t mean it still does. You can make better websites if you test those assumptions every now and then.

\n
\n
", "content_text": "Just because you know something needs JavaScript, doesn’t mean it still does. You can make better websites if you test those assumptions every now and then.", "date_published": "2023-12-03T20:17:41+01:00", "date_modified": "2023-12-03T20:17:41+01:00", "authors": [ { "name": "Zsolt Benke", "url": "https://decoding.io/author/zsbenke/", "avatar": "https://secure.gravatar.com/avatar/d2f7385024c21eb525b487cf362987f5?s=512&d=mm&r=g" } ], "author": { "name": "Zsolt Benke", "url": "https://decoding.io/author/zsbenke/", "avatar": "https://secure.gravatar.com/avatar/d2f7385024c21eb525b487cf362987f5?s=512&d=mm&r=g" }, "tags": [ "Development", "JavaScript", "Bookmarks" ] }, { "id": "https://decoding.io/?p=2010", "url": "https://decoding.io/2023/03/2010/", "content_html": "

Really? Are we accepting this bullshit that a freaking chat app written is JavaScript is bigger than a full music production application?

\n

\"Screenshot

\n
", "content_text": "Really? Are we accepting this bullshit that a freaking chat app written is JavaScript is bigger than a full music production application?", "date_published": "2023-03-18T08:49:48+01:00", "date_modified": "2023-03-18T08:49:48+01:00", "authors": [ { "name": "Zsolt Benke", "url": "https://decoding.io/author/zsbenke/", "avatar": "https://secure.gravatar.com/avatar/d2f7385024c21eb525b487cf362987f5?s=512&d=mm&r=g" } ], "author": { "name": "Zsolt Benke", "url": "https://decoding.io/author/zsbenke/", "avatar": "https://secure.gravatar.com/avatar/d2f7385024c21eb525b487cf362987f5?s=512&d=mm&r=g" }, "tags": [ "Application", "electron", "JavaScript" ] }, { "id": "https://decoding.io/?p=1486", "url": "https://decoding.io/2022/01/how-i-built-a-date-picker/", "title": "How I Built a Date Picker", "content_html": "

Entering date and time values into an application is hard. I combined these two interactions into one UI to make things easier. Here’s how I did it.

\n

\n
\n

How the date picker works

\n

On a simple scale, a date picker is just a table with six rows and seven columns. As a skeleton for the calendar, we have to fill this table with dates using rows and columns as coordinates for each day.

\n

With this in mind, we can already assume some essential bits.

\n
    \n
  1. Some months spans across six weeks, so we need six rows.
  2. \n
  3. Columns represent days with a fixed order, so Monday is anchored to 0, Tuesday to 1, Wednesday to 2, etc.
  4. \n
  5. We can go back and forth between months just by adding and subtracting the current month offset.
  6. \n
  7. We're always working with two dates: one currently selected, and proposing another one as a new value for the input field. These dates can be on the same day, but we're not concerned with that.
  8. \n
\n

These are the basic building blocks of our date picker, so we can see how these pieces fit together with a little bit of diagramming.

\n

\"Initial

\n

The date picker is using three layers of models.

\n
    \n
  1. The HTML view draws the rows of columns of the calendar skeleton and some UI parts.
  2. \n
  3. The state/controller layer changes the date, proposed date, and month offset values responding to events\u2014also parsing dates.
  4. \n
  5. The renderer, which is a reactive layer, watching state changes and echoing each day of the subjected month into the correct row and column coordinate. Also showing or hiding remaining empty week rows.
  6. \n
\n

A quick word about popovers

\n

We will base the date picker on another Stimulus controller, which acts as a popover. This controller's task is to attach itself to a button or link and toggle its target box on and off. The date picker is also acting as a popover, so instead of building it into the date picker controller, we can extract this behavior and use it separately. It's also a great example of how multiple Stimulus controllers can work together.

\n

The view

\n
\n

Related files:

\n\n
\n

The date picker will be a part of a Rails app, so we will use its features to render the view part without any fuss.

\n

First, there is a shared partial under app/views/shared/_date_picker.html, which contains the required HTML. It has a couple of jobs.

\n
    \n
  1. Since there is a separate Stimulus controller for the popover functionality, the view should generate a random ID property for each date picker. Having different IDs allows us to have more than one date picker instance on the same page and we\u2019re toggling the right one on or off.
  2. \n
  3. It creates a text_field to attach the date picker to it in the parent form.
  4. \n
  5. This partial also maps Stimulus targets and events to each controller.
  6. \n
  7. Since day names are not going to change in this example, the partial can prerender a table header so that day names can come from the global I18n localizations.
  8. \n
  9. For the calendar skeleton, we have to render an empty table body for six rows and seven columns.
  10. \n
  11. The UI also needs two additional hour and minute fields to change the time.
  12. \n
\n

The other part of the view is a custom FormBuilder class, making two new methods available in a form_for block. The date_picker_field and date_time_picker_field are simple methods rendering the _date_picker.html.erb partial into any form. This way, we can seamlessly use the date picker like any other Rails form helpers.

\n

To make our job a bit easier, we can create an additional global helper method called record_form_for, which can be used in place of the standard form_for to make our customized FormBuilder subclass available everywhere in the view.

\n

Styling

\n
\n

Related files:

\n\n
\n

As I mentioned before, we will show the date picker in a popover, so we should base its styling on the popover base class. We can do this by extending the base .popover CSS class with a .date_picker_popover to target all date picker specific CSS in a custom popover class.

\n

Our date picker has styles for the navigation buttons, the day names header, the calendar view, and the optional time picker fields. Also, it overrides the base .show class to show the popover with a custom animation.

\n

The base .date_picker_popover class is also scaled down by 0.825 using the transform attribute for desktop browsers because there we have more precise mouse-based input. We scale back to the original size on touch devices to have bigger tap targets.

\n
\n\"Comparison
Comparison of the date picker scaling: macOS on the left and iPadOS on the right.
\n

The Stimulus controller

\n
\n

Related files:

\n\n
\n

Our controller has two distinct layers separated into two pieces. One is the renderer, which uses a JavaScript Proxy object; the other is the controller itself, which has a state object and a couple of methods that respond to events and modify properties on the state. The renderer part watches these changes and updates the UI reactively.

\n

Let\u2019s start with the first piece. On a higher level, this is our renderer without any implementation code. The first part sets attribute values on the state object; the second part runs the UI manipulation code responding to those changes.

\n
\nrenderer = {\n  set: (target, property, value) => {\n    // Set the value of the state object then respond to those changes down below.\n    target[property] = value\n\n    if (property === 'proposedDate') {\n      console.log('Render the calendar and optionally set the date.')\n    }\n\n    if (property === 'date') {\n      console.log('Set the value of the date field')\n    }\n\n    if (property === 'month') {\n      console.log('Render the calendar responding to month changes.')\n    }\n\n    if (property === 'started' && value === false) {\n      console.log('Dismiss the UI.')\n    }\n\n    return true\n  }\n}\n
\n

The code example above is a compelling way to manipulate the UI. We can set a couple of values on the state which gets updated by the controller, but we extracted our UI manipulation code into a renderer. You can run wild and create an entirely separate module for the renderer, you can even have multiple renderers, one for a desktop and one for mobile, but I like to keep them in the controller since we have access to everything in it via this as well.

\n

To use the renderer, we have to proxy it through the state object. The best place for this is in the controller connect method, which runs when Stimulus connects the controller to the HTML view.

\n
\nconnect() {\n  this.state = new Proxy({}, this.renderer)\n\n  this.dateFieldTarget.readOnly = this.isTouch\n  this.timePickerTarget.style.display = this.isTimeActive ? 'flex' : 'none'\n}\n
\n

You may also notice that other parts of the code deal with displaying the time picker fields and changing attributes on the date field. Why not move these pieces into the renderer?

\n

Since these changes happen once, it\u2019s better to keep them in the connect method. Sure we can extract them into state properties, but since we don\u2019t update them anymore in the controller\u2019s lifecycle, it\u2019s easier to deal with them right here. Having this flexibility is why Stimulus is so awesome. You don\u2019t have to deal with a predefined reactive state like in other frameworks; you can create your own if you want using native JavaScript features, but you can also update the DOM directly from anywhere if that fits your code better.

\n

Now let\u2019s talk about the most critical parts of the controller\u2019s skeleton.

\n
\nimport { Controller } from \"stimulus\"\n\nexport default class extends Controller {\n  static targets = [\n    // ...\n  ]\n\n  currentMonth(event) { \n    // ... \n  }\n\n  nextMonth(event) {\n    // ... \n  }\n\n  previousMonth() { \n    // ... \n  }\n\n  pickDate(event) { \n    // ... \n  }\n\n  start(event) { \n    // ... \n  }\n\n  parseDate(event) { \n    // ... \n  }\n\n  dismiss(event) { \n    // ... \n  }\n\n  getCoordinates(date) { \n    // ... \n  }\n}\n
\n\n

We also have some other helpers in the controller, but the main logic runs in the methods listed above. The cool thing is that there is no DOM manipulation code here; we change a couple of values on the state, do some date and time calculation using Chrono and Moment.js, but that\u2019s it. It\u2019s simple and easy to understand.

\n
\n

UI behaviors

\n

A date picker seems a simple component, but it has a surprisingly complex behavior set. It\u2019s essential to get this right because picking a date isn't a fun thing to do. Our date picker should get this job done quickly then get out of the way.

\n

And it has to work in multiple ways to remain flexible for a different type of people. Let's see how these behaviors can work together to add up as a flexible tool.

\n

1. Animations

\n

Animations used right can bring our attention to something, surprise us, or even bring a bit of joy to an otherwise dull task.

\n

We attached our date picker to an input field, so in our example, we mark these fields with a calendar icon to indicate what type of data we\u2019re expecting. It makes sense to use this icon as an anchor point for our animation. The date picker grows out from the left side of the input field when we click on it, indicating that it has to do something with the calendar.

\n

When the animation finishes, there is a small bounce, which gives a bit of playfulness to the UI.

\n
\n \n
\n

2. 2-way data update

\n

We have two types of input methods for the date picker.

\n
    \n
  1. Typing values in the date field.
  2. \n
  3. Selecting dates in the calendar.
  4. \n
\n

These two have to morph together and be connected. This connection needs to happen in real-time, so it doesn\u2019t matter if we\u2019re typing something in the field or selecting a date in the calendar. We should see changes immediately without switching modes or waiting for something to finish.

\n
\n \n
\n

3. Click-away date parsing

\n

When people are dealing with popovers, they usually try to exit them by clicking away. We should respect this behavior and remember that we\u2019re dealing with formatted data, so we shouldn\u2019t just leave the raw values in the field. When the user blurs out from the date field, we still have a chance to do a final date parsing to have valid data in our input field. We can give something valuable to the user, even when she wants to exit from the interaction.

\n
\n \n
\n

4. Keyboard-only access

\n

Power users are very good with keyboards; you can spot them when you see somebody signing up for your service. They give you clues like using the Tab key to switch fields because they want data input interactions to be quick and painless. We can always do more to speed things up for them.

\n

In the case of a date picker, natural language parsing can be robust. We integrated it into the date field, and because of the two-way data binding, you can see it working in realtime. The calendar switches months as you type in a date. Hours and minutes filled into their respective fields.

\n

Everything works from the keyboard. Switching away from the field triggers the click-away date parser mentioned above, so you can press Tab (or Return) and get the correctly formatted date every time.

\n
\n \n
\n

5. Mouse-only access

\n

In contrast, novice people not accompanied using just the keyboard. Having the date and time picker available as a WYSIWYG-like interface is the whole point of creating a unique controller for this type of field.

\n

Switching months, selecting the date, and adjusting the time can be done via the mouse\u2014no need to type anything. And the 2-way data update also gives instant feedback with the final output.

\n

It\u2019s a great place to mention again that our UI scaling takes the input method into account. On touch devices, the date picker scales up to use the calendar with our fingers without feeling cramped.

\n
\n \n
\n
\n

Try it for yourself

\n

Everything we discussed in this article is also available on GitHub. In our example, we use a simple post model where the date picker is attached to the published date field.

\n

The repository is a simple Rails app without any external dependencies (it uses SQLite for its database), so setting it up should be very easy. All you have to do is to install Rails using this guide, then run rails db:setup and rails server to get it running.

\n

\n \n \n \n \n Checkout this project on GitHub\n \n

\n
\n
", "content_text": "Entering date and time values into an application is hard. I combined these two interactions into one UI to make things easier. Here’s how I did it.\n\n\nHow the date picker works\nOn a simple scale, a date picker is just a table with six rows and seven columns. As a skeleton for the calendar, we have to fill this table with dates using rows and columns as coordinates for each day.\nWith this in mind, we can already assume some essential bits.\n\nSome months spans across six weeks, so we need six rows.\nColumns represent days with a fixed order, so Monday is anchored to 0, Tuesday to 1, Wednesday to 2, etc.\nWe can go back and forth between months just by adding and subtracting the current month offset.\nWe're always working with two dates: one currently selected, and proposing another one as a new value for the input field. These dates can be on the same day, but we're not concerned with that.\n\nThese are the basic building blocks of our date picker, so we can see how these pieces fit together with a little bit of diagramming.\n\nThe date picker is using three layers of models.\n\nThe HTML view draws the rows of columns of the calendar skeleton and some UI parts.\nThe state/controller layer changes the date, proposed date, and month offset values responding to events\u2014also parsing dates.\nThe renderer, which is a reactive layer, watching state changes and echoing each day of the subjected month into the correct row and column coordinate. Also showing or hiding remaining empty week rows.\n\nA quick word about popovers\nWe will base the date picker on another Stimulus controller, which acts as a popover. This controller's task is to attach itself to a button or link and toggle its target box on and off. The date picker is also acting as a popover, so instead of building it into the date picker controller, we can extract this behavior and use it separately. It's also a great example of how multiple Stimulus controllers can work together.\nThe view\n\nRelated files:\n\n\n \n \n \n \n _date_picker.html.erb\n \n \n\n \n \n \n \n record_form_builder.rb\n \n \n\n \n \n \n \n application_helper.rb\n \n \n\n\nThe date picker will be a part of a Rails app, so we will use its features to render the view part without any fuss.\nFirst, there is a shared partial under app/views/shared/_date_picker.html, which contains the required HTML. It has a couple of jobs.\n\nSince there is a separate Stimulus controller for the popover functionality, the view should generate a random ID property for each date picker. Having different IDs allows us to have more than one date picker instance on the same page and we\u2019re toggling the right one on or off.\nIt creates a text_field to attach the date picker to it in the parent form.\nThis partial also maps Stimulus targets and events to each controller.\nSince day names are not going to change in this example, the partial can prerender a table header so that day names can come from the global I18n localizations.\nFor the calendar skeleton, we have to render an empty table body for six rows and seven columns.\nThe UI also needs two additional hour and minute fields to change the time.\n\nThe other part of the view is a custom FormBuilder class, making two new methods available in a form_for block. The date_picker_field and date_time_picker_field are simple methods rendering the _date_picker.html.erb partial into any form. This way, we can seamlessly use the date picker like any other Rails form helpers.\nTo make our job a bit easier, we can create an additional global helper method called record_form_for, which can be used in place of the standard form_for to make our customized FormBuilder subclass available everywhere in the view.\nStyling\n\nRelated files:\n\n\n \n \n \n \n _defaults.scss\n \n \n\n\nAs I mentioned before, we will show the date picker in a popover, so we should base its styling on the popover base class. We can do this by extending the base .popover CSS class with a .date_picker_popover to target all date picker specific CSS in a custom popover class.\nOur date picker has styles for the navigation buttons, the day names header, the calendar view, and the optional time picker fields. Also, it overrides the base .show class to show the popover with a custom animation.\nThe base .date_picker_popover class is also scaled down by 0.825 using the transform attribute for desktop browsers because there we have more precise mouse-based input. We scale back to the original size on touch devices to have bigger tap targets.\n\nComparison of the date picker scaling: macOS on the left and iPadOS on the right.\nThe Stimulus controller\n\nRelated files:\n\n\n \n \n \n \n date_picker_controller.js\n \n \n\n \n \n \n \n popover_toggle_controller.js\n \n \n\n\nOur controller has two distinct layers separated into two pieces. One is the renderer, which uses a JavaScript Proxy object; the other is the controller itself, which has a state object and a couple of methods that respond to events and modify properties on the state. The renderer part watches these changes and updates the UI reactively.\nLet\u2019s start with the first piece. On a higher level, this is our renderer without any implementation code. The first part sets attribute values on the state object; the second part runs the UI manipulation code responding to those changes.\n\nrenderer = {\n set: (target, property, value) => {\n // Set the value of the state object then respond to those changes down below.\n target[property] = value\n\n if (property === 'proposedDate') {\n console.log('Render the calendar and optionally set the date.')\n }\n\n if (property === 'date') {\n console.log('Set the value of the date field')\n }\n\n if (property === 'month') {\n console.log('Render the calendar responding to month changes.')\n }\n\n if (property === 'started' && value === false) {\n console.log('Dismiss the UI.')\n }\n\n return true\n }\n}\n\nThe code example above is a compelling way to manipulate the UI. We can set a couple of values on the state which gets updated by the controller, but we extracted our UI manipulation code into a renderer. You can run wild and create an entirely separate module for the renderer, you can even have multiple renderers, one for a desktop and one for mobile, but I like to keep them in the controller since we have access to everything in it via this as well.\nTo use the renderer, we have to proxy it through the state object. The best place for this is in the controller connect method, which runs when Stimulus connects the controller to the HTML view.\n\nconnect() {\n this.state = new Proxy({}, this.renderer)\n\n this.dateFieldTarget.readOnly = this.isTouch\n this.timePickerTarget.style.display = this.isTimeActive ? 'flex' : 'none'\n}\n\nYou may also notice that other parts of the code deal with displaying the time picker fields and changing attributes on the date field. Why not move these pieces into the renderer?\nSince these changes happen once, it\u2019s better to keep them in the connect method. Sure we can extract them into state properties, but since we don\u2019t update them anymore in the controller\u2019s lifecycle, it\u2019s easier to deal with them right here. Having this flexibility is why Stimulus is so awesome. You don\u2019t have to deal with a predefined reactive state like in other frameworks; you can create your own if you want using native JavaScript features, but you can also update the DOM directly from anywhere if that fits your code better.\nNow let\u2019s talk about the most critical parts of the controller\u2019s skeleton.\n\nimport { Controller } from \"stimulus\"\n\nexport default class extends Controller {\n static targets = [\n // ...\n ]\n\n currentMonth(event) { \n // ... \n }\n\n nextMonth(event) {\n // ... \n }\n\n previousMonth() { \n // ... \n }\n\n pickDate(event) { \n // ... \n }\n\n start(event) { \n // ... \n }\n\n parseDate(event) { \n // ... \n }\n\n dismiss(event) { \n // ... \n }\n\n getCoordinates(date) { \n // ... \n }\n}\n\n\ncurrentMonth: Resets the state.date to the current date and state.month to 0. The method above gets called when we press the Today button.\nnextMonth: Goes to the next month by adding 1 to the state.month when we press the right arrow on the top of the date picker.\npreviousMonth: It does the opposite of its counterpart and goes to the previous month by subtracting one from the state.month. It also gets called when we press the left arrow on the top of the date picker.\npickDate(event): Handles the click event on a picked date from the calendar and set the value of the dateFieldTarget. The data-action="click->date-picker#pickDate" isn\u2019t in the HTML view; instead, it added dynamically by the renderer part. The good thing is that Stimulus picks up these data attributes automatically, so dynamic event handling works without doing anything special on our part.\n \nstart: Gets called when we focus on the date field so the date picker can start its whole date parsing and rendering process.\nparseDate: The date parser part processes the value of dateFieldTarget using Chrono and sets the state.proposedDate, which gets highlighted by the renderer as a possible date or date-time value for the dateFieldTarget. It is very flexible, accepts input from the dateFieldTarget like \u201ctomorrow evening\u201d or \u201cnext month\u201d.\ndismiss: There are multiple ways in the flow where the date and time picking interaction ends, like pressing Return in one of the time picker input fields, selecting a date from the calendar, or using the natural language parser. Since we\u2019re having a separate controller for the popover state, this method sets the state.started value to false so the renderer can hide the date picker using the PopoverToggleController.\ngetCoordinates: Gets called on each date of the current month by the renderer to determine which row and column it should modify in the DOM when the calendar gets filled with dates. It returns an object like { row: 1, column: 4 }.\n\nWe also have some other helpers in the controller, but the main logic runs in the methods listed above. The cool thing is that there is no DOM manipulation code here; we change a couple of values on the state, do some date and time calculation using Chrono and Moment.js, but that\u2019s it. It\u2019s simple and easy to understand.\n\nUI behaviors\nA date picker seems a simple component, but it has a surprisingly complex behavior set. It\u2019s essential to get this right because picking a date isn't a fun thing to do. Our date picker should get this job done quickly then get out of the way.\nAnd it has to work in multiple ways to remain flexible for a different type of people. Let's see how these behaviors can work together to add up as a flexible tool.\n1. Animations\nAnimations used right can bring our attention to something, surprise us, or even bring a bit of joy to an otherwise dull task.\nWe attached our date picker to an input field, so in our example, we mark these fields with a calendar icon to indicate what type of data we\u2019re expecting. It makes sense to use this icon as an anchor point for our animation. The date picker grows out from the left side of the input field when we click on it, indicating that it has to do something with the calendar.\nWhen the animation finishes, there is a small bounce, which gives a bit of playfulness to the UI.\n\n \n\n2. 2-way data update\nWe have two types of input methods for the date picker.\n\nTyping values in the date field.\nSelecting dates in the calendar.\n\nThese two have to morph together and be connected. This connection needs to happen in real-time, so it doesn\u2019t matter if we\u2019re typing something in the field or selecting a date in the calendar. We should see changes immediately without switching modes or waiting for something to finish.\n\n \n\n3. Click-away date parsing\nWhen people are dealing with popovers, they usually try to exit them by clicking away. We should respect this behavior and remember that we\u2019re dealing with formatted data, so we shouldn\u2019t just leave the raw values in the field. When the user blurs out from the date field, we still have a chance to do a final date parsing to have valid data in our input field. We can give something valuable to the user, even when she wants to exit from the interaction.\n\n \n\n4. Keyboard-only access\nPower users are very good with keyboards; you can spot them when you see somebody signing up for your service. They give you clues like using the Tab key to switch fields because they want data input interactions to be quick and painless. We can always do more to speed things up for them.\nIn the case of a date picker, natural language parsing can be robust. We integrated it into the date field, and because of the two-way data binding, you can see it working in realtime. The calendar switches months as you type in a date. Hours and minutes filled into their respective fields.\nEverything works from the keyboard. Switching away from the field triggers the click-away date parser mentioned above, so you can press Tab (or Return) and get the correctly formatted date every time.\n\n \n\n5. Mouse-only access\nIn contrast, novice people not accompanied using just the keyboard. Having the date and time picker available as a WYSIWYG-like interface is the whole point of creating a unique controller for this type of field.\nSwitching months, selecting the date, and adjusting the time can be done via the mouse\u2014no need to type anything. And the 2-way data update also gives instant feedback with the final output.\nIt\u2019s a great place to mention again that our UI scaling takes the input method into account. On touch devices, the date picker scales up to use the calendar with our fingers without feeling cramped.\n\n \n\n\nTry it for yourself\nEverything we discussed in this article is also available on GitHub. In our example, we use a simple post model where the date picker is attached to the published date field.\nThe repository is a simple Rails app without any external dependencies (it uses SQLite for its database), so setting it up should be very easy. All you have to do is to install Rails using this guide, then run rails db:setup and rails server to get it running.\n\n \n \n \n \n Checkout this project on GitHub", "date_published": "2022-01-24T22:28:51+01:00", "date_modified": "2023-01-30T19:40:15+01:00", "authors": [ { "name": "Zsolt Benke", "url": "https://decoding.io/author/zsbenke/", "avatar": "https://secure.gravatar.com/avatar/d2f7385024c21eb525b487cf362987f5?s=512&d=mm&r=g" } ], "author": { "name": "Zsolt Benke", "url": "https://decoding.io/author/zsbenke/", "avatar": "https://secure.gravatar.com/avatar/d2f7385024c21eb525b487cf362987f5?s=512&d=mm&r=g" }, "image": "https://decoding.io/wp-content/uploads/2022/01/datepicker@3x-1.png", "tags": [ "Development", "JavaScript", "Rails", "Stimulus", "Articles" ] } ] }