View and Search Customization

Abstract

In this tutorial we'll learn to load referential records and will make changes in project appropriately.

Keywords: WindnTrees,CRUD,CRUDS,CRUD2CRUD,Search
  • Strategy

    To achieve tutorial objectives we'll use project from View & Referential Lists.

    We'll extend (or change):

    1. Knockout ("action") template view
    2. Script to take referential "search" input
    3. EntityRepository

    Knockout View Template

    Write or change knockout view (actions) template as below:

    <script type='text/html' id='actions'>
        <div class='col-sm-12 col-md-12 col-lg-12'>
            <div class='input-group'>
                <span class='input-group-prepend'><button data-bind='click: function() { resetForm(); }' class='btn btn-default' type='button'
    title='New' data-toggle='modal' data-target='#__form'><span>New</span></button></span>
                <input class='form-control' data-bind='value: Keyword' type='text' placeholder='Keyword' />
                <span class='input-group-append'>
                    <select data-bind="options: $root.CategoriesList, optionsText: 'key', optionsValue: 'val', value: $root.Category, 
    optionsCaption: 'select category'" title="Select Category" id="searchCategory" class="form-control col-12"></select>
                </span>
                <span class='input-group-append'>
                    <select data-bind="options: $root.SkillLevelsList, optionsText: 'key', optionsValue: 'val', value: $root.SkillLevel, 
    optionsCaption: 'select skill'" title="Select Skill" id="searchSkillLevel" class="form-control col-12"></select>
                </span>
                <span class='input-group-append'>
                    <button data-bind='click: function() { search(1); }' class='btn btn-default' type='button' 
    title='Search'><span>Search</span></button>
                </span>
            </div>
        </div>
    </script>
    
  • Extend WindnTrees View Script

    Extend CRUDView as following:

           //extend view with category and skilllevel observables
            view.getObserverObject().Category = ko.observable("");
            view.getObserverObject().SkillLevel = ko.observable("");
    
            //search method
            view.getObserverObject().search = function (listNumber) {
    
                view.getObserverObject().list({
                    //"query" lets user customize search parameters,
                    //programmers can send content, key, keys, keywords, options etc.
                    //using single query object.
                    query: {
                        keyword: view.getObserverObject().Keyword(),
                        size: view.getObserverObject().ListSize(),
                        page: listNumber,
                        'keys': [
                            { 'Field': 'category', 'Value': view.getObserverObject().Category() },
                            { 'Field': 'skill', 'Value': view.getObserverObject().SkillLevel() }
                        ]
                    }
                });
            };
    
    $(function () {
    
                try {
    
                    ko.applyBindings(view.getObserverObject(), document.getElementById('ko-node-element'));
                }
                catch (e) {
    
                    console.log(e.message);
                }
    
                //load fields
                view.LoadFields();
    
                //calls search with customized search input
                view.getObserverObject().search(1);
            });
    
  • Extend Repository

    Override or change EntityRepository QueryRecords as below:

    protected override IQueryable QueryRecords(IQueryable query, SearchFilter searchQuery = null) {
    
                Expression> condition = null;
                if (!string.IsNullOrEmpty(searchQuery.keyword))
                {
                    condition = l => (l.Subject.Contains(searchQuery.keyword) || 
    l.Description1.Contains(searchQuery.keyword) || 
    l.Description2.Contains(searchQuery.keyword));
                    query = query.Where(condition);
                }
    
                //check for reference keys
                if (searchQuery.keys != null)
                {
                    //find category
                    var category = searchQuery.keys.Where(l => l.Field == "category").SingleOrDefault();
                    if (category != null)
                    {
                        Nullable categoryId = null;
    
                        //check if reference value is selected
                        if (!string.IsNullOrEmpty(category.Value))
                        {
                            try
                            {
                                categoryId = Guid.Parse(category.Value);
                            }
                            catch { }
    
                            //optimize search
                            query = query.Where(l => l.CategoryId == categoryId);
                        }
                    }
    
                    //find skill
                    var skill = searchQuery.keys.Where(l => l.Field == "skill").SingleOrDefault();
                    if (skill != null)
                    {
                        Nullable skillId = null;
    
                        //check if reference value is selected
                        if (!string.IsNullOrEmpty(skill.Value))
                        {
                            try
                            {
                                skillId = Guid.Parse(skill.Value);
                            }
                            catch { }
    
                            //optimize search
                            query = query.Where(l => l.SkillLevelId == skillId);
                        }
                    }
                }
    
                return query;
            }
    
  • Summary

    WindnTrees CRUDS provide efficient means of loading, processing and displaying referential data. Download the complete project here.