将@Html.EditorFor“Date”值传递回Controller,操纵值并传回视图以填充下拉列表

时间:2014-11-18 10:59:24

标签: javascript c# asp.net-mvc asp.net-mvc-5

我有以下MVC应用程序,请参阅下面的前端:

FinanceMVC screen - front-end

“已创建发票日期”是基于以下方法的html5兼容日期选择器:

http://www.aubrett.com/InformationTechnology/WebDevelopment/MVC/DatePickerMVC5.aspx

我对屏幕加载的要求如下:

1)在日期和文本框更新的datepicker“onSelect”上,我需要传递此值,例如2014/11/19并将其操纵为yyyymm格式(例如201411)。有一个问题。它需要能够为当前时期以及前一时期创建这样的值。

因此,2014/11/19应填写“发票编号期间”下拉列表,其中包含两个选项:

201411 (本期)
201410 (上一期)

我有没有办法通过这个日期2014/11/19,例如回到我的控制器,在那里我可以进行操作并将201411和201410返回到我的下拉列表中?或者我是否以错误的方式思考这个问题?我已经阅读了大量的Javascript文章,但没有一篇完全符合我的要求。如何以及最好的方法是什么?

我是一个MVC和Javascript newby,所以我很想知道这个......

编辑 - 这是我的代码:

Finance.cshtml

@model List<FinanceMVC.Models.FinanceViewModel>
@{
    ViewBag.Title = "Index";
}

@using (Html.BeginForm("Finance", "Finance", FormMethod.Post, new { @class = "form-horizontal" }))
{
    <div class="col-md-1 fade in" style="margin-left: 5%; width: 100%; font-size: 11px; height: auto;">
        <div id="div_Finance_Container" style="width: 100%; height: 80%; overflow: auto; text-align: left;" runat="server" class="scroll-pane">
            <div style="height: 500px; overflow: auto;">
                <div><a href="#" id="addNew" class="add-another-cat smallest">Add New</a></div>
                <table id="dataTable" border="0">
                    <tr>
                        <th>Invoice Type</th>
                        <th>Invoice Number</th>
                        <th>Invoice Number Period</th>
                        <th>Invoice Date Created</th>
                        <th></th>
                    </tr>
                    @if (Model != null && Model.Count > 0)
                    {
                        int j = 0;
                        foreach (var i in Model)
                        {
                        <tr>
                            <td>
                                <div class="col-md-1" style="width: 20%;">
                                    <select name="ddlInvoiceType">
                                        @foreach (var item in Model)
                                        {
                                            foreach(var bItem in item.InvoiceType)
                                            {
                                                <option value="@bItem.Description">@bItem.Description</option>
                                            }
                                        }
                                    </select>
                                </div>
                            </td>
                            <td>@Html.TextBoxFor(a => a[j].InvoiceNumber)</td>
                            <td>@Html.TextBoxFor(a => a[j].InvoiceNumberPeriod)</td>
                            <td>@Html.EditorFor(a => a[j].InvoiceDateCreated)</td>
                            <td>
                                @if (j > 0)
                                {
                                    <a href="#" class="remove">Remove</a>
                                }       
                            </td>
                        </tr>
                                j++;
                        }
                    }
                </table>
                <input type="submit" value="Save Bulk Data" />
            </div>
        </div>
    </div>
} 


@section Scripts{
@Scripts.Render("~/bundles/jqueryval")

<script language="javascript">
    $(function () {
        $(document).on('change', '#InvoiceDateCreated', function () {
            alert($(this).val());
        });
    });
</script>

<script type="text/javascript">
    $(document).ready(function () {
        $('#[0].InvoiceDateCreated').change(function () {
            $('#[0].InvoiceDateCreated').text('sam');
        });
    });
</script>

<script language="javascript">
    $(document).ready(function () {

        //1. Add new row
        $("#addNew").click(function (e) {
            e.preventDefault();
            var $tableBody = $("#dataTable");
            var $trLast = $tableBody.find("tr:last");
            var $trNew = $trLast.clone();

            var suffix = $trNew.find(':input:first').attr('name').match(/\d+/);
            $trNew.find("td:last").html('<a href="#" class="remove">Remove</a>');
            $.each($trNew.find(':input'), function (i, val) {
                // Replaced Name
                var oldN = $(this).attr('name');
                var newN = oldN.replace('[' + suffix + ']', '[' + (parseInt(suffix) + 1) + ']');
                $(this).attr('name', newN);
                //Replaced value
                var type = $(this).attr('type');
                if (type.toLowerCase() == "text") {
                    $(this).attr('value', '');
                }

                // If you have another Type then replace with default value
                $(this).removeClass("input-validation-error");
            });
            $trLast.after($trNew);

            // Re-assign Validation 
            var form = $("form")
                .removeData("validator")
                .removeData("unobtrusiveValidation");
            $.validator.unobtrusive.parse(form);
        });

        // 2. Remove 
        $('a.remove').live("click", function (e) {
            e.preventDefault();
            $(this).parent().parent().remove();
        });

    });
</script>
}

