Master-Detail form

Hi,

I trying to add master-detail functionality but I don't know what I'm doing wrong, when I do click on button save I expected that it redirect to controller  for to process the master and detail data but I cannot. I attach the files that I am using.

Thanks,

Attachment: MasterDetail_2659f540.rar

10 Replies

RR Rajapandi Ravi Syncfusion Team April 6, 2020 12:13 PM UTC

Hi Daniel, 

Greetings from syncfusion support 

Based on your query we suspect you like to use Maser-detail Grid, so we have prepared a sample with master-detail Grid for your reference. We have achieved the master-detail Grid by using the “RowSelected” event of Grid. In the RowSelected event, we are updating the detail Grid based on the EmployeeID (primary key) value of the master Grid. Please refer the below code example and sample for more information. 

<div>  
    <B>Master Grid</B>  
    @Html.EJS().Grid("Grid").DataSource((IEnumerable<object>)ViewBag.dataSource).Width("auto").SelectedRowIndex(0).Columns(col =>  
        {  
            col.Field("EmployeeID").HeaderText("EmployeeID").IsPrimaryKey(true).Add();  
            ...  
        }).RowSelected("selected").Render()  
</div>  
<div>  
    <B>Child Grid</B>  
    @Html.EJS().Grid("Grid1").DataSource((IEnumerable<object>)ViewBag.dataSource1).Columns(col =>  
                {  
                    col.Field("EmployeeID").HeaderText("EmployeeID").IsPrimaryKey(true).Add();  
                    ...  
                }).Render()  
</div>  
<script>  
    function selected(args) {  
        var data = @Html.Raw(Json.Encode(ViewBag.datasource));  
        var employeeID = args.data.EmployeeID;  
        var detaildata = new ej.data.DataManager(data).executeLocal(new ej.data.Query().where("EmployeeID""equal", employeeID, false).take(10));  
        var grid = document.getElementById("Grid1").ej2_instances[0];  
        grid.dataSource = new ej.data.DataManager(detaildata.slice(0, 5)).dataSource.json;  
    }  
</script>  
 

From checking your provided view page, we found in your save button click event you are getting the Grid instances like EJ1 Grid. Please refer the below code example for more information. 

 
function btnClick(args) { 
                var grid = $("#DataGrid").ejGrid("instance");    //This is  the EJ1 grid instance 
                grid.batchSave(); 
            } 

