Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Convert numeric entry into formatted time string

Posted on 2016-08-15
13
Medium Priority
?
111 Views
Last Modified: 2016-08-17
I want the user to be able to type numbers - such as 3468 - and for that to be transformed / formatted into a time string. So, 3468 would translate to 34.68 (which is 34 seconds and .68 seconds or 680 milliseconds), 10200 would translate to 1 minute, 2 seconds and 0 milliseconds. So, the user would always have to enter the time down to the milliseconds.

This is for a swimming results website, so users would expect to enter 34.68, not 34.680

I have seen the HTML 5 "time" input type, but I can't get it to only show 2 digits for the milliseconds.

Is there a ready-built control to handle this type of input, that is also cross-browser friendly (and as wide support as possible, including mobile)?

Don't mind if it is a jQuery control, JavaScript, etc but it is for a C# / MVC website.
0
Comment
Question by:ascendinternet
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 3
  • 2
  • +2
13 Comments
 
LVL 13

Expert Comment

by:Dustin Saunders
ID: 41756925
I don't quite understand what you need.  Why not just store the information as milliseconds and use code to display the format?

When they enter in the time how do you know that 10200 is 1 minute 2 seconds 0 milliseconds and not 10 seconds 200 milliseconds?
0
 

Author Comment

by:ascendinternet
ID: 41756964
Because of convention ... swimming events are recorded to .01 of a second, so 10200 is 1:02.00 - or 1 minute, 2 seconds, 0 milliseconds.

So, I want an input box where a user can type in ... 10200 (1 min, 2 sec, 0 ms), or 3459 (34 sec, 59 ms). Either when the user enters it, it should be formatted correct (a mask like the HTML 5 "Time" input), or after leaving the input box (jQuery?).
0
 
LVL 13

Expert Comment

by:Dustin Saunders
ID: 41757040
I see- in that case you can use the Masked Text Box control to format the input.  You can either have it static set to show the mask (something like 00:00.00) or have it start at 00 then use something like this to update the mask as you extend it (giving it a more dynamic feeling):

        private void maskedTextBox1_TextChanged(object sender, EventArgs e)
        {
            label1.Text = maskedTextBox1.Text.Length.ToString();
            if (maskedTextBox1.Text.Length == 2)
            {
                maskedTextBox1.Mask = "00.00";
                maskedTextBox1.SelectionStart = maskedTextBox1.Text.Length - 1;
                maskedTextBox1.SelectionLength = 0;
            }
            else if (maskedTextBox1.Text.Length == 5)
            {
                maskedTextBox1.Mask = "00:00.00";
                maskedTextBox1.SelectionStart = maskedTextBox1.Text.Length - 1;
                maskedTextBox1.SelectionLength = 0;
            }
        }

Open in new window


(in my box I have the property RightToLeft set, as well as HidePromptOnLeave)
0
The top UI technologies you need to be aware of

An important part of the job as a front-end developer is to stay up to date and in contact with new tools, trends and workflows. That’s why you cannot miss this upcoming webinar to explore the latest trends in UI technologies!

 

Author Comment

by:ascendinternet
ID: 41757059
Ah, sorry - I should have made it clearer that this is for a web page, so I can't use the Masked Text Box - at least I assume I can't!?

(Can I edit my question to add more relevant tags?!)
0
 
LVL 83

Expert Comment

by:David Johnson, CD, MVP
ID: 41757131
i HAD a vb webform open so I used this
webform2.aspx
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="webForm2.aspx.vb" Inherits="webForm2" %>
<%@ Register assembly="Telerik.Web.UI" namespace="Telerik.Web.UI" tagprefix="telerik" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>EE28963458</title>
</head>
    <body>
    <form id="form1" runat="server">
        <telerik:RadScriptManager ID="RadScriptManager1" runat="server" EnableTheming="True">
            <Scripts>
                <asp:ScriptReference Assembly="Telerik.Web.UI" Name="Telerik.Web.UI.Common.Core.js">
                </asp:ScriptReference>
                <asp:ScriptReference Assembly="Telerik.Web.UI" Name="Telerik.Web.UI.Common.jQuery.js">
                </asp:ScriptReference>
                <asp:ScriptReference Assembly="Telerik.Web.UI" Name="Telerik.Web.UI.Common.jQueryInclude.js">
                </asp:ScriptReference>
            </Scripts>
        </telerik:RadScriptManager>
        <telerik:RadStyleSheetManager ID="RadStyleSheetManager1" runat="server">
        </telerik:RadStyleSheetManager>
        <telerik:RadAjaxManager ID="RadAjaxManager1" runat="server">
        </telerik:RadAjaxManager>
    <div>
    
        <telerik:RadMaskedTextBox ID="RadMaskedTextBox1" Runat="server" AutoPostBack="True" DisplayMask="#:##.##" HideOnBlur="True" LabelWidth="64px" Mask="#:##.##" PromptChar="#" ToolTip="Minutes:Seconds.Milliseconds" Width="160px">
        </telerik:RadMaskedTextBox>
        <br />
        The Entered Time is <asp:Label ID="Label1" runat="server" Text="0"></asp:Label>
&nbsp;Minutes
        <asp:Label ID="Label2" runat="server" Text="0"></asp:Label>
&nbsp;Seconds
        <asp:Label ID="Label3" runat="server" Text="0"></asp:Label>
&nbsp;Milliseconds</div>
    </form>
</body>
</html>

Open in new window

Webform2.asps.vb
Partial Class WebForm2
    Inherits System.Web.UI.Page

    Protected Sub RadMaskedTextBox1_TextChanged(sender As Object, e As EventArgs) Handles RadMaskedTextBox1.TextChanged
        Label1.Text = Left(RadMaskedTextBox1.Text, 1)
        Label2.Text = Mid(RadMaskedTextBox1.Text, 2, 2)
        Label3.Text = Mid(RadMaskedTextBox1.Text, 4, 2)
    End Sub
