I am trying to build a REST API with AJAX.
My C# code looks like this.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using WebApplication2.Models;
using System.IO;
using System.Globalization;
namespace WebApplication2.Controllers
{
public class DefaultController : ApiController
{
List<Default>players = new List<Default>();
string path = Path.Combine(Directory.GetCurrentDirectory(), "\\players.txt");
public IHttpActionResult GetAllPlayers()
{
String line;
StreamReader file = new StreamReader(path);
string[] data;
while ((line = file.ReadLine()) != null)
{
data = line.Split(',');
Default player = new Default(data[0],data[1],data[2],data[3],DateTime.ParseExact(data[4],
"yyyy-mm-dd", CultureInfo.InvariantCulture));
players.Add(player);
}
file.Close();
return Ok (players);
}
My HTML Page Code looks like this
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
<div>
<h2> All Players</h2>
<ul id="players"/>
</div>
<div>
<br />
<h2> Search or Delete </h2>
<select name="options_for_search_delete">
<option value="id">ID</option>
<option value="name">Name</option>
</select>
<input type = "text" id="data" size="5"/>
<input type = "button" value="Search" onclick = "search()" />
<input type = "button" value="Delete" onclick = "find()" />
<br />
<p id="players"/>
</div>
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.0.3.min.js"></script>
<script>
var uri = 'api/default';
$(document).ready(function () {
$.getJSON(uri).done(function(data){
//success:function(data){
$.each(data,function(key,item){
$('<li>',{text:format(item)}).appendTo($('#players'));
});
});
});
function format(item){
return item.reg + "," + item.first + " " + item.last + "," + item.team;
}
</script>
</body>
</html>
When I access api/default page, the output is as intended. However when I access players.html, the unordered list appears as undefined. I don't know how to fix this.
Try
<ul id="players"></ul>
as it is a block element and id should be unique for elements.
Related
I basically need to create a windows form with bootstrap components. The windows form includes a login URL, email, API key fields, and a submit button. I'm creating it using webview2 control like this :
{
string html = #"<html>
<head>
<link rel=""stylesheet"" href=""https://cdn.jsdelivr.net/npm/bootstrap#4.3.1/dist/css/bootstrap.min.css"" integrity=""sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T"" crossorigin=""anonymous"">
<script src=""https://code.jquery.com/jquery-3.3.1.slim.min.js"" integrity=""sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"" crossorigin=""anonymous""></script>
<script src=""https://cdn.jsdelivr.net/npm/popper.js#1.14.7/dist/umd/popper.min.js"" integrity=""sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"" crossorigin=""anonymous""></script>
<script src=""https://cdn.jsdelivr.net/npm/bootstrap#4.3.1/dist/js/bootstrap.min.js"" integrity=""sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"" crossorigin=""anonymous""></script>
</head>
<body>
<form>
<div class=""form-group"">
<label for=""jiraurl"">Jira Url</label>
<input type=""url"" class=""form-control"" id=""jiraurl"" placeholder=""Enter Jira URL"">
</div>
<div class=""form-group"">
<label for=""jiraemail"">Email address</label>
<input type=""email"" class=""form-control"" id=""jiraemail"" placeholder=""Enter email"">
</div>
<div class=""form-group"">
<label for=""apikey"">Api Key</label>
<input type=""password"" class=""form-control"" id=""apikey"" placeholder=""Enter Api Key"">
</div>
<div class=""form-check"">
<input type=""checkbox"" class=""form-check-input"" id=""exampleCheck1"">
<label class=""form-check-label"" for=""exampleCheck1"">Check me out</label>
</div>
<button id = ""button"" type=""submit"" class=""btn btn-primary"" onclick=""myFunction"">Submit</button>
</form>
<script>
function myFunction() {
let jiralogincreds = '{""jiraurl"" : document.getElementById('jiraurl').innerText ,""jiraemail"" : document.getElementById('jiraemail').innerText ,""apikey"" : document.getElementById('apikey').innerText }' ;
window.chrome.webview.postMessage(jiralogincreds);};
</script>
</body>
</html>";
return html;
}
I want when the form opens and the user inputs the data into the fields and clicks the submit button for the data in those fields to be returned to my code.
After hours of research, I found that the webView21.CoreWebView2.WebMessageReceived component will do the trick, but I can't find out what I'm doing wrong and why my code is not catching anything.
Any tips or answers are heavily appreciated, I've reached a dead end and I have spent more than 20 hours already trying to find a solution
Below is my full code:
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace JiraLogin
{
public partial class JiraLoginWebView: Form
{
public JiraLoginWebView()
{
InitializeComponent();
//InitializeAsync();
}
async void JiraLoginWebView_Load(object sender, EventArgs e)
{
//webView21.CoreWebView2InitializationCompleted += webView2_CoreWebView2InitializationCompleted;
InitializeAsync();
}
private string getHtml()
{
string html = #"<html>
<head>
<link rel=""stylesheet"" href=""https://cdn.jsdelivr.net/npm/bootstrap#4.3.1/dist/css/bootstrap.min.css"" integrity=""sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T"" crossorigin=""anonymous"">
<script src=""https://code.jquery.com/jquery-3.3.1.slim.min.js"" integrity=""sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"" crossorigin=""anonymous""></script>
<script src=""https://cdn.jsdelivr.net/npm/popper.js#1.14.7/dist/umd/popper.min.js"" integrity=""sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"" crossorigin=""anonymous""></script>
<script src=""https://cdn.jsdelivr.net/npm/bootstrap#4.3.1/dist/js/bootstrap.min.js"" integrity=""sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"" crossorigin=""anonymous""></script>
</head>
<body>
<form>
<div class=""form-group"">
<label for=""jiraurl"">Jira Url</label>
<input type=""url"" class=""form-control"" id=""jiraurl"" placeholder=""Enter Jira URL"">
</div>
<div class=""form-group"">
<label for=""jiraemail"">Email address</label>
<input type=""email"" class=""form-control"" id=""jiraemail"" placeholder=""Enter email"">
</div>
<div class=""form-group"">
<label for=""apikey"">Api Key</label>
<input type=""password"" class=""form-control"" id=""apikey"" placeholder=""Enter Api Key"">
</div>
<div class=""form-check"">
<input type=""checkbox"" class=""form-check-input"" id=""exampleCheck1"">
<label class=""form-check-label"" for=""exampleCheck1"">Check me out</label>
</div>
<button id = ""button"" type=""submit"" class=""btn btn-primary"" onclick=""myFunction"">Submit</button>
</form>
<script>
function myFunction() {
let jiralogincreds = '{""jiraurl"" : document.getElementById('jiraurl').innerText ,""jiraemail"" : document.getElementById('jiraemail').innerText ,""apikey"" : document.getElementById('apikey').innerText }' ;
window.chrome.webview.postMessage(jiralogincreds);};
</script>
</body>
</html>";
return html;
}
private void WebView21_WebMessageReceived(object sender, CoreWebView2WebMessageReceivedEventArgs e)
{
JiraLoginWebViewDTO jiraloginwebview = JsonConvert.DeserializeObject<JiraLoginWebViewDTO>(e.TryGetWebMessageAsString());
}
private async void InitializeAsync()
{
//await webView21.EnsureCoreWebView2Async(null);
string html = getHtml();
InitializeWebView2Async(html, "");
//webView21.NavigateToString(html);
}
async void InitializeWebView2Async(string html, string tempDir = "")
{
CoreWebView2Environment webView2Environment = null;
string tempDir2 = tempDir;
if (String.IsNullOrEmpty(tempDir2))
{
tempDir2 = Path.GetTempPath();
}
CoreWebView2EnvironmentOptions options = null;
webView2Environment = await CoreWebView2Environment.CreateAsync(null, tempDir2, options);
await webView21.EnsureCoreWebView2Async(webView2Environment);
webView21.NavigateToString(html);
webView21.CoreWebView2.WebMessageReceived += WebView21_WebMessageReceived;
}
}
}
For those interested I've just released WebView2.DevTools.Dom to NuGet.org. It's free for anyone to use.
More details and examples in the Readme.
You can expose a function your JavaScript application can call.
await webView.EnsureCoreWebView2Async();
webView.CoreWebView2.DOMContentLoaded += async (s, e) =>
{
var devToolsContext = await webView.CoreWebView2.CreateDevToolsContextAsync();
await devToolsContext.ExposeFunctionAsync("jsButtonClick", () =>
{
Dispatcher.InvokeAsync(() =>
{
WindowState = WindowState switch
{
WindowState.Maximized => WindowState.Normal,
WindowState.Normal => WindowState.Maximized,
_ => WindowState.Minimized,
};
});
});
var jsButton = await devToolsContext.QuerySelectorAsync("#jsButton");
_ = jsButton.AddEventListenerAsync("click", "jsButtonClick");
};
Functions persist across navigations so you only need to register a function once.
There's a working example available at https://github.com/ChromiumDotNet/WebView2.DevTools.Dom/blob/main/WebView2.DevTools.Dom.Wpf.Example/MainWindow.xaml.cs#L22
I am using Ajax to populate a partial view in my web application. This partial view contains a link to download a PDF file based upon the data that is currently in the table / List<> of the model.
The partial view is as follows:
#model Inspection_Reports.ViewModel.SummaryReportViewModel
<table id="summaryReportTable" class="table-condensed table-striped">
<thead><tr><td>Inspector</td><td>Attendant</td><td>Property</td><td>Room Number</td><td>Date</td><td>HK Score</td><td>Maint. Score</td></tr></thead>
<tbody id="resultsContainer">
#foreach (var report in #Model.reportsList)
{
<tr><td>#report.inspect.empName</td><td>#report.attendant.empName</td><td>#report.location.locName</td><td>#report.room</td><td>#report.endTime</td><td>#report.hkDisplay</td><td>#report.mainDisplay <input type='hidden' name='reportId[i]' /></td></tr>
}
</tbody>
</table>
#Html.ActionLink("Export as PDF", "GenerateSummaryPDF", new { summary = #Model.reportsList })
GenerateSummaryPDF method:
public FileResult GenerateSummaryPDF(List<report_summary> summary) {
Document doc = pdfWorker.readyDocument("Inspection Report, Generated " + DateTime.Now.ToString("MM-dd-yyyy"));
pdfWorker.createSummaryReport(doc, summary);
pdfWorker.savePDF(doc, String.Format("{0}/Inspection_Summary_{1}.pdf", #"C:\Users\Khandokar\Desktop", DateTime.Now.ToString("MM-dd-yyyy")));
return File(String.Format("{0}/Inspection_Summary_{1}.pdf", #"PATH", DateTime.Now.ToString("MM-dd-yyyy")), "application/pdf", "Inspection.pdf");
The problem is that, when the GenerateSummaryPDF is called, the summary list is empty. The list is not null, but merely has no items in it.
However, I am not sure why this is the case. When I click the export link, there is data in Model.reportsList; it is visible in the table and further verified by setting a breakpoint.
The parent view:
#model Inspection_Reports.ViewModel.SummaryReportViewModel
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Report Summaries</title>
</head>
<body>
<h2>Summary Reports</h2>
<form class="form-horizontal">
<div class="form-group"><label class="control-label col-md-2">Start Date: </label><div class="col-md-4"><input class="form-control summaryFilter" type='text' value="#Model.fromDate" name='startDate' id='startDate' /></div><label class="control-label col-md-2">End Date: </label><div class="col-md-4"><input type='text' value="#Model.toDate" class='form-control summaryFilter' name='endDate' id='endDate' /></div></div>
<div class="form-group">
<label class="control-label col-md-2">Filter By: </label>
<div class="col-md-4">
<select class="form-control summaryFilter" name="filterTypeList" id="filterTypeList">
<option value="">Select...</option>
<option value="Property">Property</option>
<option value="Attendant">Attendant</option>
<option value="Inspector">Inspector</option>
</select>
</div>
<label class="control-label col-md-2">Filter Selection: </label><div class="col-md-4">
<select class="form-control summaryFilter" name="filterSelectionList" id="filterSelectionList"></select>
</div>
</div>
</form>
<div id="reportResults">
#{Html.RenderPartial("SummaryPartialView", Model);}
</div>
#section scripts {
<script src="~/Scripts/ajaxReports.js"></script>
}
</body>
</html>
The methods used to populate the partial view (based largely on this article: https://cmatskas.com/update-an-mvc-partial-view-with-ajax/)
[HttpGet]
public async Task<ActionResult> GetSummaryReports(string fromDate, string toDate, string filterType, string filterValue)
{
DateTime from = Convert.ToDateTime(fromDate);
DateTime to = Convert.ToDateTime(toDate);
Int32 filterValID = Int32.Parse(filterValue);
SummaryReportViewModel vm = await GetSummaryVM(from, to, filterType, filterValID);
return PartialView("SummaryPartialView", vm);
}
private async Task<SummaryReportViewModel> GetSummaryVM(DateTime from, DateTime to, string filterType, int filterValID)
{
SummaryReportViewModel vm = new SummaryReportViewModel();
to = to.AddDays(1);
var reports = dbContext.report_summary.Where(r => r.endTime <= to && r.endTime >= from);
if (filterType.Equals("Property"))
{
reports = reports.Where(r => r.locationID == filterValID);
}
else if (filterType.Equals("Attendant"))
{
reports = reports.Where(r => r.employee == filterValID);
}
else
{
reports = reports.Where(r => r.inspector == filterValID);
}
vm.reportsList = reports.ToList<report_summary>();
return vm;
}
The Ajax
$(".summaryFilter").change(function () {
var fromDate = $("#startDate").val();
var toDate = $("#endDate").val();
var filterType = $("#filterTypeList").val();
var filterValue = $("#filterSelectionList").val();
if (filterValue != null || typeof (filterValue) != typeof (undefined)) {
$.ajax({
url: "GetSummaryReports?fromDate=" + fromDate + "&toDate=" + toDate + "&filterType=" + filterType + "&filterValue=" + filterValue,
type: 'get',
success: function (data) {
$("#reportResults").html(data);
},
});
}
});
Thanks for any help.
You're asking a bit much of a Get method - you should instead switch to a form that Posts to allow model binding to handle your complex list object.
I have table in a excel sheet called ListProduct.xls. When I import the excel file I want it to print the table in success page. The index page works fine I can click on browse and lets me pick the excel file. But when I click import it gives me an error on my Product controller.
string path = Server.MapPath("~/Content/" + excelfile.FileName);
It gives me an error in this line. The error it shows is
NotSupportedException was unhandled by user code. An exception of type 'System.NotSupportedException' occurred in mscorlib.dll but was not handled in user code
ProductController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Excel = Microsoft.Office.Interop.Excel;
using System.IO;
using ImportExcelFileInASPNETMVC.Models;
namespace ImportExcelFileInASPNETMVC.Controllers
{
public class ProductController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Import(HttpPostedFileBase excelfile)
{
if (excelfile == null || excelfile.ContentLength == 0)
{
ViewBag.Error = "Please select a excel file<br>";
return View("Index");
}
else
{
if (excelfile.FileName.EndsWith("xls") || excelfile.FileName.EndsWith("xlsx"))
{
string path = Server.MapPath("~/Content/" + excelfile.FileName);
if (System.IO.File.Exists(path))
System.IO.File.Delete(path);
excelfile.SaveAs(path);
// Read data from excel file
Excel.Application application = new Excel.Application();
Excel.Workbook workbook = application.Workbooks.Open(path);
Excel.Worksheet worksheet = workbook.ActiveSheet;
Excel.Range range = worksheet.UsedRange;
List<Product> listProducts = new List<Product>();
for (int row = 3; row <= range.Rows.Count; row++)
{
Product p = new Product();
p.Name = ((Excel.Range)range.Cells[row, 2]).Text;
listProducts.Add(p);
}
ViewBag.ListProducts = listProducts;
return View("Success");
}
else
{
ViewBag.Error = "File type is incorrect<br>";
return View("Index");
}
}
}
}
}
Index.cshtml
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
#using (Html.BeginForm("Import", "Product", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.Raw(ViewBag.Error)
<span>Excel File </span><input type="file" name="excelfile" />
<br />
<input type="submit" value="Import" />
}
</body>
</html>
Success.cshtml
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Success</title>
</head>
<body>
<table cellpadding="2" cellspacing="2" border="1">
<tr>
<th>Name</th>
</tr>
#foreach (var p in ViewBag.ListProducts)
{
<tr>
<td>#p.Name</td>
</tr>
}
</table>
</body>
</html>
its a problem probably because of HttpPostedFileBase. Try this, post the file by keeping input[type='file'] in your #Html.BeginForm. And on server access the file using this,
var firstFile=Request.Files[0];
In addition you need to check on client as well as on server the type of file to allow (in your case it should be excel file)
I am building an MVC based ASP.NET application. One of the functionalities should be to be able to upload files asynchronously using a progress bar.
I've had success with uploading files without the progress bar. The code below does that.
View Code:
<input class="file" type="file" name="file" id="file" />
<input type="submit" name="submit" value="Upload" />
Controller Code:
public ActionResult Upload(){
return View();
}
[HttpPost]
public ActionResult Upload(Resource resource)
{
try
{
if (resource.File.ContentLength > 0)
{
var fileName = Path.GetFileName(resource.File.FileName);
var path = Path.Combine(Server.MapPath("~/Content/Resources"), fileName);
resource.File.SaveAs(path);
}
}
catch (Exception e)
{
Console.WriteLine("Cannot upload file. Exception of type : {0}", e.ToString());
}
return RedirectToAction("Upload");
}
This code works absolutely fine. With slight modifications, I am even able to upload multiple files. But, even though I've tried finding it, I am not able to upload files using a progress bar.
Any help is appreciated.
This is how I do it - the controller code is much the same, but the client has some javascript in it to monitor and update progress of the ajax posting. The UI Html is like this:
<div id="uploadDetails" class="form-group">
<div class="input-group">
<span class="input-group-btn">
<span class="btn btn-primary btn-file">
Browse… <input type="file" name="file" id="file" />
</span>
</span>
<input type="text" id="filename" class="form-control fullwidth" readonly />
<span class="input-group-btn">
<button class="btn btn-primary" type="button" id="uploadFile"><span class="glyphicon glyphicon-upload"></span> Upload File </button>
</span>
</div>
</div>
And the javascript for the upload like this:
$(document).on('click', '#uploadFile', function (e) {
var fileElement = document.getElementById('file');
var file = fileElement.files[0];
var formData = new FormData();
formData.append("filename", fileElement.files[0].name);
formData.append("id", '#Model.SharedIP.Id');
formData.append("file", file, fileElement.files[0].name);
var html = $('#uploadFile').html();
$('#uploadFile').html('Uploading...');
$.ajax({
url: "#Url.Action("UploadFile", "SharedIP")",
type: "POST",
data: formData,
processData: false, // tell jQuery not to process the data
contentType: false, // tell jQuery not to set contentType
xhr: function(){
var xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener("progress", function(evt){
if (evt.lengthComputable) {
$('#uploadFile').html('Uploading... ' + Math.round((evt.loaded / evt.total) * 100) + '%');
}
else $('#uploadFile').html('hmmm');
}, false);
return xhr;
},
success: function (results) {
updateFilesList();
$('#uploadFile').html(html);
fileElement.files = [];
var control = $('#file');
control.replaceWith(control.clone(false));
$('#filename').val("")
},
error: function (xhr, ajaxOptions, thrownError) {
$('#uploadFile').html(html);
alert(xhr.responseText);
}
});
});
For completeness, here's the Controller signature, it's .net Core RC1 so might not work in your target framework, but you will get the idea.
[HttpPost]
public IActionResult UploadFile(string filename, Guid id, IFormFile file)
{
IPFile ipfile = new IPFile()
{
ContentType = file.ContentType,
DateUploaded = DateTime.Now,
Filename = filename,
SharedIPId = (id == Guid.Empty ? (Guid?)null : id),
Id = Guid.NewGuid(),
UploadedBy = User.Alias(),
};
ipfile = FileManager.AddFileFromStream(User.Alias(), ipfile, file.OpenReadStream());
return Ok(ipfile);
}
Hope that answers your question.
[EDIT] Just realised this isn't a "progress bar" - but it's got all the workings and % display - to put a progress bar in, you'd just apply CSS to an element that renders the % graphically for you - see posts like http://www.w3schools.com/bootstrap/bootstrap_progressbars.asp for examples.
Here is the code that I have tried. It's a bare minimum code but works as expected. It still has some bugs and I would appreciate if someone could make it bug free.
Some bugs:
Progress bar does not reset on a new file upload.
Add a button to do the upload (I can do it myself as well).
Model Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace NewDeploymentsTesting.Models
{
public class UploadFilesResult
{
public string Name { get; set; }
public int Length { get; set; }
public string Type { get; set; }
}
}
Controller Code:
using NewDeploymentsTesting.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace NewDeploymentsTesting.Controllers
{
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
return View();
}
[HttpPost]
public ContentResult UploadFiles()
{
var r = new List<UploadFilesResult>();
foreach (string file in Request.Files)
{
HttpPostedFileBase hpf = Request.Files[file] as HttpPostedFileBase;
if (hpf.ContentLength == 0) continue;
string savedFileName = Path.Combine(Server.MapPath("~/Content/Resource"), Path.GetFileName(hpf.FileName));
hpf.SaveAs(savedFileName);
r.Add(new UploadFilesResult()
{
Name = hpf.FileName,
Length = hpf.ContentLength,
Type = hpf.ContentType
});
}
return Content("{\"name\":\"" + r[0].Name + "\",\"type\":\"" + r[0].Type + "\",\"size\":\"" + string.Format("{0} bytes", r[0].Length) + "\"}", "application/json");
}
}
}
View Code:
#{Layout = null;}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Uploading Files</title>
<link href="~/Content/bootstrap/bootstrap.min.css" rel="stylesheet" />
<link href="~/Content/bootstrap/bootstrap-theme.css" rel="stylesheet" />
<link href="~/Content/jquery.fileupload.css" rel="stylesheet" />
<script src="~/Scripts/jquery-1.9.1.min.js"></script>
<script src="~/Scripts/jquery.ui.widget.js"></script>
<script src="~/Scripts/bootstrap.min.js"></script>
<script src="~/Scripts/jquery.fileupload.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$('#fileupload').fileupload({
dataType: 'json',
url: '/Home/UploadFiles',
autoUpload: true,
done: function (e, data) {
$('.file_name').html(data.result.name);
$('.file_type').html(data.result.type);
$('.file_size').html(data.result.size);
}
}).on('fileuploadprogressall', function (e, data) {
var progress = parseInt(data.loaded / data.total * 100, 10);
$('.progress .progress-bar').css('width', progress + '%');
});
});
</script>
</head>
<body>
<div class="container">
<span class="btn btn-success fileinput-button">
<i class="glyphicon glyphicon-plus"></i>
<span>Add Files ...</span>
<input id="fileupload" type="file" name="files[]" multiple />
</span><br />
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%;">
<span class="sr-only">0% Complete</span>
</div>
</div><br />
<div class="file_name"></div><br />
<div class="file_type"></div><br />
<div class="file_size"></div><br />
</div>
</body>
</html>
Here is what it looks like on the browser window.
I'm following this example and I'm having some hard time displaying data in a gridview. When the page is loaded it gets to GetData and returns values.
If in the immediate windows after I fill datatable and see the count ?dtResult.Rows.Count I get 1001. So I know I have data.
However, when the I debug the app I just get the three buttons. What am I missing here?
Here's the aspx code:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="test.aspx.cs" Inherits="TestApp.test" %>
<%# Register Assembly="Trirand.Web" TagPrefix="trirand" Namespace="Trirand.Web.UI.WebControls" %>
<!DOCTYPE html>
<html lang="en-us">
<head id="Head1" runat="server">
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" media="screen" href="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.10.3/themes/redmond/jquery-ui.css" />
<!-- The jQuery UI theme extension jqGrid needs -->
<link rel="stylesheet" type="text/css" media="screen" href="/themes/ui.jqgrid.css" />
<!-- jQuery runtime minified -->
<script src="http://ajax.microsoft.com/ajax/jquery/jquery-2.0.3.min.js" type="text/javascript"></script>
<!-- The localization file we need, English in this case -->
<script src="/js/trirand/i18n/grid.locale-en.js" type="text/javascript"></script>
<!-- The jqGrid client-side javascript -->
<script src="/js/trirand/jquery.jqGrid.min.js" type="text/javascript"></script>
<style type="text/css">
body, html { font-size: 80%; }
</style>
</head>
<body>
<form id="form1" runat="server">
<div>
<div id="message">
<script type="text/javascript">
function addRow() {
var grid = jQuery("#<%= JQGrid1.ClientID %>");
grid.editGridRow("new", grid.addDialogOptions);
}
function editRow() {
var grid = jQuery("#<%= JQGrid1.ClientID %>");
var rowKey = grid.getGridParam("selrow");
var editOptions = grid.getGridParam('editDialogOptions');
if (rowKey) {
grid.editGridRow(rowKey, editOptions);
}
else {
alert("No rows are selected");
}
}
function delRow() {
var grid = jQuery("#<%= JQGrid1.ClientID %>");
var rowKey = grid.getGridParam("selrow");
if (rowKey) {
grid.delGridRow(rowKey, grid.delDialogOptions);
}
else {
alert("No rows are selected");
}
}
</script>
<input type="button" onclick="addRow()" value="Add" />
<input type="button" onclick="editRow()" value="Edit" />
<input type="button" onclick="delRow()" value="Delete" />
<trirand:jqgrid runat="server" ID="JQGrid1"
OnRowDeleting="JQGrid1_RowDeleting"
OnRowAdding="JQGrid1_RowAdding"
OnRowEditing="JQGrid1_RowEditing">
<Columns>
<trirand:JQGridColumn DataField="Addressbookid" Editable="false" PrimaryKey="true" />
<trirand:JQGridColumn DataField="ClientName" Editable="true" />
<trirand:JQGridColumn DataField="Clientno" Editable="true" />
<trirand:JQGridColumn DataField="IndustryName" Editable="true" />
</Columns>
<ToolBarSettings ShowEditButton="true" ShowAddButton="true" ShowDeleteButton="true" />
<EditDialogSettings CloseAfterEditing="true" Caption="The Edit Dialog" />
<AddDialogSettings CloseAfterAdding="true" />
</trirand:jqgrid>
</div>
<br /><br />
</div>
</form>
Here's the codebehind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
using System.Data;
using System.Configuration;
namespace TestApp
{
public partial class test : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
JQGrid1.DataSource = GetData();
JQGrid1.DataBind();
}
protected DataTable GetData()
{
if (Session["EditDialogData"] == null)
{
// Create a new Sql Connection and set connection string accordingly
SqlConnection sqlConnection = new SqlConnection();
sqlConnection.ConnectionString = ConfigurationManager.ConnectionStrings["Sandbox"].ConnectionString;
sqlConnection.Open();
string sqlStatement = "Select * from voiceportal.dbo.clients_v";
// Create a SqlDataAdapter to get the results as DataTable
SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(sqlStatement, sqlConnection);
// Create a new DataTable
DataTable dtResult = new DataTable();
// Fill the DataTable with the result of the SQL statement
sqlDataAdapter.Fill(dtResult);
Session["EditDialogData"] = dtResult;
return dtResult;
}
else
{
return Session["EditDialogData"] as DataTable;
}
}
}
}
Any suggestions on how I can fix this?
Thanks
My two cents.
Make sure that the grid locale js file is in the right place and served well to your browser. See the related line:
<script src="/js/trirand/i18n/grid.locale-en.js" type="text/javascript"></script>
Open up your developer console with F12, refresh the page and look for the downloaded files and error messages on the console which can tell if this doesn't go well.
Double check that the data you serve matches the column configuration. Pay special attention to camel casing. .NET properties start with uppercase, they are camel cased, but JSON data often starts with lowercase. That also depends on if you use any transformations (like NewtonSoft and stuff). I don't know what's in your voiceportal.dbo.clients_v table, please specify your schema. In your ASPX code Addressbookid and Clientno are not camel cased. Shouldn't they be AddressbookId and ClientNo? Depends on your schema and what actually comes through the wire.