Adding Multiple Rows At Once

4 posts, 0 answers
  1. Roland
    Roland avatar
    4 posts
    Member since:
    Oct 2017

    Posted 27 Apr 2018 Link to this post

    Hello,

    I am using a TreeList to allow users to configure a Question and Answer tree.  The user needs to be able to add a question row, then a list of potential answers (these are multiple choice questions) and then under each answer add a follow up question that should be asked in the event that that answer is selected.  

    Ideally, when a user creates a new question row, he would be presented with 3 or 4 editable rows - the top one intended to be the text of the question and then the additional rows to supply the answer choices for that question so that he can add questions AND answers with just one operation.  So my first question is whether this is possible at all in TreeList (my attempts to call addRow() multiple times have not been successful).  

    If giving the user multiple editable rows all at once is not an option, then the second-best thing would be to automatically create some "default" answers in the database (I am using a remote datasource with this TreeList) and then upon the Create operation completing, show the new question they've added to the list as well as the two default answer rows below it.  I have attempted this as well - when the transport Create operation is called, 3 new records are created in the database (the latter two records having a "parent" value of the ID of the first one), and I am returning JSON containing all 3 rows.  The new question row then shows on the TreeList, but the new answers do not get added.  I can collapse and re-expand the tree, but they still do not show up until I refresh the page and the TreeList loads from scratch again.  So my second question is is it possible to have one transport create operation add multiple rows to the tree and have them be displayed immediately upon completion of the operation.  

     

    Thank you.

  2. Alex Hajigeorgieva
    Admin
    Alex Hajigeorgieva avatar
    1054 posts

    Posted 01 May 2018 Link to this post

    Hello, Roland,

    Thank you for the concise explanation of your scenario. 

    Unfortunately, the Kendo UI TreeList does not support batch operations out of the box. It is a highly upvoted feature request in our UserVoice portal. Please add your vote to it as well. The most popular items are put forward to the planning of future implementations:

    http://kendoui-feedback.telerik.com/forums/127393-kendo-ui-feedback/suggestions/7122151-treelist-batch-editing

    As far as the question at hand is concerned, I trust these are the options that you have:

    1) Using a Kendo UI Grid with hierarchy and batch editing of the child grids. We have an example that shows a similar scenario

    https://docs.telerik.com/kendo-ui/controls/data-management/grid/how-to/Editing/edit-master-row-data-in-detail-template

    2) Custom implementation of editing with own custom UI. This is also applicable to the questions that you have. I tested with one of our demos and was able to create two records simultaneously with one request. Calling the data source sync() method at the end will refresh the Kendo UI TreeList. Perhaps, one way of implementing that would be with custom command buttons which can bring up a custom popup with inputs. 

    https://dojo.telerik.com/@bubblemaster/eLoPUZuz

    $("#add").click(function(){
      treelist.dataSource.insert({FirstName: "Jane",LastName:"Doe", Position:"Unknown", ReportsTo:null});
      treelist.dataSource.insert({FirstName: "John",LastName:"Doe", Position:"Unknown", ReportsTo:null});
      treelist.dataSource.sync();     
    });

    Let me know what you think.

    Kind Regards,
    Alex Hajigeorgieva
    Progress Telerik
    Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  3. Roland
    Roland avatar
    4 posts
    Member since:
    Oct 2017

    Posted 01 May 2018 in reply to Alex Hajigeorgieva Link to this post

    Hi Alex, 

     

    Thank you for getting back to me.  

    I wasn't sure where I should perform the dataSource.insert() and dataSource.sync() calls.  I assume it has to be after the transport calls complete, so I changed my dataSource from a remote (wherein each transport operation just specified the URL of the webservice and I used parameterMap to send the appropriate data) to a local datasource, where each transport operation performs an AJAX call to that same webservice.  I then added the insert() and sync() call to the success callback for that AJAX call so my code looks as follows:

    create: function(options) {
       //some code removed here that sets some variables to pass to the webservice
       $.ajax(
       {
           url: "thewebserviceurl",
           data:  {parameter1: parameter1value, parameter2: parameter2value}
           },
           error: function(request, error) {
               console.log(error);
           },
           success: function (response) {
               try {
                   var results = JSON.parse(response);
                   var treelist = $("#treelist").data("kendoTreeList");
                   $.each(results,  function( i, result ) {
                     treelist.dataSource.insert(result);
                   });
                   treelist.dataSource.sync();
               }
               catch (e) {
                   console.log(e);
               }
           }
       });
    }

     

    Once parsed, the JSON returned by the AJAX call will be an array of 3 records which, to use the schema in your example, would look like the below - notice that the IDs are specified in my schema because the records have already been added to the database.  Notice also how the latter 2 rows report to the ID of the first row: 

    {id:101, FirstName: "New", LastName:"Boss", ReportsTo:null}
    {id:102, FirstName: "New", LastName:"Subordinate1", ReportsTo:101}
    {id:103, FirstName: "New", LastName:"Subordinate1", ReportsTo:101}

    My required result is that a new row be added at the root level of the TreeList for "New Boss" and that the 2 rows for the New Subordinates be immediately displayed nested underneath "New Boss". 

    But the actual result is that all 3 rows are added, non-nested, at the top level of the treelist.  Once the operation completes, if I refresh the page with the Treelist on it, the hierarchy all comes up as desired.  But I need this to happen without the page refresh, and for the user to then be free to add new subordinates to "New Boss" or even to the New Subordinates via this same process. 

    Am I doing something wrong that is keeping the records inserted into the datasource from honoring their parent and being drawn in the tree correctly?  Or is this unsupported functionality?

  4. Alex Hajigeorgieva
    Admin
    Alex Hajigeorgieva avatar
    1054 posts

    Posted 03 May 2018 Link to this post

    Hello, Roland,

    Yes, batch editing for the Kendo UI TreeList is still not supported out of the box. However, I believe that you may achieve the requirement programmatically with the help of the data source API. I believe the issue with the provided snippet is the timing and that the create function of the data source does not notify it's success(e.success(result)):

    https://docs.telerik.com/kendo-ui/framework/datasource/crud#create-local

    I seem to have found a solution which allows you to create the "Boss" item, sync the data source, then at the requestEnd event of that dataSource obtain the newly assigned Id and finally, push the desired subordinates. The only downside is that it needs to be executed a little later because we need to make sure the data source has triggered its change event and the "Boss" item is part of it already. This will solve the problem with the subordinates appearing at the root level:

    $("#add").click(function(){
      treelist.dataSource.insert(0,{FirstName: "Boss",LastName:"Doe", Position:"Boss", ReportsTo:null});
      treelist.dataSource.sync();
    });        
     requestEnd: function(e){
       var ds = e.sender;
       if(e.type === "create" && e.response.length === 1){
        var bossId = e.response[0].EmployeeId;
         setTimeout(function(){
           ds.insert({ FirstName: "Subordinate FirstName1", LastName: "Subordinate LastName1", ReportsTo:bossId  });
           ds.insert({ FirstName: "Subordinate FirstName2", LastName: "Subordinate LastName2", ReportsTo:bossId  });
           ds.sync();
         });
       }           
     }

    https://dojo.telerik.com/IFUdoXoY

    Kind Regards,
    Alex Hajigeorgieva
    Progress Telerik
    Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Back to Top