Grouped View/Complex Datasource

4 posts, 0 answers
  1. Ashleigh L
    Ashleigh L avatar
    113 posts
    Member since:
    Jun 2012

    Posted 19 Jun 2015 Link to this post

    I've got a page that can be viewed in either a grouped or ungrouped view. I've attached screenshots of the two different views, for clarity.

    In both views, each tile is a course, which may or may not have a tag. In the grouped view, each course needs to be grouped under it's associated tag (with a group at the bottom for all untagged courses).

    Here's a sample of my template and associated function:

    <script id="tile_template" type="text/x-kendo-template">
        # if (data.GroupBy == 'Category') { #
        <!--- loop over the tags to create the headers --->
        <div class="list-items-group-content-area ui-layout-west k-widget k-listview">
            <div class="list-items-content-area-heading padding k-block">
                <h2>Group Header</h2>
            </div>
            <!--- then for each tag, loop over the courses, seeing if their tag value matches the parent, and if so, create the tile --->
        # } #
            <div class="col-xs-12 col-md-6 col-lg-4 course-content">
                <div class="k-block list-items">
                    <div class="course-type">
                        <i class="fa-icon-desktop"></i>
                    </div>
                    <div class="list-items-heading padding k-block">
                        <div class="list-items-heading-icons">
                            <a data-role="button" class="k-button info-button" role="button" aria-disabled="false" tabindex="0">
                                <i class="fa-icon-info-circle"></i>
                            </a>
                        </div>
                        <div class="list-items-heading-ellipsis">
                            <a>
                                <h3 class="item-title">#= data.Name #</h3>
                            </a>
                        </div>
                    </div>
                    <div class="padding list-items-body">
                        <div class="tile-img">
                            # if (data.Tag.length > 0) { #
                                <div class="tag-overlay"><i class="fa-icon-tag"></i>#= data.Tag #</div>
                            # } #
                            <img src="/image/#= data.Image #" class="img-responsive border-radius" />
                        </div>
                        # if (data.Due.length > 0) { #
                            <div class="date-overlay">
                                #= kendo.toString(kendo.parseDate(data.Due), 'dd-MMM-yyyy') #
                            </div>
                        # } #
                        <div class="progress-bar-div">
                            <input type="hidden" class="progress_value" value="#= data.Progress #">
                            <div class="progress-bar k-widget k-progressbar k-progressbar-horizontal" data-role="progressbar">
                                <div class="k-state-selected" style="width:#= data.Progress #%;">
                                    <span class="k-progress-status-wrap" style="width: 100%;"><span class="k-progress-status">#= data.Progress #%</span></span>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="padding list-items-footer k-block">
                        <a href="/launchcourse/index.cfm" class="btn btn-success">
                            <i class="fa-icon-play"></i>
                            <span class="hidden-xs">Continue</span>
                        </a>
                    </div>
                </div>
            </div>
        # if (data.GroupBy == 'Category') { #
        </div>
        # } #
    </script>

    function generateCourseView() {
        var template_html = $('#tile_template').html();
        var course_data = {};
     
        var template = kendo.template(template_html, {useWithBlock:false});
        var no_records_template = kendo.template($('#no_records_template').html());
     
        var datasource = new kendo.data.DataSource({
            transport: {
                read: {
                    type: "GET",
                    url: "/Controllers/MainController.cfc?method=getCourses",
                    processData: true,
                    dataType: "json"
                }          
            },
            schema : {
                type: "json",
                data: "Courses"
            }
        });
         
        datasource.bind("change", function() {
            var view = datasource.view();  
            var html = "";
             
            if (view.length) {
                //courses, render the tile template
                html = kendo.render(function(data) {   
                    return template($.extend(data, {GroupBy: group_by}));
                }, view);
            }
            else {
                //no courses, render the "no data" template
                html = no_records_template({});
            }
             
            $('#tile_display').html(html); 
        });
         
        datasource.read(); 
    }

    And the JSON returned from the function:

    {"Courses":[{"Due":"07\/15\/2015","Tag":"test","Name":"Enrolled (All Tasks)","Grade":"","Progress":29.0,"Image":"","ID":501292},{"Due":"10\/14\/2015","Tag":"","Name":"Enrolled (Expired Subscription)","Grade":"","Progress":0.0,"Image":"","ID":501386,},{"Due":"10\/14\/2015","Tag":"second tag","Name":"Enrolled (Expired Subscription)","Grade":"",Progress":0.0,"Image":"","ID":501385}]}

    So for each course I know the Tag they need to be displayed under, but I don't have the full list of tags to loop over and create the groups. And since I can't add a "Tags":[{}] section to the JSON returned from the function that populates the datasource, I'm at a bit of a loss as to how to accomplish this.

    I thought I might be able to use the solution provided to my last question (http://www.telerik.com/forums/pass-value-to-template-w-o-datasource), but that was adding a simple string to the datasource, not a full complex object. I'm also unsure how to structure that, even if it's possible - if the view is supposed to be grouped, do an AJAX call to get the tags and then append them to the datasource? How do I handle the render, since the call would (sometimes) be asynchronous? How would I access the tags in the template? data.Tags.Name?

    Any help you can provide would be appreciated, even if it's telling me I'm going in the complete wrong direction :)

  2. Rosen
    Admin
    Rosen avatar
    3234 posts

    Posted 23 Jun 2015 Link to this post

    Hello shimmoril,

    Maybe you could use the built-in grouping feature of the DataSource. You could use the group method to set the field on which the data should be grouped. The view method will return an array with the groups and the individual records as children (inside the items field). You should be able to modify the template appropriately to render the grouped items.

    Regards,
    Rosen
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
  3. Kendo UI is VS 2017 Ready
  4. Ashleigh L
    Ashleigh L avatar
    113 posts
    Member since:
    Jun 2012

    Posted 23 Jun 2015 in reply to Rosen Link to this post

    That looks pretty close to what I need! Couple of questions though:

    1. When setting up the data with my JSON, the name would map to the course name, and the category would map to the tag value, correct? And there's no special way to do this mapping (vs say the schema/model way, which I've used before).
    2. Looking at the example, it looks like I'd need to know the category in order to reference it in the template (ie. "beverages.items[0].name", where "beverages" is the category), so I think we're back to "how do I get the full list of tags so I can reference them in the template?"
    3. Can the datasource handle a record having an empty category? Not all courses have tags (and I'd want an "untagged" group displayed visually for these items)
    4. As noted in my question, the grouped view is an option, the user can also choose an ungrouped view. Will having the categories set on the datasource affect the ungrouped view in any way?

    I've tried to create a small sample of using the grouping in a template, but I can't see to even get the value of the group to display, never mind of the rest of it. Here's the link, and I've attached a saved version, in case that doesnt work. ​

  5. Rosen
    Admin
    Rosen avatar
    3234 posts

    Posted 24 Jun 2015 Link to this post

    Hello shimmoril,

    Straight to your questions:

    1. I'm not sure I understood your question. Please clarify.

    2. The data in the group view contains object which has information about the field on which data is grouped its value, the items in the group etc. Thus, you will could iterate the groups-items and show the information in the appropriate format. IN most cases there is not need to know the values of the group to do so.

    3. Data will be grouped by unique values of the given field. Therefore, the records which have empty string as a value will be grouped in a single group item.

    4. You should use the group method instead of setting initial group expression if conditionally grouping is required.

    Here you can find a modified version of the test page.

    Regards,
    Rosen
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
Back to Top
Kendo UI is VS 2017 Ready