[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 125
  • Last Modified:

Convert numeric entry into formatted time string

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
ascendinternet
Asked:
ascendinternet
  • 6
  • 3
  • 2
  • +2
1 Solution
 
Dustin SaundersDirector of OperationsCommented:
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
 
ascendinternetAuthor Commented:
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
 
Dustin SaundersDirector of OperationsCommented:
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
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
ascendinternetAuthor Commented:
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
 
David Johnson, CD, MVPOwnerCommented:
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
 
ascendinternetAuthor Commented:
Unfortunately, price-wise, the Telerik controls are a "massive sledgehammer" to crack a fairly small "nut"! :-(
0
 
Julian HansenCommented:
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
 
ascendinternetAuthor Commented:
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
 
Julian HansenCommented:
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
 
ascendinternetAuthor Commented:
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
 
Gustav BrockCIOCommented:
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
 
Julian HansenCommented:
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
 
ascendinternetAuthor Commented:
There is a little extra code in the linked to sample which was needed to make it a more complete answer.
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

  • 6
  • 3
  • 2
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now