End Class

Open in new window


This requires the telerik web UI Controls.. I don't know how much coding you do if  buying the controls is worthwhile for you
0
 

Author Comment

by:ascendinternet
ID: 41757134
Unfortunately, price-wise, the Telerik controls are a "massive sledgehammer" to crack a fairly small "nut"! :-(
0
 
LVL 59

Expert Comment

by:Julian Hansen
ID: 41757459
Here is a simple implementation
HTML
<input class="millisecs" type="text" />

Open in new window

JQuery
<script src="http://code.jquery.com/jquery.js"></script>
<script>
$(function() {
  $('.millisecs').on('keypress',function(e) {

    // Check for valid input and return false if
    // not a number or a navigation key
    if ((e.charCode < 48 || e.charCode > 57) &&
      e.keyCode != 8 &&
      e.keyCode != 9 &&
      e.keyCode != 13 &&
      e.keyCode != 18 &&
      e.keyCode != 35 &&
      e.keyCode != 36 &&
      e.keyCode != 37 &&
      e.keyCode != 39 &&
      e.keyCode != 46) {
      
      return false;
    }
  });
  // Format the output  
  $('.millisecs').on('keyup',function() {
    var x = $(this).val();
    // Get rid of any previous decimal
    while (x - parseInt(x) > 0) {
      x *=10;
    }
    // Set the new output
    $(this).val((x/100).toFixed(2));
  });
});
</script>

Open in new window

Working sample here
1
 

Author Comment

by:ascendinternet
ID: 41757474
Julian - thanks for your post.

I seem to have forgotten to mention a few things in my post (it's a shame I can't change it), but for seconds and milliseconds the format is 34.56. However, for minutes, seconds and milliseconds it needs to be 1:34.56.

I found a jQuery "mask" plugin http://igorescobar.github.io/jQuery-Mask-Plugin/ which has given me (hopefully) the functionality I need:

<input type="text" maxlength="8" class="form-control timeInput" name="timeInput" id="@RaceNumber">

Open in new window


and
        var opts = {
            reverse: true,
            onKeyPress: function(cep, e, field, options) {
                if (cep.length === 6) {
                    e.preventDefault();
                }
            }
        };
        $('.timeInput').mask('00:00.00', opts);

Open in new window


However, if I could write the jQuery code myself (and/or with help!!) then that would probably be preferable.
0
 
LVL 59

Expert Comment

by:Julian Hansen
ID: 41757507
The mask plugin is probably the way to go - my code is just a quick and dirty.

Here is an update that should handle the new format

$('.millisecs').on('keyup',function() {
    var current = $(this).val();
    var clean = '' + parseInt(current.replace(/[^\d]/g,''));
    var masked = '';
    for (i = clean.length - 1;i >=0;i--) {
      // Add the .
      if (clean.length - i == 3) {
        masked = '.' + masked;
      }
      // Add the :
      if (clean.length - i == 5) {
        masked = ':' + masked;
      }
      masked = clean[i] + masked;
    }

  $(this).val(masked);

Open in new window

Updated sample here
0
 

Author Comment

by:ascendinternet
ID: 41757632
That looks very interesting and almost works ;-) (delete all digits and you get "NaN").

The plugin works but if it can be done in as few lines as above, I might prefer to pursue that option.
0
 
LVL 51

Expert Comment

by:Gustav Brock
ID: 41757659
As you have C# you could use this to build the string:
String entry;
TimeSpan result;
string format = "hh':'mm':'ss'.'ff";

entry = "23453241";

int formatSubLength = entry.Length;
formatSubLength -= 3 * (-(formatSubLength - 1) / 2);
format = format.Substring (format.Length - formatSubLength);
char pad = '0';
entry = entry.PadLeft(8, pad);
IFormatProvider formatProvider =  System.Globalization.CultureInfo.InvariantCulture;
result = TimeSpan.ParseExact(entry, "hhmmssff", formatProvider);

entry = result.ToString(format); 
// 23:45:32.41

Open in new window

Wrap it in a try-error to catch invalid entries from typing errors like the eight (8) here: 23458271

/gustav
0
 
LVL 59

Accepted Solution

by:
Julian Hansen earned 2000 total points
ID: 41757663
Fix for NaN
  $('.millisecs').on('keyup',function() {
    var current = $(this).val();
    if (current == '') {
      masked = '';
    }
    else {
      var clean = '' + parseInt(current.replace(/[^\d]/g,''));
      var masked = '';
      for (i = clean.length - 1;i >=0;i--) {
        // Add the .
        if (clean.length - i == 3) {
        masked = '.' + masked;
        }
        // Add the :
        if (clean.length - i == 5) {
          masked = ':' + masked;
        }
        masked = clean[i] + masked;
      }
    }
   
    $(this).val(masked);
  });

Open in new window

Updated sample here
0
 

Author Closing Comment

by:ascendinternet
ID: 41760070
There is a little extra code in the linked to sample which was needed to make it a more complete answer.
0

Featured Post

Certified OpenStack Administrator Course

We just refreshed our COA course based on the Newton exam.  With 14 labs, this course goes over the different OpenStack services that are part of the certification: Dashboard, Identity Service, Image Service, Networking, Compute, Object Storage, Block Storage, and Orchestration.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
This article aims to explain the working of CircularLogArchiver. This tool was designed to solve the buildup of log file in cases where systems do not support circular logging or where circular logging is not enabled
The viewer will learn how to dynamically set the form action using jQuery.
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)
Suggested Courses

721 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question