Asked  6 Months ago    Answers:  5   Viewed   26 times

I know ../ means go up a path, but what does ./ mean exactly?

I was recently going through a tutorial and it seems to be referring to just a file in the same location, so is it necessary at all? Can I just not use it if that's all it's doing?



./ is the the folder that the working file is in:

So in /index.htm ./ is the root directory
but in /css/style.css ./ is the css folder.

This is important to remember because if you move CSS from /index.htm to /css/style.css the path will change.

Tuesday, June 1, 2021
answered 6 Months ago

Even if you did have a path (some browsers used to give it to you), there is no way to set the path of a input of type file.

Therefore, it is not possible to do what you want with plain JS and the DOM.

I said it wasn't possible, but now that you asked I do think there is a way, with new File API. The following steps outline what needs to be done, but have in no way been tested, and I don't expect it to work, it's just to show you the way, also global variables are bad, it's just the simplest way to show you. Here's a good page with examples on using the File API

First You need an input of type file, then you can use once a user selects a file, you are given access to the File object.

<input type="file" id="files" name="files[]" multiple />
  var fileBlobs = [];
  function handleFileSelect(evt) {
    var files =; // FileList object

    // files is a FileList of File objects. You may now read their contents
    var reader = new FileReader();
    for (var i = 0, f; f = files[i]; i++) {
  document.getElementById('files').addEventListener('change', handleFileSelect, false);

Second Now you have the content as a binary string. You can use the File API to store the file locally in a way that you can access later using the FileWriter and FileSaver interfaces

var bb = new BlobBuilder();
window.saveAs(bb.getBlob(), "test_file");

Third You need to make an Ajax request passing that blob to the server, tracking how much of the upload is complete. It doesn't look like tracking progress can be done on the client. Your may have to poll the server for actual progress. A possible solution to know where to start an interrupted upload is to have upload ids and when you restart an upload, you ask the server how much of the file has been uploaded.

Sorry I can't provide a full answer, but this is not an easy problem. The steps I gave you should take you in the right direction.

Wednesday, March 31, 2021
answered 9 Months ago

If your template is receiving AnonymousUser, the reference to {{}} will not be found. Previously, you must ask if {{request.user.is_authenticated }}.

You must check if it is included django.core.context_processors.auth context processor in TEMPLATE_CONTEXT_PROCESSORS section of settings. If you are using Django 1.4 or latest, then context processor is django.contrib.auth.context_processors.auth. This context processor is responsible to include user object in every request.

Monday, August 9, 2021
Craig Ringer
answered 4 Months ago

It's the Super key, like M- is the Meta key (alt key on a PC keyboard, Command key on your keyboard) and C- is the Control key.

I have of course never actually seen a super key on my keyboard... they are from a long gone era. Wikipedia has an image of this impressive "Space Cadet keyboard" which has all the modifiers you'll ever need:

Monday, September 13, 2021
answered 3 Months ago


In order to detect line-clicks we need to record all path information.

The following example is a modified version of the code provided in original post and includes a stroke recorder which records each stroke (between mouse down and mouse down) to an array which contains all strokes.

For simplicity we listen here to mouse clicks when we alter mode. When in click mode we iterate the stroke collection and re-build the paths we previously recorded for then to check if our mouse position is in one of these lines.

The code can be optimized by using a hit region before building paths to reduce overhead but for the sake of demo only the essential code is included:

Demo code


To record we need to have something to store the lines/strokes in:

var lines = [], line;

We add an event listener for clicks that we'll use when we switch mode. Note that normally you would share mousedown/up events perhaps instead:

canvas.addEventListener("click", checkLine, false);

To make the lines more "clickable" we use a thicker line width here (fixed for demo):

context.lineWidth = 3;

In order to record we need to modify the existing callbacks. There is also a bug in it which causes the line to be redrawn of top of each other for each mouse move which eventually will slow down the drawing if the line is long.

We also need to adjust mouse positions so it becomes relative to canvas:

function startDraw(event) {

    /// if we are in "click" mode exit from here (for demo)
    if (mode.checked === true) return;

    /// adjust mouse position
    var pos = mouseXY(canvas, event);

    drawing = true;

    /// start a new path
    context.moveTo(pos.x, pos.y);

    /// create a new stroke and push first position to it
    line = [];
    line.push([pos.x, pos.y]);

For each part we draw we need to reset path so we don't redraw the whole line (in your final render/redraw you would of course just redraw the line in one go, but not while drawing it):

function continueDraw(event) {
    if (drawing) {

        /// adjust mouse position
        var pos = mouseXY(canvas, event);

        /// complete one line segment started in mouse down
        context.lineTo(pos.x, pos.y);    

        /// reset path and start from where we ended this line
        context.moveTo(pos.x, pos.y);

        /// store current point to stroke/line
        line.push([pos.x, pos.y]);

And finally when line is finished we store our stroke:

function endDraw(event) {
    if (drawing)    {
        var pos = mouseXY(canvas, event);
        context.lineTo(pos.x, pos.y);    
        drawing = false;

        /// push stroke/line to line stack

We use this to adjust mouse position::

function mouseXY(c, e) {
    var r = c.getBoundingClientRect();
    return {x: e.clientX - r.left, y: e.clientY -};

Checking line clicks

To check a line we need to iterate through our line collection and rebuild each line as a path. There is no need to draw these paths so the speed is OK. When a path is rebuilt we check the adjusted mouse position against the path by using isPointInStroke:

function checkLine(e) {
    if (mode.checked === false) return;

    var i = 0, line, l, p, pos = mouseXY(canvas, e);

    /// make sure stroke has same width as originally recorded        
    context.lineWidth = 3;

    /// loop through line collection
    for(; line = lines[i]; i++) {

        /// reset path

        /// begin stroke
        context.moveTo(line[0][0], line[0][1]);

        /// iterate through each point stored
        for(l = 1; p = line[l]; l++) {
            /// add a line
            context.lineTo(p[0], p[1]);

        /// then we check the point
        if (context.isPointInStroke(pos.x, pos.y) === true) {
            alert('hit line ' + i); /// show "ID" of line clicked

Even complex overlapping lines can be detected with no problem:

Demo snapshot

(Yes I know! I could beat Dali and Munch any day! X-p )

Saturday, November 20, 2021
answered 1 Week ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :