iT邦幫忙

0

.net core mvc 和 Bootstrap Model 的問題.

請教各位先進二個問題..
1.我使用 Bootstrap Model 寫了一個 PartialView 並在其中寫了 JavaScript 當我驗證失敗反應原本的 PartialView 後 我所寫的 JavaScript 就無法執行了。但是當第一次顯示時是可以正常執行的。
我可以如何修正這個問題?
2.在 Bootstrap Model 中採用 ajax POST 到 Controller 其他類型的資料都沒有問題可以找得到值,但是只有 SelectListItem 的表單元件為Null

ajax

var PlaceHolderElement = $('#PlaceHolderHere');
PlaceHolderElement.on('click', '[data-save="modal"]', function (event) {

        var form = $(this).parents('.modal').find('form');
        var actionUrl = form.attr('action');
        var sendData = new FormData(form.get(0));
        console.log(sendData);
        $.ajax({
            url: actionUrl,
            method: 'post',
            data: sendData,
            processData: false,
            //contentType:"application/json; charset=utf-8",
            contentType: false,
            cache: false,
            success: function (redata) {
                if (redata.status === "success") {
                    //新增成功則關掉視窗
                    PlaceHolderElement.find('.modal').modal('hide');
                    //顯示資料成功新增的訊息
                    var notificationsPlaceholder = $('#notification');
                    var notificationsUrl = notificationsPlaceholder.data('url');
                    $.get(notificationsUrl).done(function (notifications) {
                        notificationsPlaceholder.html(notifications);
                    });
                    //自動關閉訊息
                    setTimeout(function () {
                        $(".alert").alert('close');
                    }, 3000);
                    //重析整理資料
                    //Click the query to use refresh to process the refresh parameters
                    $('#table').bootstrapTable('refresh');
                }
                else {
                    var newBody = $('.modal-body', redata);
                    PlaceHolderElement.find('.modal-body').replaceWith(newBody);
                }
            },
            error: function (message) {
                alert(message);
            }
        })


    })

問題1--View

@model WebERP.Models.EIP.Roles
<!-- Modal -->
<div class="modal fade" id="AddEditRoles" tabindex="-1">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="AddEditRolesLabel">新增角色資料</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">×</span>
                </button>
            </div>

            <div class="modal-body">
                <form asp-action="Create" id="Edit" enctype="multipart/form-data">
                    @Html.AntiForgeryToken()
                    <div asp-validation-summary="All" class="text-danger"></div>

                    <div class="input-group">
                        <span class="input-group-text">@Html.DisplayNameFor(m => m.ID)</span>
                        @if (Model.ID != null)
                        {
                            <input asp-for="ID" class="form-control" readonly />
                        }
                        else
                        {
                            <input asp-for="ID" class="form-control" autocomplete="off" />
                        }
                        <span asp-validation-for="ID" class="text-danger"></span>
                    </div>
                    <div class="input-group">
                        <span class="input-group-text">@Html.DisplayNameFor(m => m.Title)</span>
                        <input type="text" asp-for="Title" class="form-control" autocomplete="off" />
                        <span asp-validation-for="Title" class="text-danger"></span>
                    </div>
                    <div class="input-group">
                        <span class="input-group-text">@Html.DisplayNameFor(m => m.CompanyCode)</span>
                        <input type="text" asp-for="CompanyCode" class="form-control col-md-3" readonly>
                        <input type="text" id="CompanyName" class="form-control"
                               placeholder="請輸入統編或公司名關鍵字"
                               data-url="@Url.Action("GetCompanyByAutoComplete", "Company")"
                               autocomplete="off" />
                        <span asp-validation-for="CompanyCode" class="text-danger"></span>
                    </div>
                    <div class="input-group">
                        <span class="input-group-text">@Html.DisplayNameFor(m => m.BossID)</span>
                        <input type="text" asp-for="BossID" class="form-control col-md-3" readonly />
                        <input id="BossName" class="form-control" type="text"
                               placeholder="請輸入中文或英文名關鍵字。"
                               autocomplete="off" />
                        <span asp-validation-for="BossID" class="text-danger"></span>
                    </div>
                    <div class="input-group">
                        <span class="input-group-text">@Html.DisplayNameFor(m => m.DepartmentCode)</span>
                        <input type="text" asp-for="DepartmentCode" class="form-control col-md-3" readonly />
                        <input id="DepartmentName" class="form-control" type="text"
                               placeholder="請輸入代碼或部門名關鍵字。"
                               autocomplete="off" />
                        <span asp-validation-for="DepartmentCode" class="text-danger"></span>
                    </div>
                    <div class="input-group">
                        <span class="input-group-text">@Html.DisplayNameFor(m => m.isVirtualGroup)</span>
                        <input asp-for="isVirtualGroup" class="form-control" autocomplete="off" />
                        <span asp-validation-for="isVirtualGroup" class="text-danger"></span>
                    </div>
                    <div id="GroupRoles" class="input-group">
                        <span class="input-group-text">@Html.DisplayNameFor(m => m.ListRoles)</span>
                        <button class="btn" type="button" id="AddRolesGroup">增加角色</button>
                        <button class="btn" type="button" id="Clear">清除所有</button>
                        <span asp-validation-for="ListRoles" class="text-danger"></span>
                    </div>
                    <div id="area">
                        <select id="EmpSelect" class="form-select col-md-12" size="8"
                                multiple aria-label="multiple select Employee">
                            <option selected>請選擇要放入選組的角色</option>
                        </select>
                        <button class="btn" type="button" id="ClearSelect">清除所選角色</button>
                        <select asp-for="ListRolesItem" class="form-select col-md-12" size="8"
                                multiple aria-label="ListRolesItem">
                        </select>
                    </div>
                    <div asp-validation-summary="All" class="text-danger"></div>
                </form>
            </div>

            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                <button type="button" class="btn btn-primary" data-save="modal">Save changes</button>
            </div>
        </div>
    </div>
