playlist structure updated
video thumbs ratios updated css minified playlist default thumb image added unnecessary js and css removed
This commit is contained in:
parent
3058e65648
commit
5131f2f175
23 changed files with 77 additions and 8392 deletions
|
@ -1,6 +1,6 @@
|
||||||
<div onclick="get_ep_video('{$video.videoid}')" class="featured-video clearfix">
|
<div onclick="get_ep_video('{$video.videoid}')" class="featured-video clearfix">
|
||||||
<div class="video_thumb">
|
<div class="video_thumb">
|
||||||
<img src="{getThumb vdetails=$video size=128x80}" {ANCHOR place="video_thumb" data=$video} class="img-responsive">
|
<img src="{getThumb vdetails=$video size=168x105}" {ANCHOR place="video_thumb" data=$video} class="img-responsive">
|
||||||
<time datetime="2016-15-03" class="duration">
|
<time datetime="2016-15-03" class="duration">
|
||||||
{if $video.duration>1}{$video.duration|SetTime}{else}00:00{/if}</time>
|
{if $video.duration>1}{$video.duration|SetTime}{else}00:00{/if}</time>
|
||||||
</div> <!--VIDEO_THUMB END-->
|
</div> <!--VIDEO_THUMB END-->
|
||||||
|
|
|
@ -3,20 +3,21 @@
|
||||||
{$count_items = $cbvid->action->count_playlist_items($list_id)}
|
{$count_items = $cbvid->action->count_playlist_items($list_id)}
|
||||||
|
|
||||||
<!-- storing default thumb in variable -->
|
<!-- storing default thumb in variable -->
|
||||||
{assign var='playlist_def_thumb' value=get_playlist_thumb($playlist)}
|
{assign var='playlist_def_thumb' value=get_playlist_thumb($playlist,'416x260')}
|
||||||
|
|
||||||
{if $playlist_def_thumb|substr:-18 == 'playlist_thumb.png'}
|
{if $playlist_def_thumb|substr:-18 == 'playlist_thumb.png'}
|
||||||
{assign var='playlist_def_thumb' value=$theme|cat:'/images/playlist-default.png'}
|
{assign var='playlist_def_thumb' value=$theme|cat:'/images/playlist-default.jpg'}
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<div class="playlist-thumb">
|
<div class="playlist-thumb">
|
||||||
<h2><a href="{videoLink vdetails=$first[0]}">{$playlist.playlist_name}</a></h2>
|
|
||||||
<a href="{videoLink vdetails=$first[0]}" class="playlist-box">
|
<a href="{videoLink vdetails=$first[0]}" class="playlist-box">
|
||||||
<img class="img-responsive" src="{$playlist_def_thumb}">
|
<img class="img-responsive" src="{$playlist_def_thumb}">
|
||||||
<span>
|
<div class="playlist-count">
|
||||||
{$count_items}<br>Videos
|
<span>{prettyNum($count_items)}</span>Videos
|
||||||
<img src="{$theme}/images/folder-icon.png">
|
</div>
|
||||||
</span>
|
|
||||||
</a>
|
</a>
|
||||||
<time datetime="{$playlist.date_added}" class="date-time">{$playlist.date_added|niceTime}</time>
|
<div class="playlist-info">
|
||||||
|
<h2><a href="{videoLink vdetails=$first[0]}">{$playlist.playlist_name}</a></h2>
|
||||||
|
<time datetime="{$playlist.date_added}" class="date-time">{$playlist.date_added|niceTime}</time>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
|
@ -1,7 +1,7 @@
|
||||||
{if $display_type=='popVideos'}
|
{if $display_type=='popVideos'}
|
||||||
<div class="col-lg-5 col-md-6 col-sm-6 col-xs-6 thumb-holder">
|
<div class="col-lg-5 col-md-6 col-sm-6 col-xs-6 thumb-holder">
|
||||||
<a class="video_link" href="{videoLink($pop_video)}" title="{$pop_video.title|title}">
|
<a class="video_link" href="{videoLink($pop_video)}" title="{$pop_video.title|title}">
|
||||||
<img class="img-responsive" src="{getThumb vdetails=$pop_video size=512x320 }">
|
<img class="img-responsive" src="{getThumb vdetails=$pop_video size=168x105 }">
|
||||||
</a>
|
</a>
|
||||||
<div class="item-footer">
|
<div class="item-footer">
|
||||||
<span class="duration">{if $pop_video.duration>1}{$pop_video.duration|SetTime}{else}00:00{/if}</span>
|
<span class="duration">{if $pop_video.duration>1}{$pop_video.duration|SetTime}{else}00:00{/if}</span>
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
<div class="featured-video clearfix">
|
<div class="featured-video clearfix">
|
||||||
<a href="{videoLink($pop_video)}">
|
<a href="{videoLink($pop_video)}">
|
||||||
<div class="video_thumb">
|
<div class="video_thumb">
|
||||||
<img src="{getThumb vdetails=$pop_video size=128x80}" {ANCHOR place="video_thumb" data=$pop_video} class="img-responsive">
|
<img src="{getThumb vdetails=$pop_video size=168x105}" {ANCHOR place="video_thumb" data=$pop_video} class="img-responsive">
|
||||||
<time datetime="2016-15-03" class="duration">
|
<time datetime="2016-15-03" class="duration">
|
||||||
{if $pop_video.duration>1}{$pop_video.duration|SetTime}{else}00:00{/if}</time>
|
{if $pop_video.duration>1}{$pop_video.duration|SetTime}{else}00:00{/if}</time>
|
||||||
</div> <!--VIDEO_THUMB END-->
|
</div> <!--VIDEO_THUMB END-->
|
||||||
|
@ -42,7 +42,7 @@
|
||||||
{if $display_type=='homeVideos'}
|
{if $display_type=='homeVideos'}
|
||||||
<div class="clearfix thumb-holder">
|
<div class="clearfix thumb-holder">
|
||||||
<a class="video-link" href="{videoLink($video)}" title="{$video.title|title}">
|
<a class="video-link" href="{videoLink($video)}" title="{$video.title|title}">
|
||||||
<img class="img-responsive" src="{getThumb vdetails=$video size=512x320 }">
|
<img class="img-responsive" src="{getThumb vdetails=$video size=416x260 }">
|
||||||
</a>
|
</a>
|
||||||
<div class="item-footer">
|
<div class="item-footer">
|
||||||
{ANCHOR place='in_video_thumb' data=$video}
|
{ANCHOR place='in_video_thumb' data=$video}
|
||||||
|
@ -69,7 +69,7 @@
|
||||||
<div style="display: none" class="item-video col-lg-4 col-md-4 col-sm-4 col-xs-12">
|
<div style="display: none" class="item-video col-lg-4 col-md-4 col-sm-4 col-xs-12">
|
||||||
<div class="clearfix thumb-holder">
|
<div class="clearfix thumb-holder">
|
||||||
<a class="video-link" href="{videoLink($video)}" title="{$video.title|title}">
|
<a class="video-link" href="{videoLink($video)}" title="{$video.title|title}">
|
||||||
<img class="img-responsive" src="{getThumb vdetails=$video size=512x320 }">
|
<img class="img-responsive" src="{getThumb vdetails=$video size=416x260 }">
|
||||||
</a>
|
</a>
|
||||||
<div class="item-footer">
|
<div class="item-footer">
|
||||||
<span class="duration">{if $video.duration>1}{$video.duration|SetTime}{else}00:00{/if}</span>
|
<span class="duration">{if $video.duration>1}{$video.duration|SetTime}{else}00:00{/if}</span>
|
||||||
|
@ -95,7 +95,7 @@
|
||||||
<div class="featured-video clearfix">
|
<div class="featured-video clearfix">
|
||||||
<a href="{videoLink($video)}">
|
<a href="{videoLink($video)}">
|
||||||
<div class="video_thumb">
|
<div class="video_thumb">
|
||||||
<img src="{getThumb vdetails=$video size=128x80}" {ANCHOR place="video_thumb" data=$video} class="img-responsive">
|
<img src="{getThumb vdetails=$video size=168x105}" {ANCHOR place="video_thumb" data=$video} class="img-responsive">
|
||||||
<time datetime="2016-15-03" class="duration">
|
<time datetime="2016-15-03" class="duration">
|
||||||
{if $video.duration>1}{$video.duration|SetTime}{else}00:00{/if}</time>
|
{if $video.duration>1}{$video.duration|SetTime}{else}00:00{/if}</time>
|
||||||
</div> <!--VIDEO_THUMB END-->
|
</div> <!--VIDEO_THUMB END-->
|
||||||
|
@ -117,7 +117,7 @@
|
||||||
<div style="display: none" class="item-video col-lg-6 col-md-6 col-sm-6 col-xs-12">
|
<div style="display: none" class="item-video col-lg-6 col-md-6 col-sm-6 col-xs-12">
|
||||||
<div class="clearfix thumb-holder">
|
<div class="clearfix thumb-holder">
|
||||||
<a class="video-link" href="{videoLink($video)}" title="{$video.title|title}">
|
<a class="video-link" href="{videoLink($video)}" title="{$video.title|title}">
|
||||||
<img class="img-responsive" src="{getThumb vdetails=$video size=512x320 }">
|
<img class="img-responsive" src="{getThumb vdetails=$video size=632x395 }">
|
||||||
<h2 class="title">{$video.title|truncate:50}</h2>
|
<h2 class="title">{$video.title|truncate:50}</h2>
|
||||||
</a>
|
</a>
|
||||||
<div class="item-footer">
|
<div class="item-footer">
|
||||||
|
@ -141,7 +141,7 @@
|
||||||
$video.duration>1}{$video.duration|SetTime}{else}00:00{/if}{*$video.duration|date_format:$config.time*}
|
$video.duration>1}{$video.duration|SetTime}{else}00:00{/if}{*$video.duration|date_format:$config.time*}
|
||||||
</span>
|
</span>
|
||||||
<i class="icon-playweb play-icon"></i>
|
<i class="icon-playweb play-icon"></i>
|
||||||
<img class="img-responsive" src="{getThumb vdetails=$video size=512x320 } " border="1" />
|
<img class="img-responsive" src="{getThumb vdetails=$video size=416x260 } " border="1" />
|
||||||
</a>
|
</a>
|
||||||
{ANCHOR place='in_video_thumb' data=$video}
|
{ANCHOR place='in_video_thumb' data=$video}
|
||||||
<button data-quick="quick-{$video.videoid}"
|
<button data-quick="quick-{$video.videoid}"
|
||||||
|
@ -176,7 +176,7 @@
|
||||||
{if $display_type=='user_videos'}
|
{if $display_type=='user_videos'}
|
||||||
<div class="col-md-3 col-sm-4 col-xs-6">
|
<div class="col-md-3 col-sm-4 col-xs-6">
|
||||||
<a href="{videoLink($video)}" title="{$video.title|title}">
|
<a href="{videoLink($video)}" title="{$video.title|title}">
|
||||||
<img alt="{$video.title|title}" src="{getThumb vdetails=$video size='171x120'}" id="thumbs_{$video.videoid}" title="{$video.title|title}"/>
|
<img alt="{$video.title|title}" src="{getThumb vdetails=$video size='416x260'}" id="thumbs_{$video.videoid}" title="{$video.title|title}"/>
|
||||||
</a>
|
</a>
|
||||||
<p class="cbHomeVidDuration duration_view">
|
<p class="cbHomeVidDuration duration_view">
|
||||||
{if $video.duration>1}
|
{if $video.duration>1}
|
||||||
|
@ -195,7 +195,7 @@
|
||||||
{if $display_type=='playlistVideos'}
|
{if $display_type=='playlistVideos'}
|
||||||
<div class="video_thumb">
|
<div class="video_thumb">
|
||||||
<a class="video_link" href="{videoLink($video)}" title="{$video.title|title}">
|
<a class="video_link" href="{videoLink($video)}" title="{$video.title|title}">
|
||||||
<img class="img-responsive" src="{getThumb vdetails=$video size=512x320 }">
|
<img class="img-responsive" src="{getThumb vdetails=$video size=416x260 }">
|
||||||
<div class="play-info">
|
<div class="play-info">
|
||||||
<strong class="title">{$video.title|truncate:30}</strong>
|
<strong class="title">{$video.title|truncate:30}</strong>
|
||||||
<i class="icon-playweb"></i>
|
<i class="icon-playweb"></i>
|
||||||
|
@ -217,7 +217,7 @@
|
||||||
$video.duration>1}{$video.duration|SetTime}{else}00:00{/if}{*$video.duration|date_format:$config.time*}
|
$video.duration>1}{$video.duration|SetTime}{else}00:00{/if}{*$video.duration|date_format:$config.time*}
|
||||||
</span>
|
</span>
|
||||||
<i class="icon-playweb play-icon"></i>
|
<i class="icon-playweb play-icon"></i>
|
||||||
<img class="img-responsive" src="{getThumb vdetails=$video size=512x320 } " border="1" />
|
<img class="img-responsive" src="{getThumb vdetails=$video size=416x260 } " border="1" />
|
||||||
</a>
|
</a>
|
||||||
{ANCHOR place='in_video_thumb' data=$video}
|
{ANCHOR place='in_video_thumb' data=$video}
|
||||||
<button data-quick="quick-{$video.videoid}"
|
<button data-quick="quick-{$video.videoid}"
|
||||||
|
@ -247,7 +247,7 @@
|
||||||
$video.duration>1}{$video.duration|SetTime}{else}00:00{/if}{*$video.duration|date_format:$config.time*}
|
$video.duration>1}{$video.duration|SetTime}{else}00:00{/if}{*$video.duration|date_format:$config.time*}
|
||||||
</span>
|
</span>
|
||||||
<i class="icon-playweb play-icon"></i>
|
<i class="icon-playweb play-icon"></i>
|
||||||
<img class="img-responsive" src="{getThumb vdetails=$video size=512x320 } " border="1" />
|
<img class="img-responsive" src="{getThumb vdetails=$video size=416x260 } " border="1" />
|
||||||
</a>
|
</a>
|
||||||
{ANCHOR place='in_video_thumb' data=$video}
|
{ANCHOR place='in_video_thumb' data=$video}
|
||||||
<button data-quick="quick-{$video.videoid}"
|
<button data-quick="quick-{$video.videoid}"
|
||||||
|
@ -272,7 +272,7 @@
|
||||||
$video.duration>1}{$video.duration|SetTime}{else}00:00{/if}{*$video.duration|date_format:$config.time*}
|
$video.duration>1}{$video.duration|SetTime}{else}00:00{/if}{*$video.duration|date_format:$config.time*}
|
||||||
</span>
|
</span>
|
||||||
<i class="icon-playweb play-icon"></i>
|
<i class="icon-playweb play-icon"></i>
|
||||||
<img class="img-responsive" src="{getThumb vdetails=$video size=512x320 } " border="1" />
|
<img class="img-responsive" src="{getThumb vdetails=$video size=416x260 } " border="1" />
|
||||||
</a>
|
</a>
|
||||||
{ANCHOR place='in_video_thumb' data=$video}
|
{ANCHOR place='in_video_thumb' data=$video}
|
||||||
<img src="{$imageurl}/dot.gif" data-quick="quick-{$video.videoid}"
|
<img src="{$imageurl}/dot.gif" data-quick="quick-{$video.videoid}"
|
||||||
|
|
|
@ -38,8 +38,6 @@
|
||||||
|
|
||||||
<link rel="stylesheet" href="{$theme}/css/custom-elements.css?cache={$cache_buster}">
|
<link rel="stylesheet" href="{$theme}/css/custom-elements.css?cache={$cache_buster}">
|
||||||
|
|
||||||
<link rel="stylesheet" href="{$theme}/css/circle.css?cache={$cache_buster}">
|
|
||||||
|
|
||||||
{*if !in_dev()*}
|
{*if !in_dev()*}
|
||||||
<link rel="stylesheet" href="{$theme}/css/all.css?cache={$cache_buster}">
|
<link rel="stylesheet" href="{$theme}/css/all.css?cache={$cache_buster}">
|
||||||
{*/if*}
|
{*/if*}
|
||||||
|
@ -56,11 +54,8 @@
|
||||||
<script src="{$theme}/js/custom.js"></script>
|
<script src="{$theme}/js/custom.js"></script>
|
||||||
|
|
||||||
<script src="{$theme}/js/bootstrap.min.js"></script>
|
<script src="{$theme}/js/bootstrap.min.js"></script>
|
||||||
<script src="{$theme}/js/dropdowns-enhancement.js"></script>
|
|
||||||
|
|
||||||
<script src="{$theme}/js/ui_plugins.js"></script>
|
<script src="{$theme}/js/ui_plugins.js"></script>
|
||||||
|
|
||||||
<script src="{$theme}/js/progress-circle.js"></script>
|
|
||||||
|
|
||||||
<script src="{$baseurl}/js/clipbucket.js"></script>
|
<script src="{$baseurl}/js/clipbucket.js"></script>
|
||||||
<script src="{$theme}/js/uslider_js/jquery.mousewheel.js"></script>
|
<script src="{$theme}/js/uslider_js/jquery.mousewheel.js"></script>
|
||||||
|
|
|
@ -143,8 +143,6 @@
|
||||||
{$videos = get_videos(['videoid'=>$videoid,'limit'=>'2'])}
|
{$videos = get_videos(['videoid'=>$videoid,'limit'=>'2'])}
|
||||||
{foreach $videos as $video}
|
{foreach $videos as $video}
|
||||||
<a href="{videoLink($video)}&play_list={$playlist.playlist_id}">
|
<a href="{videoLink($video)}&play_list={$playlist.playlist_id}">
|
||||||
|
|
||||||
|
|
||||||
<img src="{getThumb vdetails=$video size=168x105}" class="img-responsive">
|
<img src="{getThumb vdetails=$video size=168x105}" class="img-responsive">
|
||||||
</a>
|
</a>
|
||||||
{/foreach}
|
{/foreach}
|
||||||
|
|
|
@ -72,10 +72,10 @@
|
||||||
</section>
|
</section>
|
||||||
<aside id="sidebar">
|
<aside id="sidebar">
|
||||||
<div class="box-ad ad">{AD place='ad_300x250'}</div>
|
<div class="box-ad ad">{AD place='ad_300x250'}</div>
|
||||||
<h2>Featured Photos</h2>
|
|
||||||
<div class="clearfix sidebar-items">
|
|
||||||
{$featured=get_photos(["featured"=>"yes","limit"=>6])}
|
{$featured=get_photos(["featured"=>"yes","limit"=>6])}
|
||||||
{if $featured}
|
{if $featured}
|
||||||
|
<h2>Featured Photos</h2>
|
||||||
|
<div class="clearfix sidebar-items">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
{foreach $featured as $photo}
|
{foreach $featured as $photo}
|
||||||
<div class="item-photo col-lg-6 col-md-6 col-sm-12 col-xs-12">
|
<div class="item-photo col-lg-6 col-md-6 col-sm-12 col-xs-12">
|
||||||
|
@ -83,10 +83,8 @@
|
||||||
</div>
|
</div>
|
||||||
{/foreach}
|
{/foreach}
|
||||||
</div>
|
</div>
|
||||||
{else}
|
|
||||||
<div class="well well-info">No Photo(s) Found !</div>
|
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
|
{/if}
|
||||||
{$row = $myquery->Get_Website_Details()}
|
{$row = $myquery->Get_Website_Details()}
|
||||||
{if $row.collectionsSection == 'yes'}
|
{if $row.collectionsSection == 'yes'}
|
||||||
{$collections = $cbcollection->get_collections(['limit'=>5, 'active'=>'yes'])}
|
{$collections = $cbcollection->get_collections(['limit'=>5, 'active'=>'yes'])}
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="clearfix">
|
<div class="clearfix">
|
||||||
<section id="content" class="clearfix">
|
<section id="content" class="clearfix">
|
||||||
|
{if $uservideos}
|
||||||
<div class="player-items">
|
<div class="player-items">
|
||||||
<div class="clearfix player-holder">
|
<div class="clearfix player-holder">
|
||||||
<div id="cb_player" class="clearfix cb_player">
|
<div id="cb_player" class="clearfix cb_player">
|
||||||
|
@ -19,6 +20,7 @@
|
||||||
</div>
|
</div>
|
||||||
<img src="{$theme}/images/player-ratio.png" class="playerRatio">
|
<img src="{$theme}/images/player-ratio.png" class="playerRatio">
|
||||||
</div>
|
</div>
|
||||||
|
{/if}
|
||||||
<div id="messageFav" class="alert alert-info marginTop" style="display:none"></div>
|
<div id="messageFav" class="alert alert-info marginTop" style="display:none"></div>
|
||||||
<div class="channel-tabs flat-tabs clearfix">
|
<div class="channel-tabs flat-tabs clearfix">
|
||||||
<ul class="clearfix nav nav-tabs">
|
<ul class="clearfix nav nav-tabs">
|
||||||
|
@ -144,12 +146,12 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="tab-pane fade in clearfix" id="user-playlist">
|
<div class="tab-pane fade in clearfix" id="user-playlist">
|
||||||
<div class="clearfix row ch-playlists">
|
|
||||||
{*$u.userid*}
|
{*$u.userid*}
|
||||||
{$playlists = $cbvid->action->get_playlists(["user"=>$u.userid,"order"=>"date_added DESC","limit"=>""])}
|
{$playlists = $cbvid->action->get_playlists(["user"=>$u.userid,"order"=>"date_added DESC","limit"=>""])}
|
||||||
|
|
||||||
{if $playlists}
|
{if $playlists}
|
||||||
{*pr($playlists,true)*}
|
{*pr($playlists,true)*}
|
||||||
|
<div class="clearfix row ch-playlists">
|
||||||
|
|
||||||
{foreach $playlists as $playlist}
|
{foreach $playlists as $playlist}
|
||||||
<div class="playlist-item col-lg-4 col-md-4 col-sm-6 col-xs-12">
|
<div class="playlist-item col-lg-4 col-md-4 col-sm-6 col-xs-12">
|
||||||
|
@ -157,28 +159,24 @@
|
||||||
</div>
|
</div>
|
||||||
{/foreach}
|
{/foreach}
|
||||||
|
|
||||||
|
</div>
|
||||||
{else}
|
{else}
|
||||||
<div class="well well-info">no playlist found</div>
|
<div class="well well-info">no playlist found</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<aside id="sidebar">
|
<aside id="sidebar">
|
||||||
|
{assign var=userFeeds value=$cbfeeds->getUserFeeds($u)}
|
||||||
|
{if $userFeeds}
|
||||||
<h2>{lang code="Recent Activities"}</h2>
|
<h2>{lang code="Recent Activities"}</h2>
|
||||||
<div id="userFeeds" class="user-activities clearfix sidebar-items">
|
<div id="userFeeds" class="user-activities clearfix sidebar-items">
|
||||||
{assign var=userFeeds value=$cbfeeds->getUserFeeds($u)}
|
|
||||||
{if $userFeeds}
|
|
||||||
{foreach from=$userFeeds item=userFeed}
|
{foreach from=$userFeeds item=userFeed}
|
||||||
{include file="$style_dir/blocks/feed.html" feed=$userFeed}
|
{include file="$style_dir/blocks/feed.html" feed=$userFeed}
|
||||||
{/foreach}
|
{/foreach}
|
||||||
{else}
|
|
||||||
<div class="well well-info clearfix">
|
|
||||||
{lang code='no_activity' assign=no_activity} {$no_activity|sprintf:$u.username}
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
|
{/if}
|
||||||
{$popular = get_users(['order'=>'profile_hits DESC limit 5'])}
|
{$popular = get_users(['order'=>'profile_hits DESC limit 5'])}
|
||||||
{if $popular}
|
{if $popular}
|
||||||
<h2>{lang code="Popular Users"}</h2>
|
<h2>{lang code="Popular Users"}</h2>
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,87 +0,0 @@
|
||||||
/****************************************************************
|
|
||||||
*
|
|
||||||
* CSS Percentage Circle
|
|
||||||
* Based on CSS provided by Andre Firchow
|
|
||||||
*
|
|
||||||
*****************************************************************/
|
|
||||||
|
|
||||||
.prog-circle .slice {
|
|
||||||
position : absolute;
|
|
||||||
width : 1em;
|
|
||||||
height : 1em;
|
|
||||||
clip : rect(0em, 1em, 1em, 0.5em);
|
|
||||||
}
|
|
||||||
.prog-circle .slice.clipauto {
|
|
||||||
clip : rect(auto, auto, auto, auto);
|
|
||||||
}
|
|
||||||
.prog-circle .fill, .prog-circle .bar {
|
|
||||||
position : absolute;
|
|
||||||
border : 0.84em solid #036db4;
|
|
||||||
width : 1em !important;
|
|
||||||
height : 1em !important;
|
|
||||||
clip : rect(0em, .5em, 1em, 0em);
|
|
||||||
-webkit-border-radius : 50%;
|
|
||||||
-moz-border-radius : 50%;
|
|
||||||
-ms-border-radius : 50%;
|
|
||||||
-o-border-radius : 50%;
|
|
||||||
border-radius : 50%;
|
|
||||||
-webkit-transform : rotate(20deg);
|
|
||||||
-moz-transform : rotate(20deg);
|
|
||||||
-ms-transform : rotate(20deg);
|
|
||||||
-o-transform : rotate(20deg);
|
|
||||||
transform : rotate(20deg);
|
|
||||||
}
|
|
||||||
.prog-circle {
|
|
||||||
position : relative;
|
|
||||||
font-size : 100px;
|
|
||||||
width : 1em;
|
|
||||||
height : 1em;
|
|
||||||
-webkit-border-radius : 50%;
|
|
||||||
-moz-border-radius : 50%;
|
|
||||||
-ms-border-radius : 50%;
|
|
||||||
-o-border-radius : 50%;
|
|
||||||
border-radius : 50%;
|
|
||||||
float : left;
|
|
||||||
margin : 0 0em 0.1em 0;
|
|
||||||
background-color : #95c9fe;
|
|
||||||
}
|
|
||||||
.prog-circle .percenttext {
|
|
||||||
position : absolute;
|
|
||||||
width : 100%;
|
|
||||||
height : 1em;
|
|
||||||
z-index : 1;
|
|
||||||
margin : auto;
|
|
||||||
top : 0;
|
|
||||||
left : 0;
|
|
||||||
right : 0;
|
|
||||||
bottom : 0;
|
|
||||||
font-size : 0.3em;
|
|
||||||
color : #036db4;
|
|
||||||
display : block;
|
|
||||||
text-align : center;
|
|
||||||
white-space : nowrap;
|
|
||||||
line-height : 100%;
|
|
||||||
-webkit-transition-duration : 0.2s;
|
|
||||||
-moz-transition-duration : 0.2s;
|
|
||||||
-o-transition-duration : 0.2s;
|
|
||||||
transition-duration : 0.2s;
|
|
||||||
-webkit-transition-timing-function : ease-out;
|
|
||||||
-moz-transition-timing-function : ease-out;
|
|
||||||
-o-transition-timing-function : ease-out;
|
|
||||||
transition-timing-function : ease-out;
|
|
||||||
}
|
|
||||||
.prog-circle .after {
|
|
||||||
position : absolute;
|
|
||||||
top : 0.08em;
|
|
||||||
left : 0.08em;
|
|
||||||
display : block;
|
|
||||||
content : " ";
|
|
||||||
-webkit-border-radius : 50%;
|
|
||||||
-moz-border-radius : 50%;
|
|
||||||
-ms-border-radius : 50%;
|
|
||||||
-o-border-radius : 50%;
|
|
||||||
border-radius : 50%;
|
|
||||||
background-color : #FFFFFF;
|
|
||||||
width : 0.84em;
|
|
||||||
height : 0.84em;
|
|
||||||
}
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
BIN
upload/styles/cb_28/theme/images/playlist-default.jpg
Normal file
BIN
upload/styles/cb_28/theme/images/playlist-default.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 7 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.8 KiB |
|
@ -1,267 +0,0 @@
|
||||||
/* ========================================================================
|
|
||||||
* Bootstrap Dropdowns Enhancement: dropdowns-enhancement.js v3.1.1 (Beta 1)
|
|
||||||
* http://behigh.github.io/bootstrap_dropdowns_enhancement/
|
|
||||||
* ========================================================================
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
|
||||||
* ======================================================================== */
|
|
||||||
|
|
||||||
(function($) {
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var toggle = '[data-toggle="dropdown"]',
|
|
||||||
disabled = '.disabled, :disabled',
|
|
||||||
backdrop = '.dropdown-backdrop',
|
|
||||||
menuClass = 'dropdown-menu',
|
|
||||||
subMenuClass = 'dropdown-submenu',
|
|
||||||
namespace = '.bs.dropdown.data-api',
|
|
||||||
eventNamespace = '.bs.dropdown',
|
|
||||||
openClass = 'open',
|
|
||||||
touchSupport = 'ontouchstart' in document.documentElement,
|
|
||||||
opened;
|
|
||||||
|
|
||||||
|
|
||||||
function Dropdown(element) {
|
|
||||||
$(element).on('click' + eventNamespace, this.toggle)
|
|
||||||
}
|
|
||||||
|
|
||||||
var proto = Dropdown.prototype;
|
|
||||||
|
|
||||||
proto.toggle = function(event) {
|
|
||||||
var $element = $(this);
|
|
||||||
|
|
||||||
if ($element.is(disabled)) return;
|
|
||||||
|
|
||||||
var $parent = getParent($element);
|
|
||||||
var isActive = $parent.hasClass(openClass);
|
|
||||||
var isSubMenu = $parent.hasClass(subMenuClass);
|
|
||||||
var menuTree = isSubMenu ? getSubMenuParents($parent) : null;
|
|
||||||
|
|
||||||
closeOpened(event, menuTree);
|
|
||||||
|
|
||||||
if (!isActive) {
|
|
||||||
if (!menuTree)
|
|
||||||
menuTree = [$parent];
|
|
||||||
|
|
||||||
if (touchSupport && !$parent.closest('.navbar-nav').length && !menuTree[0].find(backdrop).length) {
|
|
||||||
// if mobile we use a backdrop because click events don't delegate
|
|
||||||
$('<div class="' + backdrop.substr(1) + '"/>').appendTo(menuTree[0]).on('click', closeOpened)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0, s = menuTree.length; i < s; i++) {
|
|
||||||
if (!menuTree[i].hasClass(openClass)) {
|
|
||||||
menuTree[i].addClass(openClass);
|
|
||||||
positioning(menuTree[i].children('.' + menuClass), menuTree[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
opened = menuTree[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
proto.keydown = function (e) {
|
|
||||||
if (!/(38|40|27)/.test(e.keyCode)) return;
|
|
||||||
|
|
||||||
var $this = $(this);
|
|
||||||
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
|
|
||||||
if ($this.is('.disabled, :disabled')) return;
|
|
||||||
|
|
||||||
var $parent = getParent($this);
|
|
||||||
var isActive = $parent.hasClass('open');
|
|
||||||
|
|
||||||
if (!isActive || (isActive && e.keyCode == 27)) {
|
|
||||||
if (e.which == 27) $parent.find(toggle).trigger('focus');
|
|
||||||
return $this.trigger('click')
|
|
||||||
}
|
|
||||||
|
|
||||||
var desc = ' li:not(.divider):visible a';
|
|
||||||
var desc1 = 'li:not(.divider):visible > input:not(disabled) ~ label';
|
|
||||||
var $items = $parent.find(desc1 + ', ' + '[role="menu"]' + desc + ', [role="listbox"]' + desc);
|
|
||||||
|
|
||||||
if (!$items.length) return;
|
|
||||||
|
|
||||||
var index = $items.index($items.filter(':focus'));
|
|
||||||
|
|
||||||
if (e.keyCode == 38 && index > 0) index--; // up
|
|
||||||
if (e.keyCode == 40 && index < $items.length - 1) index++; // down
|
|
||||||
if (!~index) index = 0;
|
|
||||||
|
|
||||||
$items.eq(index).trigger('focus')
|
|
||||||
};
|
|
||||||
|
|
||||||
proto.change = function (e) {
|
|
||||||
|
|
||||||
var
|
|
||||||
$parent,
|
|
||||||
$menu,
|
|
||||||
$toggle,
|
|
||||||
selector,
|
|
||||||
text = '',
|
|
||||||
$items;
|
|
||||||
|
|
||||||
$menu = $(this).closest('.' + menuClass);
|
|
||||||
|
|
||||||
$toggle = $menu.parent().find('[data-label-placement]');
|
|
||||||
|
|
||||||
if (!$toggle || !$toggle.length) {
|
|
||||||
$toggle = $menu.parent().find(toggle);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$toggle || !$toggle.length || $toggle.data('placeholder') === false)
|
|
||||||
return; // do nothing, no control
|
|
||||||
|
|
||||||
($toggle.data('placeholder') == undefined && $toggle.data('placeholder', $.trim($toggle.text())));
|
|
||||||
text = $.data($toggle[0], 'placeholder');
|
|
||||||
|
|
||||||
$items = $menu.find('li > input:checked');
|
|
||||||
|
|
||||||
if ($items.length) {
|
|
||||||
text = [];
|
|
||||||
$items.each(function () {
|
|
||||||
var str = $(this).parent().find('label').eq(0),
|
|
||||||
label = str.find('.data-label');
|
|
||||||
|
|
||||||
if (label.length) {
|
|
||||||
var p = $('<p></p>');
|
|
||||||
p.append(label.clone());
|
|
||||||
str = p.html();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
str = str.html();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
str && text.push($.trim(str));
|
|
||||||
});
|
|
||||||
|
|
||||||
text = text.length < 4 ? text.join(', ') : text.length + ' selected';
|
|
||||||
}
|
|
||||||
|
|
||||||
var caret = $toggle.find('.caret');
|
|
||||||
|
|
||||||
$toggle.html(text || ' ');
|
|
||||||
if (caret.length)
|
|
||||||
$toggle.append(' ') && caret.appendTo($toggle);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
function positioning($menu, $control) {
|
|
||||||
if ($menu.hasClass('pull-center')) {
|
|
||||||
$menu.css('margin-right', $menu.outerWidth() / -2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($menu.hasClass('pull-middle')) {
|
|
||||||
$menu.css('margin-top', ($menu.outerHeight() / -2) - ($control.outerHeight() / 2));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function closeOpened(event, menuTree) {
|
|
||||||
if (opened) {
|
|
||||||
|
|
||||||
if (!menuTree) {
|
|
||||||
menuTree = [opened];
|
|
||||||
}
|
|
||||||
|
|
||||||
var parent;
|
|
||||||
|
|
||||||
if (opened[0] !== menuTree[0][0]) {
|
|
||||||
parent = opened;
|
|
||||||
} else {
|
|
||||||
parent = menuTree[menuTree.length - 1];
|
|
||||||
if (parent.parent().hasClass(menuClass)) {
|
|
||||||
parent = parent.parent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
parent.find('.' + openClass).removeClass(openClass);
|
|
||||||
|
|
||||||
if (parent.hasClass(openClass))
|
|
||||||
parent.removeClass(openClass);
|
|
||||||
|
|
||||||
if (parent === opened) {
|
|
||||||
opened = null;
|
|
||||||
$(backdrop).remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSubMenuParents($submenu) {
|
|
||||||
var result = [$submenu];
|
|
||||||
var $parent;
|
|
||||||
while (!$parent || $parent.hasClass(subMenuClass)) {
|
|
||||||
$parent = ($parent || $submenu).parent();
|
|
||||||
if ($parent.hasClass(menuClass)) {
|
|
||||||
$parent = $parent.parent();
|
|
||||||
}
|
|
||||||
if ($parent.children(toggle)) {
|
|
||||||
result.unshift($parent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getParent($this) {
|
|
||||||
var selector = $this.attr('data-target');
|
|
||||||
|
|
||||||
if (!selector) {
|
|
||||||
selector = $this.attr('href');
|
|
||||||
selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, ''); //strip for ie7
|
|
||||||
}
|
|
||||||
|
|
||||||
var $parent = selector && $(selector);
|
|
||||||
|
|
||||||
return $parent && $parent.length ? $parent : $this.parent()
|
|
||||||
}
|
|
||||||
|
|
||||||
// DROPDOWN PLUGIN DEFINITION
|
|
||||||
// ==========================
|
|
||||||
|
|
||||||
var old = $.fn.dropdown;
|
|
||||||
|
|
||||||
$.fn.dropdown = function (option) {
|
|
||||||
return this.each(function () {
|
|
||||||
var $this = $(this);
|
|
||||||
var data = $this.data('bs.dropdown');
|
|
||||||
|
|
||||||
if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)));
|
|
||||||
if (typeof option == 'string') data[option].call($this);
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
$.fn.dropdown.Constructor = Dropdown;
|
|
||||||
|
|
||||||
$.fn.dropdown.clearMenus = function(e) {
|
|
||||||
$(backdrop).remove();
|
|
||||||
$('.' + openClass + ' ' + toggle).each(function () {
|
|
||||||
var $parent = getParent($(this));
|
|
||||||
var relatedTarget = { relatedTarget: this };
|
|
||||||
if (!$parent.hasClass('open')) return;
|
|
||||||
$parent.trigger(e = $.Event('hide' + eventNamespace, relatedTarget));
|
|
||||||
if (e.isDefaultPrevented()) return;
|
|
||||||
$parent.removeClass('open').trigger('hidden' + eventNamespace, relatedTarget);
|
|
||||||
});
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// DROPDOWN NO CONFLICT
|
|
||||||
// ====================
|
|
||||||
|
|
||||||
$.fn.dropdown.noConflict = function () {
|
|
||||||
$.fn.dropdown = old;
|
|
||||||
return this
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
$(document).off(namespace)
|
|
||||||
.on('click' + namespace, closeOpened)
|
|
||||||
.on('click' + namespace, toggle, proto.toggle)
|
|
||||||
.on('click' + namespace, '.dropdown-menu > li > input[type="checkbox"] ~ label, .dropdown-menu > li > input[type="checkbox"], .dropdown-menu.noclose > li', function (e) {
|
|
||||||
e.stopPropagation()
|
|
||||||
})
|
|
||||||
.on('change' + namespace, '.dropdown-menu > li > input[type="checkbox"], .dropdown-menu > li > input[type="radio"]', proto.change)
|
|
||||||
.on('keydown' + namespace, toggle + ', [role="menu"], [role="listbox"]', proto.keydown)
|
|
||||||
}(jQuery));
|
|
|
@ -1,127 +0,0 @@
|
||||||
/*!
|
|
||||||
* JavaScript Custom Forms : File Module
|
|
||||||
*
|
|
||||||
* Copyright 2014-2015 PSD2HTML - http://psd2html.com/jcf
|
|
||||||
* Released under the MIT license (LICENSE.txt)
|
|
||||||
*
|
|
||||||
* Version: 1.2.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function(jcf) {
|
|
||||||
|
|
||||||
jcf.addModule(function($) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
return {
|
|
||||||
name: 'File',
|
|
||||||
selector: 'input[type="file"]',
|
|
||||||
options: {
|
|
||||||
fakeStructure: '<span class="jcf-file"><span class="jcf-upload-button"><span class="jcf-button-content"></span></span><span class="jcf-fake-input"></span></span>',
|
|
||||||
buttonText: 'Choose file',
|
|
||||||
placeholderText: 'No file chosen',
|
|
||||||
realElementClass: 'jcf-real-element',
|
|
||||||
extensionPrefixClass: 'jcf-extension-',
|
|
||||||
selectedFileBlock: '.jcf-fake-input',
|
|
||||||
buttonTextBlock: '.jcf-button-content'
|
|
||||||
},
|
|
||||||
matchElement: function(element) {
|
|
||||||
return element.is('input[type="file"]');
|
|
||||||
},
|
|
||||||
init: function() {
|
|
||||||
this.initStructure();
|
|
||||||
this.attachEvents();
|
|
||||||
this.refresh();
|
|
||||||
},
|
|
||||||
initStructure: function() {
|
|
||||||
this.doc = $(document);
|
|
||||||
this.realElement = $(this.options.element).addClass(this.options.realElementClass);
|
|
||||||
this.fakeElement = $(this.options.fakeStructure).insertBefore(this.realElement);
|
|
||||||
this.fileNameBlock = this.fakeElement.find(this.options.selectedFileBlock);
|
|
||||||
this.buttonTextBlock = this.fakeElement.find(this.options.buttonTextBlock).text(this.options.buttonText);
|
|
||||||
|
|
||||||
this.realElement.appendTo(this.fakeElement).css({
|
|
||||||
position: 'absolute',
|
|
||||||
opacity: 0
|
|
||||||
});
|
|
||||||
},
|
|
||||||
attachEvents: function() {
|
|
||||||
this.realElement.on({
|
|
||||||
'jcf-pointerdown': this.onPress,
|
|
||||||
change: this.onChange,
|
|
||||||
focus: this.onFocus
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onChange: function() {
|
|
||||||
this.refresh();
|
|
||||||
},
|
|
||||||
onFocus: function() {
|
|
||||||
this.fakeElement.addClass(this.options.focusClass);
|
|
||||||
this.realElement.on('blur', this.onBlur);
|
|
||||||
},
|
|
||||||
onBlur: function() {
|
|
||||||
this.fakeElement.removeClass(this.options.focusClass);
|
|
||||||
this.realElement.off('blur', this.onBlur);
|
|
||||||
},
|
|
||||||
onPress: function() {
|
|
||||||
this.fakeElement.addClass(this.options.pressedClass);
|
|
||||||
this.doc.on('jcf-pointerup', this.onRelease);
|
|
||||||
},
|
|
||||||
onRelease: function() {
|
|
||||||
this.fakeElement.removeClass(this.options.pressedClass);
|
|
||||||
this.doc.off('jcf-pointerup', this.onRelease);
|
|
||||||
},
|
|
||||||
getFileName: function() {
|
|
||||||
var resultFileName = '',
|
|
||||||
files = this.realElement.prop('files');
|
|
||||||
|
|
||||||
if (files && files.length) {
|
|
||||||
$.each(files, function(index, file) {
|
|
||||||
resultFileName += (index > 0 ? ', ' : '') + file.name;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
resultFileName = this.realElement.val().replace(/^[\s\S]*(?:\\|\/)([\s\S^\\\/]*)$/g, '$1');
|
|
||||||
}
|
|
||||||
|
|
||||||
return resultFileName;
|
|
||||||
},
|
|
||||||
getFileExtension: function() {
|
|
||||||
var fileName = this.realElement.val();
|
|
||||||
return fileName.lastIndexOf('.') < 0 ? '' : fileName.substring(fileName.lastIndexOf('.') + 1).toLowerCase();
|
|
||||||
},
|
|
||||||
updateExtensionClass: function() {
|
|
||||||
var currentExtension = this.getFileExtension(),
|
|
||||||
currentClassList = this.fakeElement.prop('className'),
|
|
||||||
cleanedClassList = currentClassList.replace(new RegExp('(\\s|^)' + this.options.extensionPrefixClass + '[^ ]+','gi'), '');
|
|
||||||
|
|
||||||
this.fakeElement.prop('className', cleanedClassList);
|
|
||||||
if (currentExtension) {
|
|
||||||
this.fakeElement.addClass(this.options.extensionPrefixClass + currentExtension);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
refresh: function() {
|
|
||||||
var selectedFileName = this.getFileName() || this.options.placeholderText;
|
|
||||||
this.fakeElement.toggleClass(this.options.disabledClass, this.realElement.is(':disabled'));
|
|
||||||
this.fileNameBlock.text(selectedFileName);
|
|
||||||
this.updateExtensionClass();
|
|
||||||
},
|
|
||||||
destroy: function() {
|
|
||||||
// reset styles and restore element position
|
|
||||||
this.realElement.insertBefore(this.fakeElement).removeClass(this.options.realElementClass).css({
|
|
||||||
position: '',
|
|
||||||
opacity: ''
|
|
||||||
});
|
|
||||||
this.fakeElement.remove();
|
|
||||||
|
|
||||||
// remove event handlers
|
|
||||||
this.realElement.off({
|
|
||||||
'jcf-pointerdown': this.onPress,
|
|
||||||
change: this.onChange,
|
|
||||||
focus: this.onFocus,
|
|
||||||
blur: this.onBlur
|
|
||||||
});
|
|
||||||
this.doc.off('jcf-pointerup', this.onRelease);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
}(jcf));
|
|
|
@ -1,452 +0,0 @@
|
||||||
/*!
|
|
||||||
* JavaScript Custom Forms
|
|
||||||
*
|
|
||||||
* Copyright 2014-2015 PSD2HTML - http://psd2html.com/jcf
|
|
||||||
* Released under the MIT license (LICENSE.txt)
|
|
||||||
*
|
|
||||||
* Version: 1.2.1
|
|
||||||
*/
|
|
||||||
;(function(root, factory) {
|
|
||||||
'use strict';
|
|
||||||
if (typeof define === 'function' && define.amd) {
|
|
||||||
define(['jquery'], factory);
|
|
||||||
} else if (typeof exports === 'object') {
|
|
||||||
module.exports = factory(require('jquery'));
|
|
||||||
} else {
|
|
||||||
root.jcf = factory(jQuery);
|
|
||||||
}
|
|
||||||
}(this, function($) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
// define version
|
|
||||||
var version = '1.2.1';
|
|
||||||
|
|
||||||
// private variables
|
|
||||||
var customInstances = [];
|
|
||||||
|
|
||||||
// default global options
|
|
||||||
var commonOptions = {
|
|
||||||
optionsKey: 'jcf',
|
|
||||||
dataKey: 'jcf-instance',
|
|
||||||
rtlClass: 'jcf-rtl',
|
|
||||||
focusClass: 'jcf-focus',
|
|
||||||
pressedClass: 'jcf-pressed',
|
|
||||||
disabledClass: 'jcf-disabled',
|
|
||||||
hiddenClass: 'jcf-hidden',
|
|
||||||
resetAppearanceClass: 'jcf-reset-appearance',
|
|
||||||
unselectableClass: 'jcf-unselectable'
|
|
||||||
};
|
|
||||||
|
|
||||||
// detect device type
|
|
||||||
var isTouchDevice = ('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch,
|
|
||||||
isWinPhoneDevice = /Windows Phone/.test(navigator.userAgent);
|
|
||||||
commonOptions.isMobileDevice = !!(isTouchDevice || isWinPhoneDevice);
|
|
||||||
|
|
||||||
// create global stylesheet if custom forms are used
|
|
||||||
var createStyleSheet = function() {
|
|
||||||
var styleTag = $('<style>').appendTo('head'),
|
|
||||||
styleSheet = styleTag.prop('sheet') || styleTag.prop('styleSheet');
|
|
||||||
|
|
||||||
// crossbrowser style handling
|
|
||||||
var addCSSRule = function(selector, rules, index) {
|
|
||||||
if (styleSheet.insertRule) {
|
|
||||||
styleSheet.insertRule(selector + '{' + rules + '}', index);
|
|
||||||
} else {
|
|
||||||
styleSheet.addRule(selector, rules, index);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// add special rules
|
|
||||||
addCSSRule('.' + commonOptions.hiddenClass, 'position:absolute !important;left:-9999px !important;height:1px !important;width:1px !important;margin:0 !important;border-width:0 !important;-webkit-appearance:none;-moz-appearance:none;appearance:none');
|
|
||||||
addCSSRule('.' + commonOptions.rtlClass + ' .' + commonOptions.hiddenClass, 'right:-9999px !important; left: auto !important');
|
|
||||||
addCSSRule('.' + commonOptions.unselectableClass, '-webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; -webkit-tap-highlight-color: rgba(0,0,0,0);');
|
|
||||||
addCSSRule('.' + commonOptions.resetAppearanceClass, 'background: none; border: none; -webkit-appearance: none; appearance: none; opacity: 0; filter: alpha(opacity=0);');
|
|
||||||
|
|
||||||
// detect rtl pages
|
|
||||||
var html = $('html'), body = $('body');
|
|
||||||
if (html.css('direction') === 'rtl' || body.css('direction') === 'rtl') {
|
|
||||||
html.addClass(commonOptions.rtlClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle form reset event
|
|
||||||
html.on('reset', function() {
|
|
||||||
setTimeout(function() {
|
|
||||||
api.refreshAll();
|
|
||||||
}, 0);
|
|
||||||
});
|
|
||||||
|
|
||||||
// mark stylesheet as created
|
|
||||||
commonOptions.styleSheetCreated = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
// simplified pointer events handler
|
|
||||||
(function() {
|
|
||||||
var pointerEventsSupported = navigator.pointerEnabled || navigator.msPointerEnabled,
|
|
||||||
touchEventsSupported = ('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch,
|
|
||||||
eventList, eventMap = {}, eventPrefix = 'jcf-';
|
|
||||||
|
|
||||||
// detect events to attach
|
|
||||||
if (pointerEventsSupported) {
|
|
||||||
eventList = {
|
|
||||||
pointerover: navigator.pointerEnabled ? 'pointerover' : 'MSPointerOver',
|
|
||||||
pointerdown: navigator.pointerEnabled ? 'pointerdown' : 'MSPointerDown',
|
|
||||||
pointermove: navigator.pointerEnabled ? 'pointermove' : 'MSPointerMove',
|
|
||||||
pointerup: navigator.pointerEnabled ? 'pointerup' : 'MSPointerUp'
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
eventList = {
|
|
||||||
pointerover: 'mouseover',
|
|
||||||
pointerdown: 'mousedown' + (touchEventsSupported ? ' touchstart' : ''),
|
|
||||||
pointermove: 'mousemove' + (touchEventsSupported ? ' touchmove' : ''),
|
|
||||||
pointerup: 'mouseup' + (touchEventsSupported ? ' touchend' : '')
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// create event map
|
|
||||||
$.each(eventList, function(targetEventName, fakeEventList) {
|
|
||||||
$.each(fakeEventList.split(' '), function(index, fakeEventName) {
|
|
||||||
eventMap[fakeEventName] = targetEventName;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// jQuery event hooks
|
|
||||||
$.each(eventList, function(eventName, eventHandlers) {
|
|
||||||
eventHandlers = eventHandlers.split(' ');
|
|
||||||
$.event.special[eventPrefix + eventName] = {
|
|
||||||
setup: function() {
|
|
||||||
var self = this;
|
|
||||||
$.each(eventHandlers, function(index, fallbackEvent) {
|
|
||||||
if (self.addEventListener) self.addEventListener(fallbackEvent, fixEvent, false);
|
|
||||||
else self['on' + fallbackEvent] = fixEvent;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
teardown: function() {
|
|
||||||
var self = this;
|
|
||||||
$.each(eventHandlers, function(index, fallbackEvent) {
|
|
||||||
if (self.addEventListener) self.removeEventListener(fallbackEvent, fixEvent, false);
|
|
||||||
else self['on' + fallbackEvent] = null;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// check that mouse event are not simulated by mobile browsers
|
|
||||||
var lastTouch = null;
|
|
||||||
var mouseEventSimulated = function(e) {
|
|
||||||
var dx = Math.abs(e.pageX - lastTouch.x),
|
|
||||||
dy = Math.abs(e.pageY - lastTouch.y),
|
|
||||||
rangeDistance = 25;
|
|
||||||
|
|
||||||
if (dx <= rangeDistance && dy <= rangeDistance) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// normalize event
|
|
||||||
var fixEvent = function(e) {
|
|
||||||
var origEvent = e || window.event,
|
|
||||||
touchEventData = null,
|
|
||||||
targetEventName = eventMap[origEvent.type];
|
|
||||||
|
|
||||||
e = $.event.fix(origEvent);
|
|
||||||
e.type = eventPrefix + targetEventName;
|
|
||||||
|
|
||||||
if (origEvent.pointerType) {
|
|
||||||
switch (origEvent.pointerType) {
|
|
||||||
case 2: e.pointerType = 'touch'; break;
|
|
||||||
case 3: e.pointerType = 'pen'; break;
|
|
||||||
case 4: e.pointerType = 'mouse'; break;
|
|
||||||
default: e.pointerType = origEvent.pointerType;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
e.pointerType = origEvent.type.substr(0, 5); // "mouse" or "touch" word length
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!e.pageX && !e.pageY) {
|
|
||||||
touchEventData = origEvent.changedTouches ? origEvent.changedTouches[0] : origEvent;
|
|
||||||
e.pageX = touchEventData.pageX;
|
|
||||||
e.pageY = touchEventData.pageY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (origEvent.type === 'touchend') {
|
|
||||||
lastTouch = { x: e.pageX, y: e.pageY };
|
|
||||||
}
|
|
||||||
if (e.pointerType === 'mouse' && lastTouch && mouseEventSimulated(e)) {
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
return ($.event.dispatch || $.event.handle).call(this, e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}());
|
|
||||||
|
|
||||||
// custom mousewheel/trackpad handler
|
|
||||||
(function() {
|
|
||||||
var wheelEvents = ('onwheel' in document || document.documentMode >= 9 ? 'wheel' : 'mousewheel DOMMouseScroll').split(' '),
|
|
||||||
shimEventName = 'jcf-mousewheel';
|
|
||||||
|
|
||||||
$.event.special[shimEventName] = {
|
|
||||||
setup: function() {
|
|
||||||
var self = this;
|
|
||||||
$.each(wheelEvents, function(index, fallbackEvent) {
|
|
||||||
if (self.addEventListener) self.addEventListener(fallbackEvent, fixEvent, false);
|
|
||||||
else self['on' + fallbackEvent] = fixEvent;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
teardown: function() {
|
|
||||||
var self = this;
|
|
||||||
$.each(wheelEvents, function(index, fallbackEvent) {
|
|
||||||
if (self.addEventListener) self.removeEventListener(fallbackEvent, fixEvent, false);
|
|
||||||
else self['on' + fallbackEvent] = null;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var fixEvent = function(e) {
|
|
||||||
var origEvent = e || window.event;
|
|
||||||
e = $.event.fix(origEvent);
|
|
||||||
e.type = shimEventName;
|
|
||||||
|
|
||||||
// old wheel events handler
|
|
||||||
if ('detail' in origEvent) { e.deltaY = -origEvent.detail; }
|
|
||||||
if ('wheelDelta' in origEvent) { e.deltaY = -origEvent.wheelDelta; }
|
|
||||||
if ('wheelDeltaY' in origEvent) { e.deltaY = -origEvent.wheelDeltaY; }
|
|
||||||
if ('wheelDeltaX' in origEvent) { e.deltaX = -origEvent.wheelDeltaX; }
|
|
||||||
|
|
||||||
// modern wheel event handler
|
|
||||||
if ('deltaY' in origEvent) {
|
|
||||||
e.deltaY = origEvent.deltaY;
|
|
||||||
}
|
|
||||||
if ('deltaX' in origEvent) {
|
|
||||||
e.deltaX = origEvent.deltaX;
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle deltaMode for mouse wheel
|
|
||||||
e.delta = e.deltaY || e.deltaX;
|
|
||||||
if (origEvent.deltaMode === 1) {
|
|
||||||
var lineHeight = 16;
|
|
||||||
e.delta *= lineHeight;
|
|
||||||
e.deltaY *= lineHeight;
|
|
||||||
e.deltaX *= lineHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ($.event.dispatch || $.event.handle).call(this, e);
|
|
||||||
};
|
|
||||||
}());
|
|
||||||
|
|
||||||
// extra module methods
|
|
||||||
var moduleMixin = {
|
|
||||||
// provide function for firing native events
|
|
||||||
fireNativeEvent: function(elements, eventName) {
|
|
||||||
$(elements).each(function() {
|
|
||||||
var element = this, eventObject;
|
|
||||||
if (element.dispatchEvent) {
|
|
||||||
eventObject = document.createEvent('HTMLEvents');
|
|
||||||
eventObject.initEvent(eventName, true, true);
|
|
||||||
element.dispatchEvent(eventObject);
|
|
||||||
} else if (document.createEventObject) {
|
|
||||||
eventObject = document.createEventObject();
|
|
||||||
eventObject.target = element;
|
|
||||||
element.fireEvent('on' + eventName, eventObject);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
// bind event handlers for module instance (functions beggining with "on")
|
|
||||||
bindHandlers: function() {
|
|
||||||
var self = this;
|
|
||||||
$.each(self, function(propName, propValue) {
|
|
||||||
if (propName.indexOf('on') === 0 && $.isFunction(propValue)) {
|
|
||||||
// dont use $.proxy here because it doesn't create unique handler
|
|
||||||
self[propName] = function() {
|
|
||||||
return propValue.apply(self, arguments);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// public API
|
|
||||||
var api = {
|
|
||||||
version: version,
|
|
||||||
modules: {},
|
|
||||||
getOptions: function() {
|
|
||||||
return $.extend({}, commonOptions);
|
|
||||||
},
|
|
||||||
setOptions: function(moduleName, moduleOptions) {
|
|
||||||
if (arguments.length > 1) {
|
|
||||||
// set module options
|
|
||||||
if (this.modules[moduleName]) {
|
|
||||||
$.extend(this.modules[moduleName].prototype.options, moduleOptions);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// set common options
|
|
||||||
$.extend(commonOptions, moduleName);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
addModule: function(proto) {
|
|
||||||
// proto is factory function
|
|
||||||
if ($.isFunction(proto)) {
|
|
||||||
proto = proto($, window);
|
|
||||||
}
|
|
||||||
|
|
||||||
// add module to list
|
|
||||||
var Module = function(options) {
|
|
||||||
// save instance to collection
|
|
||||||
if (!options.element.data(commonOptions.dataKey)) {
|
|
||||||
options.element.data(commonOptions.dataKey, this);
|
|
||||||
}
|
|
||||||
customInstances.push(this);
|
|
||||||
|
|
||||||
// save options
|
|
||||||
this.options = $.extend({}, commonOptions, this.options, getInlineOptions(options.element), options);
|
|
||||||
|
|
||||||
// bind event handlers to instance
|
|
||||||
this.bindHandlers();
|
|
||||||
|
|
||||||
// call constructor
|
|
||||||
this.init.apply(this, arguments);
|
|
||||||
};
|
|
||||||
|
|
||||||
// parse options from HTML attribute
|
|
||||||
var getInlineOptions = function(element) {
|
|
||||||
var dataOptions = element.data(commonOptions.optionsKey),
|
|
||||||
attrOptions = element.attr(commonOptions.optionsKey);
|
|
||||||
|
|
||||||
if (dataOptions) {
|
|
||||||
return dataOptions;
|
|
||||||
} else if (attrOptions) {
|
|
||||||
try {
|
|
||||||
return $.parseJSON(attrOptions);
|
|
||||||
} catch (e) {
|
|
||||||
// ignore invalid attributes
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// set proto as prototype for new module
|
|
||||||
Module.prototype = proto;
|
|
||||||
|
|
||||||
// add mixin methods to module proto
|
|
||||||
$.extend(proto, moduleMixin);
|
|
||||||
if (proto.plugins) {
|
|
||||||
$.each(proto.plugins, function(pluginName, plugin) {
|
|
||||||
$.extend(plugin.prototype, moduleMixin);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// override destroy method
|
|
||||||
var originalDestroy = Module.prototype.destroy;
|
|
||||||
Module.prototype.destroy = function() {
|
|
||||||
this.options.element.removeData(this.options.dataKey);
|
|
||||||
|
|
||||||
for (var i = customInstances.length - 1; i >= 0; i--) {
|
|
||||||
if (customInstances[i] === this) {
|
|
||||||
customInstances.splice(i, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (originalDestroy) {
|
|
||||||
originalDestroy.apply(this, arguments);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// save module to list
|
|
||||||
this.modules[proto.name] = Module;
|
|
||||||
},
|
|
||||||
getInstance: function(element) {
|
|
||||||
return $(element).data(commonOptions.dataKey);
|
|
||||||
},
|
|
||||||
replace: function(elements, moduleName, customOptions) {
|
|
||||||
var self = this,
|
|
||||||
instance;
|
|
||||||
|
|
||||||
if (!commonOptions.styleSheetCreated) {
|
|
||||||
createStyleSheet();
|
|
||||||
}
|
|
||||||
|
|
||||||
$(elements).each(function() {
|
|
||||||
var moduleOptions,
|
|
||||||
element = $(this);
|
|
||||||
|
|
||||||
instance = element.data(commonOptions.dataKey);
|
|
||||||
if (instance) {
|
|
||||||
instance.refresh();
|
|
||||||
} else {
|
|
||||||
if (!moduleName) {
|
|
||||||
$.each(self.modules, function(currentModuleName, module) {
|
|
||||||
if (module.prototype.matchElement.call(module.prototype, element)) {
|
|
||||||
moduleName = currentModuleName;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (moduleName) {
|
|
||||||
moduleOptions = $.extend({ element: element }, customOptions);
|
|
||||||
instance = new self.modules[moduleName](moduleOptions);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return instance;
|
|
||||||
},
|
|
||||||
refresh: function(elements) {
|
|
||||||
$(elements).each(function() {
|
|
||||||
var instance = $(this).data(commonOptions.dataKey);
|
|
||||||
if (instance) {
|
|
||||||
instance.refresh();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
destroy: function(elements) {
|
|
||||||
$(elements).each(function() {
|
|
||||||
var instance = $(this).data(commonOptions.dataKey);
|
|
||||||
if (instance) {
|
|
||||||
instance.destroy();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
replaceAll: function(context) {
|
|
||||||
var self = this;
|
|
||||||
$.each(this.modules, function(moduleName, module) {
|
|
||||||
$(module.prototype.selector, context).each(function() {
|
|
||||||
if (this.className.indexOf('jcf-ignore') < 0) {
|
|
||||||
self.replace(this, moduleName);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
refreshAll: function(context) {
|
|
||||||
if (context) {
|
|
||||||
$.each(this.modules, function(moduleName, module) {
|
|
||||||
$(module.prototype.selector, context).each(function() {
|
|
||||||
var instance = $(this).data(commonOptions.dataKey);
|
|
||||||
if (instance) {
|
|
||||||
instance.refresh();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
for (var i = customInstances.length - 1; i >= 0; i--) {
|
|
||||||
customInstances[i].refresh();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
destroyAll: function(context) {
|
|
||||||
if (context) {
|
|
||||||
$.each(this.modules, function(moduleName, module) {
|
|
||||||
$(module.prototype.selector, context).each(function(index, element) {
|
|
||||||
var instance = $(element).data(commonOptions.dataKey);
|
|
||||||
if (instance) {
|
|
||||||
instance.destroy();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
while (customInstances.length) {
|
|
||||||
customInstances[0].destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return api;
|
|
||||||
}));
|
|
|
@ -1,187 +0,0 @@
|
||||||
/*!
|
|
||||||
* JavaScript Custom Forms : Number Module
|
|
||||||
*
|
|
||||||
* Copyright 2014-2015 PSD2HTML - http://psd2html.com/jcf
|
|
||||||
* Released under the MIT license (LICENSE.txt)
|
|
||||||
*
|
|
||||||
* Version: 1.2.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function(jcf) {
|
|
||||||
|
|
||||||
jcf.addModule(function($) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
return {
|
|
||||||
name: 'Number',
|
|
||||||
selector: 'input[type="number"]',
|
|
||||||
options: {
|
|
||||||
realElementClass: 'jcf-real-element',
|
|
||||||
fakeStructure: '<span class="jcf-number"><span class="jcf-btn-inc"></span><span class="jcf-btn-dec"></span></span>',
|
|
||||||
btnIncSelector: '.jcf-btn-inc',
|
|
||||||
btnDecSelector: '.jcf-btn-dec',
|
|
||||||
pressInterval: 150
|
|
||||||
},
|
|
||||||
matchElement: function(element) {
|
|
||||||
return element.is(this.selector);
|
|
||||||
},
|
|
||||||
init: function() {
|
|
||||||
this.initStructure();
|
|
||||||
this.attachEvents();
|
|
||||||
this.refresh();
|
|
||||||
},
|
|
||||||
initStructure: function() {
|
|
||||||
this.page = $('html');
|
|
||||||
this.realElement = $(this.options.element).addClass(this.options.realElementClass);
|
|
||||||
this.fakeElement = $(this.options.fakeStructure).insertBefore(this.realElement).prepend(this.realElement);
|
|
||||||
this.btnDec = this.fakeElement.find(this.options.btnDecSelector);
|
|
||||||
this.btnInc = this.fakeElement.find(this.options.btnIncSelector);
|
|
||||||
|
|
||||||
// set initial values
|
|
||||||
this.initialValue = parseFloat(this.realElement.val()) || 0;
|
|
||||||
this.minValue = parseFloat(this.realElement.attr('min'));
|
|
||||||
this.maxValue = parseFloat(this.realElement.attr('max'));
|
|
||||||
this.stepValue = parseFloat(this.realElement.attr('step')) || 1;
|
|
||||||
|
|
||||||
// check attribute values
|
|
||||||
this.minValue = isNaN(this.minValue) ? -Infinity : this.minValue;
|
|
||||||
this.maxValue = isNaN(this.maxValue) ? Infinity : this.maxValue;
|
|
||||||
|
|
||||||
// handle range
|
|
||||||
if (isFinite(this.maxValue)) {
|
|
||||||
this.maxValue -= (this.maxValue - this.minValue) % this.stepValue;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
attachEvents: function() {
|
|
||||||
this.realElement.on({
|
|
||||||
focus: this.onFocus
|
|
||||||
});
|
|
||||||
this.btnDec.add(this.btnInc).on('jcf-pointerdown', this.onBtnPress);
|
|
||||||
},
|
|
||||||
onBtnPress: function(e) {
|
|
||||||
var self = this,
|
|
||||||
increment;
|
|
||||||
|
|
||||||
if (!this.realElement.is(':disabled')) {
|
|
||||||
increment = this.btnInc.is(e.currentTarget);
|
|
||||||
|
|
||||||
self.step(increment);
|
|
||||||
clearInterval(this.stepTimer);
|
|
||||||
this.stepTimer = setInterval(function() {
|
|
||||||
self.step(increment);
|
|
||||||
}, this.options.pressInterval);
|
|
||||||
|
|
||||||
this.page.on('jcf-pointerup', this.onBtnRelease);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onBtnRelease: function() {
|
|
||||||
clearInterval(this.stepTimer);
|
|
||||||
this.page.off('jcf-pointerup', this.onBtnRelease);
|
|
||||||
},
|
|
||||||
onFocus: function() {
|
|
||||||
this.fakeElement.addClass(this.options.focusClass);
|
|
||||||
//rameez add
|
|
||||||
this.fakeElement.addClass('number');
|
|
||||||
|
|
||||||
this.realElement.on({
|
|
||||||
blur: this.onBlur,
|
|
||||||
keydown: this.onKeyPress
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onBlur: function() {
|
|
||||||
this.fakeElement.removeClass(this.options.focusClass);
|
|
||||||
// var numberValue = $('.jcf-number').val();
|
|
||||||
// alert(numberValue);
|
|
||||||
// if ( numberValue.is(":empty") ) {
|
|
||||||
// this.fakeElement.removeClass('number');
|
|
||||||
// }
|
|
||||||
/*if ($(this).val()=='') {
|
|
||||||
this.fakeElement.removeClass('number');
|
|
||||||
}*/
|
|
||||||
//console.log(this.find('.jcf-real-element').html());
|
|
||||||
|
|
||||||
if( this.empty() )
|
|
||||||
{
|
|
||||||
this.fakeElement.removeClass('number');
|
|
||||||
}
|
|
||||||
this.realElement.off({
|
|
||||||
blur: this.onBlur,
|
|
||||||
keydown: this.onKeyPress
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onKeyPress: function(e) {
|
|
||||||
if (e.which === 38 || e.which === 40) {
|
|
||||||
e.preventDefault();
|
|
||||||
this.step(e.which === 38);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
step: function(increment) {
|
|
||||||
var originalValue = parseFloat(this.realElement.val()),
|
|
||||||
newValue = originalValue || 0,
|
|
||||||
addValue = this.stepValue * (increment ? 1 : -1),
|
|
||||||
edgeNumber = isFinite(this.minValue) ? this.minValue : this.initialValue - Math.abs(newValue * this.stepValue),
|
|
||||||
diff = Math.abs(edgeNumber - newValue) % this.stepValue;
|
|
||||||
|
|
||||||
// handle step diff
|
|
||||||
if (diff) {
|
|
||||||
if (increment) {
|
|
||||||
newValue += addValue - diff;
|
|
||||||
} else {
|
|
||||||
newValue -= diff;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
newValue += addValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle min/max limits
|
|
||||||
if (newValue < this.minValue) {
|
|
||||||
newValue = this.minValue;
|
|
||||||
} else if (newValue > this.maxValue) {
|
|
||||||
newValue = this.maxValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// update value in real input if its changed
|
|
||||||
if (newValue !== originalValue) {
|
|
||||||
this.realElement.val(newValue).trigger('change');
|
|
||||||
this.refresh();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
refresh: function() {
|
|
||||||
var isDisabled = this.realElement.is(':disabled'),
|
|
||||||
currentValue = parseFloat(this.realElement.val());
|
|
||||||
|
|
||||||
// handle disabled state
|
|
||||||
this.fakeElement.toggleClass(this.options.disabledClass, isDisabled);
|
|
||||||
|
|
||||||
// refresh button classes
|
|
||||||
this.btnDec.toggleClass(this.options.disabledClass, currentValue === this.minValue);
|
|
||||||
this.btnInc.toggleClass(this.options.disabledClass, currentValue === this.maxValue);
|
|
||||||
},
|
|
||||||
destroy: function() {
|
|
||||||
// restore original structure
|
|
||||||
this.realElement.removeClass(this.options.realElementClass).insertBefore(this.fakeElement);
|
|
||||||
this.fakeElement.remove();
|
|
||||||
clearInterval(this.stepTimer);
|
|
||||||
|
|
||||||
// remove event handlers
|
|
||||||
this.page.off('jcf-pointerup', this.onBtnRelease);
|
|
||||||
this.realElement.off({
|
|
||||||
keydown: this.onKeyPress,
|
|
||||||
focus: this.onFocus,
|
|
||||||
blur: this.onBlur
|
|
||||||
});
|
|
||||||
},
|
|
||||||
empty: function() {
|
|
||||||
|
|
||||||
var realValue = parseFloat( this.realElement.val() );
|
|
||||||
|
|
||||||
if(isNaN(realValue))
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
}(jcf));
|
|
|
@ -1,195 +0,0 @@
|
||||||
/*!
|
|
||||||
* JavaScript Custom Forms : Radio Module
|
|
||||||
*
|
|
||||||
* Copyright 2014-2015 PSD2HTML - http://psd2html.com/jcf
|
|
||||||
* Released under the MIT license (LICENSE.txt)
|
|
||||||
*
|
|
||||||
* Version: 1.2.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function(jcf) {
|
|
||||||
|
|
||||||
jcf.addModule(function($) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
return {
|
|
||||||
name: 'Radio',
|
|
||||||
selector: 'input[type="radio"]',
|
|
||||||
options: {
|
|
||||||
wrapNative: true,
|
|
||||||
checkedClass: 'jcf-checked',
|
|
||||||
uncheckedClass: 'jcf-unchecked',
|
|
||||||
labelActiveClass: 'jcf-label-active',
|
|
||||||
fakeStructure: '<span class="jcf-radio"><span></span></span>'
|
|
||||||
},
|
|
||||||
matchElement: function(element) {
|
|
||||||
return element.is(':radio');
|
|
||||||
},
|
|
||||||
init: function() {
|
|
||||||
this.initStructure();
|
|
||||||
this.attachEvents();
|
|
||||||
this.refresh();
|
|
||||||
},
|
|
||||||
initStructure: function() {
|
|
||||||
// prepare structure
|
|
||||||
this.doc = $(document);
|
|
||||||
this.realElement = $(this.options.element);
|
|
||||||
this.fakeElement = $(this.options.fakeStructure).insertAfter(this.realElement);
|
|
||||||
this.labelElement = this.getLabelFor();
|
|
||||||
|
|
||||||
if (this.options.wrapNative) {
|
|
||||||
// wrap native radio inside fake block
|
|
||||||
this.realElement.prependTo(this.fakeElement).css({
|
|
||||||
position: 'absolute',
|
|
||||||
opacity: 0
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// just hide native radio
|
|
||||||
this.realElement.addClass(this.options.hiddenClass);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
attachEvents: function() {
|
|
||||||
// add event handlers
|
|
||||||
this.realElement.on({
|
|
||||||
focus: this.onFocus,
|
|
||||||
click: this.onRealClick
|
|
||||||
});
|
|
||||||
this.fakeElement.on('click', this.onFakeClick);
|
|
||||||
this.fakeElement.on('jcf-pointerdown', this.onPress);
|
|
||||||
},
|
|
||||||
onRealClick: function(e) {
|
|
||||||
// redraw current radio and its group (setTimeout handles click that might be prevented)
|
|
||||||
var self = this;
|
|
||||||
this.savedEventObject = e;
|
|
||||||
setTimeout(function() {
|
|
||||||
self.refreshRadioGroup();
|
|
||||||
}, 0);
|
|
||||||
},
|
|
||||||
onFakeClick: function(e) {
|
|
||||||
// skip event if clicked on real element inside wrapper
|
|
||||||
if (this.options.wrapNative && this.realElement.is(e.target)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// toggle checked class
|
|
||||||
if (!this.realElement.is(':disabled')) {
|
|
||||||
delete this.savedEventObject;
|
|
||||||
this.currentActiveRadio = this.getCurrentActiveRadio();
|
|
||||||
this.stateChecked = this.realElement.prop('checked');
|
|
||||||
this.realElement.prop('checked', true);
|
|
||||||
this.fireNativeEvent(this.realElement, 'click');
|
|
||||||
if (this.savedEventObject && this.savedEventObject.isDefaultPrevented()) {
|
|
||||||
this.realElement.prop('checked', this.stateChecked);
|
|
||||||
this.currentActiveRadio.prop('checked', true);
|
|
||||||
} else {
|
|
||||||
this.fireNativeEvent(this.realElement, 'change');
|
|
||||||
}
|
|
||||||
delete this.savedEventObject;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onFocus: function() {
|
|
||||||
if (!this.pressedFlag || !this.focusedFlag) {
|
|
||||||
this.focusedFlag = true;
|
|
||||||
this.fakeElement.addClass(this.options.focusClass);
|
|
||||||
this.realElement.on('blur', this.onBlur);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onBlur: function() {
|
|
||||||
if (!this.pressedFlag) {
|
|
||||||
this.focusedFlag = false;
|
|
||||||
this.fakeElement.removeClass(this.options.focusClass);
|
|
||||||
this.realElement.off('blur', this.onBlur);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onPress: function(e) {
|
|
||||||
if (!this.focusedFlag && e.pointerType === 'mouse') {
|
|
||||||
this.realElement.focus();
|
|
||||||
}
|
|
||||||
this.pressedFlag = true;
|
|
||||||
this.fakeElement.addClass(this.options.pressedClass);
|
|
||||||
this.doc.on('jcf-pointerup', this.onRelease);
|
|
||||||
},
|
|
||||||
onRelease: function(e) {
|
|
||||||
if (this.focusedFlag && e.pointerType === 'mouse') {
|
|
||||||
this.realElement.focus();
|
|
||||||
}
|
|
||||||
this.pressedFlag = false;
|
|
||||||
this.fakeElement.removeClass(this.options.pressedClass);
|
|
||||||
this.doc.off('jcf-pointerup', this.onRelease);
|
|
||||||
},
|
|
||||||
getCurrentActiveRadio: function() {
|
|
||||||
return this.getRadioGroup(this.realElement).filter(':checked');
|
|
||||||
},
|
|
||||||
getRadioGroup: function(radio) {
|
|
||||||
// find radio group for specified radio button
|
|
||||||
var name = radio.attr('name'),
|
|
||||||
parentForm = radio.parents('form');
|
|
||||||
|
|
||||||
if (name) {
|
|
||||||
if (parentForm.length) {
|
|
||||||
return parentForm.find('input[name="' + name + '"]');
|
|
||||||
} else {
|
|
||||||
return $('input[name="' + name + '"]:not(form input)');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return radio;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getLabelFor: function() {
|
|
||||||
var parentLabel = this.realElement.closest('label'),
|
|
||||||
elementId = this.realElement.prop('id');
|
|
||||||
|
|
||||||
if (!parentLabel.length && elementId) {
|
|
||||||
parentLabel = $('label[for="' + elementId + '"]');
|
|
||||||
}
|
|
||||||
return parentLabel.length ? parentLabel : null;
|
|
||||||
},
|
|
||||||
refreshRadioGroup: function() {
|
|
||||||
// redraw current radio and its group
|
|
||||||
this.getRadioGroup(this.realElement).each(function() {
|
|
||||||
jcf.refresh(this);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
refresh: function() {
|
|
||||||
// redraw current radio button
|
|
||||||
var isChecked = this.realElement.is(':checked'),
|
|
||||||
isDisabled = this.realElement.is(':disabled');
|
|
||||||
|
|
||||||
this.fakeElement.toggleClass(this.options.checkedClass, isChecked)
|
|
||||||
.toggleClass(this.options.uncheckedClass, !isChecked)
|
|
||||||
.toggleClass(this.options.disabledClass, isDisabled);
|
|
||||||
|
|
||||||
if (this.labelElement) {
|
|
||||||
this.labelElement.toggleClass(this.options.labelActiveClass, isChecked);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
destroy: function() {
|
|
||||||
// restore structure
|
|
||||||
if (this.options.wrapNative) {
|
|
||||||
this.realElement.insertBefore(this.fakeElement).css({
|
|
||||||
position: '',
|
|
||||||
width: '',
|
|
||||||
height: '',
|
|
||||||
opacity: '',
|
|
||||||
margin: ''
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.realElement.removeClass(this.options.hiddenClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
// removing element will also remove its event handlers
|
|
||||||
this.fakeElement.off('jcf-pointerdown', this.onPress);
|
|
||||||
this.fakeElement.remove();
|
|
||||||
|
|
||||||
// remove other event handlers
|
|
||||||
this.doc.off('jcf-pointerup', this.onRelease);
|
|
||||||
this.realElement.off({
|
|
||||||
blur: this.onBlur,
|
|
||||||
focus: this.onFocus,
|
|
||||||
click: this.onRealClick
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
}(jcf));
|
|
|
@ -1,668 +0,0 @@
|
||||||
/*!
|
|
||||||
* JavaScript Custom Forms : Scrollbar Module
|
|
||||||
*
|
|
||||||
* Copyright 2014-2015 PSD2HTML - http://psd2html.com/jcf
|
|
||||||
* Released under the MIT license (LICENSE.txt)
|
|
||||||
*
|
|
||||||
* Version: 1.2.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function(jcf) {
|
|
||||||
|
|
||||||
jcf.addModule(function($, window) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var module = {
|
|
||||||
name: 'Scrollable',
|
|
||||||
selector: '.jcf-scrollable',
|
|
||||||
plugins: {
|
|
||||||
ScrollBar: ScrollBar
|
|
||||||
},
|
|
||||||
options: {
|
|
||||||
mouseWheelStep: 150,
|
|
||||||
handleResize: true,
|
|
||||||
alwaysShowScrollbars: false,
|
|
||||||
alwaysPreventMouseWheel: false,
|
|
||||||
scrollAreaStructure: '<div class="jcf-scrollable-wrapper"></div>'
|
|
||||||
},
|
|
||||||
matchElement: function(element) {
|
|
||||||
return element.is('.jcf-scrollable');
|
|
||||||
},
|
|
||||||
init: function() {
|
|
||||||
this.initStructure();
|
|
||||||
this.attachEvents();
|
|
||||||
this.rebuildScrollbars();
|
|
||||||
},
|
|
||||||
initStructure: function() {
|
|
||||||
// prepare structure
|
|
||||||
this.doc = $(document);
|
|
||||||
this.win = $(window);
|
|
||||||
this.realElement = $(this.options.element);
|
|
||||||
this.scrollWrapper = $(this.options.scrollAreaStructure).insertAfter(this.realElement);
|
|
||||||
|
|
||||||
// set initial styles
|
|
||||||
this.scrollWrapper.css('position', 'relative');
|
|
||||||
this.realElement.css('overflow', 'hidden');
|
|
||||||
this.vBarEdge = 0;
|
|
||||||
},
|
|
||||||
attachEvents: function() {
|
|
||||||
// create scrollbars
|
|
||||||
var self = this;
|
|
||||||
this.vBar = new ScrollBar({
|
|
||||||
holder: this.scrollWrapper,
|
|
||||||
vertical: true,
|
|
||||||
onScroll: function(scrollTop) {
|
|
||||||
self.realElement.scrollTop(scrollTop);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.hBar = new ScrollBar({
|
|
||||||
holder: this.scrollWrapper,
|
|
||||||
vertical: false,
|
|
||||||
onScroll: function(scrollLeft) {
|
|
||||||
self.realElement.scrollLeft(scrollLeft);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// add event handlers
|
|
||||||
this.realElement.on('scroll', this.onScroll);
|
|
||||||
if (this.options.handleResize) {
|
|
||||||
this.win.on('resize orientationchange load', this.onResize);
|
|
||||||
}
|
|
||||||
|
|
||||||
// add pointer/wheel event handlers
|
|
||||||
this.realElement.on('jcf-mousewheel', this.onMouseWheel);
|
|
||||||
this.realElement.on('jcf-pointerdown', this.onTouchBody);
|
|
||||||
},
|
|
||||||
onScroll: function() {
|
|
||||||
this.redrawScrollbars();
|
|
||||||
},
|
|
||||||
onResize: function() {
|
|
||||||
// do not rebuild scrollbars if form field is in focus
|
|
||||||
if (!$(document.activeElement).is(':input')) {
|
|
||||||
this.rebuildScrollbars();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onTouchBody: function(e) {
|
|
||||||
if (e.pointerType === 'touch') {
|
|
||||||
this.touchData = {
|
|
||||||
scrollTop: this.realElement.scrollTop(),
|
|
||||||
scrollLeft: this.realElement.scrollLeft(),
|
|
||||||
left: e.pageX,
|
|
||||||
top: e.pageY
|
|
||||||
};
|
|
||||||
this.doc.on({
|
|
||||||
'jcf-pointermove': this.onMoveBody,
|
|
||||||
'jcf-pointerup': this.onReleaseBody
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onMoveBody: function(e) {
|
|
||||||
var targetScrollTop,
|
|
||||||
targetScrollLeft,
|
|
||||||
verticalScrollAllowed = this.verticalScrollActive,
|
|
||||||
horizontalScrollAllowed = this.horizontalScrollActive;
|
|
||||||
|
|
||||||
if (e.pointerType === 'touch') {
|
|
||||||
targetScrollTop = this.touchData.scrollTop - e.pageY + this.touchData.top;
|
|
||||||
targetScrollLeft = this.touchData.scrollLeft - e.pageX + this.touchData.left;
|
|
||||||
|
|
||||||
// check that scrolling is ended and release outer scrolling
|
|
||||||
if (this.verticalScrollActive && (targetScrollTop < 0 || targetScrollTop > this.vBar.maxValue)) {
|
|
||||||
verticalScrollAllowed = false;
|
|
||||||
}
|
|
||||||
if (this.horizontalScrollActive && (targetScrollLeft < 0 || targetScrollLeft > this.hBar.maxValue)) {
|
|
||||||
horizontalScrollAllowed = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.realElement.scrollTop(targetScrollTop);
|
|
||||||
this.realElement.scrollLeft(targetScrollLeft);
|
|
||||||
|
|
||||||
if (verticalScrollAllowed || horizontalScrollAllowed) {
|
|
||||||
e.preventDefault();
|
|
||||||
} else {
|
|
||||||
this.onReleaseBody(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onReleaseBody: function(e) {
|
|
||||||
if (e.pointerType === 'touch') {
|
|
||||||
delete this.touchData;
|
|
||||||
this.doc.off({
|
|
||||||
'jcf-pointermove': this.onMoveBody,
|
|
||||||
'jcf-pointerup': this.onReleaseBody
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onMouseWheel: function(e) {
|
|
||||||
var currentScrollTop = this.realElement.scrollTop(),
|
|
||||||
currentScrollLeft = this.realElement.scrollLeft(),
|
|
||||||
maxScrollTop = this.realElement.prop('scrollHeight') - this.embeddedDimensions.innerHeight,
|
|
||||||
maxScrollLeft = this.realElement.prop('scrollWidth') - this.embeddedDimensions.innerWidth,
|
|
||||||
extraLeft, extraTop, preventFlag;
|
|
||||||
|
|
||||||
// check edge cases
|
|
||||||
if (!this.options.alwaysPreventMouseWheel) {
|
|
||||||
if (this.verticalScrollActive && e.deltaY) {
|
|
||||||
if (!(currentScrollTop <= 0 && e.deltaY < 0) && !(currentScrollTop >= maxScrollTop && e.deltaY > 0)) {
|
|
||||||
preventFlag = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.horizontalScrollActive && e.deltaX) {
|
|
||||||
if (!(currentScrollLeft <= 0 && e.deltaX < 0) && !(currentScrollLeft >= maxScrollLeft && e.deltaX > 0)) {
|
|
||||||
preventFlag = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!this.verticalScrollActive && !this.horizontalScrollActive) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// prevent default action and scroll item
|
|
||||||
if (preventFlag || this.options.alwaysPreventMouseWheel) {
|
|
||||||
e.preventDefault();
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
extraLeft = e.deltaX / 100 * this.options.mouseWheelStep;
|
|
||||||
extraTop = e.deltaY / 100 * this.options.mouseWheelStep;
|
|
||||||
|
|
||||||
this.realElement.scrollTop(currentScrollTop + extraTop);
|
|
||||||
this.realElement.scrollLeft(currentScrollLeft + extraLeft);
|
|
||||||
},
|
|
||||||
setScrollBarEdge: function(edgeSize) {
|
|
||||||
this.vBarEdge = edgeSize || 0;
|
|
||||||
this.redrawScrollbars();
|
|
||||||
},
|
|
||||||
saveElementDimensions: function() {
|
|
||||||
this.savedDimensions = {
|
|
||||||
top: this.realElement.width(),
|
|
||||||
left: this.realElement.height()
|
|
||||||
};
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
restoreElementDimensions: function() {
|
|
||||||
if (this.savedDimensions) {
|
|
||||||
this.realElement.css({
|
|
||||||
width: this.savedDimensions.width,
|
|
||||||
height: this.savedDimensions.height
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
saveScrollOffsets: function() {
|
|
||||||
this.savedOffsets = {
|
|
||||||
top: this.realElement.scrollTop(),
|
|
||||||
left: this.realElement.scrollLeft()
|
|
||||||
};
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
restoreScrollOffsets: function() {
|
|
||||||
if (this.savedOffsets) {
|
|
||||||
this.realElement.scrollTop(this.savedOffsets.top);
|
|
||||||
this.realElement.scrollLeft(this.savedOffsets.left);
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
getContainerDimensions: function() {
|
|
||||||
// save current styles
|
|
||||||
var desiredDimensions,
|
|
||||||
currentStyles,
|
|
||||||
currentHeight,
|
|
||||||
currentWidth;
|
|
||||||
|
|
||||||
if (this.isModifiedStyles) {
|
|
||||||
desiredDimensions = {
|
|
||||||
width: this.realElement.innerWidth() + this.vBar.getThickness(),
|
|
||||||
height: this.realElement.innerHeight() + this.hBar.getThickness()
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
// unwrap real element and measure it according to CSS
|
|
||||||
this.saveElementDimensions().saveScrollOffsets();
|
|
||||||
this.realElement.insertAfter(this.scrollWrapper);
|
|
||||||
this.scrollWrapper.detach();
|
|
||||||
|
|
||||||
// measure element
|
|
||||||
currentStyles = this.realElement.prop('style');
|
|
||||||
currentWidth = parseFloat(currentStyles.width);
|
|
||||||
currentHeight = parseFloat(currentStyles.height);
|
|
||||||
|
|
||||||
// reset styles if needed
|
|
||||||
if (this.embeddedDimensions && currentWidth && currentHeight) {
|
|
||||||
this.isModifiedStyles |= (currentWidth !== this.embeddedDimensions.width || currentHeight !== this.embeddedDimensions.height);
|
|
||||||
this.realElement.css({
|
|
||||||
overflow: '',
|
|
||||||
width: '',
|
|
||||||
height: ''
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// calculate desired dimensions for real element
|
|
||||||
desiredDimensions = {
|
|
||||||
width: this.realElement.outerWidth(),
|
|
||||||
height: this.realElement.outerHeight()
|
|
||||||
};
|
|
||||||
|
|
||||||
// restore structure and original scroll offsets
|
|
||||||
this.scrollWrapper.insertAfter(this.realElement);
|
|
||||||
this.realElement.css('overflow', 'hidden').prependTo(this.scrollWrapper);
|
|
||||||
this.restoreElementDimensions().restoreScrollOffsets();
|
|
||||||
}
|
|
||||||
|
|
||||||
return desiredDimensions;
|
|
||||||
},
|
|
||||||
getEmbeddedDimensions: function(dimensions) {
|
|
||||||
// handle scrollbars cropping
|
|
||||||
var fakeBarWidth = this.vBar.getThickness(),
|
|
||||||
fakeBarHeight = this.hBar.getThickness(),
|
|
||||||
paddingWidth = this.realElement.outerWidth() - this.realElement.width(),
|
|
||||||
paddingHeight = this.realElement.outerHeight() - this.realElement.height(),
|
|
||||||
resultDimensions;
|
|
||||||
|
|
||||||
if (this.options.alwaysShowScrollbars) {
|
|
||||||
// simply return dimensions without custom scrollbars
|
|
||||||
this.verticalScrollActive = true;
|
|
||||||
this.horizontalScrollActive = true;
|
|
||||||
resultDimensions = {
|
|
||||||
innerWidth: dimensions.width - fakeBarWidth,
|
|
||||||
innerHeight: dimensions.height - fakeBarHeight
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
// detect when to display each scrollbar
|
|
||||||
this.saveElementDimensions();
|
|
||||||
this.verticalScrollActive = false;
|
|
||||||
this.horizontalScrollActive = false;
|
|
||||||
|
|
||||||
// fill container with full size
|
|
||||||
this.realElement.css({
|
|
||||||
width: dimensions.width - paddingWidth,
|
|
||||||
height: dimensions.height - paddingHeight
|
|
||||||
});
|
|
||||||
|
|
||||||
this.horizontalScrollActive = this.realElement.prop('scrollWidth') > this.containerDimensions.width;
|
|
||||||
this.verticalScrollActive = this.realElement.prop('scrollHeight') > this.containerDimensions.height;
|
|
||||||
|
|
||||||
this.restoreElementDimensions();
|
|
||||||
resultDimensions = {
|
|
||||||
innerWidth: dimensions.width - (this.verticalScrollActive ? fakeBarWidth : 0),
|
|
||||||
innerHeight: dimensions.height - (this.horizontalScrollActive ? fakeBarHeight : 0)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
$.extend(resultDimensions, {
|
|
||||||
width: resultDimensions.innerWidth - paddingWidth,
|
|
||||||
height: resultDimensions.innerHeight - paddingHeight
|
|
||||||
});
|
|
||||||
return resultDimensions;
|
|
||||||
},
|
|
||||||
rebuildScrollbars: function() {
|
|
||||||
// resize wrapper according to real element styles
|
|
||||||
this.containerDimensions = this.getContainerDimensions();
|
|
||||||
this.embeddedDimensions = this.getEmbeddedDimensions(this.containerDimensions);
|
|
||||||
|
|
||||||
// resize wrapper to desired dimensions
|
|
||||||
this.scrollWrapper.css({
|
|
||||||
width: this.containerDimensions.width,
|
|
||||||
height: this.containerDimensions.height
|
|
||||||
});
|
|
||||||
|
|
||||||
// resize element inside wrapper excluding scrollbar size
|
|
||||||
this.realElement.css({
|
|
||||||
overflow: 'hidden',
|
|
||||||
width: this.embeddedDimensions.width,
|
|
||||||
height: this.embeddedDimensions.height
|
|
||||||
});
|
|
||||||
|
|
||||||
// redraw scrollbar offset
|
|
||||||
this.redrawScrollbars();
|
|
||||||
},
|
|
||||||
redrawScrollbars: function() {
|
|
||||||
var viewSize, maxScrollValue;
|
|
||||||
|
|
||||||
// redraw vertical scrollbar
|
|
||||||
if (this.verticalScrollActive) {
|
|
||||||
viewSize = this.vBarEdge ? this.containerDimensions.height - this.vBarEdge : this.embeddedDimensions.innerHeight;
|
|
||||||
maxScrollValue = Math.max(this.realElement.prop('offsetHeight'), this.realElement.prop('scrollHeight')) - this.vBarEdge;
|
|
||||||
|
|
||||||
this.vBar.show().setMaxValue(maxScrollValue - viewSize).setRatio(viewSize / maxScrollValue).setSize(viewSize);
|
|
||||||
this.vBar.setValue(this.realElement.scrollTop());
|
|
||||||
} else {
|
|
||||||
this.vBar.hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
// redraw horizontal scrollbar
|
|
||||||
if (this.horizontalScrollActive) {
|
|
||||||
viewSize = this.embeddedDimensions.innerWidth;
|
|
||||||
maxScrollValue = this.realElement.prop('scrollWidth');
|
|
||||||
|
|
||||||
if (maxScrollValue === viewSize) {
|
|
||||||
this.horizontalScrollActive = false;
|
|
||||||
}
|
|
||||||
this.hBar.show().setMaxValue(maxScrollValue - viewSize).setRatio(viewSize / maxScrollValue).setSize(viewSize);
|
|
||||||
this.hBar.setValue(this.realElement.scrollLeft());
|
|
||||||
} else {
|
|
||||||
this.hBar.hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
// set "touch-action" style rule
|
|
||||||
var touchAction = '';
|
|
||||||
if (this.verticalScrollActive && this.horizontalScrollActive) {
|
|
||||||
touchAction = 'none';
|
|
||||||
} else if (this.verticalScrollActive) {
|
|
||||||
touchAction = 'pan-x';
|
|
||||||
} else if (this.horizontalScrollActive) {
|
|
||||||
touchAction = 'pan-y';
|
|
||||||
}
|
|
||||||
this.realElement.css('touchAction', touchAction);
|
|
||||||
},
|
|
||||||
refresh: function() {
|
|
||||||
this.rebuildScrollbars();
|
|
||||||
},
|
|
||||||
destroy: function() {
|
|
||||||
// remove event listeners
|
|
||||||
this.win.off('resize orientationchange load', this.onResize);
|
|
||||||
this.realElement.off({
|
|
||||||
'jcf-mousewheel': this.onMouseWheel,
|
|
||||||
'jcf-pointerdown': this.onTouchBody
|
|
||||||
});
|
|
||||||
this.doc.off({
|
|
||||||
'jcf-pointermove': this.onMoveBody,
|
|
||||||
'jcf-pointerup': this.onReleaseBody
|
|
||||||
});
|
|
||||||
|
|
||||||
// restore structure
|
|
||||||
this.saveScrollOffsets();
|
|
||||||
this.vBar.destroy();
|
|
||||||
this.hBar.destroy();
|
|
||||||
this.realElement.insertAfter(this.scrollWrapper).css({
|
|
||||||
touchAction: '',
|
|
||||||
overflow: '',
|
|
||||||
width: '',
|
|
||||||
height: ''
|
|
||||||
});
|
|
||||||
this.scrollWrapper.remove();
|
|
||||||
this.restoreScrollOffsets();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// custom scrollbar
|
|
||||||
function ScrollBar(options) {
|
|
||||||
this.options = $.extend({
|
|
||||||
holder: null,
|
|
||||||
vertical: true,
|
|
||||||
inactiveClass: 'jcf-inactive',
|
|
||||||
verticalClass: 'jcf-scrollbar-vertical',
|
|
||||||
horizontalClass: 'jcf-scrollbar-horizontal',
|
|
||||||
scrollbarStructure: '<div class="jcf-scrollbar"><div class="jcf-scrollbar-dec"></div><div class="jcf-scrollbar-slider"><div class="jcf-scrollbar-handle"></div></div><div class="jcf-scrollbar-inc"></div></div>',
|
|
||||||
btnDecSelector: '.jcf-scrollbar-dec',
|
|
||||||
btnIncSelector: '.jcf-scrollbar-inc',
|
|
||||||
sliderSelector: '.jcf-scrollbar-slider',
|
|
||||||
handleSelector: '.jcf-scrollbar-handle',
|
|
||||||
scrollInterval: 300,
|
|
||||||
scrollStep: 400 // px/sec
|
|
||||||
}, options);
|
|
||||||
this.init();
|
|
||||||
}
|
|
||||||
$.extend(ScrollBar.prototype, {
|
|
||||||
init: function() {
|
|
||||||
this.initStructure();
|
|
||||||
this.attachEvents();
|
|
||||||
},
|
|
||||||
initStructure: function() {
|
|
||||||
// define proporties
|
|
||||||
this.doc = $(document);
|
|
||||||
this.isVertical = !!this.options.vertical;
|
|
||||||
this.sizeProperty = this.isVertical ? 'height' : 'width';
|
|
||||||
this.fullSizeProperty = this.isVertical ? 'outerHeight' : 'outerWidth';
|
|
||||||
this.invertedSizeProperty = this.isVertical ? 'width' : 'height';
|
|
||||||
this.thicknessMeasureMethod = 'outer' + this.invertedSizeProperty.charAt(0).toUpperCase() + this.invertedSizeProperty.substr(1);
|
|
||||||
this.offsetProperty = this.isVertical ? 'top' : 'left';
|
|
||||||
this.offsetEventProperty = this.isVertical ? 'pageY' : 'pageX';
|
|
||||||
|
|
||||||
// initialize variables
|
|
||||||
this.value = this.options.value || 0;
|
|
||||||
this.maxValue = this.options.maxValue || 0;
|
|
||||||
this.currentSliderSize = 0;
|
|
||||||
this.handleSize = 0;
|
|
||||||
|
|
||||||
// find elements
|
|
||||||
this.holder = $(this.options.holder);
|
|
||||||
this.scrollbar = $(this.options.scrollbarStructure).appendTo(this.holder);
|
|
||||||
this.btnDec = this.scrollbar.find(this.options.btnDecSelector);
|
|
||||||
this.btnInc = this.scrollbar.find(this.options.btnIncSelector);
|
|
||||||
this.slider = this.scrollbar.find(this.options.sliderSelector);
|
|
||||||
this.handle = this.slider.find(this.options.handleSelector);
|
|
||||||
|
|
||||||
// set initial styles
|
|
||||||
this.scrollbar.addClass(this.isVertical ? this.options.verticalClass : this.options.horizontalClass).css({
|
|
||||||
touchAction: this.isVertical ? 'pan-x' : 'pan-y',
|
|
||||||
position: 'absolute'
|
|
||||||
});
|
|
||||||
this.slider.css({
|
|
||||||
position: 'relative'
|
|
||||||
});
|
|
||||||
this.handle.css({
|
|
||||||
touchAction: 'none',
|
|
||||||
position: 'absolute'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
attachEvents: function() {
|
|
||||||
this.bindHandlers();
|
|
||||||
this.handle.on('jcf-pointerdown', this.onHandlePress);
|
|
||||||
this.slider.add(this.btnDec).add(this.btnInc).on('jcf-pointerdown', this.onButtonPress);
|
|
||||||
},
|
|
||||||
onHandlePress: function(e) {
|
|
||||||
if (e.pointerType === 'mouse' && e.button > 1) {
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
e.preventDefault();
|
|
||||||
this.handleDragActive = true;
|
|
||||||
this.sliderOffset = this.slider.offset()[this.offsetProperty];
|
|
||||||
this.innerHandleOffset = e[this.offsetEventProperty] - this.handle.offset()[this.offsetProperty];
|
|
||||||
|
|
||||||
this.doc.on('jcf-pointermove', this.onHandleDrag);
|
|
||||||
this.doc.on('jcf-pointerup', this.onHandleRelease);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onHandleDrag: function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
this.calcOffset = e[this.offsetEventProperty] - this.sliderOffset - this.innerHandleOffset;
|
|
||||||
this.setValue(this.calcOffset / (this.currentSliderSize - this.handleSize) * this.maxValue);
|
|
||||||
this.triggerScrollEvent(this.value);
|
|
||||||
},
|
|
||||||
onHandleRelease: function() {
|
|
||||||
this.handleDragActive = false;
|
|
||||||
this.doc.off('jcf-pointermove', this.onHandleDrag);
|
|
||||||
this.doc.off('jcf-pointerup', this.onHandleRelease);
|
|
||||||
},
|
|
||||||
onButtonPress: function(e) {
|
|
||||||
var direction, clickOffset;
|
|
||||||
if (e.pointerType === 'mouse' && e.button > 1) {
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
e.preventDefault();
|
|
||||||
if (!this.handleDragActive) {
|
|
||||||
if (this.slider.is(e.currentTarget)) {
|
|
||||||
// slider pressed
|
|
||||||
direction = this.handle.offset()[this.offsetProperty] > e[this.offsetEventProperty] ? -1 : 1;
|
|
||||||
clickOffset = e[this.offsetEventProperty] - this.slider.offset()[this.offsetProperty];
|
|
||||||
this.startPageScrolling(direction, clickOffset);
|
|
||||||
} else {
|
|
||||||
// scrollbar buttons pressed
|
|
||||||
direction = this.btnDec.is(e.currentTarget) ? -1 : 1;
|
|
||||||
this.startSmoothScrolling(direction);
|
|
||||||
}
|
|
||||||
this.doc.on('jcf-pointerup', this.onButtonRelease);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onButtonRelease: function() {
|
|
||||||
this.stopPageScrolling();
|
|
||||||
this.stopSmoothScrolling();
|
|
||||||
this.doc.off('jcf-pointerup', this.onButtonRelease);
|
|
||||||
},
|
|
||||||
startPageScrolling: function(direction, clickOffset) {
|
|
||||||
var self = this,
|
|
||||||
stepValue = direction * self.currentSize;
|
|
||||||
|
|
||||||
// limit checker
|
|
||||||
var isFinishedScrolling = function() {
|
|
||||||
var handleTop = (self.value / self.maxValue) * (self.currentSliderSize - self.handleSize);
|
|
||||||
|
|
||||||
if (direction > 0) {
|
|
||||||
return handleTop + self.handleSize >= clickOffset;
|
|
||||||
} else {
|
|
||||||
return handleTop <= clickOffset;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// scroll by page when track is pressed
|
|
||||||
var doPageScroll = function() {
|
|
||||||
self.value += stepValue;
|
|
||||||
self.setValue(self.value);
|
|
||||||
self.triggerScrollEvent(self.value);
|
|
||||||
|
|
||||||
if (isFinishedScrolling()) {
|
|
||||||
clearInterval(self.pageScrollTimer);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// start scrolling
|
|
||||||
this.pageScrollTimer = setInterval(doPageScroll, this.options.scrollInterval);
|
|
||||||
doPageScroll();
|
|
||||||
},
|
|
||||||
stopPageScrolling: function() {
|
|
||||||
clearInterval(this.pageScrollTimer);
|
|
||||||
},
|
|
||||||
startSmoothScrolling: function(direction) {
|
|
||||||
var self = this, dt;
|
|
||||||
this.stopSmoothScrolling();
|
|
||||||
|
|
||||||
// simple animation functions
|
|
||||||
var raf = window.requestAnimationFrame || function(func) {
|
|
||||||
setTimeout(func, 16);
|
|
||||||
};
|
|
||||||
var getTimestamp = function() {
|
|
||||||
return Date.now ? Date.now() : new Date().getTime();
|
|
||||||
};
|
|
||||||
|
|
||||||
// set animation limit
|
|
||||||
var isFinishedScrolling = function() {
|
|
||||||
if (direction > 0) {
|
|
||||||
return self.value >= self.maxValue;
|
|
||||||
} else {
|
|
||||||
return self.value <= 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// animation step
|
|
||||||
var doScrollAnimation = function() {
|
|
||||||
var stepValue = (getTimestamp() - dt) / 1000 * self.options.scrollStep;
|
|
||||||
|
|
||||||
if (self.smoothScrollActive) {
|
|
||||||
self.value += stepValue * direction;
|
|
||||||
self.setValue(self.value);
|
|
||||||
self.triggerScrollEvent(self.value);
|
|
||||||
|
|
||||||
if (!isFinishedScrolling()) {
|
|
||||||
dt = getTimestamp();
|
|
||||||
raf(doScrollAnimation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// start animation
|
|
||||||
self.smoothScrollActive = true;
|
|
||||||
dt = getTimestamp();
|
|
||||||
raf(doScrollAnimation);
|
|
||||||
},
|
|
||||||
stopSmoothScrolling: function() {
|
|
||||||
this.smoothScrollActive = false;
|
|
||||||
},
|
|
||||||
triggerScrollEvent: function(scrollValue) {
|
|
||||||
if (this.options.onScroll) {
|
|
||||||
this.options.onScroll(scrollValue);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getThickness: function() {
|
|
||||||
return this.scrollbar[this.thicknessMeasureMethod]();
|
|
||||||
},
|
|
||||||
setSize: function(size) {
|
|
||||||
// resize scrollbar
|
|
||||||
var btnDecSize = this.btnDec[this.fullSizeProperty](),
|
|
||||||
btnIncSize = this.btnInc[this.fullSizeProperty]();
|
|
||||||
|
|
||||||
// resize slider
|
|
||||||
this.currentSize = size;
|
|
||||||
this.currentSliderSize = size - btnDecSize - btnIncSize;
|
|
||||||
this.scrollbar.css(this.sizeProperty, size);
|
|
||||||
this.slider.css(this.sizeProperty, this.currentSliderSize);
|
|
||||||
this.currentSliderSize = this.slider[this.sizeProperty]();
|
|
||||||
|
|
||||||
// resize handle
|
|
||||||
this.handleSize = Math.round(this.currentSliderSize * this.ratio);
|
|
||||||
this.handle.css(this.sizeProperty, this.handleSize);
|
|
||||||
this.handleSize = this.handle[this.fullSizeProperty]();
|
|
||||||
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
setRatio: function(ratio) {
|
|
||||||
this.ratio = ratio;
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
setMaxValue: function(maxValue) {
|
|
||||||
this.maxValue = maxValue;
|
|
||||||
this.setValue(Math.min(this.value, this.maxValue));
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
setValue: function(value) {
|
|
||||||
this.value = value;
|
|
||||||
if (this.value < 0) {
|
|
||||||
this.value = 0;
|
|
||||||
} else if (this.value > this.maxValue) {
|
|
||||||
this.value = this.maxValue;
|
|
||||||
}
|
|
||||||
this.refresh();
|
|
||||||
},
|
|
||||||
setPosition: function(styles) {
|
|
||||||
this.scrollbar.css(styles);
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
hide: function() {
|
|
||||||
this.scrollbar.detach();
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
show: function() {
|
|
||||||
this.scrollbar.appendTo(this.holder);
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
refresh: function() {
|
|
||||||
// recalculate handle position
|
|
||||||
if (this.value === 0 || this.maxValue === 0) {
|
|
||||||
this.calcOffset = 0;
|
|
||||||
} else {
|
|
||||||
this.calcOffset = (this.value / this.maxValue) * (this.currentSliderSize - this.handleSize);
|
|
||||||
}
|
|
||||||
this.handle.css(this.offsetProperty, this.calcOffset);
|
|
||||||
|
|
||||||
// toggle inactive classes
|
|
||||||
this.btnDec.toggleClass(this.options.inactiveClass, this.value === 0);
|
|
||||||
this.btnInc.toggleClass(this.options.inactiveClass, this.value === this.maxValue);
|
|
||||||
this.scrollbar.toggleClass(this.options.inactiveClass, this.maxValue === 0);
|
|
||||||
},
|
|
||||||
destroy: function() {
|
|
||||||
// remove event handlers and scrollbar block itself
|
|
||||||
this.btnDec.add(this.btnInc).off('jcf-pointerdown', this.onButtonPress);
|
|
||||||
this.handle.off('jcf-pointerdown', this.onHandlePress);
|
|
||||||
this.doc.off('jcf-pointermove', this.onHandleDrag);
|
|
||||||
this.doc.off('jcf-pointerup', this.onHandleRelease);
|
|
||||||
this.doc.off('jcf-pointerup', this.onButtonRelease);
|
|
||||||
this.stopSmoothScrolling();
|
|
||||||
this.stopPageScrolling();
|
|
||||||
this.scrollbar.remove();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return module;
|
|
||||||
});
|
|
||||||
|
|
||||||
}(jcf));
|
|
|
@ -1,961 +0,0 @@
|
||||||
/*!
|
|
||||||
* JavaScript Custom Forms : Select Module
|
|
||||||
*
|
|
||||||
* Copyright 2014-2015 PSD2HTML - http://psd2html.com/jcf
|
|
||||||
* Released under the MIT license (LICENSE.txt)
|
|
||||||
*
|
|
||||||
* Version: 1.2.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function(jcf) {
|
|
||||||
|
|
||||||
jcf.addModule(function($, window) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var module = {
|
|
||||||
name: 'Select',
|
|
||||||
selector: 'select',
|
|
||||||
options: {
|
|
||||||
element: null,
|
|
||||||
multipleCompactStyle: false
|
|
||||||
},
|
|
||||||
plugins: {
|
|
||||||
ListBox: ListBox,
|
|
||||||
ComboBox: ComboBox,
|
|
||||||
SelectList: SelectList
|
|
||||||
},
|
|
||||||
matchElement: function(element) {
|
|
||||||
return element.is('select');
|
|
||||||
},
|
|
||||||
init: function() {
|
|
||||||
this.element = $(this.options.element);
|
|
||||||
this.createInstance();
|
|
||||||
},
|
|
||||||
isListBox: function() {
|
|
||||||
return this.element.is('[size]:not([jcf-size]), [multiple]');
|
|
||||||
},
|
|
||||||
createInstance: function() {
|
|
||||||
if (this.instance) {
|
|
||||||
this.instance.destroy();
|
|
||||||
}
|
|
||||||
if (this.isListBox() && !this.options.multipleCompactStyle) {
|
|
||||||
this.instance = new ListBox(this.options);
|
|
||||||
} else {
|
|
||||||
this.instance = new ComboBox(this.options);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
refresh: function() {
|
|
||||||
var typeMismatch = (this.isListBox() && this.instance instanceof ComboBox) ||
|
|
||||||
(!this.isListBox() && this.instance instanceof ListBox);
|
|
||||||
|
|
||||||
if (typeMismatch) {
|
|
||||||
this.createInstance();
|
|
||||||
} else {
|
|
||||||
this.instance.refresh();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
destroy: function() {
|
|
||||||
this.instance.destroy();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// combobox module
|
|
||||||
function ComboBox(options) {
|
|
||||||
this.options = $.extend({
|
|
||||||
wrapNative: true,
|
|
||||||
wrapNativeOnMobile: true,
|
|
||||||
fakeDropInBody: true,
|
|
||||||
useCustomScroll: true,
|
|
||||||
flipDropToFit: true,
|
|
||||||
maxVisibleItems: 10,
|
|
||||||
fakeAreaStructure: '<span class="jcf-select"><span class="jcf-select-text"></span><span class="jcf-select-opener"></span></span>',
|
|
||||||
fakeDropStructure: '<div class="jcf-select-drop"><div class="jcf-select-drop-content"></div></div>',
|
|
||||||
optionClassPrefix: 'jcf-option-',
|
|
||||||
selectClassPrefix: 'jcf-select-',
|
|
||||||
dropContentSelector: '.jcf-select-drop-content',
|
|
||||||
selectTextSelector: '.jcf-select-text',
|
|
||||||
dropActiveClass: 'jcf-drop-active',
|
|
||||||
flipDropClass: 'jcf-drop-flipped'
|
|
||||||
}, options);
|
|
||||||
this.init();
|
|
||||||
}
|
|
||||||
$.extend(ComboBox.prototype, {
|
|
||||||
init: function() {
|
|
||||||
this.initStructure();
|
|
||||||
this.bindHandlers();
|
|
||||||
this.attachEvents();
|
|
||||||
this.refresh();
|
|
||||||
},
|
|
||||||
initStructure: function() {
|
|
||||||
// prepare structure
|
|
||||||
this.win = $(window);
|
|
||||||
this.doc = $(document);
|
|
||||||
this.realElement = $(this.options.element);
|
|
||||||
this.fakeElement = $(this.options.fakeAreaStructure).insertAfter(this.realElement);
|
|
||||||
this.selectTextContainer = this.fakeElement.find(this.options.selectTextSelector);
|
|
||||||
this.selectText = $('<span></span>').appendTo(this.selectTextContainer);
|
|
||||||
makeUnselectable(this.fakeElement);
|
|
||||||
|
|
||||||
// copy classes from original select
|
|
||||||
this.fakeElement.addClass(getPrefixedClasses(this.realElement.prop('className'), this.options.selectClassPrefix));
|
|
||||||
|
|
||||||
// handle compact multiple style
|
|
||||||
if (this.realElement.prop('multiple')) {
|
|
||||||
this.fakeElement.addClass('jcf-compact-multiple');
|
|
||||||
}
|
|
||||||
|
|
||||||
// detect device type and dropdown behavior
|
|
||||||
if (this.options.isMobileDevice && this.options.wrapNativeOnMobile && !this.options.wrapNative) {
|
|
||||||
this.options.wrapNative = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.options.wrapNative) {
|
|
||||||
// wrap native select inside fake block
|
|
||||||
this.realElement.prependTo(this.fakeElement).css({
|
|
||||||
position: 'absolute',
|
|
||||||
height: '100%',
|
|
||||||
width: '100%'
|
|
||||||
}).addClass(this.options.resetAppearanceClass);
|
|
||||||
} else {
|
|
||||||
// just hide native select
|
|
||||||
this.realElement.addClass(this.options.hiddenClass);
|
|
||||||
this.fakeElement.attr('title', this.realElement.attr('title'));
|
|
||||||
this.fakeDropTarget = this.options.fakeDropInBody ? $('body') : this.fakeElement;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
attachEvents: function() {
|
|
||||||
// delayed refresh handler
|
|
||||||
var self = this;
|
|
||||||
this.delayedRefresh = function() {
|
|
||||||
setTimeout(function() {
|
|
||||||
self.refresh();
|
|
||||||
if (self.list) {
|
|
||||||
self.list.refresh();
|
|
||||||
self.list.scrollToActiveOption();
|
|
||||||
}
|
|
||||||
}, 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
// native dropdown event handlers
|
|
||||||
if (this.options.wrapNative) {
|
|
||||||
this.realElement.on({
|
|
||||||
focus: this.onFocus,
|
|
||||||
change: this.onChange,
|
|
||||||
click: this.onChange,
|
|
||||||
keydown: this.delayedRefresh
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// custom dropdown event handlers
|
|
||||||
this.realElement.on({
|
|
||||||
focus: this.onFocus,
|
|
||||||
change: this.onChange,
|
|
||||||
keydown: this.onKeyDown
|
|
||||||
});
|
|
||||||
this.fakeElement.on({
|
|
||||||
'jcf-pointerdown': this.onSelectAreaPress
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onKeyDown: function(e) {
|
|
||||||
if (e.which === 13) {
|
|
||||||
this.toggleDropdown();
|
|
||||||
} else if (this.dropActive) {
|
|
||||||
this.delayedRefresh();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onChange: function() {
|
|
||||||
this.refresh();
|
|
||||||
},
|
|
||||||
onFocus: function() {
|
|
||||||
if (!this.pressedFlag || !this.focusedFlag) {
|
|
||||||
this.fakeElement.addClass(this.options.focusClass);
|
|
||||||
this.realElement.on('blur', this.onBlur);
|
|
||||||
this.toggleListMode(true);
|
|
||||||
this.focusedFlag = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onBlur: function() {
|
|
||||||
if (!this.pressedFlag) {
|
|
||||||
this.fakeElement.removeClass(this.options.focusClass);
|
|
||||||
this.realElement.off('blur', this.onBlur);
|
|
||||||
this.toggleListMode(false);
|
|
||||||
this.focusedFlag = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onResize: function() {
|
|
||||||
if (this.dropActive) {
|
|
||||||
this.hideDropdown();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onSelectDropPress: function() {
|
|
||||||
this.pressedFlag = true;
|
|
||||||
},
|
|
||||||
onSelectDropRelease: function(e, pointerEvent) {
|
|
||||||
this.pressedFlag = false;
|
|
||||||
if (pointerEvent.pointerType === 'mouse') {
|
|
||||||
this.realElement.focus();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onSelectAreaPress: function(e) {
|
|
||||||
// skip click if drop inside fake element or real select is disabled
|
|
||||||
var dropClickedInsideFakeElement = !this.options.fakeDropInBody && $(e.target).closest(this.dropdown).length;
|
|
||||||
if (dropClickedInsideFakeElement || e.button > 1 || this.realElement.is(':disabled')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// toggle dropdown visibility
|
|
||||||
this.selectOpenedByEvent = e.pointerType;
|
|
||||||
this.toggleDropdown();
|
|
||||||
|
|
||||||
// misc handlers
|
|
||||||
if (!this.focusedFlag) {
|
|
||||||
if (e.pointerType === 'mouse') {
|
|
||||||
this.realElement.focus();
|
|
||||||
} else {
|
|
||||||
this.onFocus(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.pressedFlag = true;
|
|
||||||
this.fakeElement.addClass(this.options.pressedClass);
|
|
||||||
this.doc.on('jcf-pointerup', this.onSelectAreaRelease);
|
|
||||||
},
|
|
||||||
onSelectAreaRelease: function(e) {
|
|
||||||
if (this.focusedFlag && e.pointerType === 'mouse') {
|
|
||||||
this.realElement.focus();
|
|
||||||
}
|
|
||||||
this.pressedFlag = false;
|
|
||||||
this.fakeElement.removeClass(this.options.pressedClass);
|
|
||||||
this.doc.off('jcf-pointerup', this.onSelectAreaRelease);
|
|
||||||
},
|
|
||||||
onOutsideClick: function(e) {
|
|
||||||
var target = $(e.target),
|
|
||||||
clickedInsideSelect = target.closest(this.fakeElement).length || target.closest(this.dropdown).length;
|
|
||||||
|
|
||||||
if (!clickedInsideSelect) {
|
|
||||||
this.hideDropdown();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onSelect: function() {
|
|
||||||
this.refresh();
|
|
||||||
|
|
||||||
if (this.realElement.prop('multiple')) {
|
|
||||||
this.repositionDropdown();
|
|
||||||
} else {
|
|
||||||
this.hideDropdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.fireNativeEvent(this.realElement, 'change');
|
|
||||||
},
|
|
||||||
toggleListMode: function(state) {
|
|
||||||
if (!this.options.wrapNative) {
|
|
||||||
if (state) {
|
|
||||||
// temporary change select to list to avoid appearing of native dropdown
|
|
||||||
this.realElement.attr({
|
|
||||||
size: 4,
|
|
||||||
'jcf-size': ''
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// restore select from list mode to dropdown select
|
|
||||||
if (!this.options.wrapNative) {
|
|
||||||
this.realElement.removeAttr('size jcf-size');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
createDropdown: function() {
|
|
||||||
// destroy previous dropdown if needed
|
|
||||||
if (this.dropdown) {
|
|
||||||
this.list.destroy();
|
|
||||||
this.dropdown.remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
// create new drop container
|
|
||||||
this.dropdown = $(this.options.fakeDropStructure).appendTo(this.fakeDropTarget);
|
|
||||||
this.dropdown.addClass(getPrefixedClasses(this.realElement.prop('className'), this.options.selectClassPrefix));
|
|
||||||
makeUnselectable(this.dropdown);
|
|
||||||
|
|
||||||
// handle compact multiple style
|
|
||||||
if (this.realElement.prop('multiple')) {
|
|
||||||
this.dropdown.addClass('jcf-compact-multiple');
|
|
||||||
}
|
|
||||||
|
|
||||||
// set initial styles for dropdown in body
|
|
||||||
if (this.options.fakeDropInBody) {
|
|
||||||
this.dropdown.css({
|
|
||||||
position: 'absolute',
|
|
||||||
top: -9999
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// create new select list instance
|
|
||||||
this.list = new SelectList({
|
|
||||||
useHoverClass: true,
|
|
||||||
handleResize: false,
|
|
||||||
alwaysPreventMouseWheel: true,
|
|
||||||
maxVisibleItems: this.options.maxVisibleItems,
|
|
||||||
useCustomScroll: this.options.useCustomScroll,
|
|
||||||
holder: this.dropdown.find(this.options.dropContentSelector),
|
|
||||||
multipleSelectWithoutKey: this.realElement.prop('multiple'),
|
|
||||||
element: this.realElement
|
|
||||||
});
|
|
||||||
$(this.list).on({
|
|
||||||
select: this.onSelect,
|
|
||||||
press: this.onSelectDropPress,
|
|
||||||
release: this.onSelectDropRelease
|
|
||||||
});
|
|
||||||
},
|
|
||||||
repositionDropdown: function() {
|
|
||||||
var selectOffset = this.fakeElement.offset(),
|
|
||||||
selectWidth = this.fakeElement.outerWidth(),
|
|
||||||
selectHeight = this.fakeElement.outerHeight(),
|
|
||||||
dropHeight = this.dropdown.css('width', selectWidth).outerHeight(),
|
|
||||||
winScrollTop = this.win.scrollTop(),
|
|
||||||
winHeight = this.win.height(),
|
|
||||||
calcTop, calcLeft, bodyOffset, needFlipDrop = false;
|
|
||||||
|
|
||||||
// check flip drop position
|
|
||||||
if (selectOffset.top + selectHeight + dropHeight > winScrollTop + winHeight && selectOffset.top - dropHeight > winScrollTop) {
|
|
||||||
needFlipDrop = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.options.fakeDropInBody) {
|
|
||||||
bodyOffset = this.fakeDropTarget.css('position') !== 'static' ? this.fakeDropTarget.offset().top : 0;
|
|
||||||
if (this.options.flipDropToFit && needFlipDrop) {
|
|
||||||
// calculate flipped dropdown position
|
|
||||||
calcLeft = selectOffset.left;
|
|
||||||
calcTop = selectOffset.top - dropHeight - bodyOffset;
|
|
||||||
} else {
|
|
||||||
// calculate default drop position
|
|
||||||
calcLeft = selectOffset.left;
|
|
||||||
calcTop = selectOffset.top + selectHeight - bodyOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
// update drop styles
|
|
||||||
this.dropdown.css({
|
|
||||||
width: selectWidth,
|
|
||||||
left: calcLeft,
|
|
||||||
top: calcTop
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// refresh flipped class
|
|
||||||
this.dropdown.add(this.fakeElement).toggleClass(this.options.flipDropClass, this.options.flipDropToFit && needFlipDrop);
|
|
||||||
},
|
|
||||||
showDropdown: function() {
|
|
||||||
// do not show empty custom dropdown
|
|
||||||
if (!this.realElement.prop('options').length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// create options list if not created
|
|
||||||
if (!this.dropdown) {
|
|
||||||
this.createDropdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
// show dropdown
|
|
||||||
this.dropActive = true;
|
|
||||||
this.dropdown.appendTo(this.fakeDropTarget);
|
|
||||||
this.fakeElement.addClass(this.options.dropActiveClass);
|
|
||||||
this.refreshSelectedText();
|
|
||||||
this.repositionDropdown();
|
|
||||||
this.list.setScrollTop(this.savedScrollTop);
|
|
||||||
this.list.refresh();
|
|
||||||
|
|
||||||
// add temporary event handlers
|
|
||||||
this.win.on('resize', this.onResize);
|
|
||||||
this.doc.on('jcf-pointerdown', this.onOutsideClick);
|
|
||||||
},
|
|
||||||
hideDropdown: function() {
|
|
||||||
if (this.dropdown) {
|
|
||||||
this.savedScrollTop = this.list.getScrollTop();
|
|
||||||
this.fakeElement.removeClass(this.options.dropActiveClass + ' ' + this.options.flipDropClass);
|
|
||||||
this.dropdown.removeClass(this.options.flipDropClass).detach();
|
|
||||||
this.doc.off('jcf-pointerdown', this.onOutsideClick);
|
|
||||||
this.win.off('resize', this.onResize);
|
|
||||||
this.dropActive = false;
|
|
||||||
if (this.selectOpenedByEvent === 'touch') {
|
|
||||||
this.onBlur();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
toggleDropdown: function() {
|
|
||||||
if (this.dropActive) {
|
|
||||||
this.hideDropdown();
|
|
||||||
} else {
|
|
||||||
this.showDropdown();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
refreshSelectedText: function() {
|
|
||||||
// redraw selected area
|
|
||||||
var selectedIndex = this.realElement.prop('selectedIndex'),
|
|
||||||
selectedOption = this.realElement.prop('options')[selectedIndex],
|
|
||||||
selectedOptionImage = selectedOption ? selectedOption.getAttribute('data-image') : null,
|
|
||||||
selectedOptionText = '',
|
|
||||||
selectedOptionClasses,
|
|
||||||
self = this;
|
|
||||||
|
|
||||||
if (this.realElement.prop('multiple')) {
|
|
||||||
$.each(this.realElement.prop('options'), function(index, option) {
|
|
||||||
if (option.selected) {
|
|
||||||
selectedOptionText += (selectedOptionText ? ', ' : '') + option.innerHTML;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (!selectedOptionText) {
|
|
||||||
selectedOptionText = self.realElement.attr('placeholder') || '';
|
|
||||||
}
|
|
||||||
this.selectText.removeAttr('class').html(selectedOptionText);
|
|
||||||
} else if (!selectedOption) {
|
|
||||||
if (this.selectImage) {
|
|
||||||
this.selectImage.hide();
|
|
||||||
}
|
|
||||||
this.selectText.removeAttr('class').empty();
|
|
||||||
} else if (this.currentSelectedText !== selectedOption.innerHTML || this.currentSelectedImage !== selectedOptionImage) {
|
|
||||||
selectedOptionClasses = getPrefixedClasses(selectedOption.className, this.options.optionClassPrefix);
|
|
||||||
this.selectText.attr('class', selectedOptionClasses).html(selectedOption.innerHTML);
|
|
||||||
|
|
||||||
if (selectedOptionImage) {
|
|
||||||
if (!this.selectImage) {
|
|
||||||
this.selectImage = $('<img>').prependTo(this.selectTextContainer).hide();
|
|
||||||
}
|
|
||||||
this.selectImage.attr('src', selectedOptionImage).show();
|
|
||||||
} else if (this.selectImage) {
|
|
||||||
this.selectImage.hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.currentSelectedText = selectedOption.innerHTML;
|
|
||||||
this.currentSelectedImage = selectedOptionImage;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
refresh: function() {
|
|
||||||
// refresh fake select visibility
|
|
||||||
if (this.realElement.prop('style').display === 'none') {
|
|
||||||
this.fakeElement.hide();
|
|
||||||
} else {
|
|
||||||
this.fakeElement.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
// refresh selected text
|
|
||||||
this.refreshSelectedText();
|
|
||||||
|
|
||||||
// handle disabled state
|
|
||||||
this.fakeElement.toggleClass(this.options.disabledClass, this.realElement.is(':disabled'));
|
|
||||||
},
|
|
||||||
destroy: function() {
|
|
||||||
// restore structure
|
|
||||||
if (this.options.wrapNative) {
|
|
||||||
this.realElement.insertBefore(this.fakeElement).css({
|
|
||||||
position: '',
|
|
||||||
height: '',
|
|
||||||
width: ''
|
|
||||||
}).removeClass(this.options.resetAppearanceClass);
|
|
||||||
} else {
|
|
||||||
this.realElement.removeClass(this.options.hiddenClass);
|
|
||||||
if (this.realElement.is('[jcf-size]')) {
|
|
||||||
this.realElement.removeAttr('size jcf-size');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// removing element will also remove its event handlers
|
|
||||||
this.fakeElement.remove();
|
|
||||||
|
|
||||||
// remove other event handlers
|
|
||||||
this.doc.off('jcf-pointerup', this.onSelectAreaRelease);
|
|
||||||
this.realElement.off({
|
|
||||||
focus: this.onFocus
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// listbox module
|
|
||||||
function ListBox(options) {
|
|
||||||
this.options = $.extend({
|
|
||||||
wrapNative: true,
|
|
||||||
useCustomScroll: true,
|
|
||||||
fakeStructure: '<span class="jcf-list-box"><span class="jcf-list-wrapper"></span></span>',
|
|
||||||
selectClassPrefix: 'jcf-select-',
|
|
||||||
listHolder: '.jcf-list-wrapper'
|
|
||||||
}, options);
|
|
||||||
this.init();
|
|
||||||
}
|
|
||||||
$.extend(ListBox.prototype, {
|
|
||||||
init: function() {
|
|
||||||
this.bindHandlers();
|
|
||||||
this.initStructure();
|
|
||||||
this.attachEvents();
|
|
||||||
},
|
|
||||||
initStructure: function() {
|
|
||||||
this.realElement = $(this.options.element);
|
|
||||||
this.fakeElement = $(this.options.fakeStructure).insertAfter(this.realElement);
|
|
||||||
this.listHolder = this.fakeElement.find(this.options.listHolder);
|
|
||||||
makeUnselectable(this.fakeElement);
|
|
||||||
|
|
||||||
// copy classes from original select
|
|
||||||
this.fakeElement.addClass(getPrefixedClasses(this.realElement.prop('className'), this.options.selectClassPrefix));
|
|
||||||
this.realElement.addClass(this.options.hiddenClass);
|
|
||||||
|
|
||||||
this.list = new SelectList({
|
|
||||||
useCustomScroll: this.options.useCustomScroll,
|
|
||||||
holder: this.listHolder,
|
|
||||||
selectOnClick: false,
|
|
||||||
element: this.realElement
|
|
||||||
});
|
|
||||||
},
|
|
||||||
attachEvents: function() {
|
|
||||||
// delayed refresh handler
|
|
||||||
var self = this;
|
|
||||||
this.delayedRefresh = function(e) {
|
|
||||||
if (e && (e.which === 16 || e.ctrlKey || e.metaKey || e.altKey)) {
|
|
||||||
// ignore modifier keys
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
clearTimeout(self.refreshTimer);
|
|
||||||
self.refreshTimer = setTimeout(function() {
|
|
||||||
self.refresh();
|
|
||||||
self.list.scrollToActiveOption();
|
|
||||||
}, 1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// other event handlers
|
|
||||||
this.realElement.on({
|
|
||||||
focus: this.onFocus,
|
|
||||||
click: this.delayedRefresh,
|
|
||||||
keydown: this.delayedRefresh
|
|
||||||
});
|
|
||||||
|
|
||||||
// select list event handlers
|
|
||||||
$(this.list).on({
|
|
||||||
select: this.onSelect,
|
|
||||||
press: this.onFakeOptionsPress,
|
|
||||||
release: this.onFakeOptionsRelease
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onFakeOptionsPress: function(e, pointerEvent) {
|
|
||||||
this.pressedFlag = true;
|
|
||||||
if (pointerEvent.pointerType === 'mouse') {
|
|
||||||
this.realElement.focus();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onFakeOptionsRelease: function(e, pointerEvent) {
|
|
||||||
this.pressedFlag = false;
|
|
||||||
if (pointerEvent.pointerType === 'mouse') {
|
|
||||||
this.realElement.focus();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onSelect: function() {
|
|
||||||
this.fireNativeEvent(this.realElement, 'change');
|
|
||||||
this.fireNativeEvent(this.realElement, 'click');
|
|
||||||
},
|
|
||||||
onFocus: function() {
|
|
||||||
if (!this.pressedFlag || !this.focusedFlag) {
|
|
||||||
this.fakeElement.addClass(this.options.focusClass);
|
|
||||||
this.realElement.on('blur', this.onBlur);
|
|
||||||
this.focusedFlag = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onBlur: function() {
|
|
||||||
if (!this.pressedFlag) {
|
|
||||||
this.fakeElement.removeClass(this.options.focusClass);
|
|
||||||
this.realElement.off('blur', this.onBlur);
|
|
||||||
this.focusedFlag = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
refresh: function() {
|
|
||||||
this.fakeElement.toggleClass(this.options.disabledClass, this.realElement.is(':disabled'));
|
|
||||||
this.list.refresh();
|
|
||||||
},
|
|
||||||
destroy: function() {
|
|
||||||
this.list.destroy();
|
|
||||||
this.realElement.insertBefore(this.fakeElement).removeClass(this.options.hiddenClass);
|
|
||||||
this.fakeElement.remove();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// options list module
|
|
||||||
function SelectList(options) {
|
|
||||||
this.options = $.extend({
|
|
||||||
holder: null,
|
|
||||||
maxVisibleItems: 10,
|
|
||||||
selectOnClick: true,
|
|
||||||
useHoverClass: false,
|
|
||||||
useCustomScroll: false,
|
|
||||||
handleResize: true,
|
|
||||||
multipleSelectWithoutKey: false,
|
|
||||||
alwaysPreventMouseWheel: false,
|
|
||||||
indexAttribute: 'data-index',
|
|
||||||
cloneClassPrefix: 'jcf-option-',
|
|
||||||
containerStructure: '<span class="jcf-list"><span class="jcf-list-content"></span></span>',
|
|
||||||
containerSelector: '.jcf-list-content',
|
|
||||||
captionClass: 'jcf-optgroup-caption',
|
|
||||||
disabledClass: 'jcf-disabled',
|
|
||||||
optionClass: 'jcf-option',
|
|
||||||
groupClass: 'jcf-optgroup',
|
|
||||||
hoverClass: 'jcf-hover',
|
|
||||||
selectedClass: 'jcf-selected',
|
|
||||||
scrollClass: 'jcf-scroll-active'
|
|
||||||
}, options);
|
|
||||||
this.init();
|
|
||||||
}
|
|
||||||
$.extend(SelectList.prototype, {
|
|
||||||
init: function() {
|
|
||||||
this.initStructure();
|
|
||||||
this.refreshSelectedClass();
|
|
||||||
this.attachEvents();
|
|
||||||
},
|
|
||||||
initStructure: function() {
|
|
||||||
this.element = $(this.options.element);
|
|
||||||
this.indexSelector = '[' + this.options.indexAttribute + ']';
|
|
||||||
this.container = $(this.options.containerStructure).appendTo(this.options.holder);
|
|
||||||
this.listHolder = this.container.find(this.options.containerSelector);
|
|
||||||
this.lastClickedIndex = this.element.prop('selectedIndex');
|
|
||||||
this.rebuildList();
|
|
||||||
|
|
||||||
// save current selection in multiple select
|
|
||||||
if (this.element.prop('multiple')) {
|
|
||||||
this.previousSelection = this.getSelectedOptionsIndexes();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
attachEvents: function() {
|
|
||||||
this.bindHandlers();
|
|
||||||
this.listHolder.on('jcf-pointerdown', this.indexSelector, this.onItemPress);
|
|
||||||
this.listHolder.on('jcf-pointerdown', this.onPress);
|
|
||||||
|
|
||||||
if (this.options.useHoverClass) {
|
|
||||||
this.listHolder.on('jcf-pointerover', this.indexSelector, this.onHoverItem);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onPress: function(e) {
|
|
||||||
$(this).trigger('press', e);
|
|
||||||
this.listHolder.on('jcf-pointerup', this.onRelease);
|
|
||||||
},
|
|
||||||
onRelease: function(e) {
|
|
||||||
$(this).trigger('release', e);
|
|
||||||
this.listHolder.off('jcf-pointerup', this.onRelease);
|
|
||||||
},
|
|
||||||
onHoverItem: function(e) {
|
|
||||||
var hoverIndex = parseFloat(e.currentTarget.getAttribute(this.options.indexAttribute));
|
|
||||||
this.fakeOptions.removeClass(this.options.hoverClass).eq(hoverIndex).addClass(this.options.hoverClass);
|
|
||||||
},
|
|
||||||
onItemPress: function(e) {
|
|
||||||
if (e.pointerType === 'touch' || this.options.selectOnClick) {
|
|
||||||
// select option after "click"
|
|
||||||
this.tmpListOffsetTop = this.list.offset().top;
|
|
||||||
this.listHolder.on('jcf-pointerup', this.indexSelector, this.onItemRelease);
|
|
||||||
} else {
|
|
||||||
// select option immediately
|
|
||||||
this.onSelectItem(e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onItemRelease: function(e) {
|
|
||||||
// remove event handlers and temporary data
|
|
||||||
this.listHolder.off('jcf-pointerup', this.indexSelector, this.onItemRelease);
|
|
||||||
|
|
||||||
// simulate item selection
|
|
||||||
if (this.tmpListOffsetTop === this.list.offset().top) {
|
|
||||||
this.listHolder.on('click', this.indexSelector, { savedPointerType: e.pointerType }, this.onSelectItem);
|
|
||||||
}
|
|
||||||
delete this.tmpListOffsetTop;
|
|
||||||
},
|
|
||||||
onSelectItem: function(e) {
|
|
||||||
var clickedIndex = parseFloat(e.currentTarget.getAttribute(this.options.indexAttribute)),
|
|
||||||
pointerType = e.data && e.data.savedPointerType || e.pointerType || 'mouse',
|
|
||||||
range;
|
|
||||||
|
|
||||||
// remove click event handler
|
|
||||||
this.listHolder.off('click', this.indexSelector, this.onSelectItem);
|
|
||||||
|
|
||||||
// ignore clicks on disabled options
|
|
||||||
if (e.button > 1 || this.realOptions[clickedIndex].disabled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.element.prop('multiple')) {
|
|
||||||
if (e.metaKey || e.ctrlKey || pointerType === 'touch' || this.options.multipleSelectWithoutKey) {
|
|
||||||
// if CTRL/CMD pressed or touch devices - toggle selected option
|
|
||||||
this.realOptions[clickedIndex].selected = !this.realOptions[clickedIndex].selected;
|
|
||||||
} else if (e.shiftKey) {
|
|
||||||
// if SHIFT pressed - update selection
|
|
||||||
range = [this.lastClickedIndex, clickedIndex].sort(function(a, b) {
|
|
||||||
return a - b;
|
|
||||||
});
|
|
||||||
this.realOptions.each(function(index, option) {
|
|
||||||
option.selected = (index >= range[0] && index <= range[1]);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// set single selected index
|
|
||||||
this.element.prop('selectedIndex', clickedIndex);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.element.prop('selectedIndex', clickedIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
// save last clicked option
|
|
||||||
if (!e.shiftKey) {
|
|
||||||
this.lastClickedIndex = clickedIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
// refresh classes
|
|
||||||
this.refreshSelectedClass();
|
|
||||||
|
|
||||||
// scroll to active item in desktop browsers
|
|
||||||
if (pointerType === 'mouse') {
|
|
||||||
this.scrollToActiveOption();
|
|
||||||
}
|
|
||||||
|
|
||||||
// make callback when item selected
|
|
||||||
$(this).trigger('select');
|
|
||||||
},
|
|
||||||
rebuildList: function() {
|
|
||||||
// rebuild options
|
|
||||||
var self = this,
|
|
||||||
rootElement = this.element[0];
|
|
||||||
|
|
||||||
// recursively create fake options
|
|
||||||
this.storedSelectHTML = rootElement.innerHTML;
|
|
||||||
this.optionIndex = 0;
|
|
||||||
this.list = $(this.createOptionsList(rootElement));
|
|
||||||
this.listHolder.empty().append(this.list);
|
|
||||||
this.realOptions = this.element.find('option');
|
|
||||||
this.fakeOptions = this.list.find(this.indexSelector);
|
|
||||||
this.fakeListItems = this.list.find('.' + this.options.captionClass + ',' + this.indexSelector);
|
|
||||||
delete this.optionIndex;
|
|
||||||
|
|
||||||
// detect max visible items
|
|
||||||
var maxCount = this.options.maxVisibleItems,
|
|
||||||
sizeValue = this.element.prop('size');
|
|
||||||
if (sizeValue > 1 && !this.element.is('[jcf-size]')) {
|
|
||||||
maxCount = sizeValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle scrollbar
|
|
||||||
var needScrollBar = this.fakeOptions.length > maxCount;
|
|
||||||
this.container.toggleClass(this.options.scrollClass, needScrollBar);
|
|
||||||
if (needScrollBar) {
|
|
||||||
// change max-height
|
|
||||||
this.listHolder.css({
|
|
||||||
maxHeight: this.getOverflowHeight(maxCount),
|
|
||||||
overflow: 'auto'
|
|
||||||
});
|
|
||||||
|
|
||||||
if (this.options.useCustomScroll && jcf.modules.Scrollable) {
|
|
||||||
// add custom scrollbar if specified in options
|
|
||||||
jcf.replace(this.listHolder, 'Scrollable', {
|
|
||||||
handleResize: this.options.handleResize,
|
|
||||||
alwaysPreventMouseWheel: this.options.alwaysPreventMouseWheel
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// disable edge wheel scrolling
|
|
||||||
if (this.options.alwaysPreventMouseWheel) {
|
|
||||||
this.preventWheelHandler = function(e) {
|
|
||||||
var currentScrollTop = self.listHolder.scrollTop(),
|
|
||||||
maxScrollTop = self.listHolder.prop('scrollHeight') - self.listHolder.innerHeight();
|
|
||||||
|
|
||||||
// check edge cases
|
|
||||||
if ((currentScrollTop <= 0 && e.deltaY < 0) || (currentScrollTop >= maxScrollTop && e.deltaY > 0)) {
|
|
||||||
e.preventDefault();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
this.listHolder.on('jcf-mousewheel', this.preventWheelHandler);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
refreshSelectedClass: function() {
|
|
||||||
var self = this,
|
|
||||||
selectedItem,
|
|
||||||
isMultiple = this.element.prop('multiple'),
|
|
||||||
selectedIndex = this.element.prop('selectedIndex');
|
|
||||||
|
|
||||||
if (isMultiple) {
|
|
||||||
this.realOptions.each(function(index, option) {
|
|
||||||
self.fakeOptions.eq(index).toggleClass(self.options.selectedClass, !!option.selected);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.fakeOptions.removeClass(this.options.selectedClass + ' ' + this.options.hoverClass);
|
|
||||||
selectedItem = this.fakeOptions.eq(selectedIndex).addClass(this.options.selectedClass);
|
|
||||||
if (this.options.useHoverClass) {
|
|
||||||
selectedItem.addClass(this.options.hoverClass);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
scrollToActiveOption: function() {
|
|
||||||
// scroll to target option
|
|
||||||
var targetOffset = this.getActiveOptionOffset();
|
|
||||||
if (typeof targetOffset === 'number') {
|
|
||||||
this.listHolder.prop('scrollTop', targetOffset);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getSelectedOptionsIndexes: function() {
|
|
||||||
var selection = [];
|
|
||||||
this.realOptions.each(function(index, option) {
|
|
||||||
if (option.selected) {
|
|
||||||
selection.push(index);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return selection;
|
|
||||||
},
|
|
||||||
getChangedSelectedIndex: function() {
|
|
||||||
var selectedIndex = this.element.prop('selectedIndex'),
|
|
||||||
self = this,
|
|
||||||
found = false,
|
|
||||||
targetIndex = null;
|
|
||||||
|
|
||||||
if (this.element.prop('multiple')) {
|
|
||||||
// multiple selects handling
|
|
||||||
this.currentSelection = this.getSelectedOptionsIndexes();
|
|
||||||
$.each(this.currentSelection, function(index, optionIndex) {
|
|
||||||
if (!found && self.previousSelection.indexOf(optionIndex) < 0) {
|
|
||||||
if (index === 0) {
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
targetIndex = optionIndex;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.previousSelection = this.currentSelection;
|
|
||||||
return targetIndex;
|
|
||||||
} else {
|
|
||||||
// single choice selects handling
|
|
||||||
return selectedIndex;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getActiveOptionOffset: function() {
|
|
||||||
// calc values
|
|
||||||
var currentIndex = this.getChangedSelectedIndex();
|
|
||||||
|
|
||||||
// selection was not changed
|
|
||||||
if (currentIndex === null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// find option and scroll to it if needed
|
|
||||||
var dropHeight = this.listHolder.height(),
|
|
||||||
dropScrollTop = this.listHolder.prop('scrollTop'),
|
|
||||||
fakeOption = this.fakeOptions.eq(currentIndex),
|
|
||||||
fakeOptionOffset = fakeOption.offset().top - this.list.offset().top,
|
|
||||||
fakeOptionHeight = fakeOption.innerHeight();
|
|
||||||
|
|
||||||
// scroll list
|
|
||||||
if (fakeOptionOffset + fakeOptionHeight >= dropScrollTop + dropHeight) {
|
|
||||||
// scroll down (always scroll to option)
|
|
||||||
return fakeOptionOffset - dropHeight + fakeOptionHeight;
|
|
||||||
} else if (fakeOptionOffset < dropScrollTop) {
|
|
||||||
// scroll up to option
|
|
||||||
return fakeOptionOffset;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getOverflowHeight: function(sizeValue) {
|
|
||||||
var item = this.fakeListItems.eq(sizeValue - 1),
|
|
||||||
listOffset = this.list.offset().top,
|
|
||||||
itemOffset = item.offset().top,
|
|
||||||
itemHeight = item.innerHeight();
|
|
||||||
|
|
||||||
return itemOffset + itemHeight - listOffset;
|
|
||||||
},
|
|
||||||
getScrollTop: function() {
|
|
||||||
return this.listHolder.scrollTop();
|
|
||||||
},
|
|
||||||
setScrollTop: function(value) {
|
|
||||||
this.listHolder.scrollTop(value);
|
|
||||||
},
|
|
||||||
createOption: function(option) {
|
|
||||||
var newOption = document.createElement('span');
|
|
||||||
newOption.className = this.options.optionClass;
|
|
||||||
newOption.innerHTML = option.innerHTML;
|
|
||||||
newOption.setAttribute(this.options.indexAttribute, this.optionIndex++);
|
|
||||||
|
|
||||||
var optionImage, optionImageSrc = option.getAttribute('data-image');
|
|
||||||
if (optionImageSrc) {
|
|
||||||
optionImage = document.createElement('img');
|
|
||||||
optionImage.src = optionImageSrc;
|
|
||||||
newOption.insertBefore(optionImage, newOption.childNodes[0]);
|
|
||||||
}
|
|
||||||
if (option.disabled) {
|
|
||||||
newOption.className += ' ' + this.options.disabledClass;
|
|
||||||
}
|
|
||||||
if (option.className) {
|
|
||||||
newOption.className += ' ' + getPrefixedClasses(option.className, this.options.cloneClassPrefix);
|
|
||||||
}
|
|
||||||
return newOption;
|
|
||||||
},
|
|
||||||
createOptGroup: function(optgroup) {
|
|
||||||
var optGroupContainer = document.createElement('span'),
|
|
||||||
optGroupName = optgroup.getAttribute('label'),
|
|
||||||
optGroupCaption, optGroupList;
|
|
||||||
|
|
||||||
// create caption
|
|
||||||
optGroupCaption = document.createElement('span');
|
|
||||||
optGroupCaption.className = this.options.captionClass;
|
|
||||||
optGroupCaption.innerHTML = optGroupName;
|
|
||||||
optGroupContainer.appendChild(optGroupCaption);
|
|
||||||
|
|
||||||
// create list of options
|
|
||||||
if (optgroup.children.length) {
|
|
||||||
optGroupList = this.createOptionsList(optgroup);
|
|
||||||
optGroupContainer.appendChild(optGroupList);
|
|
||||||
}
|
|
||||||
|
|
||||||
optGroupContainer.className = this.options.groupClass;
|
|
||||||
return optGroupContainer;
|
|
||||||
},
|
|
||||||
createOptionContainer: function() {
|
|
||||||
var optionContainer = document.createElement('li');
|
|
||||||
return optionContainer;
|
|
||||||
},
|
|
||||||
createOptionsList: function(container) {
|
|
||||||
var self = this,
|
|
||||||
list = document.createElement('ul');
|
|
||||||
|
|
||||||
$.each(container.children, function(index, currentNode) {
|
|
||||||
var item = self.createOptionContainer(currentNode),
|
|
||||||
newNode;
|
|
||||||
|
|
||||||
switch (currentNode.tagName.toLowerCase()) {
|
|
||||||
case 'option': newNode = self.createOption(currentNode); break;
|
|
||||||
case 'optgroup': newNode = self.createOptGroup(currentNode); break;
|
|
||||||
}
|
|
||||||
list.appendChild(item).appendChild(newNode);
|
|
||||||
});
|
|
||||||
return list;
|
|
||||||
},
|
|
||||||
refresh: function() {
|
|
||||||
// check for select innerHTML changes
|
|
||||||
if (this.storedSelectHTML !== this.element.prop('innerHTML')) {
|
|
||||||
this.rebuildList();
|
|
||||||
}
|
|
||||||
|
|
||||||
// refresh custom scrollbar
|
|
||||||
var scrollInstance = jcf.getInstance(this.listHolder);
|
|
||||||
if (scrollInstance) {
|
|
||||||
scrollInstance.refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
// refresh selectes classes
|
|
||||||
this.refreshSelectedClass();
|
|
||||||
},
|
|
||||||
destroy: function() {
|
|
||||||
this.listHolder.off('jcf-mousewheel', this.preventWheelHandler);
|
|
||||||
this.listHolder.off('jcf-pointerdown', this.indexSelector, this.onSelectItem);
|
|
||||||
this.listHolder.off('jcf-pointerover', this.indexSelector, this.onHoverItem);
|
|
||||||
this.listHolder.off('jcf-pointerdown', this.onPress);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// helper functions
|
|
||||||
var getPrefixedClasses = function(className, prefixToAdd) {
|
|
||||||
return className ? className.replace(/[\s]*([\S]+)+[\s]*/gi, prefixToAdd + '$1 ') : '';
|
|
||||||
};
|
|
||||||
var makeUnselectable = (function() {
|
|
||||||
var unselectableClass = jcf.getOptions().unselectableClass;
|
|
||||||
function preventHandler(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
}
|
|
||||||
return function(node) {
|
|
||||||
node.addClass(unselectableClass).on('selectstart', preventHandler);
|
|
||||||
};
|
|
||||||
}());
|
|
||||||
|
|
||||||
return module;
|
|
||||||
});
|
|
||||||
|
|
||||||
}(jcf));
|
|
|
@ -1,125 +0,0 @@
|
||||||
/**************************************************************
|
|
||||||
*
|
|
||||||
* Progress Circle 1.0
|
|
||||||
*
|
|
||||||
**************************************************************/
|
|
||||||
|
|
||||||
( function( $ ){
|
|
||||||
var ProgressCircle = function( element, options ){
|
|
||||||
|
|
||||||
var settings = $.extend( {}, $.fn.progressCircle.defaults, options );
|
|
||||||
var thicknessConstant = 0.02;
|
|
||||||
var nRadian = 0;
|
|
||||||
|
|
||||||
computePercent();
|
|
||||||
setThickness();
|
|
||||||
|
|
||||||
var border = ( settings.thickness * thicknessConstant ) + 'em';
|
|
||||||
var offset = ( 1 - thicknessConstant * settings.thickness * 2 ) + 'em';
|
|
||||||
var circle = $( element );
|
|
||||||
var progCirc = circle.find( '.prog-circle' );
|
|
||||||
var circleDiv = progCirc.find( '.bar' );
|
|
||||||
var circleSpan = progCirc.children( '.percenttext' );
|
|
||||||
var circleFill = progCirc.find( '.fill' );
|
|
||||||
var circleSlice = progCirc.find( '.slice' );
|
|
||||||
|
|
||||||
if ( settings.nPercent == 0 ) {
|
|
||||||
circleSlice.hide();
|
|
||||||
} else {
|
|
||||||
resetCircle();
|
|
||||||
transformCircle( nRadians, circleDiv );
|
|
||||||
}
|
|
||||||
setBorderThickness();
|
|
||||||
updatePercentage();
|
|
||||||
setCircleSize();
|
|
||||||
|
|
||||||
function computePercent () {
|
|
||||||
settings.nPercent > 100 || settings.nPercent < 0 ? settings.nPercent = 0 : settings.nPercent;
|
|
||||||
nRadians = ( 360 * settings.nPercent ) / 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
function setThickness () {
|
|
||||||
if ( settings.thickness > 10 ) {
|
|
||||||
settings.thickness = 10;
|
|
||||||
} else if ( settings.thickness < 1 ) {
|
|
||||||
settings.thickness = 1;
|
|
||||||
} else {
|
|
||||||
settings.thickness = Math.round( settings.thickness );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setCircleSize ( ) {
|
|
||||||
progCirc.css( 'font-size', settings.circleSize + 'px' );
|
|
||||||
}
|
|
||||||
|
|
||||||
function transformCircle ( nRadians, cDiv ) {
|
|
||||||
var rotate = "rotate(" + nRadians + "deg)";
|
|
||||||
cDiv.css({
|
|
||||||
"-webkit-transform" : rotate,
|
|
||||||
"-moz-transform" : rotate,
|
|
||||||
"-ms-transform" : rotate,
|
|
||||||
"-o-transform" : rotate,
|
|
||||||
"transform" : rotate
|
|
||||||
});
|
|
||||||
if( nRadians > 180 ) {
|
|
||||||
transformCircle( 180, circleFill );
|
|
||||||
circleSlice.addClass( ' clipauto ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setBorderThickness () {
|
|
||||||
progCirc.find(' .slice > div ').css({
|
|
||||||
'border-width' : border,
|
|
||||||
'width' : offset,
|
|
||||||
'height' : offset
|
|
||||||
})
|
|
||||||
progCirc.find('.after').css({
|
|
||||||
'top' : border,
|
|
||||||
'left' : border,
|
|
||||||
'width' : offset,
|
|
||||||
'height' : offset
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function resetCircle () {
|
|
||||||
circleSlice.show();
|
|
||||||
circleSpan.text( '' );
|
|
||||||
circleSlice.removeClass( 'clipauto' )
|
|
||||||
transformCircle( 20, circleDiv );
|
|
||||||
transformCircle( 20, circleFill );
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
function updatePercentage () {
|
|
||||||
settings.showPercentText && circleSpan.text( settings.nPercent + '%' );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
$.fn.progressCircle = function( options ) {
|
|
||||||
return this.each( function( key, value ){
|
|
||||||
var element = $( this );
|
|
||||||
if ( element.data( 'progressCircle' ) ) {
|
|
||||||
var progressCircle = new ProgressCircle( this, options );
|
|
||||||
return element.data( 'progressCircle' );
|
|
||||||
}
|
|
||||||
$( this ).append( '<div class="prog-circle">' +
|
|
||||||
' <div class="percenttext"> </div>' +
|
|
||||||
' <div class="slice">' +
|
|
||||||
' <div class="bar"> </div>' +
|
|
||||||
' <div class="fill"> </div>' +
|
|
||||||
' </div>' +
|
|
||||||
' <div class="after"> </div>' +
|
|
||||||
'</div>');
|
|
||||||
var progressCircle = new ProgressCircle( this, options );
|
|
||||||
element.data( 'progressCircle', progressCircle );
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
$.fn.progressCircle.defaults = {
|
|
||||||
nPercent : 50,
|
|
||||||
showPercentText : true,
|
|
||||||
circleSize : 70,
|
|
||||||
thickness : 8
|
|
||||||
};
|
|
||||||
|
|
||||||
})( jQuery );
|
|
|
@ -1161,6 +1161,11 @@ h1{
|
||||||
color: $blue;
|
color: $blue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&.rated{
|
||||||
|
a{
|
||||||
|
color: $blue;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.like-error{
|
.like-error{
|
||||||
display: block;
|
display: block;
|
||||||
|
@ -2131,10 +2136,10 @@ textarea#comment_box{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.ch-playlists{
|
/* end view channel page */
|
||||||
.playlist-block{
|
/* playlist */
|
||||||
margin: 0 0 20px;
|
.playlist-item{
|
||||||
}
|
margin: 0 0 20px;
|
||||||
.playlist-thumb{
|
.playlist-thumb{
|
||||||
color:$block-color;
|
color:$block-color;
|
||||||
h2{
|
h2{
|
||||||
|
@ -2153,126 +2158,54 @@ textarea#comment_box{
|
||||||
display: block;
|
display: block;
|
||||||
position: relative;
|
position: relative;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
margin: 0 0 5px;
|
.playlist-count{
|
||||||
span{
|
|
||||||
background: rgba(0, 0, 0, 0.8);
|
background: rgba(0, 0, 0, 0.8);
|
||||||
height: 100%;
|
|
||||||
padding: 15px 20px;
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
text-align: center;
|
|
||||||
top: 0;
|
|
||||||
width: 80px;
|
width: 80px;
|
||||||
|
height: 80px;
|
||||||
|
border-radius: 50%;
|
||||||
|
padding: 18px 10px;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
margin: -40px 0 0 -40px;
|
||||||
|
text-align: center;
|
||||||
font-size:12px;
|
font-size:12px;
|
||||||
line-height: 18px;
|
line-height: 18px;
|
||||||
img{
|
span{
|
||||||
display: block;
|
display: block;
|
||||||
height: auto;
|
margin: 0 0 5px;
|
||||||
margin: 10px auto 0;
|
|
||||||
max-width: 20px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>img{
|
>img{
|
||||||
max-height: 100px;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.date-time{
|
.playlist-info{
|
||||||
display: block;
|
font-size: 14px;
|
||||||
background: $sprite -23px -1323px;
|
line-height: 16px;
|
||||||
color: #a3a3a3;
|
font-weight: 300;
|
||||||
font-size: 10px;
|
color: $grey-txt;
|
||||||
line-height: 14px;
|
padding: 8px;
|
||||||
margin: 5px 0 0;
|
background: darken($lt-grey, 1);
|
||||||
padding: 2px 0 2px 25px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* end view channel page */
|
|
||||||
/* playlist */
|
|
||||||
.item_playlist{
|
|
||||||
margin: 0 0 20px;
|
|
||||||
.playlist-thumb{
|
|
||||||
@include vertical-middle();
|
|
||||||
margin: 0 10px 0 0;
|
|
||||||
width: 100px;
|
|
||||||
height: 100px;
|
|
||||||
img{
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
a{
|
|
||||||
display: block;
|
|
||||||
height: 100%;
|
|
||||||
color: #fff;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
&:hover{
|
h2{
|
||||||
text-decoration: none;
|
max-height: 20px;
|
||||||
&:after{
|
overflow: hidden;
|
||||||
content: "";
|
color: $black;
|
||||||
background: rgba(0,0,0,0.6);
|
font-size: 18px;
|
||||||
position: absolute;
|
line-height: 20px;
|
||||||
width: 100%;
|
font-weight: 400;
|
||||||
height: 100%;
|
margin:0 0 5px;
|
||||||
top: 0;
|
a{
|
||||||
left: 0;
|
color: $black;
|
||||||
z-index: 1;
|
text-decoration: none;
|
||||||
}
|
&:hover{
|
||||||
i{
|
color: $blue;
|
||||||
left: 50%;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i{
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 12px;
|
|
||||||
position: absolute;
|
|
||||||
z-index: 2;
|
|
||||||
top: 50%;
|
|
||||||
left: -9999px;
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
border-radius:50%;
|
|
||||||
padding: 4px 3px 4px 5px;
|
|
||||||
margin: -10px 0 0 -10px;
|
|
||||||
text-align: center;
|
|
||||||
border:2px solid #fff;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
h3{
|
|
||||||
margin: 0 0 5px;
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 24px;
|
|
||||||
font-weight: 700;
|
|
||||||
span{
|
|
||||||
float: right;
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 14px;
|
|
||||||
font-weight: 400;
|
|
||||||
margin: 0 0 0 5px;
|
|
||||||
padding: 5px 10px;
|
|
||||||
min-width: 50px;
|
|
||||||
border-radius:12px;
|
|
||||||
background:$blue;
|
|
||||||
color: #fff;
|
|
||||||
i{
|
|
||||||
vertical-align: middle;
|
|
||||||
font-size: 8px;
|
|
||||||
line-height: 8px;
|
|
||||||
background: #fff;
|
|
||||||
padding: 2px 5px 1px;
|
|
||||||
color: $blue;
|
|
||||||
margin: 0 5px 0 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.date-time{
|
|
||||||
float: right;
|
|
||||||
font-size: 18px;
|
|
||||||
padding: 25px 10px;
|
|
||||||
line-height: 30px;
|
|
||||||
font-weight: 300;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/**/
|
/**/
|
||||||
.buy-premium{
|
.buy-premium{
|
||||||
|
|
Loading…
Add table
Reference in a new issue