Link to home
Start Free TrialLog in
Avatar of Omar Martin
Omar MartinFlag for United States of America

asked on

How to edit an image file in a form?

I am attempting to write code in node.js to edit a record which has a file location for the image's url in the database.  I was able to edit all the other field columns pretty well. However, it appears that for security reasons, editing a image is not easily allowable....but there must be a workaround this in order to edit a record with an image file's url to upload another image. I keep getting this message:

Uncaught DOMException: Failed to set the 'value' property on 'HTMLInputElement': This input element accepts a filename, which may only be programmatically set to the empty string.

Here is my code for the form file upload:
<label for="file">Profile Photo:</label>
        <input type="file" name="image" id="image" onChange={this.uploadFile}>
        <br><br>

Open in new window



Here is the frontend code for editing all records which I added the image value to:

$(document).ready(() => {
    $(document).on('click', '.edit', function (e) {
      e.preventDefault();
      $("#insertD").hide();
      $("#insertE").show();
      $("#stationForm")[0].reset();
      $("#stationForm").attr({
        action: $(e.target).attr("href"),
        //action: "/station", // PATH TO POST NEW STATION DATA ?
        method: "PUT"
      });
      var value = $(event.target).closest("div").find("input:hidden").val();
      value = JSON.parse(value);

      $("#store", "#modalStationForm").val(value.Station);
      $("#image", "#modalStationForm").val(value.Image);
      $("#location", "#modalStationForm").val(value.Address);
      $("#sales", "#modalStationForm").val(value['Monthly C-Store Sales']);
      $("#dealer", "#modalStationForm").val(value.Operator);
      $("#topitem", "#modalStationForm").val(value['Top SKU']);
      $("#id", "#modalStationForm").val(value.ID);
      $("#modalStationForm")
        .dialog("option", "title", "Editing Station")
        .dialog("open");
    });
    
    $('#insertE').click((event) => {
    //$("#stationForm", "#modalStationForm").on("submit", function (event)  
      //$("#stationForm").on("submit", function (event) {
      event.preventDefault();
      //var methodToUse = $(this).attr("method"); // PUT
      //var url = $(this).data("url");
     
      /*
      var data = {
        station: $("#store", "#modalStationForm").val(),
        address: $('#location', "#modalStationForm").val(),
        monthlycstoresales: $('#sales', "#modalStationForm").val(),
        operator: $('#dealer', "#modalStationForm").val(),
        topsku: $('#topitem', "#modalStationForm").val(),
        id: $('#id', "#modalStationForm").val()
      };
      */
    
         var data = JSON.stringify({
     
        station: $("#store", "#modalStationForm").val(),
        image: $("#image", "#modalStationForm").val(),
        address: $("#location", "#modalStationForm").val(),
        monthlycstoresales: $("#sales", "#modalStationForm").val(),
        operator: $("#dealer", "#modalStationForm").val(),
        topsku: $("#topitem", "#modalStationForm").val(),
        id: $("#id", "#modalStationForm").val()
       
      });

      var you = $(location).attr('href');
      var me = window.location.href;
      //console.log(you);
      
      $.ajax({
        
        url:'/edit/' + $('#id', "#modalStationForm").val(),
        
        //url: $(this).attr("action"),
        //url:'http://localhost:5000/edit/3',
        //url:'http://localhost:5000/station', wrong url 404 message
        data: data,
        dataType : "JSON",
        contentType: "application/json",
        method: "PUT",
        success: (data) => {
          alert('Record successfully edited')
          console.log(data);
          console.log('you and me');
          console.log(me);
          //console.log(url);
          //alert(url);
          $("#modalStationForm").dialog("close");
        }
      });
    });
  });

Open in new window