</div>

<script src="~/bootstrap-autocomplete/dist/latest/bootstrap-autocomplete.min.js"></script>
$('#CompanyName').autoComplete({
        minLength: 2,
        formatResult: function (item) {
            return {
                value: item.value,
                text: "[" + item.value + "] " + item.text,
                /*html: "<h6 style=color:blue>" + item.value + "</h6>  " + item.text*/
            }
        }
    });
    $('#CompanyName').on('autocomplete.select', function (evt, item) {
        console.log(item);
        $('#CompanyCode').val(item.value);
        $('#CompanyName').val(item.text);
    });

問題1、2--Controller

[HttpPost]
        public async Task<IActionResult> CreateAsync(Roles roles)
        {
            if (ModelState.IsValid)
            {
                RolesService service = new();
                Roles r = await service.GetCompanyRolesAsync(roles.CompanyCode,roles.ID);
                if(r == null)
                {
                    roles.Modifier = User.Identity.Name;
                    roles.ModifierTime = DateTime.Now;

                    if (await service.AddRolesDataAsync(roles))
                    {
                        Success("資料新增成功");
                        return Json(new { status = "success" });
                    }
                    else
                    {
                        ModelState.AddModelError("error", "新增資料失敗");
                        return View("_Edit", roles);
                    }
                }

            }
            ModelState.AddModelError("error", "表單驗証錯誤");
            return View("_Edit", roles);
        }

問題2--Model

[ModelMetadataType(typeof(RolesMD))]
    public partial class Roles
    {
        public IEnumerable<SelectListItem> ListRolesItem { get; set; }
    }

問題1https://ithelp.ithome.com.tw/upload/images/20210907/20117228vNCIAdfl5i.png
問題2
https://ithelp.ithome.com.tw/upload/images/20210907/20117228wW2pRpuOfB.pnghttps://ithelp.ithome.com.tw/upload/images/20210907/20117228JhDpYF5bNy.png

Homura iT邦高手 1 級 ‧ 2021-09-07 17:27:01 檢舉
Code用程式碼區塊貼上不要用貼圖
還有Code完整點才看得出問題
Miels1122 iT邦新手 5 級 ‧ 2021-09-07 18:07:08 檢舉
您好己更新。下次提問時會注意.

2 個回答

0
horace_work
iT邦新手 5 級 ‧ 2021-09-07 17:47:07

第一個問題 程式不夠完整,上面有大大提醒了
第二個問題 Select的 Tag Helper 需要有 asp-for="" asp-items="",
這兩個,但我也不確定你有沒有,因為你提供的圖檔住一部分

看更多先前的回應...收起先前的回應...
Miels1122 iT邦新手 5 級 ‧ 2021-09-07 18:07:57 檢舉

您好.
沒有 asp-items 這個 Tag.
目前正在測試是否能把值接回來.

Miels1122 iT邦新手 5 級 ‧ 2021-09-07 18:17:27 檢舉

己把 asp-items 加到 View 中了..但是還是無法把資料接回 Controller 中....

我決定直接找官方範例給你
相關連結

Miels1122 iT邦新手 5 級 ‧ 2021-09-08 10:35:23 檢舉

您好。感謝提供。
我在您提到 asp-items 時有去看過..
也把他加進去了...

<div id="area">
                        <select id="EmpSelect" class="form-select col-md-12" size="8"
                                multiple aria-label="EmpSelect">
                        </select>
                        <button class="btn" type="button" id="ClearSelect">清除所選角色</button>
                        <select asp-for="RolesList" asp-items="@Model.RolesList" class="form-select col-md-12" size="8"
                                multiple aria-label="RolesList">
                        </select>
                    </div>

但是在使用 ajax 送出時卻沒有包含在內...目前不知道為什麼.

Homura iT邦高手 1 級 ‧ 2021-09-08 10:55:12 檢舉

Miels1122
我看資料asp-item這屬性不需要加@
你要不要參考一下

Miels1122 iT邦新手 5 級 ‧ 2021-09-08 10:59:07 檢舉

