jQuery.Timer Ajax将多个表单值发送到辅助页面

时间:2018-03-19 16:29:36

标签: php jquery ajax

我使用这个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">&times;</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的保存成本和注释的按钮

generic image of page result

3 个答案:

答案 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代码中提醒它。

的index.php

<!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">&times;</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');
}

编辑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'];