We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date

CRUD on simple Master with Details grid

new to MVC and to you Grid control, sorry for silly questions and thanks in advance for any help.

Edit is working but don't understand how to return back Master data to the view after insert, it should return with id keys compiled, as they are assigned server side.

Master/Details entities are: Recipe (only Description field) and Ingredients (Description, Calories, Fat, Carb., ...), data is on Azure Table Storage, ids are PartitionKey/RowKey determined server side.

RecipeController has a common CreateEdit.vbhtml view, presenting both entities data (Recipe description plus Ingredients grid) with hidden pk/rk as they don't make sense to the user (GUID/UtcNow.Ticks...)
I can separate Create and Edit views if needed...

CreateEdit view is called from main Index, it is explicitly bound to Master/Recipe model:  @ModelType Recipe

Presenting data through separate Forms, Master/Recipe:

    <div>
    @Using Html.BeginForm
        @<fieldset>
        <legend>RECIPE</legend>
            <p>
                @Html.HiddenFor(Function(Model) Model.PartitionKey)
                @Html.HiddenFor(Function(Model) Model.RowKey)
           </p>
             <p>
                 @Html.LabelFor(Function(Model) Model.Description)
                 @Html.EJ().MaskEditTextBoxFor(Function(Model) Model.Description).MaskFormat("").InputMode(InputMode.Text)
             </p>
        </fieldset>
    End Using
    </div>