Finance.cs (型号):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;

namespace FinanceMVC.Models
{
    //public class Finance
    //{

    //}

    public partial class FinanceViewModel
    {
        /*ID*/
        [Required]
        [Display(Name = "ID")]
        public int ID { get; set; }

        /*BINL_BIND_ID*/
        [Required]
        [Display(Name = "Invoice Type")]
        //public int InvoiceType { get; set; }
        public List<C_InvoiceType> InvoiceType { get; set; }

        /*BINL_Inv_Num_Pointer*/
        [Required]
        [Display(Name = "Invoice Number")]
        public char InvoiceNumber { get; set; }

        /*BINL_Inv_Num_Period*/
        [Required]
        [Display(Name = "Invoice Number Period")]
        public int InvoiceNumberPeriod { get; set; }

        /*BINL_Created*/
        [Display(Name = "Invoice Created Date")]
        [Required]
        [DataType(DataType.DateTime)]
        public DateTime InvoiceDateCreated { get; set; }

        /*BINL_SystemInserted*/
        [Required]
        [Display(Name = "Invoice System Inserted")]
        public bool InvoiceSystemInserted { get; set; }


    }

    public class C_InvoiceType
    {
        public int ID { get; set; }
        public string Description { get; set; }
    }
}

FinanceController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using FinanceMVC.Models;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;

namespace FinanceMVC.Controllers
{
    public class FinanceController : Controller
    {
        public ActionResult Finance()
        {
            FinanceViewModel FVM = new FinanceViewModel();

            // This is only for show by default one row for insert data to the database
            List<FinanceViewModel> FinanceViewList = new List<FinanceViewModel> 
            { 
                new FinanceViewModel 
                { 
                    ID = 0 , InvoiceType = ReturnInvoiceType(), InvoiceNumber = '\0', InvoiceNumberPeriod = 0, InvoiceDateCreated = DateTime.Now, InvoiceSystemInserted = false 
                } 
            };

            return View(FinanceViewList);
        }

        // 
        // GET: /Finance/ 

        /*Matches file name of Finance.cshtml*/
        [HttpPost]
        public ActionResult Finance(List<FinanceViewModel> model)
        {
            if (ModelState.IsValid)
            {

            }

            return View(model);
        }

        // 
        // GET: /Finance/Welcome/ 

        public string Welcome()
        {
            return "This is the Welcome action method...";
        }

        public static List<C_InvoiceType> ReturnInvoiceType()
        {
            string sQ = ""
                       + " Select ID, BIND_Description \n"
                       + " From Biller_InvoiceNum_DefSet with(nolock) \n"
                       ;
            try
            {
                using (SqlConnection sCon = new SqlConnection(Application_Info.sMOB_Master_Conn()))
                {
                    if (sCon.State != ConnectionState.Open)
                    {
                        sCon.Open();
                    }

                    using (SqlCommand sCmd = new SqlCommand(sQ, sCon))
                    {
                        using (SqlDataReader sRdr = sCmd.ExecuteReader())
                        {
                            List<C_InvoiceType> list_InvoiceType = new List<C_InvoiceType>();
                            while (sRdr.Read())
                            {
                                list_InvoiceType.Add(new C_InvoiceType
                                {
                                    ID = (int)sRdr["ID"],
                                    Description = (string)sRdr["BIND_Description"]
                                });
                            }
                            return list_InvoiceType;
                        }
                    }
                }
            }
            catch
            {

            }

            return ReturnInvoiceType();
        }
    }
}

