Load data into common jsView templates from a list of fields, including list options, dates, text

491 views Asked by At

I've changed my mind about how the data looks to simplify the templating.

I have a jsFiddle for this at: http://jsfiddle.net/geewhizbang/Y44Gm/4/ I now have this working except for the select items. I don't know yet if the two-way binding works

my data looks approximately like this except that it is way more verbose

var allData = [
    {
        "DateOne": "2011-04-07T00:00:00",
        "DateTwo": "2019-03-22T00:00:00",
        "TextValue": "Some lengthy block of text",
        "AnotherTextValue": "Yadda 2013/003208",
        "SelectionBoxValue": "4 - Broad"
    }, {
        "DateOne": "2013-04-07T00:00:00",
        "DateTwo": "2019-03-22T00:00:00",
        "TextValue": "Some lengthy block of text like this",
        "AnotherTextValue": "Pinko 2013/003208",
        "SelectionBoxValue": "3 - Average"
    }
];

var config =
{
    fieldTitles: {
        "DateOne":
            "Date One",
        "DateTwo":
            "Another Date Value",
        "TextValue":
            "First Text Value",
        "AnotherTextValue":
            "Some More Text Here",
        "SelectionBoxValue":
            "Select Something"
    },
    fieldList: ['TextValue', 'DateTwo', 'SelectionBoxValue', 'AnotherTextValue'],
    fieldOptions:
    {
        "SelectionBoxValue":
            ["[Not Specified]", "1 - Very narrow", "2 - Narrow", "3 - Average", "4 - Broad", "5 - Very broad"]
    }
};

** my Templates using the deprecated jquery templates library

<script id="TextTemplate" type="text/html">
    <div class="bodyItem">
        <div class="colDec">
            <p data-content="title" data-format="getTitle"></p>
            <div data-content="decision" contenteditable="true"></div>
        </div>
        <div class="colHist">
            <p data-content="title"></p>
            <div data-content="history"></div>
        </div>
    </div>
</script>
<script id="DateTemplate" type="text/html">
    <div class="bodyItem">
        <div class="colDec">
            <p data-content="title" data-format="getTitle"></p>
            <input data-content="decision" type="text" class="date" data-format="date" />
        </div>
        <div class="colHist">
            <p data-content="title"></p>
            <div data-content="history" class="date" data-format="date"></div>
        </div>
    </div>
</script>

<script id="SelectTemplate" type="text/html">
    <div class="bodyItem">
        <div class="colDec">
            <p data-content="title"></p>
            <select data-content="decision" data-options="options" data-format="fixNull"></select>
        </div>
        <div class="colHist">
            <p data-content="title"></p>
            <div data-content="history" data-format="fixNull"></div>
        </div>
    </div>
</script>

My previous code using jQuery Templates:

var dataIndex = 0;
$bodyTemplate = null;

function fillBody() {

    var $SummaryBody = $("#SummaryBody");

    var data = {
        decision: allData[dataIndex],
        history: allData[dataIndex + 1],
        options: config.fieldOptions,
        title: config.fieldTitles
    };
    if ($bodyTemplate == null) {

        $.addTemplateFormatter({
            fixNull: function (value) {
                return (value == null ? "[Not Defined]" : value);
            },
            date: function (value) {
                if (value == null) return "";
                var d = new Date(value);
                return d.getFullYear() == 1900 ? "" : d.getMonth() + "/" + d.getDate() + "/" + d.getFullYear();
            }
        });

        $bodyTemplate = $("<div>");
        var textTemplate = $.trim($('#SummaryTextTemplate').html());
        var dateTemplate = $.trim($('#SummaryDateTemplate').html());
        var selectTemplate = $.trim($('#SummarySelectTemplate').html());

        config.fieldList.forEach(function (field) {

            var sel = config.fieldOptions[field];
            var $template = $("<div />");
            if (typeof sel != "undefined") {
                $template.html(selectTemplate);
                setDataAttrib($template, "data-options", field);
            } else {
                $template = $template.html((field.indexOf("Date") > -1 ? dateTemplate : textTemplate));
            }
            setDataAttrib($template, 'data-content', field);
            setDataAttrib($template, 'data-content-bind', field);
            $bodyTemplate.append($template.children());
        });
    }
    $SummaryBody.loadTemplate($bodyTemplate, data);
    $SummaryBody.find(".colDec .date").datepicker();


    function setDataAttrib($template, attr, field) {
        var $items = $template.find("[" + attr + "]");

        $items.each(function () {

            var $this = $(this);
            var attrValue = $this.attr(attr);
            $this.attr(attr, attrValue + "." + field);
        });
    }
}

The issue that precipitated this question was that I couldn't get values to load into text boxes to use the date picker. They would inexplicably load outside the input boxes.

I then found that the templates code is deprecated already, so now I want to move this to somehting that isn't even if it is still beta.

So I have several questions, that I will try to work on independently, but perhaps this will help someone else as an example that isn't covered very well in the sample code I've seen so far.

First of all, how do I load options into my select boxes based on this data. I don't want to have a separate template for each of the numerous fields in the data that have select options.

I don't mind if I have to restructure the data to some degree to get this to work.

And do I still need to loop on my own to build up a larger template to point the sub-templates to each field like I did before, or is there a built-in metaphor that I can use?

2

There are 2 answers

0
BorisMoore On BEST ANSWER
0
GeeWhizBang On

The answer you just made for my other question I'm trying to build up options from an array data value using jsView also helps with this one as well.

Thanks for the prompt replies. It also helps that I've been working on this a while now and I'm starting to like this a lot. I really don't need a full blown MVVM like Angular, Knockout, or Backbone just to fill out a template on a site that has pages served up independently from each other by a complex back end, and so far leaning this has been a lot easier than creating all the unnecessary abstractions just for a simple page that only has to interact with itself and a few Ajax methods.