Associating script with a button in ASP .NET MVC R

2019-09-09 03:37发布

问题:

I have a button and a script:

   <script>
   function SubmitClick () {
        var pid = $(this).data('personid');
        var sid = $(this).data('surveyid');
        var url = '@Url.Action("SubmitSurvey", "Person")';
        $.post(url, { personid: pid, surveyid: sid }, function (data) {
            alert('updated');
        });
    };
</script>

When I click the button the script is not run/called/invoked. How to make this button invoke this script?

Full view _Survey1.html this is PartialView:

<script>
   function SubmitClick () {
        var pid = $(this).data('personid');
        var sid = $(this).data('surveyid');
        var url = '@Url.Action("SubmitSurvey", "Person")';
        $.post(url, { personid: pid, surveyid: sid }, function (data) {
            alert('updated');
        });
    };
</script>

@using WebApplication2.Models
@model   System.Tuple<Person, List<Survey>>

<hr />
<h1>Surveys</h1>
<input type="button" id="Coll" value="Collapse" onclick="javascript:CollapseDiv()" />
@*<p>
        Number of Surveys: @Html.DisplayFor(x => Model.Item2.Count)
    </p>*@

@{int i = 1;}
@foreach (var survey in Model.Item2) {
    using (Html.BeginForm()) {
        <h2>Survey @(i)</h2>
        <p />
        @Html.EditorFor(x => survey.Questions)


        <button class='mybutton' type='button' data-personid="@Model.Item1.Id" data-surveyid="@survey.Id" onclick="javascript:SubmitClick()">Click Me</button>
    }
    i++;
    <hr style="background-color:rgb(126, 126, 126);height: 5px" />
}
<hr />

The SubmitSurvey method in PersonController:

 public void SubmitSurvey(int personId, int surveyId) {
        System.Diagnostics.Debug.WriteLine("UPDATING DATABASE");

    }

The result is that after clicking the button I get error saying that SubmitClickhaven't been found:

Details.cshtml (the _Survey1.cshtml) is rendered inside of it.

@model WebApplication2.Models.Person

@{
    ViewBag.Title = "Details";
}

<script>
    function BtnOnclick() {
        $.ajax({
            type: 'POST',
            url: '@Url.Content("~/Person/_Survey1")',
            data: {
                id: '@Model.Id'
            },
            success: function (data) {
                $('#divpopup').css("display", "block");
                $('#btnExpand').css("display", "none");
                $('#divpopup')[0].innerHTML = data;
            }
        });
    }
    function CollapseDiv() {
        $('#divpopup').css("display", "none");
        $('#btnExpand').css("display", "block");
    }




</script>
<h2>Details</h2>

<div>
    <h4>Person</h4>
    <hr />
    <dl class="dl-horizontal">
        <dt>
            @Html.DisplayNameFor(model => model.FirstName)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.FirstName)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.LastName)
        </dt>


        <dd>
            @Html.DisplayFor(model => model.LastName)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.CellNumber)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.CellNumber)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.SecondaryPhoneNumber)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.SecondaryPhoneNumber)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.Address)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Address)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.BirthDate)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.BirthDate)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.Pesel)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Pesel)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.Notes)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Notes)
        </dd>
        <dt>
            @Html.DisplayNameFor(model => model.Status)
        </dt>
        <dd>
            @Html.DisplayFor(model => model.Status.Name)
        </dd>
        <dt>
            @Html.DisplayNameFor(model => model.PersonalDataProcessing)
        </dt>
        <dd>
            @Html.DisplayFor(model => model.PersonalDataProcessing)
        </dd>
    </dl>
</div>
<!--BEGIN-->
<p>
    <input type="button" value="Expand" id="btnExpand"
           onclick="javascript:BtnOnclick();" />
</p>
<div id="divpopup" style="display:none">

</div>
<!--END-->

<p>@Html.ActionLink("Call Cell Phone", "Call", new { id = Model.Id, number = Model.CellNumber }, new { @class = "btn btn-default" })</p>
<p> @Html.ActionLink("Call Client's Secondary Number »", "Call", new { id = Model.Id, number = Model.SecondaryPhoneNumber }, new { @class = "btn btn-default" })</p>
<p>
    @Html.ActionLink("Edit", "Edit", new { id = Model.Id })
    @Html.ActionLink("Back to List", "Index")
</p>

回答1:

Remove the script from the foreach loop and add a single script at the bottom of the page. In the loop, assign the values you want to pass to the post method as data attributes of the button so they can be accessed in the script. For example

@foreach (var survey in Model.Item2) {
  using (Html.BeginForm()) {
    ....
    <button class='mybutton' type='button' data-personid="@Model.Item.ID" data-surveyid="@Survey.ID">Click Me</button>

And the script

$('.mybutton').click(function() {
  var pid = $(this).data('personid');
  var sid = $(this).data('surveyid');
  var url = '@Url.Action("SubmitSurvey", "Person")';
  $.post(url, { personid: pid, surveyid: sid }, function(data) {
    alert('updated');
  });
});

Note: the post method should return JSON data indicating success or otherwise so you can test the result - for example return Json(true) or return Json(null), then in the script if(data) { alert('updated'); } else { alert('oops'); }



回答2:

Don't put the script in the razor block, and as possible as put all script to the bottom of the page, in order to improve the page response well.



回答3:

I had to put script in the Details.cshtml which is master View to the _Survey1.cshtml(Partial View). Also putting this script in Details.csthml caused that server tried to execute it when I went to Details.cshtml(before even I clicked a button) causing runtime error:

$('.mybutton').click(function() {
  var pid = $(this).data('personid');
  var sid = $(this).data('surveyid');
  var url = '@UrlAction("SubmitSurvey", "Person")';
  $.post(url, { personid: pid, surveyid: sid }, function(data) {
    alert('updated');
  });
});

So I changed it to:

  function SubmitClick(pid, sid) {     
        var url = '@Url.Action("SubmitSurvey", "Person")';
        $.post(url, { personid: pid, surveyid: sid }, function (data) {
            alert('updated' + pid + " " + sid);
        });
    }

I had to add parameters because without them pid and sid were undefined, even though data-personid="@Model.Item1.Id" data-surveyid="@survey.Id" where defined in the button.

The button looks like:

  <button class='mybutton' type='button' onclick="javascript:SubmitClick(@Model.Item1.Id, @survey.Id.);" >Click Me</button>