JSFiddle - React, Tailwind, and code Playground

by ivanov_vitaly

HTML

<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.5/themes/base/jquery-ui.css">
<script src="http://knockoutjs.com/downloads/knockout-2.0.0.js"></script>
<div id="holder">
<ul id="filtersholder" data-bind='foreach: filters'>
    <li>
        <div class="filter-template">
            <input type="button" class="delete-filter" value="-"
                data-bind="click: function() { $root.removeFilter($data); }" />

            <select data-bind="options: $root.columns,                                
                               optionsValue: Column,
                               optionsText: 'Display',
                               value: ColumnObj">
            </select>

            <select class="opperator"
                data-bind="options: AvailableConditions, 
                           value: Condition">
            </select>
            
            <input type="text" data-bind="value: Value, datePicker: Type" />            

            <select style="width: 54px;" 
                data-bind="options: $root.nextFilterBinaryConditions,
                           value: NextFilterBinaryCondition">
            </select>

            <input type="button" class="add-filter" value="+"
                    data-bind="click: function() { $root.addFilter($data); }" />
        </div>
    </li>
</ul>

<p>
    <input type="button" id="submitFilters"  value="Submit" data-bind="click: postFilters" />
</p>

</div>

CSS

#filtersholder, #submitFilters {
    margin: 10px;
}
.delete-filter, .add-filter {
    width: 24px;
    height: 24px;
}

.opperator {
    width: 80px;
}

JavaScript

ko.bindingHandlers.datePicker = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
        var type = ko.utils.unwrapObservable(valueAccessor());

        if (type == 'Date') {
            $(element).datepicker();
        }

    },
    update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
        var type = ko.utils.unwrapObservable(valueAccessor());

        if (type == 'Date') {
            $(element).datepicker();
        }
        else {
            $(element).datepicker("destroy");
        }
    }
};
var Conditions = {
    'Number': ['=', '!=', '>', '<'],
    'String': ['Contains', '=', '!='],
    'Date': ['=', '!=', '>', '<'],
    findByType: function(type) {
        for (p in this) {
            if (typeof this[p] === "object" && p == type) {
                return this[p];
            }
        }

        return [];
    }
};

var _columns = [
    {
    Column: 'DeveloperName',
    Display: 'Developer',
    Type: 'String'},
{
    Column: 'IssueID',
    Display: 'Issue ID',
    Type: 'Number'},
{
    Column: 'IssueTitle',
    Display: 'Issue Title',
    Type: 'String'},
{
    Column: 'IssueDescription',
    Display: 'Issue Description',
    Type: 'String'},
    {
    Column: 'IssueDate',
    Display: 'Issue Date',
    Type: 'Date'}
];

function findFilterColumn(column) {
    for (var i = 0; i < _columns.length; i++) {
        if (_columns[i].Column == column) {
            return _columns[i];
        }
    }

    return null;
};

var Filter = function(column, condition, nextFilterBinaryCondition, type, value) {
    this.ColumnObj = ko.observable(findFilterColumn(column || ""));
    this.ColumnObj.subscribe(

    function(value) {
        this.Value(null);
    }, this);
    this.Column = ko.dependentObservable(

    function() {
        return (this.ColumnObj() != null) ? this.ColumnObj().Column : "";
    }, this);

    this.Condition = ko.observable(condition || null);

    this.NextFilterBinaryCondition =...