JSFiddle - React, Tailwind, and code Playground
by sungsoonz
HTML
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<div id="timesheet_wrapper">
<div id="timesheet_nav"></div>
<div id="timesheet">
<button id="prev_hours"><i class="fa fa-caret-left"></i></button>
<div class="mask">
<div id="timesheet_content">
<div id="timesheet_header"></div>
<div id="timesheet_cell">
<div id="event_canvas"></div>
</div>
</div>
</div>
<button id="next_hours"><i class="fa fa-caret-right"></i></button>
</div>
</div>
<!-- Modal -->
<div id="datepicker_modal" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Select date</h4>
</div>
<div id="datepicker" class="modal-body">
</div>
</div>
</div>
</div>
<div id="timesheet_modal" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">New Timesheet</h4>
</div>
<div class="modal-body">
<div class="row">
<div class="col-sm-4">
<div class="form-group">
<label>Started:</label>
<input id="started" type="text" class="form-control">
</div>
</div>
<div class="col-sm-4">
<div class="form-group">
<label>Ended:</label>
<input id="ended" type="text" class="form-control">
</div>
</div>
</div>
<div class="row">
<div class="col-sm-4">
...
CSS
@import url('https://fonts.googleapis.com/css?family=Open+Sans');
body {
font-family: 'Open Sans', sans-serif;
margin: 0;
background: #fff;
}
table {
border-spacing: 0;
}
button {
outline: 0;
}
.modal-backdrop {
background: #fff;
}
.modal-footer {
text-align: left;
}
#timesheet_wrapper {
width: 760px;
margin: 20px auto;
}
#timesheet_content {
margin-left: -479px;
}
.mask {
width: 721px;
position: relative;
overflow: hidden;
margin: auto
}
#timesheet_nav {
margin-bottom: 20px;
text-align: center;
width: 721px;
margin: auto;
}
#timesheet_nav .btn-toggle .btn:focus {
outline: 0;
}
#timesheet_nav .btn-toggle .active {
background: #0E68C5;
border-color: #0E68C5;
color: #fff;
box-shadow: none;
}
#timesheet_nav .current-date {
font-size: 15px;
font-weight: 600;
}
#datepicker_toggle {
background: none;
border: none;
margin-right: 4px;
color: #999;
}
#datepicker_toggle .fa {
font-size: 16px;
}
#prev_date,
#next_date,
#prev_month,
#next_month {
background: none;
border: 0;
border: 1px solid #ddd;
border-radius: 2px;
margin: 0 30px;
height: 34px;
width: 34px;
line-height: 1;
}
#prev_date .fa,
#next_date .fa,
#prev_month .fa,
#next_month .fa {
font-size: 20px;
}
#datepicker {
margin-bottom: 30px;
margin-top: 10px;
}
#datepicker table {
margin: 0 auto;
border-collapse: collapse;
}
#datepicker td {
border: 1px solid #ddd;
padding: 0;
font-weight: 600;
text-align: center;
position: relative;
}
#datepicker td.content {
padding: 4px;
}
#datepicker tr.head td,
#datepicker tr.sub-head td {
border: 0;
padding: 10px;
}
#datepicker td a {
display:block;
color: #555;
width: 36px;
height: 36px;
cursor: pointer;
line-height: 2.5;
font-size: 14px;
}
#datepicker tr.head td {
font-size: 17px;
}
#datepicker td label {
width: 6px;
height: 6px;
border-radius: 50px;
background: #0e8ac5;
border-radius: 50px;
position: absolute;
bottom: 0px;
...
JavaScript
var startX,
currentX,
preEvent,
preEventWidth,
postEvent,
postEventWidth,
isPostEvent = false,
isPostEventClick = false,
activeEventID,
offset,
xGuide,
timesheet,
datepicker,
// Static 데이트
d = new Date(),
months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
year = d.getFullYear(),
month = d.getMonth() + 1,
date = d.getDate(),
// Dynamic 데이트
d2 = new Date(),
yy = d2.getFullYear(),
mm = d2.getMonth() + 1,
dd = d2.getDate(),
// Assigned Person의 오늘 혹은 선택된 날의 데이터
row = {
"id": ["2636-KIM1-S2-0001","2636-KIM1-S2-0002"],
"step": ["1","2"],
"start": ["2016-12-13 10:00:00","2016-12-13 13:00:00"],
"end": ["2016-12-13 10:30:00","2016-12-13 14:30:00"]
},
// 프로젝트 관련된 데이터 사전준비
staffs = ['Seong Lee','Jay Park', 'Jason Kim'];
function next_date() {
d2.setDate(d2.getDate() + 1);
yy = d2.getFullYear();
mm = d2.getMonth() + 1;
dd = d2.getDate() ;
timesheet = new Timesheet(row);
}
function prev_date() {
d2.setDate(d2.getDate() - 1);
yy = d2.getFullYear();
mm = d2.getMonth() + 1;
dd = d2.getDate() ;
timesheet = new Timesheet(row);
}
function next_month() {
d2.setMonth(d2.getMonth() + 1);
yy = d2.getFullYear();
mm = d2.getMonth() + 1;
datepicker = new Datepicker(yy, mm, row);
}
function prev_month() {
d2.setMonth(d2.getMonth() - 1);
yy = d2.getFullYear();
mm = d2.getMonth() + 1;
datepicker = new Datepicker(yy, mm, row);
}
function find_pos(obj) {
var offsetX = 0;
if (obj.offsetParent) {
do {
offsetX += obj.offsetLeft;
} while (obj = obj.offsetParent);
return offsetX;
} else {
return false;
}
}
function get_coords(e) {
e = e || window.event;
if (e.pageX) {
return {
x: e.pageX
}
}
return {
x: e.clientX + document.body.scrollLeft - document.body.clientLeft
}
}
function pixel_to_time(x) {
if (x < 60) {
if (x < 10) {
return timesheet.startHour + ':' + '' + 0 +...