JSFiddle - React, Tailwind, and code Playground

by jquery4u

HTML

<link rel="stylesheet" href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css">
<script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/js/bootstrap.min.js"></script>
<div id="media-container" class="view-1">
    <div class="loading">Loading...</div>
    <ul class="media-list">
        <li class="media"> <a class="pull-left" href="#">
      <img class="media-object thumbnail" src="http://placehold.it/64x64" />
  </a>

            <div class="media-body">
                 <h4 class="media-heading">Media heading</h4>

                <div class="media-body-left">
                    <p>Cras sit amet nibh libero, in gravida nulla. Nulla vel metus scelque ante sollicitudin commodo. Cras purus odio, vestibulum in vulputate at, tempus viverra turpis...</p>
                </div>
                <div class="media-body-right"> <a class="btn remove" href="#">Button</a>

                </div>
            </div>
        </li>
        <li class="media"> <a class="pull-left" href="#">
      <img class="media-object thumbnail" src="http://placehold.it/64x64" />
  </a>

            <div class="media-body">
                 <h4 class="media-heading">Media heading</h4>

                <div class="media-body-left">
                    <p>Cras sit amet nibh libero, in gravida nulla. Nulla vel metus scelque ante sollicitudin commodo. Cras purus odio, vestibulum in vulputate at, tempus viverra turpis...</p>
                </div>
                <div class="media-body-right"> <a class="btn remove" href="#">Button</a>

                </div>
            </div>
        </li>
    </ul> <a class="btn add">Add</a>  <a class="btn more">Load More</a>  <a class="btn refresh">Refresh</a> | <a class="btn view" data-view="1">View1</a>  <a class="btn view" data-view="2">View2</a> 
    <br/>
</div>

SCSS

/* apply a natural box layout model to all elements */
* { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; }

#media-container {
     width: 600px;    
        .loading {
        display: none;
    }
}

#media-container.view-1 {
       
    .media-list {
        
        li.media {
            list-style: none;
            position: relative;
            height: 95px;
            padding: 10px;
           transition: background .25s ease-in-out;
           -moz-transition: background .25s ease-in-out;
           -webkit-transition: background .25s ease-in-out;
            
            .media-body {
                padding-top: 3px;
            }
            
            .media-heading {
                margin: 0;
            }
            
            .media-body-left {
                float: left;
                margin-right: 115px;
                width: 77%;
                padding-right: 10px;
                font-size:0.9em;
                line-height:1.2em;
            }
            
            .media-body-right {
                position: absolute;
                width: 20%;
                right: 0;
                text-align: right;
                margin-right:10px;
            }
            
            .btn {
                width: 100%;
            }
            
        }
        
        li.media:hover {
            background: #F0F0F0;
        }
            
    }
    
}

#media-container.view-2 {

    border: 1px solid red;
   
    .media-list {
        width: 100%;
        display: inline-block;
        
        li.media {
            list-style: none;
            float: left;
            width: 95px;
            height: 95px;
            padding: 5px;
           transition: background .25s ease-in-out;
           -moz-transition: background .25s ease-in-out;
           -webkit-transition: background .25s ease-in-out;
                        
            .media-heading, .media-body-left,...

JavaScript

(function ($, W, D, undefined) {
    W.MEDIA_VIEW = {

        settings: {
            container: '#media-container',
            list: '.media-list',
            item: '.media',
            loading: '.loading',
            itemDisplayMax: 3,
            itemCacheMax: 5,
            itemCacheMin: 3
        },

        cache: {},

        init: function (options) {
            console.log('init');
            var _this = this;
            _this.settings = $.extend({}, _this.settings, options);

            // ------- DOM CACHE --------------------------------------------------------------------

            _this.cache.$container = $(_this.settings.container);
            _this.cache.$list = $(_this.settings.list);
            _this.cache.$loading = _this.cache.$container.find(_this.settings.loading);
            _this.cache.itemCache = [];
            _this.loadNewItems();

            //console.dir(_this.cache);

            // ------- EVENT HANDLERS ---------------------------------------------------------------

            //REMOVE 1 - remove a media items handler
            _this.cache.$container.on('click', '.btn.remove', function (e) {
                console.log('removing item...');
                e.preventDefault();
                $(this).closest(_this.settings.item).remove();

                //simulate add 1 for 1
                // $('.btn.add').trigger('click');
            });

            //ADD 1 - add a media items handler
            _this.cache.$container.on('click', '.btn.add', function (e) {
                console.log('adding item...');
                e.preventDefault();

                var $newItem = $(_this.cache.itemCache.pop());
                _this.cache.$list.append($newItem);
                $newItem.fadeIn(500);

                //if cache goes below threshold then load more
                console.log('checking cache ' + _this.cache.itemCache.length + ' <= ' + _this.settings.itemCacheMin);
                if...