And we found you are using BatchURL in Grid Normal edit mode. In normal editing, it will not triggers any method about the Batch. Please refer your below code example for more information. 

 
@Html.EJS().Grid("DataGrid").DataSource(dataManager => { dataManager.Url(@Url.Action("UrlDatasource", "AirQuote")).BatchUrl("BatchUpdate").Adaptor("UrlAdaptor"); }).Columns(col => 
                         { 
                  .   .    .    .    .    .   .   . 
                  .   .     .    .    .     .    .    .                                   
}).EditSettings(e => { e.AllowAdding(true).AllowEditing(true).AllowDeleting(true).Mode(Syncfusion.EJ2.Grids.EditMode.Normal); }).AllowPaging().PageSettings(page => page.PageCount(2)).Toolbar(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" }).Render() 

If you want to use normal edit mode please follow the below documentation for more information. 


If you want to use Batch edit mode. Please follow the below documentation for more information. 


Before we start proceed solution on this query, Please share the below details that will be helpful for us to provide better solution. 

  1. Please confirm you are trying to use a EJ1 or EJ2 Grid.
  2. Please share your exact requirement scenario with detailed expectation.
  3. Share the details about why you render the Grid inside a BeginForm.

Regards, 
Rajapandi R 



DA Daniel April 6, 2020 04:12 PM UTC

Hi Rajapandi R,

I have a couple input textbox field and one grid. The input controls are in one form and grid is another form, I want when I do click on button save, those information (input controls and grid) process in controller and save it.

In the first post I attached my files, you can see if you want it for a bigger idea.

I am using EJS controls.

@section ControlsSection{
   

       

           

Quote


       

        @using (Html.BeginForm())
        {
            @*Input Control*@
           


                @Html.EJS().TextBox("CODE").Placeholder("Code").FloatLabelType(FloatLabelType.Auto).Render()
           


           


                @Html.EJS().TextBox("REFERENCE").Placeholder("Reference").FloatLabelType(FloatLabelType.Auto).Render()
           


           


                @Html.EJS().DatePicker("DATE").Placeholder("Date").FloatLabelType(FloatLabelType.Auto).Render()
           


           


                @Html.EJS().DatePicker("TARGETDATE").Placeholder("Target Date").FloatLabelType(FloatLabelType.Auto).Render()
           


        }
       

            @using (Html.BeginForm())
            {
               

                    Add Service
                   


                        @*Render the grid controll*@
                        @Html.EJS().Grid("DataGrid").DataSource(dataManager => { dataManager.Url(@Url.Action("UrlDatasource", "AirQuote")).BatchUrl("BatchUpdate").Adaptor("UrlAdaptor"); }).Columns(col =>
                         {
                             col.Field("AIRQUOTE_HEADER_CODE").HeaderText("Code").IsPrimaryKey(true).Visible(false).AllowEditing(false).TextAlign(Syncfusion.EJ2.Grids.TextAlign.Right).Width("50").Add();
                             col.Field("ID").HeaderText("ID").TextAlign(Syncfusion.EJ2.Grids.TextAlign.Center).Width("250").ValidationRules(new { required = true }).Add();
                             col.Field("SERVICES_SERVICEID").HeaderText("Service ID").TextAlign(Syncfusion.EJ2.Grids.TextAlign.Center).Width("250").Add();
                             col.Field("SERVICECOST").HeaderText("Cost").TextAlign(Syncfusion.EJ2.Grids.TextAlign.Center).Width("100").Add();
                         }).EditSettings(e => { e.AllowAdding(true).AllowEditing(true).AllowDeleting(true).Mode(Syncfusion.EJ2.Grids.EditMode.Normal); }).AllowPaging().PageSettings(page => page.PageCount(2)).Toolbar(new List() { "Add", "Edit", "Delete", "Update", "Cancel" }).Render()

                   


               

            }
       


       


           

                @Html.EJS().Button("infobtn").Content("Save").CssClass("e-info").Click("btnClick").Render()
           

       

       
   

}

Controller
public class AirQuoteController : Controller
    {
        public ActionResult AirQuote()
        {
            return View();
        }

        public ActionResult BatchDataSource(DataManagerRequest dm)
        {
            IEnumerable DataSource = AirDetailRepository.GetAllRecords().ToList();
            BatchDataResult result = new BatchDataResult();
            DataOperations obj = new DataOperations();
            int count = DataSource.Cast().Count();
            if (dm.Skip != 0)
            {
                DataSource = obj.PerformSkip(DataSource, dm.Skip);
            }
            if (dm.Take != 0)
            {
                DataSource = obj.PerformTake(DataSource, dm.Take);
            }
            result.result = DataSource;
            return dm.RequiresCounts ? Json(new { result = DataSource, count = count }) : Json(DataSource);
        }

        public ActionResult BatchUpdate(List changed, List added, List deleted, List Form)
        {
            DevContext db = new DevContext();
            if (changed != null)
                AirDetailRepository.Update(changed);
            if (deleted != null)
                AirDetailRepository.Delete(deleted);
            if (added != null)
                AirDetailRepository.Add(added);
            if (Form != null)
                AirHeaderRepository.Add(Form);
            var data = AirDetailRepository.GetAllRecords();
            return Json(data, JsonRequestBehavior.AllowGet);
        }

        public class BatchDataResult
        {
            public IEnumerable result { get; set; }
            public int count { get; set; }
        }
    }





RR Rajapandi Ravi Syncfusion Team April 7, 2020 01:33 PM UTC

Hi Daniel, 

From checking your provided code example, we found you made a mistake by defining the Datasource url and Edit mode. Please refer your below code example for more information. 

In this below code example you are calling the batch url method but in editsettings you are defining the editmode as Normal. It was totally wrong. 

@Html.EJS().Grid("DataGrid").DataSource(dataManager => { dataManager.Url(@Url.Action("UrlDatasource", "AirQuote")).BatchUrl("BatchUpdate").Adaptor("UrlAdaptor"); }).Columns(col =>
                         {
                          .  .  .  .  .  .  .
                         }).EditSettings(e => { e.AllowAdding(true).AllowEditing(true).AllowDeleting(true).Mode(Syncfusion.EJ2.Grids.EditMode.Normal); }).AllowPaging().PageSettings(page => page.PageCount(2)).Toolbar(new List() { "Add", "Edit", "Delete", "Update", "Cancel" }).Render()
 

In this below code example you are calling the datasource method by defining wrong Url path. It was totally wrong. 

@Html.EJS().Grid("DataGrid").DataSource(dataManager => { dataManager.Url(@Url.Action("UrlDatasource", "AirQuote")).BatchUrl("BatchUpdate").Adaptor("UrlAdaptor"); }).Columns(col =>
                         {
                          .  .  .  .  .  .  .
                         }).EditSettings(e => { e.AllowAdding(true).AllowEditing(true).AllowDeleting(true).Mode(Syncfusion.EJ2.Grids.EditMode.Normal); }).AllowPaging().PageSettings(page => page.PageCount(2)).Toolbar(new List() { "Add", "Edit", "Delete", "Update", "Cancel" }).Render()
 

public class AirQuoteController : Controller 
    { 
        public ActionResult AirQuote() 
        { 
            return View(); 
        } 

        public ActionResult BatchDataSource(DataManagerRequest dm) 
        { 
            IEnumerable DataSource = AirDetailRepository.GetAllRecords().ToList(); 
            BatchDataResult result = new BatchDataResult(); 
            DataOperations obj = new DataOperations(); 
            int count = DataSource.Cast().Count(); 
            if (dm.Skip != 0) 
            { 
                DataSource = obj.PerformSkip(DataSource, dm.Skip); 
            } 
            if (dm.Take != 0) 
            { 
                DataSource = obj.PerformTake(DataSource, dm.Take); 
            } 
            result.result = DataSource; 
            return dm.RequiresCounts ? Json(new { result = DataSource, count = count }) : Json(DataSource); 
        } 

        public ActionResult BatchUpdate(List changed, List added, List deleted, List Form) 
        { 
            DevContext db = new DevContext(); 
            if (changed != null) 
                AirDetailRepository.Update(changed); 
            if (deleted != null) 
                AirDetailRepository.Delete(deleted); 
            if (added != null) 
                AirDetailRepository.Add(added); 
            if (Form != null) 
                AirHeaderRepository.Add(Form); 
            var data = AirDetailRepository.GetAllRecords(); 
            return Json(data, JsonRequestBehavior.AllowGet); 
        } 

        public class BatchDataResult 
        { 
            public IEnumerable result { get; set; } 
            public int count { get; set; } 
        } 
    } 

Based on your requirement we have prepared a sample of Grid with beginForm. In this below sample you can able to perform the CRUD operation which can be mapped to server-side Controller actions using the properties InsertUrl, RemoveUrl, UpdateUrl. Then when you try to save the form it will sends the post to the Action method at this time the page was reloaded because it was the default behavior of the BeginForm. So we suggest you to follow the documentation properly and implement the same in your application. Please refer the below sample and video demonstration for more information. 


Video demo:  

                              https://ej2.syncfusion.com/aspnetmvc/documentation/grid/edit/#batch-url 

If you still face the issue, Please share the following details 

  1. Please share your exact requirement scenario with detailed description
  2. Please confirm which of the edit mode you like to use Batch/Normal mode?

Regards, 
Rajapandi R 



RR Rajapandi Ravi Syncfusion Team April 7, 2020 03:44 PM UTC

Hi Daniel, 
 
We have missed to attach the Video demo link in our previous update. Please refer the below video demo for more information. 
 
 
Regards, 
Rajapandi R 



DA Daniel April 7, 2020 04:30 PM UTC

Hi Rajapandi R,

Thanks for your help, I share with you the following image:


I have the master table that contain code, reference, date and target date field and the detail table contain, code, id, serviceid and cost field. I would like that when I will do click on button save those fields save it in my database. Please if you can to see the files that attached in the first time, there are the files that I am using for this requirements.

Thanks,


RR Rajapandi Ravi Syncfusion Team April 8, 2020 02:16 PM UTC

Hi Daniel, 

Before we start providing solution on your query, we need more information to collect. Please share the below details that will be helpful for us to provide better solution. 

  1. From your screenshot we suspect after entering the value you want to save the values to the grid. So please confirm it was your requirement.
  2. Please confirm you have place the grid inside the form?

Regards, 
Rajapandi R 



DA Daniel replied to Rajapandi Ravi April 8, 2020 02:54 PM UTC

Hi Daniel, 

Before we start providing solution on your query, we need more information to collect. Please share the below details that will be helpful for us to provide better solution. 

  1. From your screenshot we suspect after entering the value you want to save the values to the grid. So please confirm it was your requirement.
  2. Please confirm you have place the grid inside the form?

Regards, 
Rajapandi R 


Hi,

  1. From your screenshot we suspect after entering the value you want to save the values to the grid. So please confirm it was your requirement
                         I want to save the data in their respective tables after click on button save, for example if you to see the image, I have 2 section Master and Detail, so the                                    master section must be save it in Master table in SQL and Detail section must be save it in Detail table in SQL.

                     2. Please confirm you have place the grid inside the form?
                         Yes, I have it.

Thanks,


RR Rajapandi Ravi Syncfusion Team April 9, 2020 01:12 PM UTC

Hi Daniel, 

From validating your query, we found you are try to submit the two forms in single button click. But by default we cannot able to submit the two forms in single button click. We have to submit only one form at the time of form submit. In your code example, you are place the grid inside the form. Inside the form you have to keep only the Input controls. But Grid is not a form component. Please refer the below documentation for information. 


If you want Grid inside the form, Please refer the below code example for more information. 

In this below code example, we have rendered the grid inside the form and prevent the default Grid action while saving the added record by using flag variable. Now you can able to save the added record only by button click. 

 
<div class="control-section"> 
    @using (Html.BeginForm()) 
    { 
    @Html.EJS().Grid("DefaultPaging").DataSource(ds => ds.Url("/Home/UrlDatasource").Adaptor("UrlAdaptor").InsertUrl("/Home/Insert").RemoveUrl("/Home/Remove").UpdateUrl("/Home/Update")).Columns(col => 
{ 
 
.  .  .  .  .  .  .  . 
 
}).Height("400").AllowPaging().Toolbar(new List<string> 
                () { "Add", "Edit", "Delete", "Cancel" }).AllowFiltering().FilterSettings(filter => filter.Type(Syncfusion.EJ2.Grids.FilterType.Menu)). ActionBegin("begin").EditSettings(edit => { edit.AllowEditing(true).AllowAdding(true).AllowDeleting(true); }).Render() 
    } 
 
</div> 
<div> 
    <button type="submit" onclick="btnClick()" value="Save" class="btn btn-primary">Save</button> 
</div> 
 
<script> 
    var flag = false; 
    function begin(args) { 
        if (args.requestType === "save" && args.action === "add" && flag == false) { 
            args.cancel = true; 
            flag = true; 
        } 
        else { 
            flag = false; 
            args.cancel = false; 
 
        } 
    } 
    function btnClick(args) {   //button click 
        var grid = document.getElementsByClassName('e-grid')[0].ej2_instances[0]; 
        grid.endEdit();        //It sends the post to the controller and saved in the database 
    } 
</script> 
 
 
 

If you want save the input control form values to the databased, for your reference we have prepared a sample. So we suggest you to follow the below way to achieve your requirement. Please refer the code example for more information. 

Index.cshtml 
 
@using (Html.BeginForm("FormPost", "Home", FormMethod.Post))  //this url helps to hit the server method with the form value 
{ 
    @Html.EJS().DatePicker("date").Placeholder("Date").Render() 
    @Html.EJS().TextBox("code").Placeholder("Code").Render() 
    @Html.EJS().Button("btn").Content("Save").Render() 
} 
 
 

HomeController.cs 
public class HomeController : Controller 
    { 
public static List<FormControls> formdata = new List<FormControls>(); 
public class FormControls 
        { 
            public int code { get; set; } 
            public DateTime date { get; set; } 
        } 
 
        [HttpPost] 
        public ActionResult FormPost(FormControls form)    
        { 
            var ins = form; 
            formdata.Insert(0, ins);   //it helps to update your record in your database 
       } 
} 
 


For your both queries we have prepared a sample and video demo.  Please refer the below sample and video demo for more information. 



Regards, 
Rajapandi R 



DA Daniel replied to Rajapandi Ravi April 16, 2020 02:37 AM UTC

Hi Daniel, 

From validating your query, we found you are try to submit the two forms in single button click. But by default we cannot able to submit the two forms in single button click. We have to submit only one form at the time of form submit. In your code example, you are place the grid inside the form. Inside the form you have to keep only the Input controls. But Grid is not a form component. Please refer the below documentation for information. 


If you want Grid inside the form, Please refer the below code example for more information. 

In this below code example, we have rendered the grid inside the form and prevent the default Grid action while saving the added record by using flag variable. Now you can able to save the added record only by button click. 

 
<div class="control-section"> 
    @using (Html.BeginForm()) 
    { 
    @Html.EJS().Grid("DefaultPaging").DataSource(ds => ds.Url("/Home/UrlDatasource").Adaptor("UrlAdaptor").InsertUrl("/Home/Insert").RemoveUrl("/Home/Remove").UpdateUrl("/Home/Update")).Columns(col => 
{ 
 
.  .  .  .  .  .  .  . 
 
}).Height("400").AllowPaging().Toolbar(new List<string> 
                () { "Add", "Edit", "Delete", "Cancel" }).AllowFiltering().FilterSettings(filter => filter.Type(Syncfusion.EJ2.Grids.FilterType.Menu)). ActionBegin("begin").EditSettings(edit => { edit.AllowEditing(true).AllowAdding(true).AllowDeleting(true); }).Render() 
    } 
 
div> 
<div> 
    <button type="submit" onclick="btnClick()" value="Save" class="btn btn-primary">Savebutton> 
div> 
 
<script> 
    var flag = false; 
    function begin(args) { 
        if (args.requestType === "save" && args.action === "add" && flag == false) { 
            args.cancel = true; 
            flag = true; 
        } 
        else { 
            flag = false; 
            args.cancel = false; 
 
        } 
    } 
    function btnClick(args) {   //button click 
        var grid = document.getElementsByClassName('e-grid')[0].ej2_instances[0]; 
        grid.endEdit();        //It sends the post to the controller and saved in the database 
    } 
script> 
 
 
 

If you want save the input control form values to the databased, for your reference we have prepared a sample. So we suggest you to follow the below way to achieve your requirement. Please refer the code example for more information. 

Index.cshtml 
 
@using (Html.BeginForm("FormPost", "Home", FormMethod.Post))  //this url helps to hit the server method with the form value 
{ 
    @Html.EJS().DatePicker("date").Placeholder("Date").Render() 
    @Html.EJS().TextBox("code").Placeholder("Code").Render() 
    @Html.EJS().Button("btn").Content("Save").Render() 
} 
 
 

HomeController.cs 
public class HomeController : Controller 
    { 
public static List formdata = new List(); 
public class FormControls 
        { 
            public int code { get; set; } 
            public DateTime date { get; set; } 
        } 
 
        [HttpPost] 
        public ActionResult FormPost(FormControls form)    
        { 
            var ins = form; 
            formdata.Insert(0, ins);   //it helps to update your record in your database 
       } 
} 
 


For your both queries we have prepared a sample and video demo.  Please refer the below sample and video demo for more information. 



Regards, 
Rajapandi R 


Hi Rajapandi,

I added two form because in this example they are using it: https://www.syncfusion.com/forums/119130/view-with-master-detail-entry-form
I just only need to send to controller both section(master/detail) with the same button, I tried to use that code but it is for EJ control, my requirement is very similar with this.

Thanks,


RR Rajapandi Ravi Syncfusion Team April 16, 2020 01:41 PM UTC

Hi Daniel,  

We have prepared a similar sample with the EJ2 controls based on your requirement. You can download it from the below link,  


Let us know if you have any concerns.  

Regards,  
Rajapandi R 


Loader.
Up arrow icon