jQuery.Timer Ajax将多个表单值发送到辅助页面 [英] jQuery.Timer Ajax send multiple form values to secondary page
问题描述
我正在使用此jquery计时器来收集运行时所花费的时间.
I'm using this jquery timer to collect time spent while it is running.
https://github.com/walmik/timer.jquery http://jquerytimer.com/
在之前的Stack Overflow帖子中,我们能够使用jQuery Ajax将当前的累积时间发布到另一页(
In a prior Stack Overflow post we were able to Post to another page the current accumulated time using jQuery Ajax (jQuery.timer how to get current value in php?). Many thinks to @Dakis
似乎我们当前的解决方案正在尝试保存计时器的任何停止和重新启动.如果选择了保存时间和注释"按钮,则只需执行保存到数据库"例程.
It seems our current solution is trying to save on any Stop and Restart of the Timer. It only needs to do a Save to DB routine IF the "Save Time and Notes" button is selected.
我一直在研究jQuery Ajax,并且了解到需要将键/值对发送到服务器/接收页面.我知道第一个值标识了从中获取键"的目标,但是我无法清楚地了解第二个值"的正确格式. 任务":$('.ta_tasks').data('任务')似乎没有传递期望的值.
I’ve been researching jQuery Ajax and understand that a key/value pair is needed to be sent to the server/receiving page. I understand the first value identifies the target from which to get the "key", but I could not get a clear understanding of proper formatting for the second "value". 'task': $('.ta_tasks').data('task’) does not seem to be passing the value as expected.
我添加了一个ID为"ta_tasks"的TextArea,并在当前工作的AJAX后面附加了:
I’ve added a TextArea with an ID of "ta_tasks" and appended the current working AJAX with:
data: {
'time': $('.timer').data('seconds'),
'state': $('.timer').data('state'),
'task': $('.ta_tasks').data('task’)
在接收页面上,我添加了一个简单的警报,以查看是否正在接收该值,但没有收到.如果我能弄清楚如何正确发送TextArea的内容,那么我也能弄清楚如何从保存时间和注释"按钮提交值,以使暂停并重新启动"也不会提交给数据库.
On the receiving page I added a simple alert to see if the value is being received but it is not. If I can figure out how to properly send the contents of the TextArea I could also figure out how to submit a value from the "Save Time and Notes" button so that a Pause and Restart will not also submit to the database.
工作页面: 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>
目标摘要 正确格式的数据位于:'task':$('.ta_tasks').data('task') 了解原因,以便了解如何在保存时间和注释"按钮调用时将成本和注释保存到数据库中
Goal Summary Proper formatting of data in: 'task': $('.ta_tasks').data('task’) Understanding of Why so as to learn how to also transfer when the 'Save Time and Notes" button to invoke saving Cost and Notes to DB
推荐答案
请勿在$(document).ready
内部定义函数.把它们带到外面.
Don't define functions inside $(document).ready
. Bring them outside.
PHP中的功能应仅驻留在用于此目的的页面中.参见 PSR-1副作用.原则上,您绝对应该阅读:PSR-1和PSR-2.可选,尤其是PSR-4.
Functions in PHP should reside only in pages destined for this purpose. See PSR-1 Side Effects. In principle you should definitely read: PSR-1 and PSR-2. Optional, especially PSR-4.
当您尝试读取通过ajax发送的值时,则应该读取该值,而不是CSS选择器.因此:错误:$task = $_POST['ta_tasks'];
,正确:$task = $_POST['task'];
.
When you try to read a value sent through ajax, then you should read the value, not the CSS selector. So: Wrong: $task = $_POST['ta_tasks'];
, correct: $task = $_POST['task'];
.
在验证发布的值(在 saveTime.php 页面顶部)之前,您不应声明任何变量或做其他事情-可以这么说.因此,在验证之前没有$cost = 50;
,但是在验证之后.不过,如果您想为 saveTime.php 定义常量,那么最好将它们放入另一个文件中,您可以将其包括在内.
Before validating posted values (on top of the page saveTime.php) you shouldn't declare any variables or do other things - so to say. So no $cost = 50;
before validations, but after them. Still, if you want to define constants for saveTime.php, then better bring them in another file, which you can include.
在这种情况下,data()
方法是 http://jquerytimer.com 的专有方法!您可以使用它来获取一些值(计时器值,计时器状态等).但是,为了获取html控件的值,您需要使用val()
或text()
或innerHtml
等.总而言之:本机js或jquery方法/函数.因此,使用这种方式:
In this case, the data()
method is a proprietary method of http://jquerytimer.com ! You can use it to fetch some values (timer value, timer state, etc). But, in order to fetch the value of a html control you need to use val()
, or text()
, or innerHtml
, etc. In a word: native js or jquery methods/functions. So, use like this:
data: {
'time': $('.timer').data('seconds'),
'state': $('.timer').data('state'),
'task': $('#ta_tasks').val()
}
您看到选择器('#ta_tasks'
)吗?它引用一个ID(由于#
).您使用了.ta_tasks
,因此引用了一个类名.您未定义的内容.
Do you see the selector ('#ta_tasks'
)? It references an id (because of #
). You used .ta_tasks
, therefore referencing a class name. Which you didn't define.
更好:将 camelCase 命名约定用于html id和名称,并对CSS类使用连字符分隔"形式:
Better: use the camelCase naming convention for html id's and names, and the "hyphen-separated" form for css classes:
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 中的代码,该代码将 task 值保存在隐藏的输入中,并从js代码中发出警报.
Avoid as much as possible referencing php code from javascript or css code. If you need a php value inside a javascript code, then pass it through a javascript function - as argument, or save the php value inside an attribute of a html control and read it through referencing the attribute by js/jquery methods/functions. As an example, see the code in saveTime.php, which saves the task value in a hidden input and alerts it from js code.
<!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>
saveTime.php
<?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;
?>
functions.php
<?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');
}
在 index.php 中,我将js函数带到了$(document).ready
之外.我忘了做.
Edit 1: In index.php, I brought the js functions outside of $(document).ready
. I forgot to do it earlier.
在
$('.resume-timer-btn').removeClass('hidden');
我发现了我评论的问题.它在我的 saveTime.php 代码中:我加载了jquery库,但是已经在 index.php 中加载了.更多内容:由于您是在已经加载了所有资源的html页面( index.php )中加载 saveTime.php 的内容,因此您无需将 saveTime.php 结构化为整个结构化的html(具有doctype,head,body等).仅定义所需的内容和脚本标记就足够了.因此,我相应地修改了 saveTime.php .
Edit 3: I found the problem about which I commented. It was in my saveTime.php code: I loaded the jquery library, but it was already loaded in index.php. More of it: since you are loading the content of saveTime.php in a html page (index.php) which already has all resources loaded, you don't need to structure the saveTime.php as a whole structured html (with doctype, head, body, etc). It is completely enough to just define the content and script tags that you need. So, I reedited saveTime.php correspondingly.
这篇关于jQuery.Timer Ajax将多个表单值发送到辅助页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!