我使用这个jquery计时器来收集它运行时花费的时间。
https://github.com/walmik/timer.jquery http://jquerytimer.com/
在之前的Stack Overflow帖子中,我们能够使用jQuery Ajax(jQuery.timer how to get current value in php?)将当前累计时间发布到另一个页面。许多人想到@Dakis
我们目前的解决方案似乎是试图节省定时器的任何停止和重启。如果选择“保存时间和注释”按钮,它只需要执行保存到数据库例程。
我一直在研究jQuery Ajax并且理解需要将一个键/值对发送到服务器/接收页面。我理解第一个值标识了从中获取&#34;键&#34;的目标,但是我无法清楚地理解第二个“值”的正确格式。 &#39;任务&#39;:$(&#39; .ta_tasks&#39;)。数据(&#39;任务')似乎没有按预期传递值。< / p>
我添加了一个ID为“ta_tasks”的TextArea,并附加了当前正在运行的AJAX:
data: {
'time': $('.timer').data('seconds'),
'state': $('.timer').data('state'),
'task': $('.ta_tasks').data('task’)
在接收页面上,我添加了一个简单的警报,以查看是否正在接收该值,但事实并非如此。如果我能弄清楚如何正确发送TextArea的内容,我还可以弄清楚如何从“Save Time and Notes”按钮提交一个值,这样Pause and Restart也不会提交给数据库。
工作页面:http://sgdesign.com/timer2.php
父页面脚本:
<script src="https://cdnjs.cloudflare.com/ajax/libs/timer.jquery/0.7.1/timer.jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
var hasTimer = false;
/**
* Save the current timer value.
*
* Performs an ajax request to the server, which will
* save the timer value in a database table and return
* a corresponding message.
*/
function saveTime() {
$.ajax({
method: 'post',
dataType: 'html',
url: 'saveTime.php',
data: {
'time': $('.timer').data('seconds'),
'state': $('.timer').data('state'),
'task': $('.ta_tasks').data('task')
},
success: function (response, textStatus, jqXHR) {
displayAlert('success', response);
},
error: function (jqXHR, textStatus, errorThrown) {
/*
* If the status code of the response is the custom one
* defined by me, the developer, in saveTime.php, then I
* can display the corresponding error message. Otherwise,
* the displayed message will be a general user-friendly
* one - so, that no system-related infos will be shown.
*/
var message = (jqXHR.status === 420)
? jqXHR.statusText
: 'An error occurred during your request. Please try again.';
displayAlert('danger', message);
},
complete: function (jqXHR, textStatus) {
//...
}
});
}
/**
* Display a bootstrap alert.
*
* @param type string success|info|warning|danger.
* @param message string Alert message.
* @return void
*/
function displayAlert(type, message) {
var alert = '<div class="alert alert-' + type + ' alert-dismissible" role="alert">'
+ '<button type="button" class="close" data-dismiss="alert" aria-label="Close">'
+ '<span aria-hidden="true">×</span>'
+ '</button>'
+ '<span>' + message + '</span>'
+ '</div>';
$('.messages').html(alert);
}
// Init timer start
$('.save-timer-btn').on('click', function () {
saveTime();
});
// Init timer start
$('.start-timer-btn').on('click', function () {
hasTimer = true;
$('.timer').timer({
editable: true
});
$(this).addClass('d-none');
$('.pause-timer-btn').removeClass('d-none');
});
// Init timer resume
$('.resume-timer-btn').on('click', function () {
$('.timer').timer('resume');
$(this).addClass('d-none');
$('.pause-timer-btn').removeClass('d-none');
});
// Init timer pause
$('.pause-timer-btn').on('click', function () {
$('.timer').timer('pause');
$(this).addClass('d-none');
$('.resume-timer-btn').removeClass('d-none');
saveTime();
});
// Remove timer. Leaves the display intact.
$('.remove-timer-btn').on('click', function () {
hasTimer = false;
$('.timer').timer('remove');
$(this).addClass('d-none');
$('.start-timer-btn').removeClass('d-none');
$('.pause-timer-btn, .resume-timer-btn').addClass('d-none');
});
// Additional focus event for this demo
$('.timer').on('focus', function () {
if (hasTimer) {
$('.pause-timer-btn').addClass('d-none');
$('.resume-timer-btn').removeClass('hidden');
}
});
// Additional blur event for this demo
$('.timer').on('blur', function () {
if (hasTimer) {
$('.pause-timer-btn').removeClass('d-none');
$('.resume-timer-btn').addClass('d-none');
}
});
});
</script>
目标网页内容:
<?php
// Price per hour variable
$cost = 50;
# require 'connection.php';
// Validate the timer value.
if (!isset($_POST['time']) || empty($_POST['time'])) {
/*
* This response header triggers the ajax error because the status
* code begins with 4xx (which corresponds to the client errors).
* I defined 420 as the custom status code. You can choose whatever
* code between 401 and 499 which is not officially assigned, e.g.
* which is marked as "Unassigned" in the official HTTP Status Code Registry.
* See the link.
*
* @link https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml HTTP Status Code Registry.
*/
header('HTTP/1.1 420 No time value defined. Did you start the timer?');
exit();
}
// Validate the timer state.
if (!isset($_POST['state']) || empty($_POST['state'])) {
header('HTTP/1.1 420 No timer state recognized. Did you start the timer?');
exit();
}
// Read the posted values.
$time = $_POST['time'];
$state = $_POST['state']; /* The state of the timer when the saving operation was triggered. */
$task = $_POST['ta_tasks'];
$r = $cost / 3600 * $time;
$rate = round($r, 2);
/*
* Save the timer value in a db table using PDO library.
*/
/* $sql = 'INSERT INTO my_timer_table (
time
) VALUES (
:time
)';
$statement = $connection->prepare($sql);
$statement->execute([
':time' => $time,
]);
// Print success message.
echo 'Time (' . $time . ' seconds) successfully saved when timer was ' . $state . '.';
exit(); */
?>
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Untitled Document</title>
<script>
var a = "<?php echo $task; ?>";
alert ('task: ' + a);
</script>
</head>
<body>
<?php function secondsToTime($seconds) {
$dtF = new \DateTime('@0');
$dtT = new \DateTime("@$seconds");
return $dtF->diff($dtT)->format('%h hours, %i minutes and %s seconds');
// return $dtF->diff($dtT)->format('%a days, %h hours, %i minutes and %s seconds');
}
?>
<?php echo secondsToTime($time);
echo '<br>';
echo 'Tasks: '.$task .'<br>';
echo 'Cost: $'. $rate;
?>
</body>
</html>
目标摘要 正确格式化数据:&#39;任务&#39;:$(&#39; .ta_tasks&#39;)。数据(&#39;任务') 了解为什么这样学习如何在“节省时间和笔记”的同时进行转移。用于调用DB的保存成本和注释的按钮
答案 0 :(得分:1)
textarea没有ta_tasks
课程,你使用id
且没有html5 data object
,更正$("#ta_tasks").val()
。
答案 1 :(得分:1)
不要在$(document).ready
内定义函数。把它们带到外面。
PHP中的函数应仅驻留在用于此目的的页面中。见PSR-1 Side Effects。原则上你应该阅读:PSR-1和PSR-2。可选,特别是PSR-4。
当您尝试读取通过ajax发送的值时,您应该读取值,而不是CSS选择器。所以:错了:$task = $_POST['ta_tasks'];
,正确:$task = $_POST['task'];
。
在验证发布的值之前(在页面顶部 saveTime.php ),你不应该声明任何变量或做其他事情 - 所以说。因此在验证之前没有$cost = 50;
,但在它们之后。不过,如果你想为 saveTime.php 定义常量,那么最好把它们放在另一个你可以包含的文件中。
在这种情况下,data()
方法是http://jquerytimer.com的专有方法!您可以使用它来获取某些值(计时器值,计时器状态等)。但是,为了获取html控件的值,您需要使用val()
,text()
或innerHtml
等。总之:native js或jquery方法/函数。所以,使用这样:
data: {
'time': $('.timer').data('seconds'),
'state': $('.timer').data('state'),
'task': $('#ta_tasks').val()
}
你看到选择器('#ta_tasks'
)了吗?它引用了一个id(因为#
)。您使用.ta_tasks
,因此引用了类名。你没有定义。
更好:对html id和名称使用 camelCase 命名约定,为css类使用“连字符分隔”形式:
data: {
'time': $('.timer').data('seconds'),
'state': $('.timer').data('state'),
'task': $('#ta_tasks').val()
}
//...
<textarea id="taTasks" name="taTasks" class="form-control" rows="4">Doh!</textarea>
尽可能避免从javascript或css代码引用php代码。如果你需要一个javascript代码中的php值,然后通过javascript函数传递它 - 作为参数,或者将php值保存在html控件的属性中,并通过js / jquery方法/函数引用属性来读取它。例如,请参阅 saveTime.php 中的代码,该代码将任务值保存在隐藏的输入中,并从js代码中提醒它。
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=yes" />
<meta charset="UTF-8" />
<!-- The above 3 meta tags must come first in the head -->
<title>Demo - Timer</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.2.1.min.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/timer.jquery/0.7.1/timer.jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
var hasTimer = false;
// Init timer start
$('.save-timer-btn').on('click', function () {
saveTime();
});
// Init timer start
$('.start-timer-btn').on('click', function () {
hasTimer = true;
$('.timer').timer({
editable: true
});
$(this).addClass('d-none');
$('.pause-timer-btn').removeClass('d-none');
});
// Init timer resume
$('.resume-timer-btn').on('click', function () {
$('.timer').timer('resume');
$(this).addClass('d-none');
$('.pause-timer-btn').removeClass('d-none');
});
// Init timer pause
$('.pause-timer-btn').on('click', function () {
$('.timer').timer('pause');
$(this).addClass('d-none');
$('.resume-timer-btn').removeClass('d-none');
saveTime();
});
// Remove timer. Leaves the display intact.
$('.remove-timer-btn').on('click', function () {
hasTimer = false;
$('.timer').timer('remove');
$(this).addClass('d-none');
$('.start-timer-btn').removeClass('d-none');
$('.pause-timer-btn, .resume-timer-btn').addClass('d-none');
});
// Additional focus event for this demo
$('.timer').on('focus', function () {
if (hasTimer) {
$('.pause-timer-btn').addClass('d-none');
$('.resume-timer-btn').removeClass('d-none');
}
});
// Additional blur event for this demo
$('.timer').on('blur', function () {
if (hasTimer) {
$('.pause-timer-btn').removeClass('d-none');
$('.resume-timer-btn').addClass('d-none');
}
});
});
/**
* Save the current timer value.
*
* Performs an ajax request to the server, which will
* save the timer value in a database table and return
* a corresponding message.
*/
function saveTime() {
$.ajax({
method: 'post',
dataType: 'html',
url: 'saveTime.php',
data: {
'time': $('.timer').data('seconds'),
'state': $('.timer').data('state'),
'task': $('#taTasks').val()
},
success: function (response, textStatus, jqXHR) {
displayAlert('success', response);
},
error: function (jqXHR, textStatus, errorThrown) {
var message = (jqXHR.status === 420)
? jqXHR.statusText
: 'An error occurred during your request. Please try again.';
displayAlert('danger', message);
},
complete: function (jqXHR, textStatus) {
//...
}
});
}
/**
* Display a bootstrap alert.
*
* @param type string success|info|warning|danger.
* @param message string Alert message.
* @return void
*/
function displayAlert(type, message) {
var alert = '<div class="alert alert-' + type + ' alert-dismissible" role="alert">'
+ '<button type="button" class="close" data-dismiss="alert" aria-label="Close">'
+ '<span aria-hidden="true">×</span>'
+ '</button>'
+ '<span>' + message + '</span>'
+ '</div>';
$('.messages').html(alert);
}
</script>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-xs-12">
<h4>
Timer Demo 2
</h4>
</div>
</div>
<div class="row">
<div class="col-xs-6 messages"></div>
</div>
<div class="row">
<div class="col-md-3">
<input type="text" id="timer" name="timer" class="form-control timer" placeholder="0 sec">
</div>
<div class="col-md-9">
<button type="button" class="btn btn-success start-timer-btn">
Start
</button>
<button type="button" class="btn btn-success resume-timer-btn d-none">
Resume
</button>
<button type="button" class="btn btn-danger pause-timer-btn d-none">
Pause
</button>
<button type="button" class="btn btn-danger remove-timer-btn d-none">
Remove Timer
</button>
<button type="button" class="btn btn-primary save-timer-btn">
Save Time and Notes
</button>
</div>
</div>
<div class="row mt-1">
<div class="col-sm-12">
<lable for="taTasks">Notes to accompany task:</lable>
<textarea id="taTasks" name="taTasks" class="form-control" rows="4">Doh!</textarea>
</div>
</div>
</div>
</body>
</html>
<?php
require_once 'functions.php';
// Validate the timer value.
if (!isset($_POST['time']) || empty($_POST['time'])) {
header('HTTP/1.1 420 No time value defined. Did you start the timer?');
exit();
}
// Validate the timer state.
if (!isset($_POST['state']) || empty($_POST['state'])) {
header('HTTP/1.1 420 No timer state recognized. Did you start the timer?');
exit();
}
// Validate the task.
if (!isset($_POST['task']) || empty($_POST['task'])) {
header('HTTP/1.1 420 No task value received.');
exit();
}
// Price per hour variable
$cost = 50;
// Read the posted values.
$time = $_POST['time'];
$state = $_POST['state']; /* The state of the timer when the saving operation was triggered. */
$task = $_POST['task'];
$r = $cost / 3600 * $time;
$rate = round($r, 2);
?>
<script type="text/javascript">
$(document).ready(function () {
alertTask();
});
function alertTask() {
var task = $('#task').val();
alert(task);
}
</script>
<input type="hidden" id="task" name="task" value="<?php echo $task; ?>">
<?php
echo secondsToTime($time);
echo '<br>';
echo 'Tasks: ' . $task . '<br>';
echo 'Cost: $' . $rate;
?>
<?php
function secondsToTime($seconds) {
$dtF = new \DateTime('@0');
$dtT = new \DateTime("@$seconds");
return $dtF->diff($dtT)->format('%h hours, %i minutes and %s seconds');
// return $dtF->diff($dtT)->format('%a days, %h hours, %i minutes and %s seconds');
}
编辑1:在 index.php 中,我将js函数置于$(document).ready
之外。我忘了早点做。
修改2 :在{/ p>中将hidden
更改为d-none
$('.resume-timer-btn').removeClass('hidden');
编辑3:我发现了我评论过的问题。它在我的 saveTime.php 代码中:我加载了jquery库,但它已经加载到 index.php 中。更多内容:因为您正在加载所有资源的html页面( index.php )中加载 saveTime.php 的内容,所以您不需要将 saveTime.php 构建为一个完整的结构化html(包含doctype,head,body等)。仅仅定义所需的内容和脚本标记就足够了。所以,我相应地重新编写了 saveTime.php 。
答案 2 :(得分:0)
检查你发送的ajax请求数据和你在saveTime.php中得到的数据,你发送'task'并在saveTime.php中接收'ta_task'
$.ajax({
method: 'post',
dataType: 'html',
url: 'saveTime.php',
data: {
'time': $('.timer').data('seconds'),
'state': $('.timer').data('state'),
'ta_task': $('.ta_tasks').data('task')
},
//other codes here
//saveTime.php
//now get the value with 'ta_task'
$task = $_POST['ta_task'];