Masriyah
Masriyah

Reputation: 2505

two page layouts into one view

I would like some advice on this matter. I have a view page that will display a number of users. One view is to display users in a grid (gallery like) of their images. Second view is to display the same users but by their name in a list layout. I will have a toggle button on the page to switch between the two. What is the best way to go about it? Having two separate view pages or have a partial view of some sort?

Update Code after suggestion below

<div data-bind="template: {name:'grid-template'}"></div>
<div data-bind="template: {name:'list-template'}"></div>

<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>

Knockout Script File

$.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.renderMode = ko.observable('grid');
        self.displayTemplate = ko.computed(function () {
            return self.renderMode() + '-layout-template';
        });

    };

Upvotes: 0

Views: 110

Answers (1)

stun
stun

Reputation: 1744

Personally, I like having clean isolated small little Partial Views especially if it is going to be regular HTTP POST.
However, based on the assumptions I am making below, I think I can suggest a better implementation design.

My Assumption

You have

  1. Index.cshtml Parent view to display a list Users.
  2. JSON object array containing your list of Users
  3. Based on what I see, you are using KnockoutJS.
    Read the KnockoutJS Template Binding especially the "Note 5: Dynamically choosing which template is used" part.

It kind of makes it easier to do what you are doing if you are using KnockoutJS or something similar.
You simply have toggle between the two rendering templates.

<script type="text/html" id="gallery-layout-template"> ... </script>
<script type="text/html" id="listing-layout-template"> ... </script>

<div id="divOutputContainer"
     data-bind="template: { name: displayTemplate, foreach: users }"></div>

<script type="text/javascript">
$(document).ready(function() {

    // I am just writing out a dummy User array here.
    // Render out your User Array JSON encoded using JSON.NET.
    var myUsers = [
        { "id" : 1, "name": "User 1" },
        { "id" : 2, "name": "User 2" }
    ];

    // here is your KnockoutJS View Model "class"
    function MyKoViewModel(users) {
        var self = this;
        self.users = ko.observableArray(users);

        // Toggle this renderMode observable's value
        // between 'listing' and 'gallery' via your Toggle button click event handler
        self.renderMode = ko.observable( 'gallery' );

        self.displayTemplate = function(user) {
            // this will return 'gallery-layout-template' or 'listing-layout-template'
            return self.renderMode() + '-layout-template';
        }
    }

    ko.applyBindings( new MyKoViewModel( myUsers ) );
});
</script>

So with that technique, you don't need to make an AJAX call every time to refresh the view with a different rendering template.
You have all your data that you want to display as a client-side JavaScript KnockoutJS view model.
Then, just switch the client-side rendering template using KnockoutJS.

Must more efficient :-)

NOTE

I have a feeling, you might have to use the ko.computed() for the MyKoViewModel's displayTemplate() function like this.

self.displayTemplate = ko.computed(function() {
    return self.renderMode() + '-layout-template';
}

Upvotes: 1

Related Questions