JavaScript draw image on canvas from image data stored in database

I am creating a persistant whiteboard app using HTML and JS, where the user draw on the canvas on the cnavas, clicks save, storing the canvas image data to a mysql db. When the page reloads, the canvas should fetch the stored image data from the db and redraw this on the canvas, creating a persistant whiteboard.

The fetch functions are working fine and the image data is correctly retrieved and stored in a data structure, however when I reload the page the image is not drawn back on the canvas. Specifically, when I use

imageData.data.set(latestDrawing)

the length of imageData does not match the length of latestDrawing as expected, which I think is the cause of the issue; does anyone know about creating new image data with pre-existing data?

the save and redraw function in WhiteBoard.js:

window.addEventListener('load', () => {
    resize();
    redraw();

    window.addEventListener('click', handleOutsideClick);
    document.addEventListener("mousedown", startdrawing);
    document.addEventListener("mousemove", sketch);
    document.addEventListener("mouseup", stopdrawing);
    document.addEventListener("mouseout", stopdrawing);
    window.addEventListener('resize', resize);

});


async function saveState() {
    // console.log("before save")

    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);

    await fetch('/WhiteBoard', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({ type: 'canvasState', data: imageData }),
    });

    console.log("saved")

}

async function redraw() {

    try {
        const response = await fetch('/WhiteBoard');

        var latestDrawing = await response.json();

        if (latestDrawing) {

            //get db data into readable image data form
            latestDrawing = JSON.parse(latestDrawing.data);
            //create a new blank image data
            var imageData = ctx.createImageData(canvas.width, canvas.height);
            imageData.data.set(latestDrawing);
            ctx.putImageData(imageData, 0, 0);
        }

    } catch (error) {
        console.error('Error:', error);
    }

}

the fetch function in Server.js:

app.get('/WhiteBoard', (req,res) => {
  // Set the content type to JSON
  res.setHeader('Content-Type', 'application/json');
  
  // Your existing query and response logic
  db.query('SELECT * FROM canvas_state ORDER BY id DESC LIMIT 1', (error, results) => {
    if (error) {
      console.error(error);
      res.status(500).send('Internal Server Error');
    } else {
      res.json(results[0]);
    }
  });
});

I have tried creating a new Uint8ClampedArray, as I read another article that suggested doing this, however the canvas still did not redraw the saved images

const dataArray = new Uint8ClampedArray(drawingData);

Update JQXTreeGrid without having all rows collapse

I have a JQX Tree Grid that I am updating from a stream.

The update works, but the tree grid is completely collapsed after the update. I would like the grid to stay expanded as it was.

I am calling .jqxTreeGrid('updateBoundData') at the end of the update.

I have tried combinations of beginUpdate/endUpdate and refresh; these did not update the grid.

function updatetreegrid(msg) {
        
    // UpdateId in message should be the column to use
    let { GridName, UpdateId, Rows } = msg;

    for (let i = 0; i < Rows.length; i++) {
        let row = Rows[i];

        let doDelete = row.IsEmpty === 'DELETE';
        let found = eval("data"+GridName+".findIndex(d => d['"+UpdateId+"'] == row[UpdateId])");

        if (doDelete) {
            if (found >= 0) {
                eval("data"+GridName+".splice(found, 1);");
            }
        }
        else {
            if (found == -1) {
                eval("data"+GridName+".push(row)");
            }
            else {
                eval("data"+GridName+"[found] = row");
            }
        }
    }
    //$("#grid"+GridName).jqxTreeGrid('beginUpdate');
    //$("#grid"+GridName).jqxTreeGrid('endUpdate');
    //$("#grid"+GridName).jqxTreeGrid('refresh');
    $("#grid"+GridName).jqxTreeGrid('updateBoundData');
    
}
    

Is there a different update command that won’t collapse all of the rows? Is it possible to ask which rows are expanded and re-apply it after the update (not great, but better than nothing).

Thanks!

‘gradlew.bat’ is not recognized as an internal or external command React Native 0.72.7

I’m creating a fresh react native project and followed all the steps from their official docs: https://reactnative.dev/docs/environment-setup but it says that 'gradlew.bat' is not recognized as an internal or external command:
enter image description here

and I even followed this solution: https://github.com/react-native-community/cli/issues/1220 and installed SDK commandline tools but running react native doctor still shows that i don’t have Android SDK:
enter image description here

How to use a Javascript

Could you please assist me in learning and improving my skills in JavaScript? I am new to this programming language and would greatly appreciate your guidance in using it more effectively. I have attempted to learn from online resources, but I have not been able to find satisfactory answers. It would be immensely helpful if someone could provide me with practical tips and techniques to enhance my JavaScript coding abilities. Additionally, any advice on optimizing my website to a professional level would be highly valued. Thank you in advance for your assistance and support.

How to save my app’s state by localStorage

I just created a simple to do list app and now I need to save the changes and everytime the user comes back The undone tasks are still there how do I do it ???
here is the GitHub repository link to my code Thank you
text

Actually I didn’t try anything
I am a complete beginner and I can’t come up with any solutions!
like I don’t really know what I should be doing for loading the dynamically created elements by JavaScript!

Subtle gradient strokes

