0

ユーザーが事前選択のチェックを外し、その状態をポストスルーオブジェクトにcheckbox保存できるフォームで作業するAJAXJSONControllerASP.Net MVC

ここに画像の説明を入力

要件:

  1. 事前に選択されたチェックボックスをオフにすると、データベース プロパティの行が "Active" = 'Y' から "Active=" = 'N' に変更されます。
  2. 新しく選択されたチェックボックスは、データベースに完全に新しい行を作成します

問題:

  1. 選択したテキスト ボックスのチェックを外した後、モデルは で更新されませんVIEW。したがって、サーバー側のデータは更新されません。AJAXデータが呼び出しに解析される前に、クライアント側の更新が必要です。
  2. チェックボックスの値の変更をキャプチャしてモデルに渡す方法がわからないため、解析されたデータをボタンのクリック/送信フォームに変更できます。
  3. 次のコードでも、送信時に dataType が間違っていると思われるため、エラー 200 が返されます (ここでボタン送信を実行します)。

意見:

@model List<DashboardPermissionTool.ViewModels.UserViewModel>
@using (@Html.BeginForm(new { id = "UserForm" }))
{
<table class="table">
    <tr>
        <th>User</th>
        @for (int i = 0; i < Model[0].Roles.Count; i++)
        {
            <th>
                @Model[0].Roles[i].RoleName
            </th>
        }
    </tr>
    @for (int i = 0; i < Model.Count; i++)
    {
        <tr>
            <td>
                @Html.HiddenFor(m => m[i].UserName)
                @Model[i].UserName
            </td>
            @for (int j = 0; j < Model[i].Roles.Count; j++)
            {
                <td>
                    @Html.CheckBoxFor(m => m[i].Roles[j].IsSelected)
                </td>
            }
        </tr>
    }
</table>

<div class="form-actions">
    <a id="SubmitUserRoles" class="btn btn-success submit" value="Save">Save changes</a>
</div>

<script>

    var parsedData = @Html.Raw( new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(Model));

    $(document).ready(function() {
        $("#SubmitUserRoles").click(function () {

            $('input[type=checkbox]').on("change",function(){
                if($(this).prop('checked'))
                {
                    $(this).attr('checked', false); 
                }
                else
                {
                    $(this).attr('checked', true); 
                }                  
            });

              $.ajax({
                url: '@Url.Action("Create", "User")',
                type: 'POST',
                contentType: 'application/json; charset=utf-8',
                cache: false,
                dataType: 'json',
                data: JSON.stringify(parsedData),
                success: function (data) {
                    console.log(data);
                }, error: function (xhr, ajaxOptions, error) {
                    alert(xhr.status);
                    alert("Error: " + xhr.responseText);
                }
            });
        });
    });
</script>

}

HTML 応答: :選択されたチェック ボックスごとの応答は次のとおりです。

<td>
     <input checked="checked" data-val="true" data-val-required="The IsSelected field is required." name="[0].Roles[0].IsSelected" type="checkbox" value="true" />
     <input name="[0].Roles[0].IsSelected" type="hidden" value="false" />
</td>

チェックされていないチェックボックスごとの応答は次のとおりです。

<td>
    <input data-val="true" data-val-required="The IsSelected field is required." name="[0].Roles[1].IsSelected" type="checkbox" value="true" />
    <input name="[0].Roles[1].IsSelected" type="hidden" value="false" />
</td>

ビューモデル:

public class UserViewModel
{
    public string UserName { get; set; }
    public List<RoleViewModel> Roles { get; set; }
}

public class RoleViewModel
{
    public string RoleName { get; set; } 
    public bool IsSelected { get; set; } 
}

コントローラ:

[HttpPost]
    public ActionResult Create(List<UserViewModel> model)
    {

        for (int i = 0; i < model.Count; i++)
        {
            for (int j = 0; j < model[i].Roles.Count; j++)
            {
                db.User.Add(new User
                {
                    username = model[i].UserName,
                    role = model[i].Roles[j].RoleName
                });                  
            }

            db.SaveChanges();
            return RedirectToAction("Index", "User");
        }
        return View("Index", model);
    }
4

1 に答える 1

1

コードには複数の問題があります。

コントローラーメソッドから始めてreturn、外側のforループ内にステートメントがあります。これは、最初の値のみを保存してUserViewModelからメソッドを終了することを意味します。すべてのレコードを保存するには、

[HttpPost]
public ActionResult Create(List<UserViewModel> model)
{
    for (int i = 0; i < model.Count; i++)
    {
        for (int j = 0; j < model[i].Roles.Count; j++)
        {
            db.User.Add(new User { username = model[i].UserName, role = model[i].Roles[j].RoleName });                  
        }
    }
    db.SaveChanges();
    return RedirectToAction("Index", "User");
}

ただし、このメソッドから明らかなようにIndex()、レコードを保存した後にメソッドにリダイレクトする必要があるため、ajax を使用してデータを送信しても意味がありません (ajax 呼び出しは同じページにとどまり、リダイレクトされません)。通常の送信を使用する必要があります。ボタンをクリックしてフォームを送信します (そしてすべてのスクリプトを削除します)。変更する必要があります

<a id="SubmitUserRoles" class="btn btn-success submit" value="Save">Save changes</a>

<input type="submit" class="btn btn-success submit" value="Save" />

また、要素valueの有効な属性ではないことにも注意してください。<a>

しかし、コードの他の問題に対処するために、同じページに留まり、DOM を更新したいと仮定しましょう。

初め

var parsedData = @Html.Raw( new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(Model));

(代わりに単に使用できますvar parsedData = @Html.Raw(Json.Encode(Model)))元のモデルをシリアル化するため、編集された値ではなく、元の値をポストバックするだけです。編集した値を渡すには、ajax オプションを次のようにする必要があります。

data: $('form').serialize(),

contentType: 'application/json; charset=utf-8',

データをjsonとして送信することを意味しますが、データを文字列化していません。それはする必要があります

data: JSON.stringify($('form').serialize()),

バインドする必要がありますが、それは不要でありcontentType、デフォルトを使用するようにオプションを削除するだけで済みます'application/x-www-form-urlencoded; charset=UTF-8'

dataType: 'json',

メソッドがjsonを返すように指定していることを意味しますが、実際にはhtmlを返すため、例外がスローされます。dataType: 'html',オプションを削除するか、単に削除する必要があり、ajax メソッドで解決できます。

$("#SubmitUserRoles").click(function () { ... }また、スクリプトを削除する必要があります。checked属性が存在するということは、それが選択されていることを意味し、またはすべてchecked="checked"がまったく同じことを意味します - チェックボックスが選択されているということです。幸いなことに、例外をスローするハンドラー内にハンドラーを追加するだけなので、そのコードが実行されることはありません (実行された場合、すべてが台無しになります) 。checked="true"check="false"checked="anything"$("#SubmitUserRoles").click(function () {

ついに

@using (@Html.BeginForm(new { id = "UserForm" }))

ルート値を追加していidます(生成したhtmlを見ると、表示されますaction="../Create/UserForm"(またはaction="../Create?id=UserForm"ルートに応じて(そしてメソッドにはパラメーターがありません))。タグに属性をstring id追加すると思います。その場合、そのacceptのオーバーロードの1 つを使用する必要があります.ただし、css または javascript セレクターで使用する属性を追加する必要があるだけなので、単に使用できますid<form>BeginForm()htmlAttributesid

@using (@Html.BeginForm())
于 2016-10-24T23:49:58.553 に答える