@@" 忘了拿掉...
拿掉後也有試過..也是沒有資料回傳.

Homura iT邦高手 1 級 ‧ 2021-09-08 11:16:30 檢舉

Miels1122
給一個Name屬性呢?

Miels1122 iT邦新手 5 級 ‧ 2021-09-08 14:43:34 檢舉

有試過了...一樣取不到回傳的資料。
等會全部重寫試試.
如果不行就只能想其他的方式來取得我要的資料了

Select的範例 我簡單寫一下,看起來可以正常取值 你可以再研究一下

model

    public class CountryViewModel
    {
        public string Country { get; set; }
        public List<string> Countrys { get; set; }
        public List<SelectListItem> Countries { get; set; }
    }

cshtml

@model CountryViewModel

<form asp-controller="Home" asp-action="Index" method="post">
    <select asp-for="Countrys" asp-items="Model.Countries" multiple></select>
    <br />
    <button type="submit">Register</button>
</form>

controller

        public IActionResult Index()
        {
            var Countries = new List<SelectListItem>
                            {
                                new SelectListItem { Value = "MX", Text = "Mexico" },
                                new SelectListItem { Value = "CA", Text = "Canada" },
                                new SelectListItem { Value = "US", Text = "USA"  },
                            };
            var model = new CountryViewModel()
            {
                Countries = Countries,
                Country = "CA",
            };
            return View(model);
        }
        
          [HttpPost]
        [ValidateAntiForgeryToken]
        public IActionResult Index(CountryViewModel model)
        {
            if (ModelState.IsValid)
            {
                var msg = model.Country + " selected";
                return RedirectToAction("IndexSuccess", new { message = msg });
            }
            return View(model);
        }      

https://ithelp.ithome.com.tw/upload/images/20210908/20138525lnwopOUSO0.jpg

關於問題一的部分我有稍微看一下
首先是我看到你綁定事件是在 id:PlaceHolderHere這個element上,
但是我在你提供的相關的程式頁面找不到,所以我不清楚你那部分的情況,第二個部分是[HttpPost]CreateAsync這個裡面出現了兩種回傳型態,一下是view一下是json,第一次看到混搭的部分,簡單猜測一下有可能的問題是,事件綁定,因為你說第一次可以,第二次不行,你可以用Edge 偵錯模式確認一下事件綁定還存不存在,有可能因為return view 刷新html導致事件綁定失效,我說的綁定部分就是

var PlaceHolderElement = $('#PlaceHolderHere');
PlaceHolderElement.on('click', '[data-save="modal"]', function (event)

補充一下驗證部分相關文件
教學文件
官方教學

Miels1122 iT邦新手 5 級 ‧ 2021-09-08 22:19:30 檢舉

感謝您的耐心查看.
id:PlaceHolderHere這個element 在主畫面中,算是一個佔位的 Div 內容.
因為並沒有太多的程式碼...所以忘了放上來了..抱歉..內容如下
<div id="PlaceHolderHere" data-url="@Url.Action("Create")"></div>

目前由於對 Partial View 還不是很了解.所以就按照我自己的需求看著硬作了.
感謝您提供的連結.
立馬來看看...

0

問題二

有確認過你的js中sendData內容嗎?
按你前端寫的post應該是沒啥問題,除非源頭sendData就不完整了


另外內容和標題有些錯誤
Bootstrap中使用的是Modal而非Model哦

看更多先前的回應...收起先前的回應...
Miels1122 iT邦新手 5 級 ‧ 2021-09-08 10:11:15 檢舉

您好..標題的部分我會再注意...感謝.
另外...請教要如何查看 SendData 的內容?
我剛才使用 Edge 查看送出的內容時發現..並沒有包含我所需要的那個 欄位名稱...

Miels1122 iT邦新手 5 級 ‧ 2021-09-08 11:10:32 檢舉

https://ithelp.ithome.com.tw/upload/images/20210908/20117228OGn70joVAQ.png
這是我看到的畫面。就是找不到我所需要的 SelectListItem 元件的資料

是說,SelectList你要傳的是,所選值的內容? 還是整個List傳去POST~我不知道整個傳有什麼作用....

如果只是傳值,Model內的型別怎麼會是整個SelectListItem ? 應該只是值的型別,無論string或int等等...

Miels1122 iT邦新手 5 級 ‧ 2021-09-08 22:13:27 檢舉

感謝回答...
我的想法比較笨一點...
想由一個 SelectlistItem 由使用者進行選取..並將選好的值 Pass 給第二個 SelectListItem。並存放第二個的內容到 DB 中.
所以才會這樣做...不過今天又想想..可以不需要這樣來處理才對.就像您說的存值就好..

我不確定你這樣做是否可行,因我不認為前端這樣拋出去,後端會看得懂此型別。可試試單純傳值作法,然後兩個SelectListItem分別可改用後端Action,ViewBag回去取得。不過若你能成功傳SelectListItem也可再分享出來~ 剩下交給其他大大

我要發表回答

立即登入回答