locked
Problem with loading Jquery function and Converting Timespan type into int in action of Controller RRS feed

  • Question

  • User1255309776 posted

    Hello,

    I develop quiz application where score for each question is calculated according to remained time. My first problem is that the timer doesn't work when loading my question view. Is there  something wrong with js (jquery function). 

    View

    @model Intellect.Models.ViewModels.AdminViewModel
    
    
        <div class="questioncontainer">        
            <form asp-action="Question" asp-controller="Home" asp-route-id="@Model.NextQuestion.Id" asp-route-count="@ViewBag.Equestions">
                <div class="row">
                    <div class="col-lg-3"></div>
                    <div class="col-lg-6 col-sm-12">
                        <table>
                            <tr>
                                <th>Qaliq vaxt</th>
                            </tr>
                            <tr>
                                <td>
                                    <input asp-for="CurrentQuestion.Remainedtime" id="time" />
                                    <input type="hidden" id="timehidden" asp-for="CurrentQuestion.Remainedtime" />
                                </td>
                            </tr>
                        </table>
                        <div class="question">@Model.CurrentQuestion.Description </div>
                    </div>
                    <div class="col-lg-3"></div>
                </div>
                <div class="row">
                    <div class="col-lg-3 col-sm-0"></div>
                    @{
                        int n = 0;
                    }
                    @foreach (Answer item in Model.Answers)
                    {
                        if (n == 0 || n == 2)
                        {
                            @: <div class="col-lg-3 col-sm-12">
                                @: <div class="firstpart">
                                }
                                <input asp-for="@item.Id" name="@item.Id" hidden />
                                <input type="radio" asp-for="@item.Id" name="myanswer" value="@item.Id" />@item.Description
    
                                <br>
                                if (n == 1 || n == 3)
                                {
                                @:</div>
                            @:</div>
                        }
    
                        n++;
                    }
                    <div class="col-lg-3"></div>
                </div>
                <div class="row">
                    <div class="col-lg-6 col-sm-4">
    
                    </div>
                    <div class="col-lg-3 col-sm-4">
    
                    </div>
                    <div class="col-lg-3 col-sm-4">
                        <div class="nextbtn">
                            @if (ViewBag.Equestions == 0)
                            {
                                <input type="submit" value="Finish" />
                            }
                            else
                            {
                                <input type="submit" value="Next" />
                            }
    
                        </div>
                    </div>
                </div>
            </form>
    
        </div>
    
    @section Script{ 
        <script>
             var start = Date.now(),
                diff,
                seconds;
            function startTimer(duration) {
                function timer() {
                    // get the number of seconds that have elapsed since
                    // startTimer() was called
                    diff = duration - (((Date.now() - start) / 1000) | 0);
    
                    // does the same job as parseInt truncates the float
                    seconds = diff;
    
                    seconds = seconds < 10 ? "0" + seconds : seconds;
    
                    $("#time").text(seconds);
                    $("#timehidden").val(seconds);
                    if (diff <= 0) {
                        // add one second so that the count down starts at the full duration
                        // example 05:00 not 04:59
                        start = Date.now() + 1000;
                    }
                };
                // we don't want to wait a full second before the timer starts
                timer();
                setInterval(timer, 1000);
            }
    
            window.onload = function () {
                var minute = @Model.CurrentQuestion.Remainedtime;
                startTimer(minute);
                $("#time").val("start");
            };
        </script>
    }

    Here is View of first question:

    https://prnt.sc/s568xl

    And after clicking Next, input string format error comes like here: https://prnt.sc/s56ecv

    Controller

     public class HomeController : Controller
        {
            private readonly IntellectDbContext _intellectDbContext;
            private readonly UserManager<ExamUser> _userManager;
            private readonly SignInManager<ExamUser> _signInManager;
            static int exam_id = 0;
            static int? PreviousId = 0;
            static int result = 0;
            static int correctAnswer = 0;
            static List<Question> RemainedQuestions = new List<Question>();
            static List<int> trueAnswers = new List<int>();
    
            public HomeController(IntellectDbContext intellectDbContext, UserManager<ExamUser> userManager, SignInManager<ExamUser> signInManager)
            {
                _intellectDbContext = intellectDbContext;
                _userManager = userManager;
                _signInManager = signInManager;
            }
             
    
            [HttpGet]
            public async Task<IActionResult> Test(int Id)
            {
                exam_id = Id;
                AdminViewModel admodel = new AdminViewModel();
                admodel.Equestions = await _intellectDbContext.Questions.Include(q => q.Answers).Where(q => q.ExamId == Id).ToListAsync();
                admodel.CurrentQuestion = await _intellectDbContext.Questions.Where(q => q.ExamId == Id).FirstOrDefaultAsync();
                RemainedQuestions = admodel.Equestions;
                PreviousId = admodel.CurrentQuestion.Id;
                return View(admodel);
            }
    
            public async Task<IActionResult> Question(int Id, int count, int myanswer)
            {
                AdminViewModel admodel = new AdminViewModel();
                admodel.CurrentQuestion = await _intellectDbContext.Questions.Where(x => x.Id == Id).SingleOrDefaultAsync();
                admodel.Answers = await _intellectDbContext.Answers.Where(y => y.QuestionId == Id).ToListAsync();
                admodel.Equestions = await _intellectDbContext.Questions.Where(q => q.ExamId == exam_id).ToListAsync();
                
                admodel.CurrentQuestion.Remainedtime = new TimeSpan(0, 0, 60);
    
                correctAnswer = _intellectDbContext.Answers.Where(a => a.QuestionId == PreviousId && a.Correct == true).SingleOrDefault().Id;
    
                if (_signInManager.IsSignedIn(User))
                {
                    ExamUser examTaker = await _userManager.GetUserAsync(HttpContext.User);
    
                    examTaker.TestTaker = await _intellectDbContext.TestTakers
                                                   .Include(tt => tt.UserQuestions) // load related navigation property
                                                   .Where(t => t.Id == examTaker.TestTakerId) // filter
                                                   .FirstOrDefaultAsync();
                    admodel.CurrentQuestion = examTaker.TestTaker.UserQuestions.Select(u => u.Question).Where(x => x.Id == Id).SingleOrDefault();
                    if (myanswer == correctAnswer)
                    {
                        admodel.CurrentQuestion.Score = int.Parse(admodel.CurrentQuestion.Remainedtime.ToString());
                       
                    }
                }
                 
                    if (count > 1)
                {
                    var question = RemainedQuestions.Single(r => r.Id == admodel.CurrentQuestion.Id);
                    PreviousId = question.Id;
                    RemainedQuestions.Remove(question);
                    admodel.NextQuestion = RemainedQuestions[0];
                    count -= 1;
                }
                else
                {
                    admodel.NextQuestion = RemainedQuestions[0];
                    count -= 1;
                }
    
                if(count == -1)
                {
                    return RedirectToAction(nameof(Finish));
                }
    
                ViewBag.Equestions = count;
    
                return View(admodel);
            }
            

    And viewmodel which hold my needed models:

    namespace Intellect.Models.ViewModels
    {
        public class AdminViewModel
        {
            public int Id { get; set; }
            public Exam Exam { get; set; }
            public Question Question { get; set; }
            public Answer Answer { get; set; }
            public IEnumerable<Exam> Exams { get; set; }
            public List<SelectListItem> Examlist { get; set; }
            public List<SelectListItem> QuestionList { get; set; }
            public IEnumerable<Question> Questions { get; set; }
            public IEnumerable<Answer> Answers { get; set; }
            public TestTaker TestTaker { get; set; }
            public IEnumerable<TestTaker> TestTakers { get; set; }
            public Question CurrentQuestion { get; set; }
            public Question NextQuestion { get; set; }
            public List<Question> Equestions { get; set; }
            public string SelectedAnswer { get; set; }
        }
    }

    For conversion problem, please, mainly focus on Question action ( admodel.CurrentQuestion.Score = int.Parse(admodel.CurrentQuestion.Remainedtime.ToString()); ) .

    Please, assist in solving this issue.

    Thank you in advance!

    Friday, April 24, 2020 11:14 AM

Answers

  • User-719153870 posted

    Hi FaridGN,

    My first problem is that the timer doesn't work when loading my question view. Is there  something wrong with js (jquery function). 

    I tested your JS code and it can work as a timer:

    $("#time").text(seconds);

    But this won't help show your timer result, replace text() with val() should fix your issue.

    admodel.CurrentQuestion.Score = int.Parse(admodel.CurrentQuestion.Remainedtime.ToString());

    admodel.CurrentQuestion.Remainedtime is TimeSpan(Int32, Int32, Int32) type, it's not available to directly convert TimeSpan.ToString() to Int type, because the format of this converted string would be like:

    Thus, to solve this error, you need to choose one of this TimeSpan value's sub value, such as Remainedtime.TotalSeconds.ToString() or TotalHours etc.

    Best Regard,

    Yang Shen

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Saturday, April 25, 2020 2:32 AM

All replies

  • User-719153870 posted

    Hi FaridGN,

    My first problem is that the timer doesn't work when loading my question view. Is there  something wrong with js (jquery function). 

    I tested your JS code and it can work as a timer:

    $("#time").text(seconds);

    But this won't help show your timer result, replace text() with val() should fix your issue.

    admodel.CurrentQuestion.Score = int.Parse(admodel.CurrentQuestion.Remainedtime.ToString());

    admodel.CurrentQuestion.Remainedtime is TimeSpan(Int32, Int32, Int32) type, it's not available to directly convert TimeSpan.ToString() to Int type, because the format of this converted string would be like:

    Thus, to solve this error, you need to choose one of this TimeSpan value's sub value, such as Remainedtime.TotalSeconds.ToString() or TotalHours etc.

    Best Regard,

    Yang Shen

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Saturday, April 25, 2020 2:32 AM
  • User1255309776 posted

    Thanks, but intellisense doesn't show any property like TotalSeconds or TotalHours for Remainedtime while I want to convert.

    Please, refer to this image link:   https://prnt.sc/s5nkxz

    Saturday, April 25, 2020 8:34 AM
  • User-719153870 posted

    Hi FaridGN,

    Sorry for this late reply, I took a vacation before.

    So this Remainedtime is not Timespan type originally, please share your Question class so that we can reproduce this issue.

    From your screenshot, there's a value property for your Remainedtime, but Timespan does not contain this property.

    Best Regard,

    Yang Shen

    Wednesday, May 13, 2020 9:19 AM
  • User1255309776 posted

    Dear Yang Shen,

    Thank you so much for still getting attention to my problem. Note that I've changed my implementation, and didn't use Timespan, and just wrote in Javascript in View and got that value from View input to controller action. Now my problem is in Question method with LINQ which causes SQlL exception.

    Please, refer to the link below, I opened new thread for my current problem in this quiz app and included almost every model, View and actions to analyze clearly:

    https://forums.asp.net/t/2166824.aspx?Problem+with+LINQ+causing+SQL+exception+Cannot+insert+duplicate+key+row

    Please, if you can, assist in finding solution to current problem with database.

    Wednesday, May 13, 2020 9:22 PM
  • User-719153870 posted

    Dear FaridGN,

    I've checked the new thread and it seems my colleague Rena's working on this issue. I'm sure there will be a new reply soon.

    In addition, if there'e no more questions about this current thread, please mark the posts that help fix related issues.

    Thanks for your patience!

    Best Regard,

    Yang Shen

    Thursday, May 14, 2020 1:44 AM
  • User1255309776 posted

    Dear Yang,

    Could you please follow Rena's reply on my thread of SQL Exception? There I replied to her, but seems she didn't get what I really needed.

    Saturday, May 16, 2020 10:38 AM