#foreach (var item in Model)
{
<img src='ShowShowcaseImage/#Html.Encode(item.ProductID)' id='#item.ProductID' />
<b>#Html.DisplayFor(m => item.ProductName)</b>
Enlarge
}
<div id="EnlargeContent" class="content">
<span class="button bClose"><span>X</span></span>
<div style="margin: 10px;" id="imageContent">
</div>
<p align="center"></p>
</div>
//Popup javascript
$('.enlargeImg').bind('click', function (e) {
$.post('/Home/EnlargeShowcaseImage/' + $(this).attr('id'), null, function (data) {
document.getElementById("imageContent").innerHTML += data;
});
$('#EnlargeContent').bPopup();
});
});
//
C# method
public ActionResult EnlargeShowcaseImage(string id)
{
var imageData = //linq query for retrive bytes from database;
StringBuilder builder = new StringBuilder();
if (imageData != null)
builder.Append("<img src='" + imageData.ImageBytes + "' />");
return Json(builder);
}
I want to show pop up of enlarged image on click of enlarge link. Image is stored in bytes in database. Two images are stored in database for each product - one is thumbnail and the other is enlarged. I am showing thumbnail image and I want to show enlarged image on click of enlarge link. I can't retrieve it from database.
I can't retrieve it from database
So your question is about retrieving an image from a database, right? It has strictly nothing to do with ASP.NET MVC?
Unfortunately you haven't told us whether you are using some ORM framework to access to your database or using plain ADO.NET. Let's assume that you are using plain ADO.NET:
public byte[] GetImage(string id)
{
using (var conn = new SqlConnection("YOUR CONNECTION STRING COMES HERE"))
using (var cmd = conn.CreateCommand())
{
conn.Open();
// TODO: replace the imageData and id columns and tableName with your actual
// database table names
cmd.CommandText = "SELECT imageData FROM tableName WHERE id = #id";
cmd.Parameters.AddWithValue("#id", id);
using (var reader = cmd.ExecuteReader())
{
if (!reader.Read())
{
// there was no corresponding record found in the database
return null;
}
const int CHUNK_SIZE = 2 * 1024;
byte[] buffer = new byte[CHUNK_SIZE];
long bytesRead;
long fieldOffset = 0;
using (var stream = new MemoryStream())
{
while ((bytesRead = reader.GetBytes(reader.GetOrdinal("imageData"), fieldOffset, buffer, 0, buffer.Length)) > 0)
{
stream.Write(buffer, 0, (int)bytesRead);
fieldOffset += bytesRead;
}
return stream.ToArray();
}
}
}
}
and if you are using some ORM it could be as simple as:
public byte[] GetImage(string id)
{
using (var db = new SomeDataContext())
{
return db.Images.FirstOrDefault(x => x.Id == id).ImageData;
}
}
and then inside your controller action:
public ActionResult EnlargeShowcaseImage(string id)
{
var imageData = GetImage(id);
if (imageData != null)
{
// TODO: adjust the MIME Type of the images
return File(imageData, "image/png");
}
return new HttpNotFoundResult();
}
and it is inside your view that you should create an <img> tag pointing to this controller action upon button click:
$('.enlargeImg').bind('click', function (e) {
$('#imageContent').html(
$('<img/>', {
src: '/Home/EnlargeShowcaseImage/' + $(this).attr('id')
})
);
$('#EnlargeContent').bPopup();
});
But hardcoding the url to your controller action in javascript like this is very bad practice because when you deploy your application it might break. It might also break if you decide to change the pattern of your routes. You should never hardcode urls like this. I would recommend you generating this url on the server.
For example I see that you have subscribed to some .enlargeImage element. Let's suppose that this is an anchor. Here's how to properly generate it:
#Html.ActionLink("Enlarge", "EnlargeShowcaseImage", "Home", new { id = item.Id }, new { #class = "enlargeImage" })
and then adapt the click handler:
$('.enlargeImg').bind('click', function (e) {
// Cancel the default action of the anchor
e.preventDefault();
$('#imageContent').html(
$('<img/>', {
src: this.href
})
);
$('#EnlargeContent').bPopup();
});
Try jQuery,
Here is one
http://superdit.com/2011/06/11/hover-image-zoom-with-jquery/
http://demo.superdit.com/jquery/zoom_hover/
Related
I'm using a webview2-control in a winforms application. I use messages to communicate between c# and Javascript
window.chrome.webview.addEventListener / window.chrome.webview.postMessage in Javascript
event .CoreWebView2.WebMessageReceived and method CoreWebView2.PostWebMessageAsString in C#
The communication works BUT only after the page in webview2 has been somehow refreshed. The first message sent by c# is always ignored/not received by JS. The messages after that are correcly received and processed.
My UI code:
public GUI()
{
InitializeComponent();
browser.Source = new Uri(System.IO.Path.GetFullPath("HTML/ui.html"));
InitializeAsync();
}
async void InitializeAsync()
{
await browser.EnsureCoreWebView2Async(null);
browser.CoreWebView2.WebMessageReceived += MessageReceived;
}
void MessageReceived(object sender, CoreWebView2WebMessageReceivedEventArgs args)
{
String content = args.TryGetWebMessageAsString();
if (content.StartsWith("getData"))
{
ReadDataFromCATIA();
var serializerSettings = new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects };
string jsonRootNode = JsonConvert.SerializeObject(this.RootNode, Formatting.Indented, serializerSettings); //here I've got the message I want to post
//String input = args.TryGetWebMessageAsString();
//MessageBox.Show("string from JS: " + input);
browser.CoreWebView2.PostWebMessageAsString(jsonRootNode);
}
else //object received
{
ProductNode received = JsonConvert.DeserializeObject<ProductNode>(content);
MessageBox.Show(received.PartNumber + " received");
}
}
and my JS in ui.html
window.chrome.webview.addEventListener('message', event => {
alert(event.data);
WriteDataFromCsharp(event.data);
});
function WriteDataFromCsharp(data) {
var target = document.getElementById('target');
if (target === null) { alert('target not found') };
//alert(target.id);
//target.textContent = event.data;
rootNode = JSON.parse(data);
target.innerHTML = addTable(rootNode); //addTable create an HTML table from the deserialized object rootNode
}
function RequestData() {
//function triggered by a button on the html page
//alert('post to c#');
window.chrome.webview.postMessage('getData');
}
So far, i've tried to:
ensure the javascript is as late as possible in the page (defer, at the end of body). No changes.
inject the javascript to the page after it has been loaded using .CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(jsCode). Same behavior.
inject the javascript after once the event NavigationCompleted has fired. same behavior.
What do I miss ?
Finally found the culprit: in my HTML-page, i've used a "submit" instead of "button". With
<input type="button" value="Load data from V5" onclick="RequestData()" />
The page behavior is as expected.
I want to download an Excel file when the user clicks on an Excel button. This is my Model and Object:
List<VMStockScreenerModel> listofStockScreener = (List<VMStockScreenerModel>)TempData["StockScreener"];
TempData["StockScreener"] = listofStockScreener;
This is the Excel button in my view:
<div class="col-md-1 padding-fx text-left" id="btn_FilterStocks">
<span onclick="DownloadFilterStocks(#listofStockScreener.ToList());" class="pull-right icon-merge" data-toggle="tooltip" title="Download">
<i class="fa fa-file-excel-o"></i>
<i class="fa fa-cloud-download"></i>
</span>
</div>
And here is my OnClick handler:
function DownloadFilterStocks() {
debugger;
var Obj = [#listofStockScreener];
Obj = JSON.stringify({ 'Obj': Obj });
var urls = '#(Html.Raw(Url.Action("Download_StockScreener","Home", new { Obj = "_Obj_"},Request.Url.Scheme)))'.replace("_Obj_", Obj);
}
Controller Code
public FileResult Download_StockScreener(VMStockScreenerModel Obj)
{
try
{
string fileName = string.Empty;
string filePath = string.Empty;
string fileName_filePath = string.Empty;
fileName_filePath = StockScreener_DownloadExcel(Obj);
if (fileName_filePath.Contains("#"))
{
filePath = fileName_filePath.Split('#')[0];
fileName = fileName_filePath.Split('#')[1];
}
if (fileName != "")
{
//return File(filePath, "text/csv", fileName);
}
else
{
return null;
}
}
catch (Exception ex)
{
Log.Logging("HomeController => Download_StockScreener", ex.Message + "\n" + ex.StackTrace);
} return null;
}
Instead of writing the whole code for you, i hope i can guide you to the answer by suggesting you the steps you need to take for making your solution work:
Instead of span, make the element an anchor a.
Render the anchor's URL server side (MVC view) without the query string part. Example: Export
In the anchor's click event, do the following:
function DownloadFilterStocks(elem) {
debugger;
var Obj = [#listofStockScreener];
var $elem = $(elem);
//this converts JS object to query string
var qParams = $.param(Obj);
//append query string to the anchor's base url
var newUrl = $elem.attr('href') + '?' + qParams;
//assign new url
$elem.attr('href', newUrl);
}
The way this will work is:
When the export link is clicked, JS code will be executed before server-side execution.
JS will update the URL/href with the query string
Server-side code will be executed with the new URL
Hope that helps you out. I ended up writing few codes anyway.
Note: My answer assumes that your server-side code is a working code.
I have /Views/Movies/Index.cshtml with
<input type="button" id="getmoviex" value="Get moviex" />
<ul id="moviex_list"/>
<p>
Title: #Html.TextBox("SearchTitle") <br />
</p>
I have /Controllers/MoviesController.cs with
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult moviex(string SearchGenre, string SearchTitle, string SearchActor)
{
var db = new CinemaContext();
db.Configuration.ProxyCreationEnabled = false;
var Movie = from m in db.Movie
select m;
if (!String.IsNullOrEmpty(SearchTitle))
{
Movie = Movie.Where(s => s.Title.Contains(SearchTitle));
}
return Json(db.Movie.ToList(), JsonRequestBehavior.AllowGet);
}
I have Javascript.js with
$(document).ready(function () {
$('#getmoviex').click(function () {
$.getJSON("/Movies", null, getmoviex);
});
});
Have I correctly written /Movies? Or this should be /Views/Movies?
function getmoviex(moviex) {
$("#moviex_list").text("");
$.each(moviex, function (i) {
$("#moviex_list").append("<li>" + this + "</li>");
});
}
How can I display info or list info from my query? Or view some output with error?
First make sure you button click does not trigger a request to server. Preventing default behavior is a standard way of doing it:
$('#getmoviex').click(function (event) {
$.getJSON("/Movies", null, getmoviex);
event.preventDefault();
});
As for the URL, it should not be to view, but to action instead. Your action is moviex and controller is Movies, so
$.getJSON("/Movies/moviex", null, getmoviex);
The rest looks fine, so that should do it.
you need to pass your arguments as well in url (GET).
Something like this could work:
$('#getmoviex').click(function(event) {
event.preventDefault();
$.getJSON("/Movies/moviex?SearchGenre=yuorgenre&SearchTitle=Cal&SearchActor=youractor", function(moviex) {
var lis;
//please check the console
console.log(moviex);
$.each(moviex, function(b) {
lis += "<li id='" + b.Id + "'>" + b.Title + "</li>");
}); document.getElementById("moviex_list").innerHTML += lis;
});
});
To avoid circular reference in Serializing you may use:
if (String.IsNullOrEmpty(SearchTitle)) {
return View("Error");
}
var db = new CinemaContext();
var Movie = (from m in db.Movie
Where m.Title.Contains(SearchTitle)
select new {
Id = m.MovieID,
Title = m.Title // can add more properties
}).ToList();
return Json(Movie, JsonRequestBehavior.AllowGet);
i have an asp.net mvc application with knockout.js
i'm using HTML5 EventSource for push messages
c#
private static void UpdateOnlineUsers()
{
var ou = Clients.Select(c => new { UserName = c.User.Name, Time = c.DateTime.ToString("G") }).ToList();
Clients.ForEach(c =>
{
c.Stream.WriteLine("data:" + new JavaScriptSerializer().Serialize(ou) + "\n\n");
});
}
and javascript is
eventSource.addEventListener('message', function (e) {
if (e.data.length) {
var json = JSON.parse(e.data);
if (json.Text) {
messages.push(json);
}
else onlineUsers(json);
}
}, false);
which is working fine.
but i want to add a specific name for the event so i added new line in c# method like
Clients.ForEach(c =>
{
c.Stream.WriteLine("event: messenger \n"); // added new
c.Stream.WriteLine("data:" + new JavaScriptSerializer().Serialize(ou) + "\n\n");
});
and changed script to
eventSource.addEventListener('messenger',...`
and it stopped working after adding event name
Please help!.
Thank you.
looks like it works if you remove the space between the event name and "\n", like so:
Clients.ForEach(c =>
{
c.Stream.WriteLine("event: messenger\n"); // added new w/o space
c.Stream.WriteLine("data:" + new JavaScriptSerializer().Serialize(ou) + "\n\n");
});
When my application start this JSonResult doesn`t exist and when I would like to use this (I get error "TypeError")
var newImg = $.parseJSON($("#UploadTarget").contents().find("#jsonResult")[0].innerHTML);
What I would like to do? I would like to have event which will tell me this object exist or this object change value.
var newImg = $.parseJSON($("#UploadTarget").contents().find("#jsonResult")[0].innerHTML);
How should I write this?
using System.Web.Mvc;
namespace pol
{
public class WrappedJsonResult : JsonResult
{
public override void ExecuteResult(ControllerContext context)
{
context.HttpContext.Response.Write("<html><body><textarea id=\"jsonResult\" name=\"jsonResult\">");
base.ExecuteResult(context);
context.HttpContext.Response.Write("</textarea></body></html>");
context.HttpContext.Response.ContentType = "text/html";
}
}
}
When I click button Image is upload to server but Result never opent important method UploadImage_Complete();
#model po.Models.Stwna
#using (Html.BeginForm("UploadImage", "StronaGlowna", FormMethod.Post,
new
{
enctype = "multipart/form-data",
id = "ImgForm",
name = "ImgForm",
target = "UploadTarget"
}))
{
<input type="file" name="imageFile" />
<input type="button" class="button" value="#Model.ZO" onclick="UploadImage()" />
}
<iframe id="UploadTarget" name="UploadTarget" onload="UploadImage_Complete();" style="position: absolute;
left: -999em; top: -999em;"></iframe>
<div id="Images">
</div>
<script type="text/javascript">
var isFirstLoad = true;
function UploadImage() {
$("#ImgForm").submit();
}
function UploadImage_Complete() {
//Check to see if this is the first load of the iFrame
if (isFirstLoad == true) {
isFirstLoad = false;
return;
}
//Reset the image form so the file won't get uploaded again
document.getElementById("ImgForm").reset();
//Grab the content of the textarea we named jsonResult . This shold be loaded into
//the hidden iFrame.
var newImg = $.parseJSON($("#UploadTarget").contents().find("#jsonResult")[0].innerHTML);
//If there was an error, display it to the user
if (newImg.IsValid == false) {
alert(newImg.Message);
return;
}
//Create a new image and insert it into the Images div. Just to be fancy,
//we're going to use a "FadeIn" effect from jQuery
var imgDiv = document.getElementById("Images");
var img = new Image();
img.src = newImg.ImagePath;
//Hide the image before adding to the DOM
$(img).hide();
imgDiv.appendChild(img);
//Now fade the image in
$(img).fadeIn(500, null);
// $('#Images').text(newImg.ImagePath);
}
</script>
MVC
[HttpPost]
public WrappedJsonResult UploadImage(HttpPostedFileWrapper imageFile)
{
return new WrappedJsonResult
{
Data = new
{
IsValid = true,
Message = string.Empty,
ImagePath = Url.Content(String.Format("http://a1.ec-images.myspacecdn.com/images01/29/4982945eb42646efafe2f94855ac3d21/l.jpg"))
}
};
}
I get this image when I click button twice but when I click once I don`t get any result.
I decide use Timer to make this Simple Timer