i am working on a website where you could upload a image onto azure storage as a blob and also to download the blob, however when i download the image it gives me a "this file format cannot be opened" when opening the pic. i was wondering where could i display the fileStream?
heres my javascript:
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div class="container">
#Html.ActionLink("Upload to Azure Blob", "UploadBlob", new { Controller = "blob" }, new { #class = "btn btn-link" })
<div class=" table table-striped table-responsive">
<table id=" tablex">
<thead>
<tr>
<th>Container</th>
<th>Actual FileName</th>
<th> Uri </th>
</tr>
</thead>
<tbody>
#if(Model != null)
{
foreach (var item in Model)
{
<tr id="row_#item.PrimaryUri">
<td>#item.BlockContainerName</td>
<td>#item.ActualFileName</td>
<td>
<a herf=#item.PrimaryUri>#item.PrimaryUri </a>
</td>
#*<td>#Html.ActionLink("Remove", "DeletedBlob", new { controller = "blob", file = #item.FileNameWithoutExt, extension = #item.FileNameWithoutExt })</td> *#
<td><a href='#Url.Action("Download", "DownloadBlob", new { file = #item.FileNameWithoutExt, extension = #item.FileNameWithoutExt })'>Download</a></td>
<td>
<input type="submit" href="#" class="btn btn-link" id="btndel" value="Remove" data-id="#item.ActualFileName" />
</td>
</tr>
}
}
</tbody>
</table>
</div>
</div>
This is the javascript method ive written in order to download the blob however i've been trying to find out where the problem
In my controller class i have:
public async Task<ActionResult> DownloadBlob(string file, string extension)
{
string downloadPath = await repo.DownloadBlobAsync(file, extension);
return Json(downloadPath);
}
and in my storage class:
public async Task<string> DownloadBlobAsync (string file, string fileExtension)
{
_cloudBlobContainerx = _cloudBlobClientx.GetContainerReference(containerNamex);
CloudBlockBlob blockBlob = _cloudBlobContainerx.GetBlockBlobReference(file + "." + fileExtension);
var path = downloadPath + file + "." + fileExtension;
using (var fileStream = System.IO.File.OpenWrite(path))
{
//fileStream.Position = 1;
//fileStream.Seek(0, SeekOrigin.Begin);
await blockBlob.DownloadToStreamAsync(fileStream);
return path;
}
}
You are using your file name as your extension in your Action;
extension = #item.FileNameWithoutExt
It could explain why get the 404, as the blob probably don't exist with this extension.
We need to use the #Url.Action as following:#Url.Action("actionName","controlName",routeValues).
Gives a HTTP404 Error (Azure Storage/Visual Studio)
It indicates that can't route that path. So you could add the controller named DownloadBlob and add the method Download. We need to make sure that it has the same paramter name are in the routeValues.
public void Download(string file, string extension)
{
var container = cloudBlobClient.GetContainerReference("test");
container.CreateIfNotExists();
var blockBlob = container.GetBlockBlobReference(file + "." + fileExtension);
blockBlob.FetchAttributes();
var contentType = blockBlob.Properties.ContentType;
MemoryStream memStream = new MemoryStream();
blockBlob.DownloadToStream(memStream);
var response = HttpContext.Response;
response.ContentType = contentType;
response.AddHeader("Content-Disposition", "Attachment; filename=" + file + "." + fileExtension);
response.AddHeader("Content-Length", blockBlob.Properties.Length.ToString());
response.BinaryWrite(memStream.ToArray());
}
The following is the test result on my side.
Related
I have one form when i create on record i can attach some photo for that ,i attach in there photos more than one but i cant click to each one them , to review and download it how can i do that click to each one of them and to view and Download each one my structure in asp.net core is MVC and i use controller and view i share my UI cod and backend code to help me
<div class="col-md-8">
#foreach (var item in #Model.Gallarys)
{
<div class="form-group col-md-4">
<div class="col-md-12 col-sm-12 text-center" style="margin-top:20px;">
<div class="fileinput fileinput-new text-center" data-provides="fileinput">
<div class="fileinput-new thumbnail">
<img src="#(item.Avatar != null ? Config.BannerThumbPicPath + item.Avatar : "/assets/img/image_placeholder.jpg")" alt="...">
</div>
</div>
</div>
</div>
}
</div>
public async Task<BaseResult> CreateGallary(Gallary gallary, IFormFile Pic)
{
gallary.CreateDate = DateTime.Now;
gallary.Avatar = await SavePic(Pic, gallary.BannerId.ToString().GetUrlFriendly() + Pic?.GetExtention());
return base.Create(gallary);
}
public List<Gallary> GetAllPic(int id)
{
return UOW.Gallaries.GetAll().Where(_ => _.BannerId == id).ToList();
}
#region ذخیره تصویر
public async Task<string> SavePic(IFormFile Pic, string FileName)
{
if (Pic != null && Pic.IsImage())
{
string LargePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot" + Config.BannerLargPicPath + FileName);
var i = 1;
string BaseName = FileName;
while (File.Exists(LargePath))
{
FileName = i + "-" + BaseName;
LargePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot" + Config.BannerLargPicPath + FileName);
i++;
}
string ThumbPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot" + Config.BannerThumbPicPath + FileName);
using (var stream1 = new FileStream(LargePath, FileMode.Create))
{
await Pic.CopyToAsync(stream1);
}
using (var stream2 = new FileStream(ThumbPath, FileMode.Create))
{
await Pic.CopyToAsync(stream2);
}
ImageResizer.CropImage(LargePath, LargePath, LargeWidth, LargeHeight, 100);
ImageResizer.CropImage(ThumbPath, ThumbPath, ThumbWidth, ThumbHeight, 100);
return FileName;
}
return null;
}
I am trying to fetch some SQL data whenever user comes to the Index page in my ASP.NET Core application (using Razor Pages). In my Index.cshtml.cs I am trying to establish connection to SQL Server and storing the rows in a list. Now I want to fetch this list in Index.cshtml. I am not sure about this approach but here is what I tried..
This is my Index.cshtml.cs
namespace SQLICMAlertWebApp.Pages
{
[Authorize]
public class IndexModel : PageModel
{
public IConfiguration Configuration { get; }
public IndexModel(IConfiguration configuration)
{
Configuration = configuration;
con.ConnectionString = Configuration.GetConnectionString("OEM_US_SQL_CORL");
}
SqlCommand com = new SqlCommand();
SqlDataReader dr;
SqlConnection con = new SqlConnection();
List<ProActive_Monitoring_Missing_PVR_Orders> table_errors = new List<ProActive_Monitoring_Missing_PVR_Orders>();
public void OnGet()
{
if (table_errors.Count > 0)
{
table_errors.Clear();
}
try
{
con.Open();
com.Connection = con;
com.CommandText = "SELECT * FROM ProActiveMonitoring_Missing_PVR_Orders WHERE isICMSent = 'No'";
dr = com.ExecuteReader();
while (dr.Read())
{
table_errors.Add(new ProActive_Monitoring_Missing_PVR_Orders()
{
CustomerNbr = dr["CustomerNbr"].ToString(),
CustomerName = dr["CustomerName"].ToString(),
MSOrderNumber = dr["MSOrderNumber"].ToString(),
Quantity = dr["Quantity"].ToString(),
PromoQuantity = dr["PromoQuantity"].ToString(),
QtyDiff = dr["QtyDiff"].ToString(),
NetAmount = dr["NetAmount"].ToString(),
PromoNetAmount = dr["PromoNetAmount"].ToString(),
AmtDiff = dr["AmtDiff"].ToString(),
ExtendedAmount = dr["ExtendedAmount"].ToString(),
PromoExtendedAmount = dr["PromoExtendedAmount"].ToString(),
IsICMSent = dr["IsICMSent"].ToString()
});
}
con.Close();
}
catch (Exception ex)
{
throw new Exception("Error: " + ex);
}
}
}
}
Here is the Index.cshtml to retrieve data from table_errors variable defined above.
#page
#model SQLICMAlertWebApp.Pages.IndexModel
#{
ViewData["Title"] = "Home";
string[] TableHeaders = new string[] {"CustomerNbr"
,"CustomerName"
,"MSOrderNumber"
,"Quantity"
,"PromoQuantity"
,"QtyDiff"
,"NetAmount"
,"PromoNetAmount"
,"AmtDiff"
,"ExtendedAmount"
,"PromoExtendedAmount"};
bool checkEmty = true;
}
<div class="HomePage">
<div class="myNavbar">
<div class="header-title">SQL Data Mismatch Tables</div>
<button class="LogoutButton" onclick={location.replace('/home/logout')}>Logout</button>
</div>
<div class="HomePageBody">
<div class="table">
<table class="table table-bordered table-hover">
<thead>
<tr>
<th class="th_table_name" colspan="11">
ProActive_Monitoring_Missing_PVR_Orders_Errors
</th>
</tr>
<tr>
#{
foreach (var head in TableHeaders)
{
<th>
#head
</th>
}
}
</tr>
</thead>
<tbody>
#{
if (Model != null)
{
foreach (var Data in table_errors)
{
checkEmty = false;
<tr>
<td>#Data.CustomerNbr</td>
<td>#Data.CustomerName</td>
<td>#Data.MSOrderNumber</td>
<td>#Data.Quantity</td>
<td>#Data.PromoQuantity</td>
<td>#Data.QtyDiff</td>
<td>#Data.NetAmount</td>
<td>#Data.PromoNetAmount</td>
<td>#Data.AmtDiff</td>
<td>#Data.ExtendedAmount</td>
<td>#Data.PromoExtendedAmount</td>
</tr>
}
if (checkEmty)
{
<tr>
<td colspan="11">No Errors</td>
</tr>
}
}
}
</tbody>
</table>
</div>
</div>
</div>
I am not sure if it should work in this way or not, but Index.cshtml is not recognizing table_errors variable. What should I change in my approach if this isn't correct!!
EDIT #2
After changing table_errors to Model.table_errors it worked fine!! But I encountered another error in the code, do you have any idea about this?
Razor Pages uses the MVVM pattern. So if you want to access to an object in View (int this case: Index.cshtml), you should access to object through the Model.
For example, to use table_errors in View, do this way: #Model.table_errors
This code will work:
<tbody>
#{
if (Model.table_errors != null)
{
foreach (var Data in Model.table_errors)
{
checkEmty = false;
<tr>
<td>#Data.CustomerNbr</td>
<td>#Data.CustomerName</td>
<td>#Data.MSOrderNumber</td>
<td>#Data.Quantity</td>
<td>#Data.PromoQuantity</td>
<td>#Data.QtyDiff</td>
<td>#Data.NetAmount</td>
<td>#Data.PromoNetAmount</td>
<td>#Data.AmtDiff</td>
<td>#Data.ExtendedAmount</td>
<td>#Data.PromoExtendedAmount</td>
</tr>
}
if (checkEmty)
{
<tr>
<td colspan="11">No Errors</td>
</tr>
}
}
}
</tbody>
I have a project in .Net core that generates ID Card. Everything works fine when I print ID Card for one students but I'm having problem printing multiple ID Cards.
I have get method in my controller as follows:
[HttpGet]
[AllowAnonymous]
public IActionResult BulkCard()
{
//values = ViewBag.Cards;
var values = (object[])TempData["students"]; //This retrieves all students that has been selected to print their ID Card
ViewBag.Cards = values.ToArray();
var designtemplate = _context.Settings.First();
if (designtemplate.CardTemplate == 1)
{
ViewBag.Template = "1";
}
else if (designtemplate.CardTemplate == 2)
{
ViewBag.Template = "2";
ViewBag.TemplateView = "This is template 2";
}
else if (designtemplate.CardTemplate == 3)
{
ViewBag.Template = "3";
ViewBag.TemplateView = "This is template 3";
}
else
{
return RedirectToAction("CardSettings", "Settings");
}
var model = new ModelClasses();
foreach (var item in values)
{
model.Students = _context.Students.ToList();
model.Student = _context.Students.Include(c => c.Department).Include(c => c.Department.Faculty).Include(c => c.ProgramType).Include(c => c.ClassLevels).Include(c => c.Session).ToList().FirstOrDefault(c => c.Id == Convert.ToInt32(item));
ViewBag.Students = _context.Students.Include(c => c.Department).Include(c => c.Department.Faculty).Include(c => c.ProgramType).Include(c => c.ClassLevels).Include(c => c.Session).ToList().Where(c => c.Id == Convert.ToInt32(item)).ToList();
var surname = model.Student.Surname;
var firstname = model.Student.FirstName;
var middleName = model.Student.MiddleName[0];
var fullname = surname + " " + firstname + " " + middleName + ".";
ViewBag.FullName = fullname;
ViewBag.MatricNumber = model.Student.MatricNumber;
ViewBag.Department = model.Student.Department;
ViewBag.Faculty = model.Student.Faculty;
ViewBag.Passport = "/Uploads" + "/Passport/" + model.Student.Passport;
ViewBag.Signature = "/Uploads" + "/Signature/" + model.Student.Signature;
var qrdata = model.Student.QRCodeData.ToString().Replace("/", "");
using (MemoryStream ms = new MemoryStream())
{
QRCodeGenerator qrGenerator = new QRCodeGenerator();
QRCodeData qrCodeData = qrGenerator.CreateQrCode(qrdata, QRCodeGenerator.ECCLevel.Q);
QRCode qrCode = new QRCode(qrCodeData);
using (Bitmap bitMap = qrCode.GetGraphic(20))
{
bitMap.Save(ms, ImageFormat.Png);
ViewBag.QRCodeImage = "data:image/png;base64," + Convert.ToBase64String(ms.ToArray());
}
}
}
return View(model);
}
And in my view is as follow:
#foreach (var item in ViewBag.Students)
{
#if (ViewBag.Template == "1")
{
<table>
<tr>
<td>
BULK CARD PRINTING
<img src="#ViewBag.QRCodeImage" class="qrcode">
</td>
</tr>
</table>
#*<table>
<tr>
<td>
<div class="wrapper">
<div class="container">
<div style="position: absolute;color: lightgray;opacity: 0.05;font-size: 3em;width: 50%;top: 25%; left: 80px;text-align: center;z-index: 0;background-attachment: fixed;"><img src="~/img/fedpolel-Logo.png" width="150" /></div>
<img src="~/Uploads/Passport//#item.Passport" alt="" class="profile-img">
<img src="~/img/fedpolel-Logo.png" class="logo" />
<img src="#ViewBag.QRCodeImage" class="qrcode">
<div class="content">
<table>
<tr>
<td>
<div class="title">
<h4>THE FEDERAL POLYTECHNIC</h4>
<span>ILE OLUJI, ONDO STATE.</span>
</div>
<div class="sub-content">
<center>
<h1>#item.FullName</h1>
</center>
<p>#item.MatricNumber</p>
</div>
<div class="vr"></div>
<div class="vr-right"></div>
<div class="data">
<div class="inner-data">
<span>Gender</span>
<p>#item.Gender<p />
<br>
<span>Session</span>
<p class="session">#item.Session.SessionName</p>
</div>
<div class="inner-data2">
<span>Level</span>
<p>#item.ClassLevels.ClassLevel</p>
<span>Department</span>
<p>#item.Department.DepartmentName</p>
<span>Faculty</span>
<p>#item.Department.Faculty.FacultyName</p>
</div>
<div class="inner-data3">
<div class="hr"></div>
<p><img src="#ViewBag.Signature" width="50" /></p>
<div class="paragra">Signature</div>
</div>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
</td>
</tr>
</table>*#
}
else if (ViewBag.Template == "2")
{
#ViewBag.TemplateView
}
else if (ViewBag.Teplate == "3")
{
#ViewBag.TemplateView
}
else
{
#ViewBag.NoTemplateView
}
}
This code only returns data for the last student.
My challenge: if I have 5 students pre-selected, I want to return data of the five students. Please, how do I achieve this?
This is happening because you are always setting ViewBag.Students to new list in every loop iteration (which contains only one record, because you are filtering by Id).
Initialize ViewBag.Students outside of loop (e.g. ViewBag.Students = new List<Student> and inside of loop just add already read student from the database (model.Student)
e.g.:
ViewBag.Students.Add(model.Student);
Also try to fill model.Students outside of for loop, since currently you are making unneccessary trip to the databse on each iteration (model.Students = _context.Students.ToList()). On each for loop iteration you read complete students to the model property, which is redundant. Once should be enough.
I also think that you do not need setting ViewBag's properties to that of a model. Just pass a model (maybe add some needed properties) to the view and read data from the model.
I am trying to create a system where it is possible to add/ change device configurations. The user should be able to add / delete rows at the same time.
Everytime a config is saved, a new config_id is created and VersionNr is increased.
I am 100% sure I am doing something wrong, and what is going wrong. But I dont know how to fix it or improve it.
Here is my code:
public ActionResult Edit(int? Id)
{
//create new list
var Device_Pricelist = new List<Device_Pricelist>(db.Device_Pricelist.Where(r => r.DeviceConfig.Device_config_id == Id));
//create new SelectList in Device_Pricelist
var SelectedCMI = (from d in db.pricelist
select new { d.Price_id, Value = d.bas_art_nr }).Distinct();
//call viewbag based on SelectedCMI query
ViewBag.SelectedCMI = new SelectList(SelectedCMI.Distinct(), "Price_id", "Value");
return View(Device_Pricelist);
}
public ActionResult Edit([Bind(Include = "id,Device_config_id,Price_id,amount,assembly_order")]DeviceConfig deviceConfig, List<Device_Pricelist> device_Pricelists)
{
if (ModelState.IsValid)
{
try
{
try
{
db.DeviceConfig.Add(deviceConfig).Device_config_id = deviceConfig.Device_config_id++;
db.DeviceConfig.Add(deviceConfig).device_type_id = deviceConfig.device_type_id = 13;
db.DeviceConfig.Add(deviceConfig).Active = true;
//Needs to be based on current VersionNr in deviceConfig
db.DeviceConfig.Add(deviceConfig).VersionNr = deviceConfig.VersionNr + 1;
db.DeviceConfig.Add(deviceConfig).Date = deviceConfig.Date = DateTime.Now;
}
finally
{
foreach (var item in device_Pricelists)
{
db.Entry(item).State = EntityState.Added;
}
}
db.SaveChanges();
TempData["SuccesMessage"] = "Data is Succesfully saved";
return RedirectToAction("Index");
}
catch
{
TempData["AlertMessage"] = "Saving Data Failed, " + "Try Again";
}
}
return View(device_Pricelists);
}
view:
#model List<ConcremoteDeviceManagment.Models.Device_Pricelist>
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
#using (Html.BeginForm("Edit", "Home", FormMethod.Post))
{
<h1>
#Html.DisplayName("Edit Configuration")
</h1>
<h2>
#* #Html.DisplayFor(model => model.DeviceType.name)<br />*#dammit
</h2>
if (TempData["AlertMessage"] != null)
{
<p class="alert alert-danger" id="FailMessage">#TempData["AlertMessage"]</p>
}
#Html.ValidationSummary(true)
#Html.AntiForgeryToken()
<div>
#* Add New*#
</div>
<table class="table table-hover" id="dataTable">
<tr>
<th class="table-row">
#Html.DisplayName("BAS artikelnummer")
</th>
<th class="table-row">
#Html.DisplayName("Beschrijving")
</th>
<th class="table-row">
#Html.DisplayName("Aantal")
</th>
<th class="table-row">
#Html.DisplayName("Bouw Volgorde")
</th>
<th class="table-row">
Add New Row
</th>
</tr>
#if (Model != null && Model.Count > 0)
{
int j = 0;
foreach (var item in Model)
{
<tr>
#Html.HiddenFor(a => a[j].id)
#Html.HiddenFor(a => a[j].Device_config_id)
#* #Html.HiddenFor(a => a[j].Price_id)*#
<td class="table-row">
#Html.DropDownListFor(a => a[j].Price_id, (IEnumerable<SelectListItem>)ViewBag.SelectedCMI, null, new { #class = "form-control" })
</td>
<td class="table-row">
#Html.DisplayFor(a => a[j].Pricelist.description, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(a => a[j].Pricelist.description, "", new { #class = "text-danger" })
</td>
<td class="table-row">
#Html.EditorFor(a => a[j].amount, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(a => a[j].amount, "", new { #class = "text-danger" })
</td>
<td class="table-row">
#Html.EditorFor(a => a[j].assembly_order, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(a => a[j].assembly_order, "", new { #class = "text-danger" })
</td>
#*<td class="table-row">
#Html.DisplayFor(a => a[j].DeviceConfig.Date, new { htmlAttributes = new { #class = "form-control" } })
</td>*#
<td>
#if (j > 0)
{
Remove
}
</td>
</tr>
j++;
}
}
</table>
<input type="submit" value="Save Device Data" class="btn btn-primary" />
<button onclick="location.href='#Url.Action("Index", "Home")';return false; " class="btn btn-primary">Back to list</button>
}
#section Scripts{
#*#Scripts.Render("~/bundles/jqueryval")*#
<script language="javascript">
$(document).ready(function () {
//1. Add new row
$("#addNew").click(function (e) {
e.preventDefault();
var $tableBody = $("#dataTable");
var $trLast = $tableBody.find("tr:last");
var $trNew = $trLast.clone();
var suffix = $trNew.find(':input:first').attr('name').match(/\j+/);
$trNew.find("td:last").html('Remove');
$.each($trNew.find(':input'), function (i, val) {
// Replaced Name
var oldN = $(this).attr('name');
var newN = oldN.replace('[' + suffix + ']', '[' + (parseInt(suffix) + 1) + ']', '[' + suffix + ']', '[' + (parseInt(suffix) + 1) + ']', '[' + suffix + ']', '[' + (parseInt(suffix) + 1) + ']');
$(this).attr('name', newN);
//Replaced value
var type = $(this).attr('type');
//if (type.toLowerCase() == "text") {
// $(this).attr('value', '');
//}
// If you have another Type then replace with default value
$(this).removeClass("input-validation-error");
});
$trLast.after($trNew);
// Re-assign Validation
//var form = $("form")
// .removeData("validator")
// .removeData("unobtrusiveValidation");
//$.validator.unobtrusive.parse(form);
});
// 2. Remove
//$('a.remove').live("click", function (e) { --> this is for old jquery library
$('body').on("click", '#remove', function (e) {
e.preventDefault();
$(this).parent().parent().remove();
});
});
</script>
<script type="text/javascript">
function SelectedIndexChanged() {
//Form post
document.demoForm.submit();
}
</script>
I hope somebody is able to help me.
More information will be given when needed.
Your method accepts 2 parameters but you are only posting 1 object - List<Device_PriceList>. Let's assume you want to construct a new DeviceConfig based on the existing one, you should change your Action method to the following:
public ActionResult Edit(List<Device_Pricelist> device_Pricelists)
{
if (ModelState.IsValid)
{
try
{
var deviceConfig = db.DeviceConfig.Find(device_Pricelists.First().Device_config_id);
deviceConfig.device_type_id = 13;
deviceConfig.Active = true;
deviceConfig.VersionNr++;
deviceConfig.Date = DateTime.Now;
db.DeviceConfig.Add(deviceConfig);
foreach(var item in device_Pricelists)
{
item.Device_config_id = deviceConfig.Device_config_id;
}
db.Device_Pricelists.AddRange(device_Pricelists);
db.SaveChanges();
TempData["SuccesMessage"] = "Data is Succesfully saved";
return RedirectToAction("Index");
}
catch
{
TempData["AlertMessage"] = "Saving Data Failed, Try Again";
}
}
return View(device_Pricelists);
}
Remember when posting a list, you need to post complete sets of the object you're trying to map to. That is for example [0].Id, [0].Device_config_id (etc), [1].Id, [1].Device_config_id (etc).
Your JS doesn't seem correct, particularly the .replace(..) call with 6 parameters, so you're probably seeing lots of [0]s when you clone the rows. Some simpler JS that will get you the same result is:
var oldN = $(this).attr('name');
var idx = parseInt(oldN.substr(1, oldN.indexOf(']')));
var newN = oldN.replace('[' + idx + ']', '[' + (idx + 1) + ']');
I have implemented the "Contact Management ASP.NET MVC Application" with Razor view.
http://www.asp.net/mvc/tutorials/iteration-7-add-ajax-functionality-cs
Now I want to add Sorting and Searching functionality.
And Paging too.
snapshot: ->
http://www.freeimagehosting.net/daf63
I want to display the sorted and searched results inside the "green box", by click of a sort links and search button.
What changes do I need to perform?
My current Index Controller:
public ActionResult Index(int? id, string sortorder, string searchstring)
{
ViewBag.CurrentSort = sortorder;
ViewBag.disp = n2;
ViewBag.NameSortParm = String.IsNullOrEmpty(sortorder) ? "Namedesc" : " ";
ViewBag.NameSortParma = String.IsNullOrEmpty(sortorder) ? "Nameasc" : " ";
ViewBag.NameSortParmb = String.IsNullOrEmpty(sortorder) ? "Namedescx" : " ";
ViewBag.NameSortParmc = String.IsNullOrEmpty(sortorder) ? "Nameascx" : " ";
if (sortorder != null || searchstring != null)
{
var matches = cmu.Contacts.Where(a => a.GroupId == (int)id);
var contacts = from s in matches
select s;
if (!String.IsNullOrEmpty(searchstring))
{
contacts = contacts.Where(s => s.FirstName.ToUpper().Contains(searchstring.ToUpper()) || s.LastName.ToUpper().Contains(searchstring.ToUpper()));
}
switch (sortorder)
{
case "Namedesc":
contacts = contacts.OrderByDescending(s => s.FirstName);
break;
case "Nameasc":
contacts = contacts.OrderBy(s => s.FirstName);
break;
case "Namedescx":
contacts = contacts.OrderByDescending(s => s.LastName);
break;
case "Nameascx":
contacts = contacts.OrderBy(s => s.LastName);
break;
}
return PartialView("SearchSort", contacts.ToList());
}
// Get selected group
var selectedGroup = _service.GetGroup(id);
if (selectedGroup == null)
return RedirectToAction("Index", "Group");
// Normal Request
if (!Request.IsAjaxRequest())
{
var model = new IndexModel
{
Groups = _service.ListGroups(),
SelectedGroup = selectedGroup
};
return View("Index", model);
}
return PartialView("ContactList", selectedGroup);
}
My Index View:
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
#model New_Contact_Manager_with_Razor_View.Models.Validation.IndexModel
#using New_Contact_Manager_with_Razor_View.Helpers
<style type = "text/css">
#gallery {
border: 0.5px solid #1D0C16;
height: 150;
width: 150px;
display:inline-table;
border-spacing : 5px;
margin-bottom:5px;
border-style:outset;
}
</style>
<style type="text/css">
h1, h2, h3, h4, h5, h6, h7 {color:black}
</style>`
<script type="text/javascript">
function Showtdata(item) {
var elements = document.getElementsByClassName(item);
for (var i = 0, length = elements.length; i < length; i++) {
elements[i].style.visibility = "visible";
elements[i].style.display = "block";
}
}
function Cleartdata(item) {
var elements = document.getElementsByClassName(item);
for (var i = 0, length = elements.length; i < length; i++) {
elements[i].style.visibility = "hidden";
elements[i].style.display = "none";
}
}
</script>
<script type="text/javascript">
var _currentGroupId = -1;
Sys.Application.add_init(pageInit);
function pageInit() {
// Enable history
Sys.Application.set_enableHistory(true);
// Add Handler for history
Sys.Application.add_navigate(navigate);
}
function navigate(sender, e) {
// Get groupId from address bar
var groupId = e.get_state().groupId;
// If groupId != currentGroupId then navigate
if (groupId != _currentGroupId) {
_currentGroupId = groupId;
$("#divContactList").load("/Contact/Index/" + groupId);
selectGroup(groupId);
}
}
function selectGroup(groupId) {
$('#leftColumn li').removeClass('selected');
if (groupId)
$('a[groupid=' + groupId + ']').parent().addClass('selected');
else
$('#leftColumn li:first').addClass('selected');
}
function beginContactList(args) {
// Highlight selected group
_currentGroupId = this.getAttribute("groupid");
selectGroup(_currentGroupId);
// Add history point
Sys.Application.addHistoryPoint({ "groupId": _currentGroupId });
// Animate
$('#divContactList').fadeOut('normal');
}
function successContactList() {
// Animate
$('#divContactList').fadeIn('normal');
}
function failureContactList() {
alert("Could not retrieve contacts.");
}
</script>
#using New_Contact_Manager_with_Razor_View.Helpers
#{
ViewBag.Title = "Contacts";
}
<table>
<tr>
<td>
<h3>
<form>
<table>
<tr>
<td>
Display->      
<input type = "radio" value = "Display " name = "display" onclick= Showtdata("HD") />
</td>
</tr>
<tr>
<td>
Not Display->
<input type = "radio" value = "Not Display " name= "display" onclick= Cleartdata("HD") />
</td>
</tr>
</table>
</form>
</h3>
</td>
<td>
       
</td>
<td>
<b><strong>Sort :~> </strong></b>
<table>
<tr>
<td>
#Html.ActionLink("First Name Desc", "Index", new { sortorder = ViewBag.NameSortParm })
</td>
</tr>
<tr>
<td>
#Html.ActionLink("First Name", "Index", new { sortorder = ViewBag.NameSortParma })
</td>
</tr>
<tr>
<td>
#Html.ActionLink("Last Name desc", "Index", new { sortorder = ViewBag.NameSortParmb })
</td>
</tr>
<tr>
<td>
#Html.ActionLink("Last Name", "Index", new { sortorder = ViewBag.NameSortParmc })
</td>
</tr>
</table>
</td>
<td>
     
</td>
<td>
#using (Html.BeginForm())
{
<p>
<b>Find by name:</b> #Html.TextBox("searchstring")
<input type="submit" value = "search" />
</p>
}
</td>
</tr>
</table>
<ul id="leftColumn">
#foreach (var item in Model.Groups)
{
<li #Html.Selected(item.Id, Model.SelectedGroup.Id) >
#Ajax.ActionLink(item.Name, "Index", new { id = item.Id }, new AjaxOptions { UpdateTargetId = "divContactList", OnBegin = "beginContactList", OnSuccess = "successContactList", OnFailure = "failureContactList" }, new { groupid = item.Id })
</li>
}
</ul>
<div id="divContactList" >
#Html.Partial("ContactList", Model.SelectedGroup)
</div>
<div class="divContactList-bottom"> </div>
Is it possible to add sorting and searching functionality by AJAX or JavaScript?
Any help would be heartily appreciated.
Thank You.
While it's a different type of answer, I would have a look at jqGrid. It's a jquery plugin that will help you page, sort, and search through your tabular data.
http://www.trirand.com/blog/