1

I am new to MVC and trying to implement a dynamic table for a Course-Class structure. CourseCode will be a value coming from the previous form, and the dynamic table will contain all the classes related to that particular CourseCode. My problem is, I have to take CourseCode in one column compulsorily (because my model is a list type model which has all four fields). However, I am not able to display the value of the viewbag in my subsequent CourseCode textfields after the initial row. It is due to this line "$trNew.find("input").val("");" I believe, but I need the new row to give me ClassCode, CLassName and Promotion fields blank but the CourseCode should be a textbox containing viewbag CourseCode value by default. Although when I debug the script, the value for the newly added blank textboxes for CourseCode is set to the viewbag value but the textbox is blank in my view. I want the textbox to show the CourseCode by default when a row is added and the other three textboxes should be blank.

This is my model :

public partial class CourseClass
    {          

        [Key]
        [Column(Order = 0)]
        public string CourseCode { get; set; }
        [Key]
        [Column(Order = 1)]
        public string ClassCode { get; set; }
        public string ClassName { get; set; }
        public string Promotion{ get; set; }

        public virtual Course course{ get; set; }
        public virtual ICollection<Subject> subjects{ get; set; }
    }

This is my Controller :

        [HttpGet]
        public ActionResult BIndexed(string CourseCode)
        {
            // This is only for show by default one row for insert data to the database
            ViewBag.CourseCode= CourseCode;
            List<CourseClass> ci = new List<CourseClass> { new CourseClass{ CourseCode= CourseCode, ClassCode= "", ClassName= "", Promotion= "" } };
            return View(ci);     
        }



    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult BIndexed(List<CourseClass> ci)
    {
        if (ModelState.IsValid)
        {                
                foreach (var i in ci)
                {
                    db.Class.Add(i);
                }
                db.SaveChanges();                   
                ModelState.Clear();
                return RedirectToAction("Index");                   
        }
        return View(ci);
    }

This is my view :

<table id="dataTable" border="0" cellpadding="0" cellspacing="0">

            <tr>
                <th style="display:none;>Course Code</th>
                <th>Class Code</th>
                <th>Class Name</th>
                <th>Promotion</th>
                <th></th>

            </tr>

            @if (Model != null && Model.Count > 0)
            {
                int j = 0;
                foreach (var i in Model)
                {
                    <tr style="border:1px solid black">


                        <td>@Html.TextBoxFor(a => a[j].CourseCode,(string)@ViewBag.CourseCode)</td>
                        <td>@Html.TextBoxFor(a => a[j].ClassCode)</td>
                        <td>@Html.TextBoxFor(a => a[j].ClassName)</td>
                        <td>@Html.TextBoxFor(a => a[j].Promotion)</td>
                        <td>
                            @if (j > 0)
                            {
                                <a href="#" class="remove">Remove</a>
                            }
                        </td>
                    </tr> 
                    j++;                        
                }
            }

    </table>

This is the script :

$(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);

            var j = parseInt(suffix) + 1;

            //Replaced value
            $trNew.find("input").val("");
            $("#U_CCODE").attr('value','@ViewBag.U_CCode');
           }

            // 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
    $(document).on("click", "a.remove", function (e) {
        e.preventDefault();
        $(this).parent().parent().remove();
    });

});

Any help on this will be appreciated. Thanks!

Poonam
  • 153
  • 1
  • 12
  • You should not be cloning the last row. Instead create a template to clone. See the answers [here](http://stackoverflow.com/questions/29161481/post-a-form-array-without-successful/29161796#29161796) and [here](http://stackoverflow.com/questions/28019793/submit-same-partial-view-called-multiple-times-data-to-controller/28081308#28081308). And you `ViewBag` property is not required an its just `@Html.TextBoxFor(a => a[j].CourseCode)` –  May 04 '16 at 11:00
  • And you do not even need that textbox at all if you were to do this the right way and use a view model. –  May 04 '16 at 11:04

0 Answers0