And Details/Ingredients grid:

    <div>
        @Using Html.BeginForm
            @<fieldset>
                <legend>INGREDIENTS</legend>
                 <div class="col-md-9 ptiles">
                     @Html.EJ().Grid(Of Ingredient)("Grid").Datasource......
                    ................
                    ds.URL(Url.Action("IngredientsDataSource", "Recipe", Nothing, Request.Url.Scheme)).BatchURL(Url.Content("BatchSave")).Adaptor(AdaptorType.UrlAdaptor)
                                        .................
                    .EditSettings......
                                                ep.AllowEditing(True).AllowAdding(True).AllowDeleting(True).EditMode(EditMode.Batch).ShowConfirmDialog()
                                ......................................
                        .Columns(Sub(column)
                            column.Field(Function(obj) (obj.PartitionKey)).HeaderText(Html.DisplayNameFor(Function(obj) (obj.PartitionKey)).ToString).IsPrimaryKey(True).Visible(False).Add()
                            column.Field(Function(obj) (obj.RowKey)).HeaderText(Html.DisplayNameFor(Function(obj) (obj.RowKey)).ToString).IsPrimaryKey(True).Visible(False).Add()
                            column.Field(Function(obj) (obj.Description)).Type("string").EditType(EditingType.String).Add()
                            column.Field(Function(obj) (obj.Calories)).Type("number").EditType(EditingType.Numeric).DefaultValue(0).Add()
                                                        ...........
                    .ClientSideEvents(Function(events) (events.ActionBegin("actionBegin").ActionComplete("actionComplete")))
                 </div>
            </fieldset>
        End Using
    </div>

Following your suggestions from an older post I'm appending Master form value before sending grid form value to controller, intercepting ajaxSend.
By the way, i'm forcing url parameter passing pk/rk to "IngredientsDataSource" but I guess this is the wrong place??

$(document).ajaxSend(function (event, xhr, opt) {
    var description = $("#Description").ejMaskEdit("get_StrippedValue");
    var data = JSON.parse(opt.data);
    data.Form = [{ PartitionKey: '@Model.PartitionKey', RowKey: '@Model.RowKey', Description: description }];

    //This is not needed for BatchSave controller method, as it receives master form data...
    opt.url += "?pk=" + '@Model.PartitionKey' + "&rkRecipe=" + '@Model.RowKey';

    opt.data = JSON.stringify(data)
})

Controller's datasource:

        Function IngredientsDataSource(ByVal pk As String, rkRecipe As String) As ActionResult
            Dim list As New List(Of Ingredient)
            If Not String.IsNullOrEmpty(rkRecipe) Then
                 'Reading ingredients children matching with Recipe pk/rk...
                 '...........................    
            End If

            Dim result As New BatchDataResult
            result.result = list
            result.count = list.Count
            Return Json(result, JsonRequestBehavior.AllowGet)
        End Function

Controller's batch save:

        <HttpPost()>
        Function BatchSave(ByVal changed As List(Of Ingredient), ByVal added As List(Of Ingredient),
                             ByVal deleted As List(Of Ingredient), ByVal Form As List(Of Recipe)) As ActionResult

            Try

                  'CRUD works fine, business logic sets new pk/rk and both entities are correctly updated/created
                  ............

                Dim list = db.Table("Recipe").ExecuteQuery(Of Ingredient)(query).ToList

                Return Json(list, JsonRequestBehavior.AllowGet)

            Catch ex As Exception
                Return Nothing
            End Try
        End Function

returning from BatchSave after creating a new Recipe and its Ingredients the view still has old Master/Recipe model, still without pk/rk...
I'd like not to use ViewData/ViewBag objects if possible as view is already bound to Model...
Not sure if what I'm doing, asking and assumig makes sense...any suggestion will be much appreciated!

5 Replies

MF Mohammed Farook J Syncfusion Team January 17, 2017 06:58 AM UTC

Hi Macro, 

Thanks for contacting syncfusion supports. 

Based requirement and we already discussed in UG documents. Please find the link 




Regards, 
J. Mohammed Farook 



CR croma January 17, 2017 07:33 AM UTC

Hi Mohammed, thank you for your reply.

Unfortunately I'm not able to get any suggestion from provided link, as my main question/problem was

1. "don't understand how to return back Master data to the view after insert, it should return with id keys compiled, as they are assigned server side".

Btw linked documentation shows controller's batch update action with an additional parameter ("int? key") but I can't see any razor/js code to pass that parameter...
Anyway that's not relevant because I'm successfully passing first Form data (Recipe=Master) to controller BatchSave action intercepting ajaxSend, as shown in my post code:

    var description = $("#Description").ejMaskEdit("get_StrippedValue");
    var data = JSON.parse(opt.data);
    data.Form = [{ PartitionKey: '@Model.PartitionKey', RowKey: '@Model.RowKey', Description: description }];
    opt.data = JSON.stringify(data)

View is bound to Master/Recipe Model, BatchSave action returns Detail/Ingredients rows, BatchSave code assigns both entities Id and master/detail foreign key logic (TableStorage PartitionKey/RowKey). How can I 'refresh' view Master entity after creation, getting the object completed with key ids compiled server side?



RU Ragavee U S Syncfusion Team January 19, 2017 12:50 PM UTC

Hi Marco, 

We understand your requirement as follows. 

Having a form and a grid. The dataSource for the grid is bound based on the form value. So, upon inserting a new record to the grid, the master data also to be passed to the controller. In the controller, you have updated the primary key values of the grid data and thus need to get the updated data at the client side once the batch save action completes. 

If your requirement is different from the above explained scenario, please get back with more details. 

Regards, 
Ragavee U S. 



CR croma January 19, 2017 01:37 PM UTC

i Ragavee, thank you for your patience.

Well...quite correct but maybe not exactly, or I'm missing something, sorry for my poor english, I hope to explain better:

Problem is with 1 view/1 controller:
View is bound to MASTER model, meaning that razor begins with: @ModelType Recipe
Inside view there are 2 separate, non nested, divs both with BeginForm/Fieldset as you can see in my first message.
Div1 contains MASTER fields (Description and keys)
Div2 contains DETAIL Ingredients grid, getting data (through UrlAdaptor) from action "IngredientsDataSource" of Recipe controller, there details data is filtered by Recipe keys and returned back correctly as grid datasource.
Editing mode is batch, Grid save button calls Recipe controller's "BatchSave" action, passing also Div1 Form data (Master/Recipe entity) as you can see looking at my ajaxSend.

I use same view for Create and Edit
Editing an existing Recipe always works because I already have master Recipe keys: adding one new detail Ingredient to the list and passing Recipe Form data to controller I'm able to set Detail/Ingredient keys and foreign matching inside controller's BatchSave action code, so far so good.

When I create a new master Recipe with (say) one detail Ingredient obviously I have empty keys.
Hitting save the view again sends grid data plus master form data (without keys) and calls controller's BatchSave action, where I assign keys and foreign matching on my entities, saving storage data works well.
The action returns Json detail Ingredients list BUT how can I transmit back to the view MASTER Recipe entity changed with keys assigned server side?



RU Ragavee U S Syncfusion Team January 20, 2017 12:20 PM UTC

Hi Marco,  

We considered this query “Update Master table on adding new record in child table” as a custom sample request and a support incident has been created under your account to track the status of this. Please log on to our support website to check for further updates.

https://www.syncfusion.com/account/login?ReturnUrl=/support/directtrac/incidents    

Regards,  
Ragavee U S.  


Loader.
Up arrow icon