locked
Number format not working! RRS feed

  • Question

  • User-79977429 posted

    Hi

    In my model metadata i've using this code to format quantity number with n1 :

    public partial class DefaultVisitProductDetailsMetadata
    {
            [DisplayName("Drug Name")]
            [Required(ErrorMessage = "{0} Required!")]
            public int? ProductID { get; set; }
    
            [Column(TypeName = "money")]
            [DisplayName("Drug Quantity")]
            [Required(ErrorMessage = "{0} Required!")]
            [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:N1}")] // Not working
            public decimal? Quantity { get; set; }
    }
    
    [ModelMetadataType(typeof(DefaultVisitProductDetailsMetadata))]
    public partial class DefaultVisitProductDetails
    {
    
    }

    But it does not works. Here is my view :

    @model DefaultVisitProductDetails
    
    <div class="row">
        <div class="col-md-6">
            <form id="frmEditPackageDetailItem" asp-action="UpdatePackageDetailItem" method="post">
                <div asp-validation-summary="All" class="text-danger"></div>
                <input type="hidden" asp-for="DefaultVisitProductDetailRowID" value="@Model.DefaultVisitProductDetailRowID" />
                <input type="hidden" asp-for="DefaultVisitProductHeaderRowID" value="@Model.DefaultVisitProductHeaderRowID" />
                <div class="form-group">
                    <label asp-for="ProductID" class="control-label"></label>
                    <select asp-for="ProductID" class="form-control" asp-items="@ViewBag.ProductID" value="@Model.ProductID">
                        <option></option>
                    </select>
                    <span asp-validation-for="ProductID" class="text-danger"></span>
                </div>
                <div class="form-group">
                    <label asp-for="Quantity" class="control-label"></label>
                    <input asp-for="Quantity" class="form-control" dir="ltr" value="@Model.Quantity" />
                    <span asp-validation-for="Quantity" class="text-danger"></span>
                </div>
                <div class="form-group">
                    <label asp-for="Description" class="control-label"></label>
                    <textarea asp-for="Description" class="form-control" value="@Model.Description"></textarea>
                    <span asp-validation-for="Description" class="text-danger"></span>
                </div>
                <div class="modal-footer text-right">
                    <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
                    <button type="button" id="btnUpdate" class="btn btn-success" onclick="frmEditPackageDetailItem_onSubmitClick()">Save</button>
                </div>
            </form>
        </div>
    </div>

    Can anybody help me what's the problem & how to solve it ?

    Thanks in advance

    Monday, May 25, 2020 9:07 AM