Here is the backend code:
app.put("/edit/:id", (req, res) => {
	//var sql = "UPDATE stores SET station = ?, address = ?, `Monthly C-Store Sales` = ?,Operator = ?, `Top SKU` = ? WHERE id = 2";

	//var sql = UPDATE `stores` SET `Station` = 'Baillou Hill', `Address` = '564 Jackson Ave.', `Monthly C-Store Sales` = '800', `Operator` = 'Marla Pikes', `Top SKU` = 'Burgers' WHERE `stores`.`ID` = 2;

	//var sql = UPDATE `stores`
	//SET `Station` = 'Baillou Hill', `Address` = '564 Jackson Ave.', `Monthly C-Store Sales` = '800', `Operator` = 'Marla Pikes', `Top SKU` = 'Burgers', WHERE `ID` = 2;

	//Note: All spaces and special characters have to be removed.
	/*
var query = "UPDATE `stores` SET";
    query += "`station`= '"+req.body.Station+"',";
    query += "`address`= '"+req.body.Address+"',";
    //query += "`monthly c-store sales`= '"+req.body[MonthlyCStoreSales]+"',";
    query += "`operator`= '"+req.body.Operator+"',";
    //query += "`top sku`= '"+req.body.TopSKU+"'";
    //query += " WHERE `id`= 3";
    query += " WHERE `id`= "+ req.query.ID+"";
*/

	station = req.body.station;
	image = req.file.path;
	//image = req.files.image;
	address = req.body.address;
	monthlycstoresales = req.body.monthlycstoresales;
	operator = req.body.operator;
	topsku = req.body.topsku;
	//id = req.params.ID;
	id = req.body.id;

	console.log(req.body);

	var sql =
		"UPDATE stores SET `station` = ?, `image` = ?, `address` = ?, `monthly c-store sales` = ?,`operator` = ?, `top sku` = ? WHERE `id` = ?";

	/*
  db.query(query,(err, results) => {
  */

	//db.query(sql, [station, address, monthlycstoresales, operator, topsku, id], (err, results, field) => {

	db.query(
		sql,
		[
			req.body.station,
			req.file.path,
			//req.files.image,
			req.body.address,
			req.body.monthlycstoresales,
			req.body.operator,
			req.body.topsku,
			req.body.id
		],
		(err, results, field) => {
			let message = {};
			if (results !== null) {
				console.log("results is not null");
				message.status = "OK";
			} else {
				console.log("results is null");
				message.status = "KO"; // ?
			}

			if (sql !== null) {
				console.log("sql is not null");
			} else {
				console.log("sql is null");
			}

			if (req.body.station !== null) {
				console.log("req.body is not null");
			} else {
				console.log("req.body is null");
			}

			if (req.body.station !== undefined) {
				console.log("req.body.Station is not undefined");
			} else {
				console.log("req.body.Station is undefined");
			}

			if (results !== undefined) {
				console.log("results is not undefined");
			} else {
				console.log("results is undefined");
			}

			if (sql !== undefined) {
				console.log("sql is not undefined");
			} else {
				console.log("sql is undefined");
			}

			if (err) {
				console.log(err);
				res.sendStatus(500);
				return callback(rows);
			} else {
				//console.log(req.body.station);
				//res.redirect("/alldata");
				//res.send(rows);
				message.results = results;
				//res.send(message);
				res.send(results);
			}
		}
	);
});

Open in new window

Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

On line 16 you have this
 $("#image", "#modalStationForm").val(value.Image);

Open in new window


#image refers to a file upload control - for security reasons you cannot set the value of this control (except to the empty string) which is exactly what the error message is telling you.

The file input is for a user to select a file to send to the server - not for setting the path of an already uploaded file. For that you will need to use an <img> element and set its src attribute to the path to the image.
Avatar of Omar Martin

ASKER

Thanks Julian:

I created an image element when I wanted to display the image in the record data: See  the code below......... So in order to edit or change the existing path or file, what is required exactly. I am not sure what to do.

I understand I need to remove this image value but what must I replace it with?
$("#image", "#modalStationForm").val(value.Image);


