0

I've been doing a lot of searching the last few days on AJAX. I see why I postponed learning that particular area of JavaScript, it seems a little complex.

I notice that most questions and answers are formulated around how to SEND data via POST, but I can't find any detailed examples of what to DO with the data once the POST has completed.

I want to use JavaScript rather than php to process the data server side, and I haven't found any useful Q/A. tutorials or discussion on the topic, excluding PHP. I figure I have to ask the specific question myself.

To help visualize my question I'll give the specific example that stimulates my question.

I have a file containing a list of tasks pending, and a list of tasks completed.

The functionality in this list is that when a user clicks on the task, it is inserted into a database, where it is associated with the user.

Multiple users see this page and anyone logged in can "log" a task completed by clicking on the list item. The list item also opens another page containing more details on the item and cascades to some other functions while logging the completion and user data to the database.

<h3>To Do!</h3>
<ol class="pending>
<li><a class="pending_task" href="localhost://nextstep.html">Task Three</a></li>
<li><a class="pending_task" href="localhost://nextstep.html">Task Five</a></li>
<li><a class="pending_task" href="localhost://nextstep.html">Task Six</a></li>
</ol>

On the same page is the "Completed" task list which is populated when the pending is clicked:

<h3>Completed!</h3>
<ol class="completed">
<li><a class="completed_task" href="localhost://nextstep.html">Task One</a></li>
<li><a class="completed_task" href="localhost://nextstep.html">Task Two</a></li>
<li><a class="completed_task" href="localhost://nextstep.html">Task Four</a></li>
</ol>

The code which manages that:

$(document).ready(function(){
    $('.pending').on('click', function(){
        evt.preventDefault();
        $(this).toggleClass("pending").parent().appendTo("ol.completed");
    });
});

My goal is to have the static html updated server side, when a task has been completed, so that when the page reloads or is accessed by another user, the new configuration of "Pending" vs "Completed", is current. As a friend explained, I can't just write the updated file to server from the client side, so I realized AJAX was the best solution. Send the updated information to the server and have a script on the server side rewrite the source file when a task has been clicked as complete. I have done the $_POST[key] functionality with PHP, but I have been more impressed with JavaScript so I want to learn how to do this purely in JavaScript.

Based on my new understanding, I changed the code a bit:

$(document).ready(function(){
    $('.pending').on('click', function(){
        evt.preventDefault();
        $(this).toggleClass("pending").parent().appendTo("ol.completed");
        var newData = $("ul.pending") + $("ul.completed");
        console.log(newData);

        var xhr = $.ajax({ //jshint ignore: line 
            method:'POST',
            data: newData,
            url:"update.js",
            success: function(){
                console.log("completed POST");
            },
            dataType: 'html',
        }); //xhr

    });
});

So I get this far and I'm confused by how to properly activate the receiving script so that the file is rewritten and also perhaps reload the file so that the persistence of the change is maintained.

I'm looking to understand the details of handling the POST data, without using PHP or a DATABASE. I just want to rewrite the HTML with the updated changes to the <ol> items.

If this is not the proper forum for that or there are resources that would help enlighten me, I would appreciate advice on how to find the best resources.

Thank You.

UPDATE: I am using node.js on the server side. The HTML is being presented via an app.js so the idea of doing server side operations is deeply connected to using node.js

Update 2:

I'm a little lost in the process of the POST/response dynamic. The script initiating the POST will get a response, of that I am clear.

So if I want the POSTEd html to be manipulated on the server side, then the response will come from the node.js indicating that the file has been rewritten, as requested by the POST? So the response can/will be a result of something I code on the server side.

My question remains though: How do I manipulate the POST data on the server side?

In PHP it is $_POST[key]. What is it in JavaScript?

And since I am sending HTML as the POST data, how should I handle it? Will it be a hash {key, value} or is it in some other form? I can't find these details in my google searching. I'm not sure how to phrase the question to get the answer I need.

And further, what triggers the node script to execute on the server side once it has been addressed y the POST call? Or am I overthinking that part?

Ken Ingram
  • 1,538
  • 5
  • 27
  • 52
  • POST needs to send to a server-side script. You can't send directly to a Javascript file. – Barmar Jan 05 '17 at 21:07
  • heh, well, if not php, you'll need to use something serverside, like php, to do that work. node.js just so happens to be javascript that runs on the serverside, but you're asking for way too much for us to provide a meaningful answer. – Kevin B Jan 05 '17 at 21:07
  • The whole point of AJAX is that you send some data to a server script, it processes the data, and returns a response that you can then use to update the page that's being displayed. – Barmar Jan 05 '17 at 21:08

2 Answers2

2

You seem to misunderstand the server/client model. You cannot use html/javascript to change things in your server, for that you will have to use your PHP server.

You can have a javascript server with Node.js https://nodejs.org , but that will probably replace your current PHP server. You can have multiple server in different languages, but that will make your project a bit harder to maintain.

Now about the AJAX request, it's like any other http request. You will send a header with your meta data and you will receive the answer from the server. If you want the server to do something (like write to a file or DB) every time it receives an specific request, you will need to code that by yourself.


UPDATE

You edited your question, now I know you're using nodejs. Here are a few extra info that might help

