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 class="media-container">
    <div class="loading">Loading...</div>
    <ul class="media-list">
        <li>
            <div 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>
            </div>
        </li>
        <li>
            <div 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 scelsque 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>
            </div>
        </li>
        <li>
            <div class="media"> <a class="pull-left" href="#">
      <img class="media-object thumbnail" src="http://placehold.it/64x64" />
  </a>

                <div class="media-body">
                     <h4...

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

.media-container .loading {
    display: none;
}

.media-list li {
    list-style: none;
}

.media {
    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:hover {
    background: #F0F0F0;
}

.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;
    }

.media-list .btn {
    width: 100%;
}

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 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 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 (_this.cache.itemCache.length <=...