Summernote is an online WYSIWYG (What You See Is What You Get) editor that is lightweight and easy to integrate into any platform. Its tools resemble those of MS Word, making it user-friendly and intuitive. By default, Summernote stores images as base64 strings in the database. However, this approach is not ideal from a bandwidth and performance perspective.
A better solution is to store images on a server and save only the file paths in the editor. Summernote also supports adding images via URL, providing additional flexibility.
In this post, I share my custom solution for saving images to a server and integrating them into the editor. Although the example is based on an ASP.NET MVC5 C# web application, the approach is platform-independent and uses jQuery AJAX to handle image uploads.
HTML for Editor
@model ShriAdityaNarayanSingh.Models.MenuDataModel
@{
Layout = null;
}
<HTML>
<head>
<title>Management
Message Update</title>
<link href="~/AppCss/gcss.css" rel="stylesheet" />
<link href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/summernote@0.8.15/dist/summernote.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/summernote@0.8.15/dist/summernote.min.js"></script>
</head>
<body>
<ol class="breadcrumb">
<li><a href="/admin/Index">Dashboard</a></li>
<li><a href="/admin/MenuIndex">Menu Data
Index</a></li>
<li> Update
Page </li>
</ol>
<div class="container">
<h3>@ViewBag.SubMenuName</h3><hr />
<input type="hidden" id="hidContent" value="@Model.PageData" />
<input type="hidden" id="MenuPageid" value="@Request.QueryString["rid"]" />
<div class="row">
<div class="col-md-9">
<div id="summernote">
</div><br />
<input type="button" value="Update" class="btn-danger
btn" onclick="SaveDescription()" />
</div>
<div class="col-md-3">
<!--
===== Modal Other File ======-->
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Upload Blog Image </h4>
</div>
<div class="modal-body">
<form>
<div class="fileUpload btn
btn-primary">
<span>Browse</span>
<input type="file" class="upload" onchange="readURL(this)" id="MenuPageImage" accept="image/jpeg" /><br />
</div><br /><br />
<img id="blah" /><br /><br />
<input type="button" value="Upload" class="btn
btn-success" onclick="UploadMenuPageImage()" />
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn
btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<!--
===== // Modal Other File ======-->
<span id="lblMsgCopy" style="color:green;display:none;text-align:center;padding:2px;background-color:#edffd8;margin-bottom:6px">Path Copied</span><br />
<input type="button" value="Upload New Image" onclick="ShowM()" class="btn btn-success" />
<input type="button" class="btn btn-danger" value="Delete" style="float:right" onclick="DelImg()" />
<!--======== Image Container =========-->
<div class="divImgContainer" id="divImgContainer">
</div>
<input type="hidden" id="hidImgID" />
<input type="hidden" id="hidImgName" />
<!--======== // Image Container =========-->
</div>
</div>
</div>
<script>
$(document).ready(function () {
$('#summernote').summernote(
);
$('#summernote').summernote('code', $("#hidContent").val());
GetMenuPageImage($("#MenuPageid").val());
});
</script>
<script>
function ShowM() {
$('#myModal').modal('show');
document.getElementById('blah').src = '';
document.getElementById('blah').style.width = '';
document.getElementById('blah').style.height = '';
}
function ValidateAbout() {
Flag = true;
if ($('#summernote').summernote('code') == "") {
alert("Please enter something ");
Flag = false;
}
}
function SaveDescription() {
ValidateAbout();
if (Flag) {
var Userobj =
{
ID: getQueryStringValue("rid"),
PageData: $('#summernote').summernote('code')
}
$.ajax({
url: '/admin/MenuAddTextUpdate/',
dataType: "json",
type: "POST",
contentType: 'application/json; charset=utf-8',
data:
JSON.stringify(Userobj),
success: function (data) {
if (data.sMessage == "1") {
alert("Updated Successfully");
window.location = "/Admin/MenuAddText?rid=" + getQueryStringValue("rid");
}
else
alert(data.sMessage);
}
});
}
}
</script>
@{
Random ob = new Random();
int ran = ob.Next();
}
<script src="~/AppJs/menudata.js?v=@ran"></script>
</body>
</html>
CSS (gcss.css)
.note-group-select-from-files {
display: none;
}
.g-heading {
border-bottom: solid 1px #d0cdcd;
display: block;
margin: 5px;
font-size: large;
}
.fileUpload {
position: relative;
overflow: hidden;
margin-top: 0px;
}
.fileUpload input.upload {
position: absolute;
top: 0;
right: 0;
margin: 0;
padding: 0;
font-size: 20px;
cursor: pointer;
opacity: 0;
filter: alpha(opacity=0);
}
.note-insert {
display: none
}
.divImgContainer {
display: grid;
grid-template-columns: auto auto auto;
/*grid-template-rows: 80px 150px;*/
grid-gap: 10px;
padding: 10px;
height: auto;
width: 300px;
position: relative;
}
.divImgContainer div {
text-align: center;
padding: 0px 0;
font-size: 10px;
}
.divImgContainer img {
width: 110px;
height: 70px;
}
.button {
display: none;
position: absolute;
color: white;
left: 50px;
top: 40px;
text-align: center;
font-size: small;
transition: opacity .35s ease;
}
.divImgContainer div:hover .button {
display: block;
padding: 5px;
}
Java Script (menudata.js)
function UploadMenuPageImage() {
//create blog
other img rec
if (ValidateFile('MenuPageImage'))
{
var name = document.getElementById('MenuPageImage');
var fname = name.files.item(0).name;
var fileExtension = fname.split('.').pop();
CreateMenuPageImageRec(fileExtension);
$('#myModal').modal('hide');
GetMenuPageImage($("#MenuPageid").val());
}
}
function CreateMenuPageImageRec(ext) {
//create image row in MenuDataImg table and upload image with new autoid
var Userobj =
{
ID: $("#MenuPageid").val(),
Ext: ext
}
$.ajax({
url: '/admin/CreateMenuPageImgRec/',
async: false,
dataType: "json",
type: "POST",
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(Userobj),
success: function (data) {
if (data.sMessage != 0) {
UploadImage('MenuPageImage', (data.sMessage + "." + ext));
}
else
alert(data.sMessage);
}
});
}
function UploadImage(imgid,
imgname) {
if (ValidateFile(imgid)) {
var data = new
FormData();
data.append("filename", $("#" + imgid)[0].files[0]);
var name = document.getElementById(imgid);
var fname = name.files.item(0).name;
var fileExtension = fname.split('.').pop();
var newname = imgname + "." + fileExtension;
$.ajax({
url: '/admin/UploadMenuPageImg?fnm=' + imgname ,
async: false,
type: "POST",
contentType: false, // Not to
set any content header
processData: false, // Not to
process data
data: data,
success: function (result) {
if (result == "1") {
alert("Image Uploaded Successfully");
var imgNode = document.createElement('img');
imgNode.src = '/Upload/menupageimg/' + imgname;
$('#summernote').summernote('insertNode', imgNode);
}
},
error: function (abc) {
alert(abc.statusText);
}
});
}
}
function GetMenuPageImage(pageid) {
$.ajax({
url: '/admin/GetMenuPageImage/',
dataType: "json",
type: "GET",
contentType: 'application/json; charset=utf-8',
data: { pid: pageid },
success: function (data) {
if (data != '') {
$("#divImgContainer").empty();
var html = "";
$.each(data, function (i, item) {
html += "<div id='imgcon'>";
html += " <img src='/Upload/menupageimg/" + item.ID + "." + item.Ext + "' id='img" + item.ID + "'
onclick=\"CopyPath(" + item.ID + ",'" + item.Ext + "')\">"; html += "</div>";
})
$("#divImgContainer").append(html);
}
}
});
}
function ValidateFile(imgid) {
var Flag = true;
try {
if ((document.getElementById(imgid).files[0].size / 1024) > 500) {
alert("Sorry Maximum 500 KB file size is allowed");
Flag = false;
}
else
Flag = true;
}
catch (exception) {
alert('Please
select a image file');
Flag = false;
}
return Flag;
}
function CopyPath(id, ext) {
//copy the
current img path and put it in clipboard and select image id for delete
$("#hidImgID").val(id);
$("#hidImgName").val(ext);
navigator.clipboard.writeText("https://localhost:44336/Upload/menupageimg/" + id + "." + ext);
$("#imgcon
img").css("border", "none");
$('#img' + id).css({ "border": "solid 2px red", "padding": "2px" });
$("#lblMsgCopy").show();
//$("#lblMsgCopy").hide(3000);
$('#lblMsgCopy').delay(2000).hide(0);
var imgNode = document.createElement('img');
imgNode.src = '/Upload/menupageimg/' + id + "." + ext;
$('#summernote').summernote('insertNode', imgNode);
}
function DelImg() {
if ($("#hidImgID").val() == "" || $("#hidImgName").val() == "")
alert('Please
select an image for delete');
else {
var Userobj =
{
ID: $("#hidImgID").val(),
Ext: $("#hidImgName").val()
}
$.ajax({
url: '/admin/DelMenuPageImg/',
async: false,
dataType: "json",
type: "POST",
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(Userobj),
success:
function (data) {
if (data.sMessage == 1) {
$("#hidImgID").val("");
$("#hidImgName").val("");
GetMenuPageImage($("#MenuPageid").val());
}
else
alert('Some error occured del line 166');
}
});
}
}
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#blah')
.attr('src', e.target.result)
.width(250)
.height(150);
};
reader.readAsDataURL(input.files[0]);
}
}
Controller
public ActionResult MenuAddText(string rid)
{
SelectRepository ob = new SelectRepository();
MenuDataModel data = new MenuDataModel();
data = ob.GetMenuDataPDFByID(" where id=" +
Convert.ToInt32(rid));
//sub sql is
used becoz submenu id saved in menudata data and id is coming from menudata
table
ViewBag.SubMenuName =
ob.GetSingleValue("select SubMenuName from
MenuMaster where id=(select MID from MenuData where id=" + Convert.ToInt32(rid) + ")");
return View(data);
}
public JsonResult MenuAddTextUpdate(MenuDataModel data)
{
string ErrMsg = "";
UpdateRepository obj = new UpdateRepository();
if (obj.UpdateMenuPageDataText(data, ref ErrMsg) == true)
{
return Json(new {
sMessage = "1",
JsonRequestBehavior.AllowGet });
}
else
{
return Json(new {
sMessage = ErrMsg, JsonRequestBehavior.AllowGet });
}
}
{
string ErrMsg = "", imgname = "";
InsertRepository obj = new InsertRepository();
if (obj.AddMenuDataImgRec(data, ref ErrMsg, ref imgname)
== true)
{
return Json(new {
sMessage = imgname, JsonRequestBehavior.AllowGet });
}
else
{
return Json(new {
sMessage = ErrMsg, JsonRequestBehavior.AllowGet });
}
}
[HttpPost]
public JsonResult UploadMenuPageImg(string fnm)
{
if (Request.Files.Count > 0)
{
try
{
// Get all files from
Request object
HttpFileCollectionBase
files = Request.Files;
for (int i = 0; i <= files.Count - 1; i++)
{
HttpPostedFileBase file = files[I];
string fname = files[0].FileName;
string fileExtension =
Path.GetExtension(fname);
fname = fnm;
// Get the complete folder path and store the file inside it.
fname =
Path.Combine(Server.MapPath("~/Upload/menupageimg/"), fname);
WebImage img = new WebImage(file.InputStream);
img.Resize(Convert.ToInt16(800), Convert.ToInt16(500), false, false);
img.Save(fname);
}
// Returns message that successfully uploaded
var msg = "1";
return Json(msg,
JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
return Json("Error
occurred. Error details: " + ex.Message);
}
}
else
{
return Json("No files selected.");
}
}
public JsonResult
GetMenuPageImage(string pid)
{
List<MenuDataModel> data = new List<MenuDataModel>();
SelectRepository ob = new SelectRepository();
data =
ob.GetMenuPageImage(pid);
return Json(data,
JsonRequestBehavior.AllowGet);
}
public JsonResult DelMenuPageImg(MenuDataModel data)
{
UpdateRepository ob = new UpdateRepository();
string sql = "", ErrMsg = "";
sql = "delete from MenuDataImg where id=" + Convert.ToInt32(data.ID);
string file = Server.MapPath("~/Upload/menupageimg/" + data.ID + "." + data.Ext);
if (ob.UpdateCommon(sql, ref ErrMsg))
{
if (System.IO.File.Exists(file))
{
System.IO.File.Delete(file);
}
return Json(new {
sMessage = "1",
JsonRequestBehavior.AllowGet });
}
else
return Json(new {
sMessage = "0",
JsonRequestBehavior.AllowGet });
}
Repository
public bool UpdateMenuPageDataText(MenuDataModel ob, ref string ErrMsg)
{
String result = "";
try
{
using (SqlConnection dbcon = new SqlConnection(ConfigurationManager.ConnectionStrings["dbConnection"].ToString()))
{
using (SqlCommand cmd = new SqlCommand("[dbo].[UpdateMenuPageDataText]", dbcon))
{
cmd.CommandType =
CommandType.StoredProcedure; cmd.Parameters.AddWithValue("@rid", Convert.ToInt32(ob.ID));
cmd.Parameters.AddWithValue("@PageData", ob.PageData);
if (dbcon.State ==
ConnectionState.Closed)
dbcon.Open();
cmd.ExecuteNonQuery();
result = "1";
}
}
}
catch (Exception ex)
{
ErrMsg = ex.Message;
}
if (result == "1")
return true;
else
return false;
}
public bool
AddMenuDataImgRec(MenuDataModel ob, ref string ErrMsg, ref string imgname)
{
String result = "";
try
{
using (SqlConnection dbcon = new SqlConnection(ConfigurationManager.ConnectionStrings["dbConnection"].ToString()))
{
using (SqlCommand cmd = new SqlCommand("[dbo].[AddPageDataImage]", dbcon))
{
cmd.CommandType =
CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@pid", Convert.ToInt32(ob.ID));
cmd.Parameters.AddWithValue("@ext", ob.Ext);
cmd.Parameters.Add("@imgid",
SqlDbType.Int);
cmd.Parameters["@imgid"].Direction =
ParameterDirection.Output;
if (dbcon.State ==
ConnectionState.Closed)
dbcon.Open();
cmd.ExecuteNonQuery();
imgname =
Convert.ToString(cmd.Parameters["@imgid"].Value);
result = "1";
}
}
}
catch (Exception ex)
{
ErrMsg = ex.Message;
}
if (result == "1")
return true;
else
return false;
}
public List<MenuDataModel> GetMenuPageImage(string bid)
{
List<MenuDataModel> Record = new List<MenuDataModel>();
string sql = "select ID, ImgName
from MenuDataImg where PageID=" + bid;
try
{
using (SqlConnection dbcon = new
qlConnection(ConfigurationManager.ConnectionStrings["dbConnection"].ToString()))
{
using (SqlCommand cmd = new SqlCommand(sql, dbcon))
{
if (dbcon.State ==
ConnectionState.Closed)
dbcon.Open();
using (SqlDataReader drOb =
cmd.ExecuteReader())
{
if (drOb.HasRows)
{
while (drOb.Read())
{
MenuDataModel data = new MenuDataModel();
data.ID =
drOb.IsDBNull(0) ? " " : Convert.ToString(drOb["ID"]);
data.Ext =
Convert.ToString(drOb["ImgName"]);
Record.Add(data);
}
}
}
}
}
}
catch (Exception ex)
{
}
return Record;
}
public bool
UpdateCommon(string sql, ref string ErrMsg)
{
String result = "";
try
{
using (SqlConnection dbcon = new SqlConnection(ConfigurationManager.ConnectionStrings["dbConnection"].ToString()))
{
using (SqlCommand cmd = new SqlCommand(sql, dbcon))
{
if (dbcon.State ==
ConnectionState.Closed)
dbcon.Open();
cmd.ExecuteNonQuery();
result = "1";
}
}
}
catch (Exception ex)
{
ErrMsg = ex.ToString();
}
if (result == "1")
return true;
else
return false;
}
No comments:
Post a Comment