1 - Take a look at this question (it's really basic stuff and might help a lot)

Basic Ajax send/receive with node.js

2 - Change this line:

 var newData = $("ul.pending") + $("ul.completed");

to this:

 var newData = $("ul.pending").html() + $("ul.completed").html();

3 - This question will show you how to handle POST in node How do you extract POST data in Node.js?

Community
  • 1
  • 1
rafaelcastrocouto
  • 11,781
  • 3
  • 38
  • 63
  • No. I'm not misunderstanding client/server methodology. I have written code in PHP to accomplish this. I need the details of what processing the POST data looks like in this scenario. I can't wrap my head around it with generalities. I need specifics. – Ken Ingram Jan 05 '17 at 21:37
  • @KenIngram your success callback will receive a response as the first parameter. `success: (response) => { // do something with response }`. Take a look at the response object. If you're returning html, then update the appropriate tag with your new html. – Jecoms Jan 05 '17 at 21:43
  • Thanks @Jecoms. I'm a little lost in the process of the POST/response dynamic. The script initiating the POST will get a response, of that I am clear. So if I want the POSTEd html to be manipulated on the server side, then the response will come from the node.js indicating that the file has been rewritten, as requested by the POST? So the response will be a result of something I code on the server side. – Ken Ingram Jan 05 '17 at 22:36
  • @KenIngram what you're trying to do with node would be equivalent of posting to a .php file and from that file editing an html file. whether you do it with node.js or php is mostly irrelevent. – Kevin B Jan 05 '17 at 22:41
  • Ok. Got Thanks it. @Kevn B. Is the reference to POST data the same? $_POST[key]? – Ken Ingram Jan 05 '17 at 22:53
  • Thanks @rafaelcastrocouto That was helpful. I was having a hard time finding info of that type. Maybe it would have taken a few days. I am spoiled by the availability of info. *Want it NOW*. Must have patience. The learning is often in the journey. – Ken Ingram Jan 05 '17 at 22:57
  • You will get there soon! I added one extra item that I think you might find useful. If you are not using express or want a simpler way to get the post data just ask and I can make you a fiddle! – rafaelcastrocouto Jan 05 '17 at 23:55
  • 1
    Excellent 3rd point. I have been using Express on other projects, and I was trying to keep this one really basic so I could focus on understanding AJAX without too many places for things to go wrong. I will study this for a while and try out some things until I get stuck. Thank You. – Ken Ingram Jan 06 '17 at 00:07
0

This was the final code I developed after coming to an understanding of AJAX:

http.createServer(function(req, res){
    if ((req.method === 'POST') && (req.url === '/result')){
        var body = '';
        res.statusCode = 200;
        res.end("Message Received!");

        req.on('data', function(data){
            body += data;
        });

        req.on('end', function () {
            var suffix = getDateTime();
            var output = "Links" + "_" + suffix + ".html";
            // Copy the original First
            fs.writeFileSync(output, fs.readFileSync("./Links.html"));

            // Overwrite the original file with the updated list configuration
            fs.writeFileSync("./Links.html", body, 'utf-8');
    });
    } else if (req.method === 'GET') { // Reorganized 2017 01 05 @ 2237
        // Serve the static html
        var filename = req.url || "Links.html";
        var ext = path.extname(filename);
        var localPath = __dirname;
        var validExtensions = {
            ".html": "text/html",
            ".css": "text/css",
            ".js": "application/javascript",
            ".txt": "text/plain",
            ".jpg": "image/jpeg",
            ".gif": "image/gif",
            ".png": "image/png",
            ".woff": "application/font-woff",
            ".woff2": "application/font-woff2",
            ".ico": "image/x-icon",
            ""    : "text/html"
        };

        var validMimeType = true;
        var mimeType = validExtensions[ext];

        if (checkMimeType){
            validMimeType = validExtensions[ext] !== undefined;
        }

        if (validMimeType){
            localPath += filename;
            fs.exists(localPath, function(exists){
                if (exists){
                    getFile(localPath, res, mimeType);
                } else {
                    console.log("File not found: " + localPath);
                    res.writeHead(404);
                    res.end();
                }
            });
        } else {
            console.log("Invalid file extension detected: " + ext + "(" + filename + ")");
        }
    }
}).listen(port, serverURL);

function getFile(localPath, res, mimeType){
    fs.readFile(localPath, function(err, contents){
        if (!err) {
            res.setHeader("Content-Length", contents.length);
            if (mimeType !== undefined){
                res.setHeader("Content-Type", mimeType);
            }
            res.statusCode = 200;
            res.end(contents);
        } else {
            res.writeHead(500);
            res.end();
        }
    });
}

The other relevant code:

/* jslint node: true, browser: true */ /* globals $:false */
"use strict";
var ajax_url ="/result";


$(document).ready(function(){
    $('.source_link').on('click', function(){
        //evt.preventDefault();
        $(this).toggleClass("source_link downloaded").parent().appendTo("ol.downloaded");
        var front = "<!doctype html><html>";
        var head1 = "<head><link rel=\"stylesheet\" href=\"link.css\">";
        var head2 = "<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js\"></script>";
        var head3 = "<script src=\"links.js\"></script>";
        var head4 = "<script src=\"nameanchor.js\"></script>";
        var head5 = "</head><body>";
        var bottom = "</body></html>";
        var newData = front + head1 + head2 + head3 + head4 + head5 + "<ol class=\"pending\">" + $('ol.pending').html() + 
            "</ol>" + "<ol class=\"downloaded\">" + $('ol.downloaded').html() + "</ol>" + bottom;

        $.ajax({
            method:'POST',
            data: newData,
            url: ajax_url,
            success: function(result, status, jqxhr){
                console.log("Response: " + jqxhr.responseText);
                console.log("POST status: " + status);
            },
            dataType: 'html',
        });
    });

});
Ken Ingram
  • 1,538
  • 5
  • 27
  • 52