I need to save canvas image by using ajax or javascript...!!
tks!
my view
#using (Html.BeginForm("SaveImage", "Campaign", FormMethod.Post, new { id = "drawingForm" }))
{
<canvas id="myCanvas" width="352" height="352"
style="border: 1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.
</canvas>
<input type="hidden" name="imageData" id="imageData"/>
<input type="button" id="btnSave" value="Save Drawing"/>
}
[HttpPost]
public ActionResult SaveImage(CampaignViewModel model, string imageData)
{
//code.....
return RedirectToAction("Index", "Home");
}
We in ImindQ Online export the canvas as PNG with the following adapted code for your scenario:
In view:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Image</title>
</head>
<body>
<div>
#using (Html.BeginForm("SaveImage", "Campaign", FormMethod.Post, new { id = "drawingForm" }))
{
<canvas id="myCanvas" width="352" height="352"
style="border: 1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.
</canvas>
<input type="hidden" name="imageData" id="imageData" />
<input type="button" id="btnSave" value="Save Drawing" />
}
<script>
(function () {
document.getElementById('btnSave').addEventListener('click', function () {
var r = new XMLHttpRequest();
r.open("POST", "SaveImage", true);
r.onreadystatechange = function () {
if (r.readyState != 4 || r.status != 200) return;
};
var p = document.getElementById('myCanvas').toDataURL('image/png').replace('data:image/png;base64,', '');
r.send(p);
});
})();
</script>
</div>
</body>
</html>
in Controller:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
namespace WebApplication2.Controllers
{
//public class CampaignViewModel
//{
// public string ImageData { get; set; }
//}
public class CampaignController : Controller
{
// GET: Campaign
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult SaveImage()
{
int len = (int)Request.InputStream.Length;
byte[] buffer = new byte[len];
int c = Request.InputStream.Read(buffer, 0, len);
string png64 = Encoding.UTF8.GetString(buffer, 0, len);
byte[] png = Convert.FromBase64String(png64);
System.IO.File.WriteAllBytes("d:\\a.png", png);
//string pngz = Encoding.UTF8.GetString(png, 0, png.Length);
//code.....
return RedirectToAction("Index", "Home");
}
//
}
}
in view :
#using (Html.BeginForm("SaveImage", "Campaign", FormMethod.Post, new { id = "drawingForm" }))
{
<canvas id="myCanvas" width="352" height="352"
style="border: 1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.
</canvas>
<input type="hidden" name="imageData" id="imageData"/>
<input type="button" onclick="saveimage(event)" id="btnSave" value="Save Drawing" />
<img style="display: none" src="images/ajax-loader/ajax-loader.gif" id="progressbar"/>
}
#*call action*#
<script>
function saveimage(event) {
#*prevent call back to server*#
event.preventDefault();
#*show progress bar *#
var progress = document.getElementById("progressbar");
$(progress).css('display', 'block');
#*get form data *#
var data = $("#drawingForm").serialize();
#*save image information to imageData tag *#
var image = document.getElementById("myCanvas").toDataURL("image/png");
image = image.replace('data:image/png;base64,', '');
$("#imageData").val(image);
#*make ajax call *#
$.ajax({
url: "/Campaign/SaveImage",
data: data,
type: "Post",
dataType: "Json",
success: function (data) {
//do something
},
error: function (xhr, status, error) {
//do something
},
complete: function (data) {
$(progress).css('display', 'none');
}
});
}</script>
and in controller :
[HttpPost]
public ActionResult SaveImage(CampaignViewModel model, string imageData)
{
//path of folder taht you want to save the canvas
var path = Server.MapPath("~/images/canvaseimg");
//produce new file name
var fileName = GetPictureName(path);
//get full file path
var fileNameWitPath = Path.Combine(path, fileName);
//save canvas
using (var fs = new FileStream(fileNameWitPath, FileMode.Create))
{
using (var bw = new BinaryWriter(fs))
{
var data = Convert.FromBase64String(imageData);
bw.Write(data);
bw.Close();
}
fs.Close();
}
//do somthing with model
return RedirectToAction("Index", "Home");
}
Related
So I'm trying to build an virtual file storage, im stuck at the part where I have to upload files and after that display them in a File-s view so that the user can download, delete or see them. The form input together with the file upload is in a modal box. To process the modal form I have used #Html.BeginForm and to process the file upload I have used ajax. What I have achieved until now is that I can upload the files to the server folder, but I dont konw how I can save the file name and the file path to the database of file-s table. And I also need help on how to display these files in a specific view. Thank you in advance.
Html
<div class="modal-body">
#using (Html.BeginForm("SaveRecord", "NgarkoDokument", FormMethod.Post, new { enctype = "mulptiple/form-data" }))
{
<div class="form-group">
<label for="exampleFormControlSelect1">Lloji i dokumentit</label><br />
<select title="Lloji i dokumentit" name="lloji" class="form-control col-md-3 box" id="tipiDropdown"> </select>
<input type="button" title="Ngarko dokument" name="ngarko" value="Ngarko" id="uploadPop" class="btn btn-info col-md-3" onclick="document.getElementById('file').click();" />
<input type="file" onchange="javascript: updateList()" multiple="multiple" style="display:none;" id="file" name="postedFiles"/>
<div id="fileList"></div>
</div>
<br /><br />
<div class="form-group">
<label for="formGroupExampleInput">Fusha indeksimi</label> <br />
#*<input title="Indeksimi dokumentit" id="indeksimi" class="form-control col-md-3" type="text" name="indeksimi" placeholder="indeksimi" required />*#
#Html.TextBoxFor(a => a.Fusha_Indeksimit.Emri_Indeksimit, new { #class = "form-control", #placeholder = "indeksimi" })
#* <button title="Shto indeksim" id="modalPlus" type="submit" class="btn btn-info"><i class="glyphicon glyphicon-plus"></i></button>*#
</div>
<label for="formGroupExampleInput">Vendndodhja fizike e dokumentit</label><br>
<div id="zyraModal" class="form-group col-md-4">
#*<input title="Zyra fizike" id="zyra" class="form-control" type="text" name="zyra" placeholder="Zyra" />*#
#Html.TextBoxFor(a => a.Vendndodhja_fizike.Zyra, new { #class = "form-control", #placeholder
= "Zyra" })
</div>
<div class="form-group col-md-4">
#* <input title="Kutia fizike" id="kutia" class="form-control" type="number" name="kutia" placeholder="Nr i kutisë" />*#
#Html.TextBoxFor(a => a.Vendndodhja_fizike.Nr_Kutise, new { #class = "form-control", #placeholder = "Nr i kutisë" })
</div>
<div class="form-group col-md-4">
#* <input title="Rafti fizik" id="rafti" class="form-control" type="text" name="rafti" placeholder="Rafti" />*#
#Html.TextBoxFor(a => a.Vendndodhja_fizike.Rafti, new { #class = "form-control", #placeholder = "Rafti" })
</div>
<br /><br />
<div class="row" id="ruaj">
<button title="Ruaj dokumentin" type="submit" class="btn btn-success">Ruaj</button>
</div>
}
</div>
Ajax script
<script type="text/javascript">
$(document).ready(function () {
$("#file").change(function () {
console.log("Image selected!");
var formData = new FormData();
var totalFiles = document.getElementById("file").files.length;
for (var i = 0; i < totalFiles; i++) {
var file = document.getElementById("file").files[i];
formData.append("file", file);
}
$.ajax({
type: "POST",
url: '/UploadFile/Upload',
data: formData,
dataType: 'json',
contentType: false,
processData: false,
success: function (response) {
alert('succes!!');
}
});
});
});
</script>
Controller
public ActionResult Dokument()
{
return View();
}
[HttpPost]
public void Upload()
{
Dokumenti dok = new Dokumenti();
for (int i = 0; i < Request.Files.Count; i++)
{
var file = Request.Files[i];
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/App_Data/File/"), fileName);
file.SaveAs(path);
}
}
public ActionResult SaveRecord(NgarkoDokument model)
{
try
{
Vendndodhja_Fizike vendndodhja = new Vendndodhja_Fizike();
vendndodhja.Zyra = model.Vendndodhja_fizike.Zyra;
vendndodhja.Rafti = model.Vendndodhja_fizike.Rafti;
vendndodhja.Nr_Kutise = model.Vendndodhja_fizike.Nr_Kutise;
db.Vendndodhja_Fizike.Add(vendndodhja);
Fusha_Indeksimit indeksimi = new Fusha_Indeksimit();
indeksimi.Emri_Indeksimit = model.Fusha_Indeksimit.Emri_Indeksimit;
db.Fusha_Indeksimit.Add(indeksimi);
Dokumenti dok = new Dokumenti();
dok.Emer = model.Dokumenti.Emer;
db.Dokumenti.Add(dok);
db.SaveChanges();
//int lastUserId = dok.UserID;
}
catch(Exception ex)
{
throw ex;
}
return RedirectToAction("Dokument");
}
}
First of all, you may need to specify this because you send FormData to your controller. For example:
public async Task CreateAsync([FromForm] CreateBookDto input)
{
...
}
I care about a lot of things while uploading the file so my js file is a bit long but you can get what works for you:
$(function () {
var fileInput = document.getElementById('Book_CoverImageFile');
var file;
fileInput.addEventListener('change', function () {
var showModal = true;
file = fileInput.files[0];
document.getElementById("choose-cover-image").innerHTML = file.name;
var permittedExtensions = ["jpg", "jpeg", "png"]
var fileExtension = $(this).val().split('.').pop();
if (permittedExtensions.indexOf(fileExtension) === -1) {
showModal = false;
alert('This extension is not allowed')
$('#Book_CoverImageFile').val('');
$("#choose-cover-image").html("Choose a cover image...");
}
else if(file.size > 5*1024*1024) {
showModal = false;
alert('The file is too large');
}
var img = new Image();
img.onload = function() {
var sizes = {
width:this.width,
height: this.height
};
URL.revokeObjectURL(this.src);
if (sizes.width > 1920 && sizes.height > 1080){
alert('Height and Width must not exceed 1920*1080.')
$('#Book_CoverImageFile').val('');
$("#choose-cover-image").html("Choose a cover image...");
}
var aspectRatio = sizes.width / sizes.height;
aspectRatio = Number (aspectRatio.toFixed(1));
if (aspectRatio !== 1.8){
alert("The picture you uploaded is not in 16:9 aspect ratio!")
$('#Book_CoverImageFile').val('');
$("#choose-cover-image").html("Choose a cover image...");
}
}
if(showModal === true) {
readURL(this);
$('#myModal').modal('show');
}
var objectURL = URL.createObjectURL(file);
img.src = objectURL;
});
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#img-upload').attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
$('form#CreateBookForm').submit(function (e) {
e.preventDefault();
var title = $('#Book_Title').val().trim();
var formData = new FormData();
formData.append("Title", title);
formData.append("CoverImageFile", file);
$.ajax({
xhr: function() {
var xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
percentComplete = parseInt(percentComplete * 100);
if(percentComplete !== 100){
$( '#Book_CoverImageFile' ).prop( "disabled", true );
$( '#Book_Title' ).prop( "disabled", true );
$( '#btnSubmit' ).prop( "disabled", true );
}
}
}, false);
return xhr;
},
url: app.appPath + `api/app/Book`,
data: formData,
type: 'POST',
contentType: false,
processData: false,
success: function(data){
alert("The Book has been successfully submitted. It will be published after a review from the site admin.");
window.location.href = "/books";
},
error: function (data) {
alert(data.responseJSON.error.message);
}
});
});
This does many things, for example; file permitted extension control, control of file size, checking whether the file is more than 1920 * 1080 pixels, whether the file has 16:9 aspect ratio, disabling form elements while sending the file, etc...
And if you really care about security, you should;
To only accept permitted extensions:
public class AllowedExtensionsAttribute : ValidationAttribute
{
private readonly string[] _extensions;
public AllowedExtensionsAttribute(string[] extensions)
{
_extensions = extensions;
}
protected override ValidationResult IsValid(
object value, ValidationContext validationContext)
{
if (value == null) // If uploading a file is optional on the form screen, it should be added == CanBeNul
{
return ValidationResult.Success;
}
var file = value as IFormFile;
var extension = Path.GetExtension(file.FileName);
if (file.Length > 0 && file != null)
{
if (!_extensions.Contains(extension.ToLower()))
{
return new ValidationResult(GetErrorMessage());
}
}
return ValidationResult.Success;
}
public string GetErrorMessage()
{
return $"This extension is not allowed!";
}
}
To limit the uploaded file size:
public class MaxFileSizeAttribute : ValidationAttribute
{
private readonly int _maxFileSize;
public MaxFileSizeAttribute(int maxFileSize)
{
_maxFileSize = maxFileSize;
}
protected override ValidationResult IsValid(
object value, ValidationContext validationContext)
{
if (value == null) // If uploading a file is optional on the form screen, it should be added == CanBeNull
{
return ValidationResult.Success;
}
var file = value as IFormFile;
if (file.Length > 0)
{
if (file.Length > _maxFileSize)
{
return new ValidationResult(GetErrorMessage());
}
}
return ValidationResult.Success;
}
public string GetErrorMessage()
{
return $"Maximum allowed file size is { _maxFileSize} bytes.";
}
}
And you must add them to Dto:
public class CreateBookDto
{
[Required]
[StringLength(64)]
public string Title { get; set; }
[CanBeNull]
[DataType(DataType.Upload)]
[MaxFileSize(5*1024*1024)] // 5mb
[AllowedExtensions(new string[] { ".jpg", ".png", ".jpeg" })]
public IFormFile CoverImageFile { get; set; }
}
Finally, your HTML file should look like this:
<form method="post" id="CreateBookForm" asp-page="/Book/Create" enctype="multipart/form-data">
<div class="form-group">
<div class="custom-file">
<input asp-for="Book.CoverImageFile" type="file" name="file" class="custom-file-input" id="Book_CoverImageFile"
required="required">
<label id="choose-cover-image" class="custom-file-label" for="customFile">Choose a cover image...</label>
<small class="form-text text-muted">#L["CreateBookCoverInfo"].Value</small>
</div>
</div>
...
<button id="btnSubmit" type="submit" class="btn btn-primary btn-block">Submit</button>
</form>
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<img class="img-fluid" id="img-upload" alt=""/>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary btn-block" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
I am battling with some code in MVC, I managed to pass data form controller to a Jquery dialog widget, now i need to know how to return back to the controller depending on whether the user accepted or rejected the record. There is a list of records I upload as CSV onto MVC View, I then have a button called Validate Claims which calls a stored procedure to validate records, when validate claims is clicked a dialog pops up, with the response from the controller ViewBag passed, I want to then based on the validation response enable user to accept or reject record, when user accepts record it must save it to db then move to the next record. How can I do this in MVC JQuery, please assist.
Please see my code below:
Here is my View Code
#{
ViewBag.Title = "Home Page";
}
#*<link href="~/Content/jquery-ui.css" rel="stylesheet" />*#
<script src="~/Scripts/jquery-ui-1.11.4.min.js"></script>
<script src="~/Scripts/jquery-ui-1.11.4.js"></script>
<link href="~/Content/themes/base/dialog.css" rel="stylesheet" />
#*<script src="~/Scripts/jquery-1.8.2.js"></script>
<script src="~/Scripts/jquery-ui.js"></script>*#
#using CSVSupplierClaims.Models
#model List<CSVSupplierClaims.Models.SupplierClaimsUploadDisplayList>
<input type="submit" id="validateClaims" value="Validate Claims" size="5" />
<input type="submit" value="Import Claims to CRM" size="5" />
<div id="dialog" title="Supplier Claims Validation">
Claims Upload Confirmation
<p>
<span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0;"></span>
<table id="users" class="ui-widget ui-widget-content" height="100" width="100" border="1">
<thead>
<tr class="ui-widget-header ">
<th style="width:70%">ST Key</th>
<th style="width:70%">Supplier Claim</th>
<th style="width:70%">System Cost</th>
<th style="width:70%">Orig Inv</th>
</tr>
</thead>
<tbody>
<tr>
<td>#ViewBag.ST_Key</td>
<td>#ViewBag.SupplierClaim</td>
<td>#ViewBag.OrigInv</td>
<td>#ViewBag.Error</td>
<td>#ViewBag.SystemCost</td>
</tr>
</tbody>
</table>
</p>
</div>
<script type="text/javascript">
$(function () {
$("#dialog").dialog({
autoOpen: false
});
$("#validateClaims").click(function () {
$("#dialog").dialog("open", "resizable");
$("#dialog").dialog({
resizable: true,
height: 300,
width:500,
modal: true,
closeOnEscape: true,
buttons: {
"Accept Claim Record": function (){
$(this).dialog("close");
$(this).empty();
},
"Reject Claim Record": function () {
$(this).dialog("close");
}
}
});
});
});
</script>
<table>
<tr>
<th>Action</th>
<th>LineNo</th>
<th>TotalClaim</th>
<th>ClaimReference</th>
<th>Currency</th>
</tr>
#if (Model != null)
{
foreach (var c in Model)
{
<tr>
<td>#c.Action</td>
<td>#c.LineNo</td>
<td>#c.TotalClaim</td>
<td>#c.ClaimReference</td>
<td>#c.Currency</td>
</tr>
}
}
</table>
#Html.ValidationMessage("Error")
<form action="" method="post" enctype="multipart/form-data">
<table style="margin-top:150px">
<tr>
<td>
<label for="file"> Filename</label>
</td>
<td>
<input type="file" name="file" id="file" />
</td>
<td>
<input type="submit" value="Upload" />
</td>
</tr>
</table>
Here is my Controller Code
using CsvHelper;
using CSVSupplierClaims.Models;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Crm;
using System.Data.SqlClient;
using System.Data;
namespace CSVSupplierClaims.Controllers
{
public class HomeController : Controller
{
public ActionResult Index(HttpPostedFileBase file)
{
string path = null;
List<SupplierClaimsUploadDisplayList> supplierClaimsData = new List<SupplierClaimsUploadDisplayList>();
try
{
if (file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
path = AppDomain.CurrentDomain.BaseDirectory + "upload\\" + fileName;
file.SaveAs(path);
var csv = new CsvReader(new StreamReader(path));
var supplierList = csv.GetRecords<SupplierClaimsUpload>();
foreach (var supplier in supplierList)
{
SupplierClaimsUploadDisplayList supplierUploadDisplay = new SupplierClaimsUploadDisplayList();
supplierUploadDisplay.Action = supplier.Action;
supplierUploadDisplay.LineNo = supplier.LineNo;
supplierUploadDisplay.TotalClaim = supplier.TotalClaim;
supplierUploadDisplay.ClaimReference = supplier.ClaimReference;
supplierUploadDisplay.Currency = supplier.Currency;
supplierClaimsData.Add(supplierUploadDisplay);
}
}
}
catch
{
ViewData["error"] = "Uplaod failed";
}
Supplier_Claim_Upload_Result supplierClaimUplaod = new Supplier_Claim_Upload_Result();
var sqlConnection = "data source=WMVSQL02;initial catalog=Embrace;integrated security=True;";
using (SqlConnection conn = new SqlConnection(sqlConnection))
{
try
{
foreach (var claim in supplierClaimsData)
{
SqlCommand cmd = new SqlCommand();
cmd.CommandTimeout = 60;
SqlDataReader reader;
cmd.CommandText = "CRM.Supplier_Claim_Upload";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#Invoice", SqlDbType.NVarChar).Value = claim.LineNo;
cmd.Parameters.Add("#Amount", SqlDbType.NVarChar).Value = claim.TotalClaim;
cmd.Connection = conn;
conn.Open();
reader = cmd.ExecuteReader();
while (reader.Read())
{
supplierClaimUplaod.ST_Key = reader["ST_Key"].ToString();
if (supplierClaimUplaod.SupplierClaim != null)
{
supplierClaimUplaod.SupplierClaim = reader["Supplier_Claim"].ToString();
}
else if (supplierClaimUplaod.SupplierClaim == null && supplierClaimUplaod.OrigInv == null && supplierClaimUplaod.SystemCost == null)
{
if (supplierClaimUplaod.Error != null)
{
supplierClaimUplaod.Error = reader["Error"].ToString();
}
else if (supplierClaimUplaod.Error == null)
{
supplierClaimUplaod.SupplierClaim = "No value";
}
}
if (supplierClaimUplaod.OrigInv != null)
{
supplierClaimUplaod.OrigInv = reader["Orig_Inv"].ToString();
}
else if (supplierClaimUplaod.OrigInv == null)
{
if (supplierClaimUplaod.Error != null)
{
supplierClaimUplaod.Error = reader["Error"].ToString();
}
else if (supplierClaimUplaod.Error == null)
{
supplierClaimUplaod.OrigInv = "No value";
}
}
if (supplierClaimUplaod.SystemCost != null)
{
supplierClaimUplaod.SystemCost = reader["System_Cost"].ToString();
}
else if (supplierClaimUplaod.SystemCost == null)
{
if (supplierClaimUplaod.Error != null)
{
supplierClaimUplaod.Error = reader["Error"].ToString();
}
else if (supplierClaimUplaod.Error == null)
{
supplierClaimUplaod.SystemCost = "No Value";
}
}
}
if (supplierClaimUplaod != null)
{
ViewBag.ST_Key = supplierClaimUplaod.ST_Key;
ViewBag.SupplierClaim = supplierClaimUplaod.SupplierClaim;
ViewBag.OrigInv = supplierClaimUplaod.OrigInv;
ViewBag.Error = supplierClaimUplaod.Error;
ViewBag.SystemCost = supplierClaimUplaod.SystemCost;
ViewBag.Confirmation = supplierClaimUplaod.Error +
supplierClaimUplaod.OrigInv +
supplierClaimUplaod.ST_Key +
supplierClaimUplaod.SupplierClaim +
supplierClaimUplaod.SystemCost;
return View(supplierClaimsData);
}
conn.Close();
}
}
catch (Exception)
{
throw;
}
}
return View(supplierClaimsData);
}
}
}
I managed to pass the controller response to the dialog, I am struggling trigger the loop to go back to the controller and got through all the records. When a user click on Accept Record I want to go back to the controller, and maybe save the record somewhere(sql) and validate the next record and so on, I am basically asking how can I wire up the Jquery button click Accept or Reject to go back to the controller and run additional code based on what button the user selected.
You can do this with an ajax call to your controller action.
$.ajax({
url: "#Url.Action("YourAction", "YourController")",
data: some_parameters
type: "POST",
success: function(response){ },
error: function(jqXHR, textStatus, errorThrown) { }
});
Here for more details
I am using a map control from telerik, with shome markers:
#(Html.Kendo().Map()
.Name("map")
.Layers(layers =>
{
layers.Add()
.Type(MapLayerType.Tile)
.UrlTemplate("http://tile.openstreetmap.org/#= zoom #/#= x #/#= y #.png")
.Subdomains("a", "b", "c")
.Attribution("© <a href='http://osm.org/copyright'>OpenStreetMap contributors</a>." +
"Tiles courtesy of <a href='http://www.opencyclemap.org/'>Andy Allan</a>");
layers.Add()
.Type(MapLayerType.Marker)
.DataSource(dataSource => dataSource.GeoJson()
.Read(read => read.Action("GetMarkers", "MyController"))
)
.Tooltip(t => t.ContentHandler("GetTooltipContent"))
.LocationField("LatLng")
.TitleField("Title");
}).Events(e => e.MarkerClick("MarkerClicked")))
I need that all markers fit in the initial map view, with the correct zoom and center location.
I have used the gmaps javascript plugin for google maps and I know there are functions fitZoom()/fitBounds() to achieve this
Is there any way to achieve this with Kendo controls?
Using jQuery you can set bound for map.
function createMap() {
var markers = [
{"latlng":[34.2675,38.7409], "name": "One"},
{"latlng": [30.2707,-97.7490],"name": "Two"},
{"latlng": [30.2705,-90.4444],"name": "Three"},
{"latlng": [31.8520,33.8911], "name": "Four"}];
$("#map").kendoMap({
layers: [{
type: "tile",
urlTemplate: "http://tile.openstreetmap.org/#= zoom #/#= x #/#= y #.png",
subdomains: ["a", "b", "c"],
attribution: "© <a href='http://osm.org/copyright'>OpenStreetMap contributors</a>." +
"Tiles courtesy of <a href='http://www.opencyclemap.org/'>Andy Allan</a>"
}, {
type: "marker",
dataSource: {
data: markers
},
locationField: "latlng",
titleField: "name"
}]
});
var map = $("#map").getKendoMap();
var layer = map.layers[1];
var markers = layer.items;
var extent;
for (var i = 0; i < markers.length; i++) {
var loc = markers[i].location();
if (!extent) {
extent = new kendo.dataviz.map.Extent(loc, loc);
} else {
extent.include(loc);
}
}
map.extent(extent);
}
$(document).ready(createMap);
<!DOCTYPE html>
<html>
<head>
<base href="http://demos.telerik.com/kendo-ui/map/index">
<style>html { font-size: 12px; font-family: Arial, Helvetica, sans-serif; }</style>
<title></title>
<link rel="stylesheet" href="http://cdn.kendostatic.com/2015.1.318/styles/kendo.common-material.min.css" />
<link rel="stylesheet" href="http://cdn.kendostatic.com/2015.1.318/styles/kendo.material.min.css" />
<link rel="stylesheet" href="http://cdn.kendostatic.com/2015.1.318/styles/kendo.dataviz.min.css" />
<link rel="stylesheet" href="http://cdn.kendostatic.com/2015.1.318/styles/kendo.dataviz.material.min.css" />
<script src="http://cdn.kendostatic.com/2015.1.318/js/jquery.min.js"></script>
<script src="http://cdn.kendostatic.com/2015.1.318/js/kendo.all.min.js"></script>
</head>
<body>
<div id="example">
<div class="demo-section k-header" style="padding: 1em;">
<div id="map"></div>
</div>
</div>
</body>
</html>
I did that with an ajax call in an asp.net mvc5 application
the controller
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "Welcome to ASP.NET MVC!";
return View();
}
public ActionResult GetMarkers( )
{
var listMarkers = new List<Markers>() { new Markers() { Latitude=34.2675, Longitude= 38.7409, Name="Pos1"},
new Markers() { Latitude=30.2707, Longitude=-97.7490, Name="Pos2"},
new Markers() { Latitude=30.2705, Longitude=-90.4444, Name="Pos3"},
new Markers() { Latitude=31.8520, Longitude=33.8911, Name="Pos4"},
new Markers() { Latitude=33.8520, Longitude=32.8911, Name="Pos5"},
new Markers() { Latitude=60.2707, Longitude=-97.7490, Name="Pos6"},
new Markers() { Latitude=20.2705, Longitude=-90.4444, Name="Pos7"},
new Markers() { Latitude=50.8520, Longitude=33.8911, Name="Pos8"},
new Markers() { Latitude=40.8520, Longitude=32.8911, Name="Pos9"}};
var json = JsonConvert.SerializeObject(listMarkers);
return Json(json, JsonRequestBehavior.AllowGet);
}
}
The Model:
public class Markers
{
public string Name { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
public double[] LatLong { get { return new double[] { Latitude , Longitude}; } }
}
and the view
<ul id="panelbar">
<li class="k-state-active">
<span class="k-link k-state-selected">Getting Started</span>
<div id="map" style="width: 960px; height: 600px"></div>
</li>
<li>
</li>
</ul>
<script>
$(function () {
var markers;
$.ajax({
url: "../Home/GetMarkers",
dataType: 'json',
async: false,
success: function (data) {
markers = data;
}
});
$("#panelbar").kendoPanelBar();
$("#map").kendoMap({
layers: [{
type: "tile",
urlTemplate: "http://a.tile.openstreetmap.org/#= zoom #/#= x #/#= y #.png",
attribution: "© <a href='http://osm.org/copyright'>OpenStreetMap contributors</a>."
}, {
type: "marker",
dataSource: {
data: JSON.parse(markers)
},
locationField: "LatLong",
titleField: "Name"
}]
});
});
</script>
I have a project written in ASP.NET MVC C#. I have a problem in it. In view Index.cshtml is declared and populated a variable name image and I must pass the values stored in it to view Object3D.cshtml to use there. How can I do it? Here is the code:
ImageController.cs
using ImageView.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace ImageView.Controllers
{
public class ImageController : Controller
{
//
// GET: /Image/
public ActionResult Index()
{
return View(new ImageModel());
}
public ActionResult Object3D()
{
return View();
}
}
}
ImageMetaData.xml
<?xml version="1.0" encoding="utf-8" ?>
<images>
<image>
<filename>2483--FIXED</filename>
</image>
<image>
<filename>6a</filename>
</image>
<image>
<filename>BARF SIDE</filename>
</image>
<image>
<filename>bullet</filename>
</image>
<image>
<filename>cap_s</filename>
</image>
<image>
<filename>dan and denise</filename>
</image>
<image>
<filename>dan redo1</filename>
</image>
<image>
<filename>DY Cross</filename>
</image>
<image>
<filename>finallast_cabochon 0065</filename>
</image>
<image>
<filename>Gye Nyame_Rim--FIXED</filename>
</image>
<image>
<filename>JS 040310 10,75 7,5mm__1</filename>
</image>
<image>
<filename>jsband</filename>
</image>
<image>
<filename>Moon sun stars Gents</filename>
</image>
<image>
<filename>new_SIGNET_(20MM) 0086</filename>
</image>
<image>
<filename>trendsetter001</filename>
</image>
<image>
<filename>Weddingband</filename>
</image>
</images>
ImageModel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Xml.Linq;
namespace ImageView.Models
{
public class ImageModel : List<Image>
{
public ImageModel()
{
string directoryOfImage = HttpContext.Current.Server.MapPath("~/Images/");
XDocument imageData = XDocument.Load(directoryOfImage + #"/ImageMetaData.xml");
var images = from image in imageData.Descendants("image") select new Image(image.Element("filename").Value);
this.AddRange(images.ToList<Image>());
}
}
}
Image.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace ImageView.Models
{
public class Image
{
public Image(string path)
{
Path = path;
}
public string Path { get; set; }
}
}
Index.cshtml
#model ImageView.Models.ImageModel
#{
ViewBag.Title = "Gallery";
Layout = "~/Views/Shared/_Layout.cshtml";
var picture="";
}
<html>
<head>
<title>Image Index</title>
<link rel="stylesheet" href="../Content/colorbox.css" />
<script src="../Scripts/jquery-1.7.1.js"></script>
<script src="../Scripts/jquery.colorbox.js"></script>
<script src="../Scripts/bootstrap.min.js"></script>
<link href="../Content/bootstrap.min.css" rel="stylesheet" />
<script>
$(document).ready(function () {
//Examples of how to assign the Colorbox event to elements
$(".group1").colorbox({ rel: 'group1' });
$(".iframe").colorbox({ iframe: true, width: "90%", height: "90%" });
});
</script>
</head>
<body>
<div id="container">
<div id="header">
<h1>Images</h1>
</div>
<div class="row">
#foreach (var image in ViewData.Model) {
<div class="col-lg-3 col-md-4 col-xs-6 thumb">
<a class="thumbnail group1 iframe" href="#Url.Action("Object3D","Image")">
<img class="img-responsive" src="images/#String.Concat(#image.Path,".png")" alt="" />
</a>
<div class="caption">
<h3>#image.Path</h3>
<p>Text text text</p>
</div>
</div>
picture = #image.Path;
}
#ViewBag.Picture = picture;
</div>
</div>
</body>
</html>
Object3D.cshtml
#model ImageView.Models.ImageModel
#{
ViewBag.Title = "Index";
Layout = null;
}
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>3D Model</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="../Scripts/three.min.js"></script>
<script src="../Scripts/STLLoader.js"></script>
<script src="../Scripts/Detector.js"></script>
<script src="../Scripts/stats.min.js"></script>
<script src="../Scripts/TrackballControls.js"></script>
</head>
<body>
#ViewBag.Picture
<script>
function onLoad() {
initScene();
function initScene() {
// Grab the canvas
var myCanvas = document.getElementById("myCanvas");
//Create a new renderer and set the size
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true, canvas: myCanvas });
renderer.setSize(myCanvas.offsetWidth, myCanvas.offsetHeight);
//Create a new scene
scene = new THREE.Scene();
//Create a perspective camera
camera = new THREE.PerspectiveCamera(75, myCanvas.offsetWidth / myCanvas.offsetHeight, 1, 1000);
camera.position.z = 20;
//Add camera to the scene
scene.add(camera);
//Add controls for interactively moving the camera with mouse
controls = new THREE.TrackballControls(camera, renderer.domElement);
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 1.2;
controls.panSpeed = 0.2;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = false;
controls.dynamicDampingFactor = 0.3;
controls.minDistance = 10;
controls.maxDistance = 100;
scene.add(new THREE.AmbientLight(0x777777));
//Add some lights
addShadowedLight(1, 1, 1, 0xffaa00, 1.35);
addShadowedLight(0.5, 1, -1, 0xffaa00, 1);
//The model's material
var material = new THREE.MeshPhongMaterial({ ambient: 0x555555, color: 0xAAAAAA, specular: 0x111111, shininess: 200 });
//Loading the object
var loader = new THREE.STLLoader();
loader.addEventListener('load', function (event) {
var geometry = event.content;
var mesh = new THREE.Mesh(geometry, material);
mesh.position.set(-13, -15, 0);
mesh.rotation.set(-Math.PI / 2, 0, 0);
mesh.castShadow = true;
mesh.receiveShadow = true;
scene.add(mesh);
});
loader.load("../STLFiles/6a.stl");
//Call the animate function
animate();
}
//Function that adds the lights
function addShadowedLight(x, y, z, color, intensity) {
var directionalLight = new THREE.DirectionalLight(color, intensity);
directionalLight.position.set(x, y, z)
scene.add(directionalLight);
directionalLight.castShadow = true;
var d = 1;
directionalLight.shadowCameraLeft = -d;
directionalLight.shadowCameraRight = d;
directionalLight.shadowCameraTop = d;
directionalLight.shadowCameraBottom = -d;
directionalLight.shadowCameraNear = 1;
directionalLight.shadowCameraFar = 4;
directionalLight.shadowMapWidth = 1024;
directionalLight.shadowMapHeight = 1024;
directionalLight.shadowBias = -0.005;
directionalLight.shadowDarkness = 0.15;
}
//Function that animates the object
function animate() {
requestAnimationFrame(animate);
render();
}
//Function that draws the object
function render() {
controls.update(); //for cameras
renderer.render(scene, camera);
}
}
window.onload = window.onresize = function () { onLoad(); }
</script>
<canvas id="myCanvas" style="width: 100%; height: 100%;" ></canvas>
</body>
</html>
This is a lot of code! What I understand is that you need to pass the image path back to your Object3D method where the path is base on which item you select from the list of thumbnail.
Index.cshtml
<div class="row">
#foreach (var image in ViewData.Model) {
<div class="col-lg-3 col-md-4 col-xs-6 thumb">
<a class="thumbnail group1 iframe" href="#Url.Action("Object3D","Image",new { path = image.Path })"> <-- pass parameter to action method
<img class="img-responsive" src="images/#String.Concat(#image.Path,".png")" alt="" />
</a>
<div class="caption">
<h3>#image.Path</h3>
<p>Text text text</p>
</div>
</div>
}
</div>
Notice I use Url.Action("Object3D","Image",new { path = image.Path }. This is because the way you assigning the #ViewBag.Picture = picture; is not serving it's purpose. It will always be the last image.Path of the for-each loop.
Using the above way also requires you to expect parameter from your action method:
ImageController.cs
public ActionResult Object3D (string path)
{
ViewBag.Picture = path;
return View();
}
You can get the path from your action method and then you assign it to ViewBag.Picture. Then the Object3D.cshtml page will get the value.
i am trying to upload files with the jqueryform plugin. I have to file upload controls but the second one cant upload?
<div>
<h2>
Upload test</h2>
<script src="../../Scripts/jquery-1.5.1.min.js" type="text/javascript"></script>
<script src="../../Scripts/jquery-ui-1.8.12.custom.min.js" type="text/javascript"></script>
<script src="../../Scripts/jqueryform.js" type="text/javascript"></script>
<script src="../../Scripts/jblock.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function (event) {
$(function () {
$("#ajaxUploadForm").ajaxForm({
iframe: true,
dataType: "json",
beforeSubmit: function () {
$("#ajaxUploadForm").block({ message: ' Uploading Image' });
},
success: function (result) {
$("#ajaxUploadForm").unblock();
$("#ajaxUploadForm").resetForm();
//$.growlUI(null, result.message);
if (result.message != 'Success') {
alert(result.message);
}
else {
}
},
error: function (xhr, textStatus, errorThrown) {
$("#ajaxUploadForm").unblock();
$("#ajaxUploadForm").resetForm();
}
});
});
});
</script>
<form id="ajaxUploadForm" action="<%= Url.Action("Upload", "Home")%>" method="post"
enctype="multipart/form-data">
<input type="file" name="file" />
<input type="file" name="file2" />
<input id="ajaxUploadButton" type="submit" value="upload file" />
</form>
</div>
public ActionResult Index()
{
return View();
}
public FileUploadJsonResult Upload(HttpPostedFileBase file)
{
if (file == null)
{
return new FileUploadJsonResult { Data = new { message = "error" } };
}
if (file.ContentLength > 0)
{
//save file or something
}
return new FileUploadJsonResult { Data = new { message = string.Format("success") } };
}
public class FileUploadJsonResult : JsonResult
{
public override void ExecuteResult(ControllerContext context)
{
this.ContentType = "text/html";
context.HttpContext.Response.Write("<textarea>");
base.ExecuteResult(context);
context.HttpContext.Response.Write("</textarea>");
}
}
You have two file inputs on your form named respectively file and file1. You controller action that handles the upload has only a single HttpPostedFileBase argument named file. So you could add a second one:
public FileUploadJsonResult Upload(
HttpPostedFileBase file,
HttpPostedFileBase file1
)
{
if (file == null || file1 == null)
{
return new FileUploadJsonResult { Data = new { message = "error" } };
}
if (file.ContentLength > 0)
{
//save file or something
}
if (file1.ContentLength > 0)
{
//save the second file or something
}
return new FileUploadJsonResult { Data = new { message = string.Format("success") } };
}
Or if you wanted to handle multiple files you could give them the same name on your form:
<input type="file" name="files" />
<input type="file" name="files" />
<input type="file" name="files" />
<input type="file" name="files" />
<input type="file" name="files" />
...
and your controller action could then take a list of files:
public FileUploadJsonResult Upload(IEnumerable<HttpPostedFileBase> files)
{
if (files)
{
return new FileUploadJsonResult { Data = new { message = "error" } };
}
foreach (var file in files)
{
if (file.ContentLength > 0)
{
//save file or something
}
}
return new FileUploadJsonResult { Data = new { message = string.Format("success") } };
}
You may checkout the following blog post about uploading files in ASP.NET MVC.