All replies

  • User475983607 posted

    The DefaultVisitProductDetails class is missing properties.  I assume that is what you mean by "not working".  

    I built a demo and the numeric format exactly as written official numeric formatting documentation for my culture setting; https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings.

        public partial class DefaultVisitProductDetailsMetadata
        {
            [DisplayName("Drug Name")]
            [Required(ErrorMessage = "{0} Required!")]
            public int? ProductID { get; set; }
    
            [Column(TypeName = "money")]
            [DisplayName("Drug Quantity")]
            [Required(ErrorMessage = "{0} Required!")]
            [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:N1}")] // Not working
            public decimal? Quantity { get; set; }
        }
    
        [ModelMetadataType(typeof(DefaultVisitProductDetailsMetadata))]
        public partial class DefaultVisitProductDetails
        {
            public int? ProductID { get; set; }
            public decimal? Quantity { get; set; }
    
        }
    @model MvcBasic.Models.DefaultVisitProductDetails
    
    @{
        ViewData["Title"] = "Index";
    }
    
    <h1>Index</h1>
    
    <h4>DefaultVisitProductDetails</h4>
    <hr />
    <div class="row">
        <div class="col-md-4">
            <form asp-action="Index">
                <div asp-validation-summary="ModelOnly" class="text-danger"></div>
                <div class="form-group">
                    <label asp-for="ProductID" class="control-label"></label>
                    <input asp-for="ProductID" class="form-control" />
                    <span asp-validation-for="ProductID" class="text-danger"></span>
                </div>
                <div class="form-group">
                    <label asp-for="Quantity" class="control-label"></label>
                    <input asp-for="Quantity" class="form-control" />
                    <span asp-validation-for="Quantity" class="text-danger"></span>
                </div>
                <div class="form-group">
                    <input type="submit" value="Create" class="btn btn-primary" />
                </div>
            </form>
        </div>
    </div>
    
    <div>
        <a asp-action="Index">Back to List</a>
    </div>
    
    
    public ActionResult Index()
    {
        DefaultVisitProductDetails model = new DefaultVisitProductDetails()
        {
            ProductID = 1,
            Quantity = 2222222.0m
        };
    
        return View(model);
    }

    Monday, May 25, 2020 11:16 AM
  • User-79977429 posted

    The DefaultVisitProductDetails class is missing properties.

    The given class is partial class to extend functionality of main class. Here is main class of DefaultVisitProductDetails :

    public partial class DefaultVisitProductDetails
        {
            [Key]
            public Guid DefaultVisitProductDetailRowID { get; set; }
            public Guid? DefaultVisitProductHeaderRowID { get; set; }
            public int? ProductID { get; set; }
            [Column(TypeName = "money")]
            public decimal? Quantity { get; set; }
            public string Description { get; set; }
    
            [ForeignKey(nameof(DefaultVisitProductHeaderRowID))]
            [InverseProperty(nameof(DefaultVisitProductHeaders.DefaultVisitProductDetails))]
            public virtual DefaultVisitProductHeaders DefaultVisitProductHeaderRow { get; set; }
            [ForeignKey(nameof(ProductID))]
            [InverseProperty(nameof(Products.DefaultVisitProductDetails))]
            public virtual Products Product { get; set; }
        }

    I've tested again & see it working in list mode, but in edit mode not working!! I think the property 'ApplyFormatInEditMode' for DisplayFormat attribute not working for input controls.

    Here is my list view which formatting works :

    @model IEnumerable<DefaultVisitProductHeaders>
    @{
        ViewData["Title"] = "Index";
    }
    
    <h4>Drugs Package</h4>
    <hr />
    
    <a class="btn text-success" asp-action="New" asp-controller="Package">
        <span class="fa fa-plus"></span> New Item
    </a>
    <table class="table table-responsive-sm table-striped table-hover">
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.DefaultVisitProductHeaderName)
            </th>        
            <th></th>
        </tr>
    
        @if (Model != null && Model.Count() > 0)
        {
            foreach (var item in Model)
            {
                <tr class="table-Content">
                    <td>
                        @Html.DisplayFor(modelItem => item.DefaultVisitProductHeaderName)
                    </td>                
                    <td>
    
                        @if (item.CreatedBy.HasValue && item.CreatedBy.Value == HelperClasses.CurrentAccountRowID)
                        {
                            <a class="btn" asp-action="Edit" asp-controller="Package" asp-route-id="@item.DefaultVisitProductHeaderRowID">
                                <span class="fa fa-edit text-warning"></span>
                            </a>
    
                            <button type="button" class="btn" onclick="deletePackageHeaderItem('@item.DefaultVisitProductHeaderRowID')">
                                <span class="fa fa-trash text-danger"></span>
                            </button>
                        }
    
                    </td>
                </tr>
            }
        }

    Is there any technique to use formatting in edit mode ?

    Thanks in advance.

    Monday, May 25, 2020 4:44 PM
  • User475983607 posted

    Is there any technique to use formatting in edit mode ?

    I provided working example above.  

    Monday, May 25, 2020 5:22 PM
  • User-79977429 posted

    I could not find example project from this link :

    https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings

    Can u give direct link?

    Thanks

    Monday, May 25, 2020 5:31 PM
  • User475983607 posted

    See the source code posted in my first reply.
    Monday, May 25, 2020 8:01 PM
  • User-79977429 posted

    Sorry

    But i don't understand what's difference between my code & your code.

    Can u provide a sample project for me?

    Thanks in advance

    Monday, May 25, 2020 8:06 PM
  • User475983607 posted

    hamed_1983

    Sorry

    But i don't understand what's difference between my code & your code.

    Can u provide a sample project for me?

    I'm not sure what else I can do for you.   The code I posted above formats the number according to my current culture; 2,222,222.0.  Essentially, the code works exactly as written in the openly published reference documentation.  I'm not sure why your code does not work as you expect.  Also, you have not told us what results you expect for your culture.  Please read the docs, it really helps.

    Monday, May 25, 2020 8:27 PM
  • User-79977429 posted

    Thanks for reply

    As i told in my previous posts, this code works for me in list mode, NOT IN INPUT FORMS!

    Does this code works for you in INPUT CONTROLS?

    Tuesday, May 26, 2020 9:51 AM
  • User475983607 posted

    As i told in my previous posts, this code works for me in list mode, NOT IN INPUT FORMS!

    Does this code works for you in INPUT CONTROLS?

    Yes!!!  The forum inputs are formatted exactly as described in the openly published reference documentation.  I've explained this several time now!

    I created a test DefaultVisitProductDetails model and populated the model in the Action method.

        public partial class DefaultVisitProductDetailsMetadata
        {
            [DisplayName("Drug Name")]
            [Required(ErrorMessage = "{0} Required!")]
            public int? ProductID { get; set; }
    
            [Column(TypeName = "money")]
            [DisplayName("Drug Quantity")]
            [Required(ErrorMessage = "{0} Required!")]
            [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:N1}")] // Not working
            public decimal? Quantity { get; set; }
        }
    
        [ModelMetadataType(typeof(DefaultVisitProductDetailsMetadata))]
        public partial class DefaultVisitProductDetails
        {
            public int? ProductID { get; set; }
            public decimal? Quantity { get; set; }
    
        }
    public ActionResult Index()
    {
        DefaultVisitProductDetails model = new DefaultVisitProductDetails()
        {
            ProductID = 1,
            Quantity = 2222222.0m
        };
    
        return View(model);
    }

    The View...

    @model MvcBasic.Models.DefaultVisitProductDetails
    
    @{
        ViewData["Title"] = "Index";
    }
    
    <h1>Index</h1>
    <div>
        <a asp-action="SelectEntrants">SelectEntrants</a>
    </div>
    
    <h4>DefaultVisitProductDetails</h4>
    <hr />
    <div class="row">
        <div class="col-md-4">
            <form asp-action="Index">
                <div asp-validation-summary="ModelOnly" class="text-danger"></div>
                <div class="form-group">
                    <label asp-for="ProductID" class="control-label"></label>
                    <input asp-for="ProductID" class="form-control" />
                    <span asp-validation-for="ProductID" class="text-danger"></span>
                </div>
                <div class="form-group">
                    <label asp-for="Quantity" class="control-label"></label>
                    <input asp-for="Quantity" class="form-control" />
                    <span asp-validation-for="Quantity" class="text-danger"></span>
                </div>
                <div class="form-group">
                    <input type="submit" value="Create" class="btn btn-primary" />
                </div>
            </form>
        </div>
    </div>
    
    <div>
        <a asp-action="Index">Back to List</a>
    </div>
    
    

    Renders the text box as; 2,222,222.0.

    I'm unable to reproduce your results.  Debug your code or provide source code, that I can easily run, which illustrates the problem.  I need to know, as requested several times now, your expected results.  

    Tuesday, May 26, 2020 10:21 AM
  • User-79977429 posted

    Hi again!

    Please see my sample project :

    http://s12.picofile.com/d/8398277868/da3abbd2-664d-475e-98f7-f7b595b8f41b/TestFormatting01.rar

    After opening project, Plz check out 'Stock' class which have a property named 'Quantity' & have DisplayFormat attribute with {0:n1} format.

    Then run project & see Index view. In index view, you see the format string is working, But when u click edit, The Display format string not working in edit view. For example, when u click on Edit for the Last item in Index view (with quantity 3.1 in Index view), In Edit view, You see 3.125 in textBox!

    Tuesday, May 26, 2020 11:39 AM
  • User475983607 posted

    I have no idea how to download your project from the link.  Share your project on GitHub or create a simple demo that can be reproduced like I provided above.  I updated my demo code and it still functions as expected; 3.1.  

    public ActionResult Index()
    {
        DefaultVisitProductDetails model = new DefaultVisitProductDetails()
        {
            ProductID = 1,
            Quantity = 3.125m
        };
    
        return View(model);
    }

    I'm guessing there's other issue with your code or your understanding.  Does your culture use the "dot" to represent decimal or a comma?  If so,  the format is probably correct and it is your understanding that has the bug.  Can you clarify?  Is the value 3 or 3 thousand?

    It is quite irritating that it took so many posts before you shared your expected results!  

    Tuesday, May 26, 2020 12:13 PM
  • User-79977429 posted

    Hi again

    If you have problem to download my simple demo project, Plz check out this another link.

    Tuesday, May 26, 2020 3:42 PM
  • User475983607 posted

    You specifically set the value which overrides the tag helper ability to format the input.  Either apply the format...

    <input asp-for="Quantity" class="form-control" value="@Model.Quantity.ToString("N1")"/>

    or let the tag helper apply the format.

    <input asp-for="Quantity" class="form-control" />

    Tuesday, May 26, 2020 4:11 PM
  • User-79977429 posted

    You specifically set the value which overrides the tag helper ability to format the input.  Either apply the format...

    <input asp-for="Quantity" class="form-control" value="@Model.Quantity.ToString("N1")"/>

    Yes, it works. But 2 quetsions :

    If i should use format string in view, then i don't need to use DisplayFormat attribute?

    Why DisplayFormat attribute not working when i set value for my input controls?

    Thanks in advance

    Tuesday, May 26, 2020 4:27 PM
  • User475983607 posted

    If i should use format string in view, then i don't need to use DisplayFormat attribute?

    Why DisplayFormat attribute not working when i set value for my input controls?

    You misunderstand.  The tag helper formats the model property according to the display format.  Your code overrides the tag helper.   you need to pick one approach or the other. Use the tag helper and do not set the value.  Or set the value and apply formatting.

    Tuesday, May 26, 2020 6:02 PM
  • User-79977429 posted

    The tag helper formats the model property according to the display format.

    So, Why set 'ApplyFormatInEditMode = true' in DisplayFormat attribute?

    [DisplayName("Quantity")]
            [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:n1}")]
            public decimal Quantity { get; set; }

    Wednesday, May 27, 2020 9:24 AM
  • User475983607 posted

    mgebhard

    The tag helper formats the model property according to the display format.

    So, Why set 'ApplyFormatInEditMode = true' in DisplayFormat attribute?

    [DisplayName("Quantity")]
            [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:n1}")]
            public decimal Quantity { get; set; }

    The attribute tells the tag helper how to format the decimal.   Your code ignores this attribute and manually sets the input value.  

    It seems that you made an incorrect assumption regarding fundamentals and are having a hard time changing you mindset.  In other words, the code is functioning as expected but not how you expect.

    Wednesday, May 27, 2020 9:53 AM