I’m here today because I have a question on how I can achieve something similar to the subtle gradient effect in the image below. I’ve looked through their HTML & CSS and I personally can’t see how they’ve done it. I’ve then tried to search Google but no luck.

Subtle gradient effect

If anyone is able to help me out, that would be amazing!

I’ve tried to give an SVG of a similar shape a gradient but struggled.

Javascript detection of user choice in browser beforeunload popup

I have read several articles here on SO on the topic of displaying custom messages when a user is trying to unload a page. The general consensus seems to be that as of present (2023) browsers do not allow alert() or confirm() statements during an beforeunload event.

window.onbeforeunload = function(ev){
  if(someCondition){
     ev.preventDefault();
     alert("Are you sure?"); // this will generate an error message in the console saying alert is blocked during beforeunload     
  }
}

Now there is a very simple way of getting around this block (at least in Chrome), but it will a) not suppress the browser’s default popup alert; b) cause the custom alert to be displayed regardless of what choice the user has made in the browser popup (“Cancel” or “Leave/Reload”, see images)

browser "Leave" popupbrowser "Reload" popup

window.onbeforeunload = function(ev){
   if(someCondition){
      ev.preventDefault();
      setTimeout(function(){
        alert("Are you sure?");
      },0);      
   }
}

However, this is very much not elegant. I guess there is no way of suppressing the default popup, but is there a way to detect what choice the user made in that popup? I would like a custom message to be displayed only in the case that the user has chosen to stay on the page (ie clicked the Cancel button).

Using newline characters in the HttpStatusCodeResult of ASP.NET MVC Action method is returning empty message when ajax is used to the action method

I am executing a ajax call from the cshtml page of an ASPNET MVC application, which calls an action method Delete from HomeController.
The action method catches exception message, if any occurred during the delete operation. The exception message contains 'rn' characters. I am unable to read the error message in ajax method. Without the 'rn' characters, the message is read.

ASPNET MVC Action Method

[HttpPost]
public ActionResult Delete(string input)
{
    try
    {
        //Code to call service to delete
    }
    catch (ServiceException ex)
    {
         int errorCode;
         errorCode = int.TryParse(ex.ErrorCode, out errorCode) ? errorCode : (int)HttpStatusCode.InternalServerError;

         var errorMessage = ex.Message ?? "An error occured";
         return new HttpStatusCodeResult(errorCode, errorMessage);
    }

    return new HttpStatusCodeResult(HttpStatusCode.NoContent);
}

Ajax call

var input = @Viewbag.Input;
   $.ajax({
       type: 'POST',
       url: '@Url.Action("Delete", "Home")',
       data: {
          "input": input
       },
       success: function () {
          alert('Deleted Successfully');
       },
       error: function (xmlHttp) {
          var title = xmlHttp.responseText.substring(xmlHttp.responseText.indexOf("<title>") + 7, xmlHttp.responseText.indexOf("</title>"));
          var div = document.createElement('div');
          alert(div.textContent);
       }
  });

The above code is not returning any text data in xmlHttp of the ajax error method. The ex.Message contains 'rn'.

Updating the action method code to sanitize the exception message as below helps in reading the message.

var errorMessage = ex.Message is null ? "An error occured" : ex.Message.Replace("rn", "<br/>");

But I could not see the alert in ajax call in multiple lines.
How can I achieve it?

Acrobat – Reject comment using Javascript

I have a huge pdf file with a lot of people comment. I would like to have a script (like a shortcut) to reject the selected comment (it seems not possible now to have a shortcut to this action directly).

The pdf is NOT a form.

I have been through the documentation of Adobe for Javascript (page 106 in Chrome it’s not opening at the page for me) :
https://opensource.adobe.com/dc-acrobat-sdk-docs/acrobatsdk/pdfs/acrobatsdk_jsdevguide.pdf#page106

and the API guide page 68 :
https://opensource.adobe.com/dc-acrobat-sdk-docs/acrobatsdk/pdfs/acrobatsdk_jsapiref.pdf#page68

My test pdf (with only one comment highlithed – we do highlight text when commenting) :
A screen shot of the test pdf

The red arrow is showing the status I want to set as rejected.

(When I first start, I was trying to make a loop on all the comments, then show a dialog box which is showing the comment and add three butons to accept, reject, do nothing – but too difficult for me 🙂 ).

I come with several version of my code, but none of them are working (I also try Bard, ChatGPT with no luck).

function rejectSelectedComment() {
  // Get the currently open PDF document
  var doc = app.activeDocument;

  // Get the currently selected comment
  var selectedComment = doc.activeAcroForm.currentPage.comments.getSelectedComment();

  // Check if a comment is selected
  if (selectedComment) {
    // Reject the selected comment
    selectedComment.reject();
  } else {
    // Alert the user that no comment is selected
    app.alert("Please select a comment to reject.");
  }
rejectSelectedComment()
}

Always getting either a doc undefined or a this.getComments is not a function

I have tried that from the console, and in an action but I can’t get the doc selected.
I have tried to get the script as a .js file in the Javascript folder.
I am able to show some app alert.
I have tried with the method this.syncAnnotScan(); describes in the Adobe pdf with no more luck;

I have check some projects on github.

The expected result should be to have the comment status set as rejected. So the user can go the the next one and apply script.

Thanks for reading !