0

I'm new to C# and HTML and trying to write an expiration date calculator for our labs using Blazor. I have the logic all figured out behind the output besides the specific date format according to the if...else statement ---BUT--- my actual question is if someone could give me an idea on how to write the part of my code so when a user clicks the "Submit" button on this Blazor application, it will output what the logic had calculated.

I've looked through several pages on SO but none of them are quite what I'm looking for. I believe this may take an onClick event that's probably binded somehow to the function I wrote in the "@ code" part but if someone could explain the proper way of doing it, that would be awesome!

Thank you :) (P.S the entire portion of the code that I am in charge of is below, the first part is HTML and after @ code it's C#)

EDIT: When the first "if" statement executes, the DateTime should be formatted as "mm/yyyy" in numeric terms like "09/2022". If the first "if" statement doesn't pass, meaning one of the parameters was not met, then the date should be formatted as "yyyy/mm/dd" like "2022/10/28"

`

<!DOCTYPE html>
    <html>
    <body> 
    <!--
        Code to create mix date textbox for input   
    -->
        Mix Date:
            <input type="tel" id="date" name="mix date" placeholder="DD/MM/YYYY" pattern="[0-9]{2}/[1-12]{2}/[0-9]{4}">
                <br>
                <br>
    <!--
        Creates the two checkboxes
    -->
        <form action="/action_page.php">
        <input type="checkbox" id="mbefore" name="mbefore" value="false" @onclick="boxcheck2">
            <label for="mbefore"> Made Before September 10th, 2022</label><br>
                <input type="checkbox" id="pproduct" name="pproduct" value="false" @onclick="boxcheck1">
                    <label for="pproduct"> Plate Product</label><br>        
        </form>
    <!--
        Code to create shelf life textbox
    -->
                <br>
        <label for="slife">Shelf Life:</label>
             <input type="text" id="slife" name="slife" @bind="shelfLife"/> 
                <br>
                <br>
    <!--
        Code to create submit button
    -->

    <button onclick="myFunction()">Submit</button>

    <!--
        Calculated expiration date (need to figure out how to get above to output into below textbox) and with the correct formatting depending on if..else conditions
        Def an onlcick action
    -->
                <br>
                <br>
        <label for="exp">Expiration Date:</label>
    <input type="text" id="exp" name="exp">
    <p id="demo"></p>

    

    </body>
    </html>

@code {
    private double shelfLife;
    private DateTime mixDate;
    private DateTime expDate;
    private bool checkbox1;
    private bool checkbox2;


    private void boxcheck1()
    {
        checkbox1 = !checkbox1;
    }
    private void boxcheck2()
    {
        checkbox2 = !checkbox2;

    }
    private void myFunction() {
        DateTime nMix = Convert.ToDateTime(mixDate);


        if ((checkbox1 == true) && (checkbox2 == true) && (shelfLife > 90)) {

            DateTime expDate = (mixDate + TimeSpan.FromDays(shelfLife)) + TimeSpan.FromDays(30);
            Console.WriteLine(expDate);
        }

        else if ((checkbox1 == false) || (checkbox2 == false) || (shelfLife <90)) {

            DateTime expDate = (mixDate + TimeSpan.FromDays(shelfLife)) - TimeSpan.FromDays(1);
            Console.WriteLine(expDate);
        }

        else {
            Console.WriteLine ("Please Try Again. Information Not Satisfactory");
        }
    }
}

`

Sahar
  • 13
  • 5
  • 1
    Take a look at this question https://stackoverflow.com/questions/58196812/blazor-onclick-event-not-triggered – JamesS Oct 27 '22 at 15:37
  • @JamesS thanks for the link! I'll give it a read :) – Sahar Oct 27 '22 at 16:00
  • Hi Sahar, Have you looked at any of the online tutorials? You're mixing classic html and Blazor. If you want to use Blazor you need to build a Blazor application and code Blazor forms. The tutorials will get you started. There are MS ones and many on YouTube - just search. – MrC aka Shaun Curtis Oct 27 '22 at 16:20
  • @MrCakaShaunCurtis mhm! This is just one of the files within the Blazor Package that I am working with where the main body of code is. This code replaces everything within the home page that Blazor creates when you run it through VS but the counter and temperature page are still there :) – Sahar Oct 27 '22 at 16:48
  • [Polite] ` ` doesn't belong in a Blazor component, nor does `
    `. If you are including that type of code then you probably do need the help you'll get from the online tutorials.
    – MrC aka Shaun Curtis Oct 27 '22 at 17:01

2 Answers2

2

This is how you would do it at a very basic level. Source

@Message


<button @onclick="MyFunction">Submit</button>



@code {  
    string Message { get; set; }

    void MyFunction()
    {
        if(...)
        {
           Message = expDate;
        }
        else
        {
           Message = "Please try again."
        }
    }    
}
2

Here's a demo page with support classes that shows how you can do what you want to.

I've updated it to show you how to do the date formatting. This may look a little over the top but it builds the necessary functionality into one place - for more info search on "Primitive Obsession".

@page "/"
<div>
    <div class="mb-3">
        <label class="form-label">Mix Date:</label>
        <input class="form-control" type="date" placeholder="DD/MM/YYYY" @bind-value=this.recordEditContext.MixDate>
        <div class="form-text">Enter the mix date for the item</div>
    </div>
    <div class="mb-3 form-check">
        <input class="form-check-input" type="checkbox" @bind-value=this.recordEditContext.IsBeforeDate>
        <label class="form-check-label">Made Before September 10th, 2022</label>
    </div>
    <div class="mb-3 form-check">
        <input class="form-check-input" type="checkbox" @bind-value=this.recordEditContext.IsPlate>
        <label class="form-check-label">Plate Product</label>
    </div>
    <div class="mb-3">
        <label class="form-label">Shelf Life:</label>
        <input class="form-control" type="number" @bind-value=this.recordEditContext.ShelfLife>
        <div class="form-text">Enter the shelf life for the item (days)</div>
    </div>
    <div class="mb-3 text-end">
        <button disabled="@(!this.recordEditContext.IsDirty)" class="btn btn-primary" @onclick=CalculateExpiryDate>Calculate Expiry Date</button>
    </div>
</div>

@if (this.IsError)
{
    <div class="alert alert-danger mt-3">
        @this.errorMessage
    </div>
}

@if (!this.ExpiryDate.IsNull && !recordEditContext.IsDirty)
{
    <div class="alert alert-info mt-3">
        Calculated Expiry Date: @this.ExpiryDate.ToString()
    </div>
}

@code {
    private RecordEditContext recordEditContext = new RecordEditContext(new());
    private ExpirationDate ExpiryDate = new ExpirationDate();
    private string errorMessage = string.Empty;

    private bool IsError => this.errorMessage != string.Empty;

    private void CalculateExpiryDate()
    {
        this.errorMessage = string.Empty;
        this.ExpiryDate.Value = DateTime.MinValue;
        this.recordEditContext.SetToClean();

        if ((recordEditContext.IsBeforeDate == true) && (recordEditContext.IsPlate == true) && (recordEditContext.ShelfLife > 90))
        {
            this.ExpiryDate.Value = (recordEditContext.MixDate + TimeSpan.FromDays(recordEditContext.ShelfLife)) + TimeSpan.FromDays(30);
            this.ExpiryDate.Format = ExpirationDate.ExpiryDateFormat.MonthYear;
            return;
        }

        if ((recordEditContext.IsBeforeDate == false) || (recordEditContext.IsPlate == false) || (recordEditContext.ShelfLife < 90))
        {
            this.ExpiryDate.Value = (recordEditContext.MixDate + TimeSpan.FromDays(recordEditContext.ShelfLife)) - TimeSpan.FromDays(1);
            this.ExpiryDate.Format = ExpirationDate.ExpiryDateFormat.YearMonthDay;
            return;
        }

        this.errorMessage = "Please Try Again. Information Not Satisfactory";
    }
}

And support classes:

    public record RecordData
    {
        public int ShelfLife { get; init; }
        public DateTime MixDate { get; init; } = DateTime.Now;
        public bool IsBeforeDate { get; init; }
        public bool IsPlate { get; init; }
    }

    public record RecordEditContext
    {
        private RecordData _baseRecord;

        public int ShelfLife { get; set; }
        public DateTime MixDate { get; set; }
        public bool IsBeforeDate { get; set; }
        public bool IsPlate { get; set; }

        public bool IsDirty => !_baseRecord.Equals(this.Record);

        public RecordData Record =>
            new RecordData
                {
                    ShelfLife = this.ShelfLife,
                    MixDate = this.MixDate,
                    IsBeforeDate = this.IsBeforeDate,
                    IsPlate = this.IsPlate
                };

        public RecordEditContext(RecordData record)
        {
            _baseRecord = record;
            this.ShelfLife = record.ShelfLife;
            this.MixDate = record.MixDate;
            this.IsBeforeDate = record.IsBeforeDate;
            this.IsPlate = record.IsPlate;
        }

        public void SetToClean()
            => _baseRecord = Record;

    }
    public class ExpirationDate
    {
        public DateTime Value { get; set; }

        public ExpiryDateFormat Format { get; set; } = ExpiryDateFormat.Normal;

        public override string ToString()
            => this.Format switch
            {
                ExpiryDateFormat.MonthYear => this.Value.ToString("MM/yyyy"),
                ExpiryDateFormat.YearMonthDay => this.Value.ToString("yyyy/MM/dd"),
                _ => this.Value.ToLongDateString()
            };

        public bool IsNull
            => Value == DateTime.MinValue;

        public enum ExpiryDateFormat
        {
            Normal,
            MonthYear,
            YearMonthDay
        }
    }
MrC aka Shaun Curtis
  • 19,075
  • 3
  • 13
  • 31
  • oh my god... this is literally exactly what I am looking for, its literally everything except the formatting that I omitted from the question above. You are so nice thank you so much for reformatting it! It has been like weeks since I've been working on this and the tutorials you suggested I watch was picking my brain. LOL I literally gasped so loud in the office, thank you for being so generous with your answer – Sahar Oct 27 '22 at 20:50
  • If you are curious about the formatting is basically if all parameters pass (referencing the if statement) the date format outputted should be mm/yyyy in number form and if any of those parameters fail (referencing the else statement here) then the format would be dd/mm/yyyy. You made my job so much easier thank you so much – Sahar Oct 27 '22 at 20:59
  • NP. Keep watching/reading, and make sure you understand how the code is working. Put break points in and watch what gets called when. – MrC aka Shaun Curtis Oct 27 '22 at 21:29
  • So I noticed that in the code you wrote, you used the a global variable "ToLongDateString" which means the calculated date displays as "name of day, month, number ,year" but I want to use a local variable to format the final output at a numeric date based on the if statements. What would be a good way to convert/modify that global variable to do what I need it to do? – Sahar Oct 28 '22 at 15:40
  • Ive looked at TryParseEXact and ParseExact for DateTime.ToString but is that the way to do it? – Sahar Oct 28 '22 at 15:42
  • 1
    See my addition to the answer. How do you want to format it - put it in your question. PS If this is your preferred answer can you tick it. – MrC aka Shaun Curtis Oct 28 '22 at 16:16
  • i edited my question but here is what I said: When the first "if" statement executes, the DateTime should be formatted as "mm/yyyy" in numeric terms like "09/2022". If the first "if" statement doesn't pass, meaning one of the parameters was not met, then the date should be formatted as "yyyy/mm/dd" like "2022/10/28" – Sahar Oct 28 '22 at 16:32
  • See my revised answer. – MrC aka Shaun Curtis Oct 28 '22 at 17:26
  • That worked perfectly! I was putting code in the wrong spots before looking at your answer. Thank you so much for your help!! I hope I ticked the answer correctly. Thank you for all the time you've put into helping me – Sahar Oct 28 '22 at 18:14