Sliding Inputs

A fancy input widget

by nirmaljpatel

HTML

<link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<div data-role="page">
    <div data-role="header">
        <h1>Attendance Marker</h1>
    </div>
    <div data-role="content">
        <div class="container">
            <div class="present" id="preBtn">
                <span>Present</span>
                <span class="arrow">&#187;</span>
                <div class="close">x</div>
                <input name="code" placeholder="Enter Verification Code"></input>
            </div><!-- Cannot leave space between inline divs
 --><div class="absent" id="absBtn">
            <span class="arrow">&#171;</span>
            <span>Absent</span>
            <div class="close">x</div>
            </div>
        </div>
        <div id="swipeMsg">
                Swipe the tabs to record your attendance...
            </div>
    </div>
</div>

CSS

* { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; }
.container{
    position: relative;
    border: solid black thin;
    height: 6em;
    overflow: hidden;
}
.container > div {
    height: 100%;
    text-align: center;
    line-height: 3.5em;
    font-size: 1.5em;
    width: 49%;    
    display: inline-block;
    position: absolute;
    
    
    transition: 
        width .5s linear,
        border-radius .5s linear;
    -webkit-transition: 
        width .5s linear,
        border-radius .5s linear;
}
.container > div.expand {
    width: 100%;
    border-radius: 0;
    
}
.present {
    border: solid green thin;
    background-color: green;
    border-top-right-radius: 1.5em;
    border-bottom-right-radius: 1.5em;
}
.present.expand span,
.present.expand .arrow,
.absent.expand .arrow {
    display: none;
}
.present.expand div,
.present.expand input {
    display: inline;
}
.present.expand input {
    width: 50%;
}
.present div, 
.present input {
    display: none;
}
.close{
    border-radius: 0.4em;
    width:2em;
    height:2em;
    line-height:2em;
    border: solid black thick;
    background-color: black;
    color: white;
    cursor: pointer;
}
.absent {
    border: solid red thin;
    background-color: red;
    right: 0;
    border-top-left-radius: 1.5em;
    border-bottom-left-radius: 1.5em;
}
.absent .close {
    display: none;
}
.absent.expand .close{
    display: inline;
}
.arrow {
    font-size: 2em;
    position: absolute;
    top: -5%;
}
.present .arrow {
    right: 5%;
}
.absent .arrow {
    left: 5%;
}
#swipeMsg {
    display: inline-block;
}

JavaScript

var expander = function(btnToExpand, othBtn, event){
    console.log("Expander: "+btnToExpand);
    $(btnToExpand).css("zIndex",9);
    $(othBtn).css("zIndex",8);
    $(btnToExpand).addClass("expand");
};
$(".container").on("swipeleft", function(btnToExpand, othBtn){
    return function(event){ expander(btnToExpand, othBtn, event); };
}("#absBtn", "#preBtn"));
$(".container").on("swiperight", function(btnToExpand, othBtn){
    return function(event){ expander(btnToExpand, othBtn, event); };
}("#preBtn", "#absBtn"));

var shaker = function(elemId) {
    if ($(elemId).hasClass("expand")) {
        return;
    }
    $(elemId + " span.arrow").effect("shake");
};
var absShaker = function (event) {
    shaker("#absBtn");
};
var preShaker = function(event){
    shaker("#preBtn");
};
$(".absent").on("click", absShaker);
$(".present").on("click", preShaker);

var cssCloser = function(expBtn, othBtn, event) {
    event.stopPropagation();
    event.preventDefault();
    $(expBtn).removeClass("expand");
};
$("#preBtn .close").on("click", function(expBtn, othBtn){
    return function(event) {cssCloser(expBtn, othBtn, event);};
}("#preBtn", "#absBtn"));
$("#absBtn .close").on("click", function(expBtn, othBtn){
    return function(event) {cssCloser(expBtn, othBtn, event);};
}("#absBtn", "#preBtn"));

/* JS Animations */
var absMarker = function(event){
    console.log("Absent button clicked...");
    var $tgt = $(event.target);
    if (!$tgt.hasClass("absent")) {
        $tgt = $tgt.parent(".absent");
    }
    $tgt.animate({width:"100%"}, 
                 {duration: 600, 
                  step: function(now, fx){
                      $("#preBtn").width(100-now+"%");
                  },
                  complete: function(){
                      console.log("Animation complete...");
                      $("#preBtn").css('z-index', 8);
                      $("#absBtn").css('z-index', 9);
                      $("#absBtn").addClass("expand");
                      
      ...