How to show a pop up or warning to user if the DB Row is going to be overwritten in ASP.NET MVC 5

天大地大妈咪最大 提交于 2019-12-11 07:28:23

问题


Requirement: I have a referral form, where user can fill in the details to apply for a job. Now, As per my requirement, if a user wants to reapply for the same job, he can do so, multiple number of times (humor me on this). So, If I detect that user has already applied for the job before then I need to update the old referral request, if not then create a new request.

Current Behaviour: I have successfully written the logic to overwrite the existing value (if user had already applied before). But I want to show a pop up or some confirmation, if I detect that the user has already applied to this job, before updating resume and datetime and other fields. And once user says Yes, then only I want to overwrite the values.

Issue: I have no clue how to achieve above. Because once the request goes to backend controller action then only I can detect that this is something new or this is something which is already existing and needs to be overwritten and a POP UP needs to be shown.

View:

@model Bridge.ViewModels.ReferralViewModel
@using (Html.BeginForm())
{
    <div class="form-horizontal">
        <h4>Job Request</h4>
        <div class="form-group">
            @Html.LabelFor(model => model.CompanyId, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownListFor(m => m.CompanyId, Model.Companies, "Please Select", new { @class = "form-control", data_url = Url.Action("ListOfCoverLetterByCompanyId", "Referral") })
            </div>
        </div>
       @* SOME FIELDS REMOVED FOR BREVITY*@
        <div class="form-group">
            @Html.LabelFor(model => model.ResumeId, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownListFor(m => m.ResumeId, Model.Resumes, new { @class = "form-control" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.CoverLetterId, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownListFor(m => m.CoverLetterId, Model.CoverLetters, "Please select", new { @class = "form-control" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

Controller Action

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(ReferralViewModel viewModel)
{
    var candidateId = User.Identity.GetUserId();
    var referral = _context.Referrals.Where(r => (r.CandidateId == candidateId) && (r.CompanyId == viewModel.CompanyId)).SingleOrDefault();
    if (referral != null)
    {
        // if already existing then show a confirmation/warning before updating
        referral.ResumeId = viewModel.ResumeId;
        referral.CoverLetterId = viewModel.CoverLetterId;
        referral.dateTime = DateTime.Now;
    }
    else
    {
      // If new then add the entry
    }
    _context.SaveChanges();

    return RedirectToAction("ReferralCenter");
}

EDIT

Attempt 1:

View:

@section scripts {
        <script>
            $('form').submit(function () {
                var data = $('form').serialize();
                var url = '@Url.Action("CheckForExistingReferral")';
                $.ajax({
                    url: url,
                    type: 'POST',
                    data: data,
                    success(data)
                    {
                        debugger;
                        alert("hello");
                        // some logic
                    },
                    error()
                    {
                        debugger;
                    alert("error");
                     //some logic
                }
                });
            });     
        </script>
    }

AJAX Action:

[HttpPost]
public JsonResult CheckForExistingReferral(ReferralViewModel viewModel)
{
    bool hasPreviousRequest = false;
    var candidateId = User.Identity.GetUserId();
    var referral = _context.Referrals.Where(r => (r.CandidateId == candidateId) && (r.CompanyId == viewModel.CompanyId) && (r.SkillId == viewModel.SkillId) && (string.IsNullOrEmpty(r.ReferrerId))).SingleOrDefault();
    hasPreviousRequest = referral != null;
    return Json(new { hasPreviousRequest = hasPreviousRequest });

}

Issue:

Breakpoint at JSON Function gets hit, but before it can return the result, my Actual Form POST Method breakpoint gets hit. I want the Form POST controller action to wait for AJAX call return.

Attempt 2

View

@section scripts {
    <script>
            var canSubmit = false;
            debugger;
            $('form').submit(function (e) {
                if (!canSubmit)
                    e.preventDefault();
                var data = $('form').serialize();
                var url = '@Url.Action("CheckForExistingReferral")';
                $.ajax({
                    url: url,
                    type: 'POST',
                    data: data,
                    success(response){
                        if (response.hasPreviousRequest)
                        {
                            if (confirm("You've already applied for this job. Apply again?")) {
                                canSubmit = true;
                                $('form').submit();
                            }
                        }
                        else {
                            canSubmit = true;
                            $('form').submit();
                        }
                    },
                    error(){
                       alert("error");
                    }
                }); 
            });
        </script>
    }

Issue: For single click, my Json Action gets hit atleast 3 times. It should be hit just once.

Attempt 3

Gave an Id to the form:

@using (Html.BeginForm("Create", "Referral", FormMethod.Post, new { id = "job-form" }))
{}

Script:

@section scripts {
    <script>
            var canSubmit = false;
            debugger;
            $('#job-form').submit(function (e) {
                if (!canSubmit)
                    e.preventDefault();
                var data = $('#job-form').serialize();
                var url = '@Url.Action("CheckForExistingReferral")';
                $.ajax({
                    url: url,
                    type: 'POST',
                    data: data,
                    success: function (response) {
                        if (response.hasPreviousRequest)
                        {
                            if (confirm("You've already applied for this job. Apply again?")) {
                                canSubmit = true;
                                $('#job-form').submit();
                            }
                        }
                        else {
                            canSubmit = true;
                            $('#job-form').submit();
                        }
                    },
                    error: function (){ 
                       alert("error");
                    }
                }); 
            });
        </script>
    }

ISSUE: I keep on seeing the JS Pop up in a loop.


回答1:


You can basically repeat the check you use in the POST action currently, but return a simple JSON value instead:

public ActionResult CheckForExistingReferral(ReferralViewModel viewModel)
{
    bool hasPreviousRequest = false;

    var candidateId = User.Identity.GetUserId();
    var referral = _context.Referrals.Where(r => (r.CandidateId == candidateId) && (r.CompanyId == viewModel.CompanyId)).SingleOrDefault();

    hasPreviousRequest = referral != null;

    return Json(new { hasPreviousRequest = hasPreviousRequest }, JsonRequestBehavior.AllowGet);
}

In your view, you'd do something like:

var data = $('form').serialize();
var url = '@Url.Action("CheckForExistingReferral")';

$.get(url, data)
    .done(function(response, status, jqxhr){
        if(response.hasPreviousRequest){
            // show alert?
        }
        else{
            // post form?
        }
    });

This is using jQuery's $.get helper, which (mostly) just wraps their $.ajax function. serialize will URL-encode your form values into a format suitable for submitting through the Ajax request, or you can manually construct a JavaScript object, if you prefer.

The .done() function handles successful responses (anything with a 200 status code). If you want to handle bad/failed requests, you'd add a .fail() function, something like this:

$.get(url, data)
    .done(function(response, status, jqxhr){
    })
    .fail(function(jqxhr, status, error){
    });

error will contain an object that contains the error details returned from the server. jqxhr, in both instances, is the XMLHTTPRequest created by jQuery.

Of course, since you'd now be repeating a chunk of code, you should probably refactor this duplicate check into something like a helper method, and then replace the check in both actions.

Since you don't want to allow the form submission unless the user has confirmed the resubmission (or there wasn't a previous submission), you need to prevent the form submission. Here's an example:

// check variable - we'll update this in the handler below
var canSubmit = false;

$('form').on('submit', function(e){   
    // Have we checked for resubmissions yet, or has the user approved the resubmit?
    if(!canSubmit){
        e.preventDefault();

        var data = $('form').serialize();
        var url = '@Url.Action("CheckForExistingReferral")';

        $.get(url, data)
            .done(function(response, status, jqxhr){
                if(response.hasPreviousRequest){
                    // show alert?
                    if(confirm("You've already applied for this job. Apply again?")){
                        canSubmit = true;
                        // $('form').submit(); re-triggers the form submission. 
                        // Since the value is now true, the form submission occurs normally
                        $('form').submit();
                    }                       
                }
                else{
                    // post form?
                    canSubmit = true;
                    $('form').submit();
                }
            });
    }
});


来源:https://stackoverflow.com/questions/46028241/how-to-show-a-pop-up-or-warning-to-user-if-the-db-row-is-going-to-be-overwritten

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!