station_data += '<div class="store">' + '<img src="http://localhost:5000/'+ value.Image +'" width="70" height="70">' + '<li>ID: ' + value.ID + '</li>' +
                '<li>Station: ' + value.Station + '</li>' +
                '<li>Address: ' + value.Address + '</li>' +
                '<li>Sales: ' + value['Monthly C-Store Sales'] + '</li>' +
                '<li>Operator: ' + value.Operator + '</li>' +
                '<li>Top SKU: ' + value['Top SKU'] + '</li>' + '</ul>' +
                '<div class="store-action">' +
                '<input type="hidden" value=\'' + JSON.stringify(value) + '\'>' +
                '<a class="edit" href="http://localhost:5000/edit/' + value.ID + '">Edit</a>' + '  |  ' +
                '<a class="delete" href="http://localhost:5000/stationNames/number/' + value.ID + '" id="del">Delete</a>' +
                '</div>' + '<br/>';
            });

Open in new window

Are you wanting to change the image path by typing in a new one
OR
By letting the user select a different file?
By letting the user select a different file........

How can I do this?
You give them a <input type="file" but you don't try to set it to anything.

They select the new file - you then upload that using a form or AJAX and replace the current file with the existing one.

You will need to write the code to do this all the control does is selects the file for you.
If you could just give me a snippet or two of some code which can point me in the right direction, It would go a long way....I've been searching online most of the day, unfortunately, I am unable to find any information regarding this.
Your question is far too open ended - the solution space for this is big and is dependent on the rest of your system, how you are communiting with the server, what server etc.
Here is the basic approach using a form. You might need to add your other editing items to the form, change the styling. When the form is submitted the new image is sent to the server where you can process it.
<img src="clientoldimage.jpg">
<p>Select your updated image here</p>
<form method="post" action="updateImage/">
<input type="file" name="userFile">
<input type="submit">
</form>

Open in new window

Other options are to upload using AJAX - DropZone.js can potentially provide a solution there.

If you need a better answer you will need to narrow your question down a bit - basically it is working out to write the application for you which is beyond the scope of these threads.

I am not sure why you are struggling to find information - if you google HTML upload file node.js there are plenty of examples demonstrating how to do this.

My advice is take a look at some of those and then come back with specific questions.
User generated image
I have found a way how to upload photos by using multer......see the image attached above.  I wish to know how to "edit" the image that has been uploaded.....which I can't seem to find online.....if I google HTML upload file node.js there are plenty of examples demonstrating how to do what I already have done.

Please see my existing code on uploading an image which I am currently using. What needs to be tweaked for me to be able to update/edit an image along with the records:

const multer = require("multer");
//Setting Storage Engine

const storage = multer.diskStorage({
	destination: function(req, file, cb) {
	   cb(null, 'uploads/')
	},
	filename: function(req, file, cb) {
		cb(null,`${new Date().toISOString().replace(/:/g, "-")}${file.originalname}`);
	  },
	path: function(req, file, cb) {
	cb(null, path.replace(/\\/g, "/"));
		},
      });

     const fileFilter = function(req, file, cb) {
	if (
		file.mimetype === "image/jpeg" ||
		file.mimetype === "image/png" ||
		file.mimetype === "image/gif"
	) {
		cb(null, true);
	} else {
		cb(new Error("Only .jpeg, png or gifs files are accepted"), true);
	}
};

const upload = multer({
	storage: storage,
	limits: {
		fileSize: 1024 * 1024 * 5
	},
	fileFilter: fileFilter
});


//Init Upload
const upload = multer({
	storage: storage,
	limits: {
		fileSize: 1000000
	},
	fileFilter: function (req, file, cb) {
		checkFileType(file, cb);
	}
}).single('image');

//Check File Type
function checkFileType(file, cb) {
	//Allowed Extension
	const filetypes = /jpeg|jpg|png|gif/;
	//Check Extension
	const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
	//Check Mime Type
	const mimetype = filetypes.test(file.mimetype);

	if (mimetype && extname) {
		return cb(null, true);
	} else {
		cb('Error: Images Only!');
	}
}
const app = express();
//(5)Inserting information within the database - checked with postman.
app.use(bodyParser.json());
app.use(
	bodyParser.urlencoded({
		extended: true
	})
);
app.post("/station", upload.single("image"), (req, res, next) => {
var sql =
		"INSERT INTO stores (`id`, `station`, `image`, `address`, `monthly c-store sales`, `operator`, `top sku`)  VALUES (?, ?, ?, ?, ?, ?, ?)";
id = req.body.id;
	station = req.body.station;

	let fileUrl = req.file.path.replace(/\\/g, "/")
	image = fileUrl;
	
	address = req.body.address;
	monthlycstoresales = req.body.monthlycstoresales;
	operator = req.body.operator;
	topsku = req.body.topsku;

db.query(sql,
		[id, station, image, address, monthlycstoresales, operator, topsku],

(err, results) => {
	if (err) {
				console.log(err);
				res.sendStatus(500);
				return;
			} else {
				//res.send(results);
				res.redirect("/");
			}
		}
	);
});