3 个答案:

答案 0 :(得分:2)

您可以使用jquery执行此客户端,而无需调用服务器。由于您有多行,因此您需要为控件指定一个类名,以便可以选择它们,例如

@Html.EditorFor(a => a[j].InvoiceDateCreated, new { htmlAttributes = new { @class = "InvoiceDateCreated" }})

并添加以下脚本

function padLeft(nr, n, str) {
  return Array(n - String(nr).length + 1).join(str || '0') + nr;
}

$('.InvoiceDateCreated').change(function () {
  var row = $(this).closest('tr');
  var date = new Date($(this).val());
  var currentMonth = date.getFullYear().toString() + padLeft(date.getMonth() + 1, 2);
  date.setMonth(date.getMonth() - 1);
  var previousMonth = date.getFullYear().toString() + padLeft(date.getMonth() + 1, 2);
  var select = row.find('.InvoiceNumberPeriod').empty();
  select.append($('<option></option>').val(currentMonth).text(currentMonth));
  select.append($('<option></option>').val(previousMonth).text(previousMonth));
});

答案 1 :(得分:1)

如果你想从javascript调用控制器,你可以使用ajax post函数。

    $.ajax({
        type: "POST",
        url: "Finance/Finance",
        dataType: "json",
        data: {
           // pass in some data
        },
        success: function (results) {
            // do something (or nothing) with the returned data
        },
        error: function (e) {
            alert(e.status + " - " + e.statusText);
        }
    });

答案 2 :(得分:1)

修改

对于使用MVC 5而非MVC 5.1的任何人,请继续阅读并找到下面的解决方法。对于使用MVC 5.1的任何人,请参阅@StephenMuecke的回答,因为这适用于5.1。

原帖:

致@StephenMuecke的信用,我找到了一个解决方案,以防其他人与同样的人挣扎

的事情。以下是我的完整解释和代码。

有些帖子建议使用 TextBoxFor ,但这会破坏默认html5 datepicker

基本上,我们的应用程序是一个空白的MVC 5应用程序(带有Web安装程序的Visual Studio 2012)

引发了 EditorFor 控件不接受htmlattributes作为参数的问题。请

请参阅以下链接:

MVC5 and Bootstrap3: Html.EditorFor wrong class? How to change?

Asp.net MVC5 with Bootstrap EditorFor size

Is there a solution for using ASP.NET MVC 5 Html.EditorFor() and Bootstrap 3.0?

从上面可以看出,MVC 5.1具有此功能。任何使用MVC 5的人都无法添加@class属性,如下所示:

@Html.EditorFor(a => a[j].InvoiceDateCreated, new { htmlAttributes = new { @class = "InvoiceDateCreated" }})

相反,我使用了下面提到的解决方法:

Change id attribute of an html.editorfor helper in MVC4 with Razor

这就是结果:

@Html.EditorFor(a => a[j].InvoiceDateCreated, null, "ID")

如果我们查看Chrome(再次感谢Stephen),则会产生以下代码:

<input class="form-control datecontrol" data-val="true" data-val-date="The field Invoice Created Date must be a date." data-val-required="The Invoice Created Date field is required." id="myID" name="myID" type="date" value="2014/11/19" />

正如我们所看到的,现在使用id属性呈现控件,我们可以在jQuery中使用它,见下文:

<script>
    function padLeft(nr, n, str) {
        return Array(n - String(nr).length + 1).join(str || '0') + nr;
    }

    $('#myID').change(function () {
        var row = $(this).closest('tr');
        var date = new Date($(this).val());
        var currentMonth = date.getFullYear().toString() + padLeft(date.getMonth() + 1, 2);
        date.setMonth(date.getMonth() - 1);
        var previousMonth = date.getFullYear().toString() + padLeft(date.getMonth() + 1, 2);
        var select = row.find('#InvoiceNumberPeriod').empty();
        select.append($('<option></option>').val(currentMonth).text(currentMonth));
        select.append($('<option></option>').val(previousMonth).text(previousMonth));
    });
</script>

现在它完美无缺。不确定它是否是最优雅的解决方案或它在多大程度上评价“最佳实践”列表,但它确实有效。