简体   繁体   English

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

[英]pass @Html.EditorFor “Date” value back to Controller, manipulate value and pass back to view to populate Dropdown list

I have the following MVC application, see front-end below: 我有以下MVC应用程序,请参见下面的前端:

FinanceMVC屏幕-前端

"Invoice Date Created" is a html5 compatable datepicker based on the following method: “发票日期已创建”是基于html5的兼容日期选择器,其基于以下方法:

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

My requirement on screen load is the following: 我对屏幕加载的要求如下:

1) On datepicker "onSelect" of date and textbox updates, I need to pass this value eg 2014/11/19 and manipulate it to be in the format of yyyymm (eg 201411). 1)在日期选择器“ onSelect”的日期和文本框更新上,我需要传递此值(例如2014/11/19)并将其操纵为yyyymm格式(例如201411)。 There's a catch. 有一个陷阱。 It needs to be able create such a value for the current period, as well as the previous period. 它需要能够为当前期间以及上一个期间创建这样的值。

So, 2014/11/19 should populate "Invoice Number Period" Dropdown list with two options namely: 因此,2014/11/19应该在“发票编号期间”下拉列表中填充两个选项,即:

201411 (for current period) 201411 (当前期间)
201410 (for previous period) 201410 (上期)

Is there a way I can pass this date 2014/11/19 eg back to my controller where I can do the manipulation and return 201411 and 201410 back to my dropdown list? 有什么方法可以将日期2014/11/19传递回我的控制器,在那里我可以进行操作并将201411和201410返回到我的下拉列表? Or am I thinking about this the wrong way? 还是我在想这是错误的方式? I have read plenty of Javascript articles but none do exactly what I need to do. 我已经阅读了很多Javascript文章,但没有一篇完全符合我的需要。 How and what is the best way to go about this? 最好的方式和方法是什么?

I am an MVC and Javascript newby, so struggeling to get my head around this one.. 我是MVC和Javascript的新手,因此努力争取这一点。

Edit - Here is my code: 编辑-这是我的代码:

Finance.cshtml : 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 (Model): 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 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();
        }
    }
}

You can do this client side using jquery without the need to call the server. 您可以使用jquery进行此客户端操作,而无需调用服务器。 Since you have multiple rows, you will need to give your controls a class name so they can be selected, for example 由于您有多行,因此需要为控件提供一个类名,以便可以选择它们,例如

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

and add the following scripts 并添加以下脚本

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));
});

If you want to call controller from javascript, you can use ajax post function. 如果要从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);
        }
    });

EDIT: 编辑:

For anyone using MVC 5 and not MVC 5.1, keep reading and find workaround below. 对于使用MVC 5而非MVC 5.1的任何人,请继续阅读并在下面找到解决方法。 For anyone using MVC 5.1, please see @StephenMuecke 's answer, as this works for 5.1. 对于使用MVC 5.1的任何人,请参见@StephenMuecke的答案,因为它适用于5.1。

Original Post: 原始帖子:

Credits to @StephenMuecke, I have found a solution in case someone else struggles with the same 归功于@StephenMuecke,我发现了一个解决方案,以防其他人为此感到困扰

thing. 事情。 Here is my complete explanation and code below. 这是我下面的完整解释和代码。

Some posts suggested using TextBoxFor instead, but this breaks the Default html5 datepicker . 有些帖子建议改用TextBoxFor ,但这会破坏Default html5 datepicker

Basically, our application is a blank MVC 5 application (Visual Studio 2012 with Web Installer) which 基本上,我们的应用程序是一个空白的MVC 5应用程序(带有Web Installer的Visual Studio 2012),

poses the problem that the EditorFor control does not accept htmlattributes as parameters. 带来了一个问题,即EditorFor控件不接受html属性作为参数。 Please

see link(s) below: 请参阅下面的链接:

MVC5 and Bootstrap3: Html.EditorFor wrong class? MVC5和Bootstrap3:Html.Editor对于错误的类? How to change? 如何改变?

Asp.net MVC5 with Bootstrap EditorFor size 带Bootstrap编辑器的Asp.net MVC5

Is there a solution for using ASP.NET MVC 5 Html.EditorFor() and Bootstrap 3.0? 是否有使用ASP.NET MVC 5 Html.EditorFor()和Bootstrap 3.0的解决方案?

From the above, MVC 5.1 has this functionality. 综上所述,MVC 5.1具有此功能。 Anyone using MVC 5 will not be able to add the @class attribute like below: 使用MVC 5的任何人将无法添加@class属性,如下所示:

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

Instead I used the following workaround mentioned below: 相反,我使用了下面提到的以下解决方法:

Change id attribute of an html.editorfor helper in MVC4 with Razor 使用Razor在MVC4中更改html.editorfor帮助程序的id属性

and this is the result: 结果是:

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

If we look in Chrome (thanks again Stephen), this results in the code: 如果我们使用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" />

As we can see this renders the control with an id attribute now which we can use in our jQuery, see below: 如我们所见,这将呈现一个具有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>

And it works perfectly now. 现在,它可以完美运行。 Not sure if its the most elegant solution or how far it rates up the "best practice" list, but it works. 不知道它是否是最优雅的解决方案,还是它在“最佳实践”列表中的排名有多高,但这是可行的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 MVC,如何将TextBoxFor值传递给Controller Action并将结果写回视图 - MVC, How to pass TextBoxFor value to Controller Action and write result back to view 将值从 JS 传递给 HTML,然后使用该值传回 JS - Passing value from JS to HTML and then using that value to pass back to JS 将返回值传递回循环 - Pass return value back to loop 将变量值传递回控制器的angularJs方法是什么? - What is the angularJs way to pass variable value back to controller 如何将值从HTML传递到Javascript,然后再传递回HTML? - How to pass a value from HTML to Javascript and back to HTML? 如何将数据传递到控制器并返回到Angular中的视图? - How to pass data to controller and back to the view in Angular? 如何将模型从视图传递到控制器,将项目添加到列表,传递回视图 - How to pass Model from View to Controller, add items to list, pass back to view 传递级联下拉列表项Web控制器的文本值 - Pass Text Value of cascading dropdown list item web controller 当用户单击文本输入框时如何在@Html.EditorFor() 中显示下拉列表 - How to show dropdown list in the @Html.EditorFor() when user clicks on the text input box 从html下拉列表中获取值,以传递到javascript函数 - Grab value from html dropdown list, to pass into javascript function
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM