0

I am using knockout js to get my data to display and i am also using it to bind templates. I have a page that displays the same information in two different ways: one is a grid view and the other is a list view. Currently i have both views displayed on the page load. I would like to create two buttons one for the grid and one for the list. I am not sure how to go about it with Knockout js any tips or help is appreciated.

View Page

<div data-bind="template: {name:'grid-template'}, visible: !showList()"></div>
<div data-bind="template: {name:'list-template'}, visible: showList()"></div>

<input type="button" value="Toggle" data-bind="click: toggleView"/>

<script style="float:left"  type="text/html" id ="grid-template">
    <section " style="width:100%; float:left">
    <section id="users" data-bind="foreach: Users">
        <div id="nameImage">
            <figure id="content">
                <img width="158" height="158" alt="Gravatar" data-bind="attr:{src: GravatarUrl}"/>
                <figcaption>
                    <a title="Email" id="emailIcon" class="icon-envelope icon-white" data-bind="attr:{'href':'mailto:' + Email()}"></a>
                    <a title="Profile" id="profileIcon" class="icon-user icon-white"></a>
                </figcaption>
            </figure>
            <p data-bind="text:Name"></p>
            </div>
        </section>
    </section>
</script>

<script style="float:left" type="text/html" id="list-template">
        <div data-bind="foreach: Users">
            <div style="width:60%; float:left; margin:10px; height:58px">
                <img style="float:left; margin-right:5px" width="58" height="58" alt="Gravatar" data-bind="attr:{src: GravatarUrl}"/>
                <p style="height:58px; float:left; vertical-align:central" data-bind="text:Name"></p>
                <a style="float:right"  title="Profile"  class="icon-user icon-black"></a>
                <a style="float:right"  title="Email" class="icon-envelope icon-black" data-bind="attr:{'href':'mailto:' + Email()}"></a>
            </div>
        </div>
</script>

@section scripts{
    @Scripts.Render("~/bundles/user" + ViewBag.Layout.AppVersionForUrls)

    <script type="text/javascript">
        (function ($) {
            $.views.User.GetUser('@url');
        })(jQuery);
    </script>
    }

Knockout JS

$.views.User.UserViewModel = function (data) {
        var self = this;
        self.Name = ko.observable(data.Name);
        self.Email = ko.observable(data.Email);
        self.ContentRole = ko.observable(data.ContentRole);
        self.MD5Email = ko.observable(data.MD5Email);
        self.GravatarUrl = ko.computed(function () {
           return 'http://www.gravatar.com/avatar/' + self.MD5Email() + '?s=300&d=identicon&r=G';
        });
        self.showList = ko.observable(true);
        self.toggleView = function () {
        self.showList(!self.showList());
        }
    };
Masriyah
  • 2,445
  • 11
  • 49
  • 91

1 Answers1

1

If I understand correctly, you could bind the visible property of each div to a boolean that you flip each time a button is pressed.

HTML:

<input type="button" value="Toggle" data-bind="click: toggleView"/>

<div data-bind="visible: showGrid()">Grid</div>
<div data-bind="visible: !showGrid()">List</div>

View Model:

var ViewModel = function() {
    var self = this;

    self.showGrid = ko.observable(true);
    self.toggleView = function() {
        self.showGrid(!self.showGrid());
    }
}

var vm = new ViewModel();
ko.applyBindings(vm);

Here's a jsFiddle.

PatrickSteele
  • 14,489
  • 2
  • 51
  • 54
  • I wasn't sure if this is something i could just add on to what i already have or not. but i changed my top two divs to be: `
    ` I am only getting the toggle button and when clicked nothing happens
    – Masriyah Apr 10 '13 at 01:52
  • And did you create a 'showList' observable on your view model? – PatrickSteele Apr 10 '13 at 01:58
  • Yes, i just updated my post with your suggested additions. Feel free to point out anything wrong or missing as i am new to knockout js – Masriyah Apr 10 '13 at 02:03
  • The UserViewModel you show appears to be the view model used *inside* the foreach (i.e. an individual User). The showList observable (and its associated toggleView function) need to be on the viewmodel that contains the "Users" collection (usually the "root" viewmodel). It's difficult to know more without seeing the complete viewmodel + HTML. – PatrickSteele Apr 10 '13 at 02:25
  • the viewmodel i have for knockout i have it in a separate js file which i call in the view page (just posted above `@section scripts...`) is there a way to change the syntax of the toggle to be placed in the view page without knockout syntax? – Masriyah Apr 10 '13 at 03:30