Open in new window


Here is the form:
<!---(7)-->
    <h3>Inserting Data into the database</h3>
    <h3>Data List</h3>
    <div id="storesF"></div>
    <div id="modalStationForm">
        
      <!--<form action="/upload" method="post" id="stationForm" enctype="multipart/form-data">-->
      <form id="stationForm" method="POST" action="/station" enctype="multipart/form-data" >
        <label>Store Name:</label>
        <!--When submitting a form, the name value is important and is used in php file, while the id is used for css and javascript(below)-->
        <input type="text" name="station" id="store" size="40" placeholder="Enter Store Name">
        <br><br>

        <label for="file">Profile Photo:</label>
        <input type="file" name="image" id="image" onChange={this.uploadFile}>
        <br><br>

        <label>Address:</label>
        <input type="text" name="address" id="location" size="40" placeholder="Enter the store's address">
        <br><br>

        <label>Store Sales:</label>
        <input type="number" name="monthlycstoresales" id="sales" size="20">
        <br><br>

        <label>Operator:</label>
        <input type="text" name="operator" id="dealer" size="40" placeholder="Enter the operator's name">
        <br><br>

        <label>Top SKU item:</label>
        <input type="text" name="topsku" id="topitem" size="40" placeholder="Enter the store's top sku item">
        <input type="hidden" id="id" name="record_id">
        <br><br>

        <input id="insertD" type="submit" value="Insert">
        <input id="insertE" type="submit" value="Edit">
        <div id="statusF"></div>
        </form>

Open in new window


Here is the frontend code:
//(6) Inserting information into the database

   $(document).ready(() => {
    $(document).on('click', '.insert', function (e) {
      //$('#insertD').click(() => {
      e.preventDefault();
      $("#insertE").remove();
      $("#insertD").show();
      $("#stationForm")[0].reset();
      $("#stationForm").attr({
        action: $(e.target).attr("href"),
        //action: "/station", // PATH TO POST NEW STATION DATA ?
        method: "POST",
        
    });
       $("#modalStationForm")
        .dialog("option", "title", "Inserting New Station")
        .dialog("open");
      });
         });

Open in new window

Ok then I don't understand what you mean by edit? I assumed you mean replace that image with another one?
yes Sir......I want to replace the image.
Then I am still confused because the samples you refer to are what you are looking for.

Here is a simple example
<form action="update" method="post" enctype="multipart/form-data">
  <!-- First display  the current image -->
  <img src="currentimage.jpg">

   <!-- now provide the file upload control for a new image
   <input type="file" name="fileUpdate">
  <input type="submit">
</form>

Open in new window

The user selects a new image, submits the form - on the server you retrieve the uploaded image and replace the one you already have with the new image.

Variations on a theme - you can
a) Make the image clickable so it opens the file upload box (hide the input but link the click of the image to the input so that you can select a file by clicking the image)
b) Do an AJAX upload, this is fairly simple to do with the FormData() object and jQuery - but there are also libraries to do it.

All of the above are just variants on selecting the image and sending it to the server. On the server side your processing of the image will be very similar to the way in which the image was originally uploaded. You would retrieve the image from the upload, verify it and then simply save it to the same path and name of the image you currently use
OR
You save it to a new name and update the user record with the new name

Which strategy you chose depends on how / if you want to implement auditing and maintain a history of uploaded images.
okay...I will get back to you after I attempt to implement these suggestions.....
This question needs an answer!
Become an EE member today
7 DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform.
View membership options
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.