I want to be able to put back an item to his original location list, by drag or by a remove button im the destiny list. Until now I have been able to drag to the final list and to remove it from the final list, but I can't find a way to put it back to the original list.
Here is the code I have by now (testable version here: http://jsfiddle.net/PmVhd/):
<style>
h1 { padding: .2em; margin: 0; }
#products { float:left; width: 500px; margin-right: 2em; cursor: move }
#cart { width: 300px; float: left; margin-top: 1em; cursor: move }
#cart ol { margin: 0; padding: 1em 0 1em 3em; }
</style>
<script>
$(function () {
$("#catalog").accordion();
$("#catalog li").draggable({
helper: "clone"
});
$("#catalog ul").droppable({
drop: function (event, ui) {
$(ui.draggable).remove();
$("<li></li>").text(ui.draggable.text()).appendTo(this);
}
});
$("#cart ol").draggable({
appendTo: "body",
helper: "clone"
});
$("#cart ol").droppable({
drop: function (event, ui) {
$(ui.draggable).remove();
$(this).find(".placeholder").remove();
var el = $("<li>" + ui.draggable.text() + "</li> <a href='#'>[x]</a>").filter('a')
.click(function () {
el.remove();
}).end().appendTo(this);
}
});
});
<div id="products">
<h1 class="ui-widget-header">Car Extras</h1>
<div id="catalog">
<h2>Security</h2>
<div>
<ul>
<li id="1">ABS</li>
<li id="2">ESP</li>
<li id="3">Airbag</li>
</ul>
</div>
<h2>Confort</h2>
<div>
<ul>
<li>Air Conditioning</li>
<li>Hands-free Phone</li>
<li>Alligator Leather</li>
</ul>
</div>
<div id="cart">
<h1 class="ui-widget-header">My Car Extras</h1>
<div class="ui-widget-content">
<ol>
<li class="placeholder">Add your items here</li>
</ol>
</div>
Thanks for any help.
After long hours of search and tests, I came to a solution that seems to cover all:
Drag from List to Favorite List
Button to send to Favorite List
Drag back to the original Section
Remove button to move back to the original Section
Fade In and Fade Out of the movement
All this based on the JQuery Photo Manager example: http://jqueryui.com/droppable/#photo-manager
Model:
public class FeatureDto
{
public int Id { get; set; }
public string Name { get; set; }
}
public class FeatureGroupDto
{
public int Id { get; set; }
public string Name { get; set; }
}
public class FeatureGroupFeaturesDto
{
public FeatureGroupDto FeatureGroup { get; set; }
public IList<FeatureDto> Features { get; set; }
}
Data for tests:
IList<FeatureGroupFeaturesDto> fcf = new List<FeatureGroupFeaturesDto>();
fcf.Add(new FeatureGroupFeaturesDto
{
FeatureGroup = new FeatureGroupDto { Id = 1, Name = "Interior" },
Features = new List<FeatureDto> {
new FeatureDto { Id = 7, Name = "Bancos Traseiros Rebatíveis" },
new FeatureDto { Id = 35, Name = "Computador de Bordo" },
new FeatureDto { Id = 38, Name = "Suporte para Telemóvel" }
},
});
fcf.Add(new FeatureGroupFeaturesDto
{
FeatureGroup = new FeatureGroupDto { Id = 2, Name = "Exterior" },
Features = new List<FeatureDto> {
new FeatureDto { Id = 13, Name = "Barras de Tejadilho" },
new FeatureDto { Id = 15, Name = "Retrovisores Aquecidos" },
new FeatureDto { Id = 16, Name = "Retrovisores Elétricos" }
},
});
Code including Accordion creation based on Test Data and all Script:
#model IEnumerable<Heelp.ViewModels.FeatureGroupFeaturesViewModel>
<div id="featuresList">
#foreach (var item in Model) {
<h1>#item.FeatureGroup.Name</h1>
<div>
<ul id="fg#(item.FeatureGroup.Id)">
#foreach (var feature in item.Features)
{
<li id="#feature.Id" class="feature">#feature.Name [»]</li>
}
</ul>
</div>
}
</div>
<h1>My Features</h1>
<div id="myFeatures">
<ol></ol>
</div>
<div id="test"></div>
<style>
.feature { cursor: move; }
h1 { cursor: pointer; }
#myFeatures ol { margin: 0; padding: 1em 0 1em 3em; background-color: lightgray; width: 200px; height: 100px; cursor: move; }
</style>
<script>
$(function () {
var $featuresList = $("#featuresList"), $myFeatures = $("#myFeatures");
// Accordion
$featuresList.accordion();
// Features List | Drag
$("ul > li", $featuresList).draggable({
revert: "invalid",
containment: "document",
helper: "clone"
});
// My Features List | Drop
$myFeatures.droppable({
accept: "#featuresList li",
drop: function (event, ui) {
addToMyFeatures(ui.draggable);
}
})
// Features List | Drop Back Again
$featuresList.droppable({
accept: "#myFeatures li",
drop: function (event, ui) {
removeFromMyFeatures(ui.draggable);
}
})
// Add to MyFeatures List function
var removeButton = "<a href='#' class='feature-remove-from-my-list'>[x]</a>";
function addToMyFeatures($feature) {
$feature.fadeOut(function () {
$feature.find("a.feature-send-to-my-list").remove();
$feature.find("span").remove();
$feature
.append("<span style='display:none'>" + $feature.parent('ul').attr('id') + "</span>")
.append(removeButton)
.appendTo("ol", $myFeatures)
.fadeIn();
});
}
// Remove from MyFeatures List function
var addButton = "<a href='#' class='feature-send-to-my-list'>[»]</a>";
function removeFromMyFeatures($feature) {
$feature.fadeOut(function () {
var featureGroup = "#" + $feature.find("span").text();
$feature.find("a.feature-remove-from-my-list").remove();
$feature
.append(addButton)
.appendTo(featureGroup)
.fadeIn();
});
}
// Click event to add or remove Feature from My List
$("#featuresList li").click(function (event) {
var $item = $(this), $target = $(event.target);
if ($target.is("a.feature-send-to-my-list")) {
addToMyFeatures($item);
}
else if ($target.is("a.feature-remove-from-my-list")) {
removeFromMyFeatures($item);
}
return false;
})
});
</script>
Related
I am doing an MVC4 project using Gijgo grid. I want a single generic repository function to work for all grids in the project. So, I have converted the server side code in Gijgo website to get data, filter and sort data into a generic function. Since in Gijgo grid's server-side code, all functionality of parameters passed from jquery to server-side code is automatically taken care of. For my customization, I need to use a ternary operator to check if the filter parameter is empty (then return all data) & if not empty, then return filtered data.
I have a service layer which service classes and a function Get for each service - which calls the generic repository function"Get" for that service module. For a module, the service class has a function "Get" which calls the repository "Get" function to get data for the grid.
Here are the explanations:
I have ProductService in my ServiceLayer which has a function "Get" to call the generic repository "Get" function.
public IEnumerable<ProductDTO> Get(string product, string subCategory, string description,int? page = null, int? pageSize = null, string sortBy = null, bool isDescending = false)
{
var products = _unitOfWork.ProductRepository
.Get(
x => (product != null ? x.EnglishProductName.Contains(product.Trim()) : false) ||
(subCategory != null ? x.DimProductSubcategory.EnglishProductSubcategoryName.Contains(subCategory.Trim()) : false) ||
(description != null ? x.EnglishDescription.Contains(description.Trim()) : false),
sortBy,
isDescending,
page,
pageSize,
includeProperties: player => player.DimProductSubcategory
).AsQueryable();
if (products.Any())
{
return products.ToList().Select(Mapper.Map<DimProduct, ProductDTO>);
}
return Enumerable.Empty<ProductDTO>();
}
Generic Repository "Get" function below
public virtual List<TEntity> Get(Expression<Func<TEntity, bool>> filter = null, string sortBy = null, bool isDescending = false,
int? page = null,
int? pageSize = null, params Expression<Func<TEntity, object>>[] includeProperties)
{
IQueryable<TEntity> query = DbSet;
foreach (Expression<Func<TEntity, object>> include in includeProperties)
query = query.Include(include);
if (filter != null)
query = query.Where(filter);
if (!string.IsNullOrEmpty(sortBy))
{
query = SortByColumnExt.OrderBy(query, sortBy, isDescending);
}
HttpContext.Current.Session["Total"] = query.Count();
if (page.HasValue && pageSize.HasValue)
{
int start = (page.Value - 1) * pageSize.Value;
var records = query.Skip(start).Take(pageSize.Value).ToList();
return (records.ToList());
}
else
{
return (query.ToList());
}
}
My problem is this code section of service function:
var products = _unitOfWork.ProductRepository
.Get(
x => (product != null ? x.EnglishProductName.Contains(product.Trim()) : false) ||
(subCategory != null ? x.DimProductSubcategory.EnglishProductSubcategoryName.Contains(subCategory.Trim()) : false) ||
(description != null ? x.EnglishDescription.Contains(description.Trim()) : false),
sortBy,
isDescending,
page,
pageSize,
includeProperties: player => player.DimProductSubcategory
).AsQueryable();
I want the ternary operator to return whole data if filter parameters EnglishProductName, EnglishProductSubcategoryName and EnglishDescription are passed as empty
""
from jquery, that is when the grid first loads or when user don't enter filter option. This is automatically taken care of in Gijgo grid (in the link I provided above).
Here's the code from Gijgo's Manage Ajax Sourced Data Grid.
Front End
<!DOCTYPE html>
<html>
<head>
<title>Manage Ajax Sourced Data With Grid</title>
<meta charset="utf-8" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" type="text/css" />
<link href="https://unpkg.com/gijgo#1.9.13/css/gijgo.css" rel="stylesheet" type="text/css" />
<style>
.form-row { display: flex; margin-bottom: 29px; }
.form-row:last-child { margin-bottom: 0px; }
.margin-top-10 { margin-top: 10px; }
.float-left { float: left; }
.float-right { float: right; }
.display-inline { display: inline; }
.display-inline-block { display: inline-block; }
.width-200 { width: 200px; }
.clear-both { clear: both; }
.gj-display-none { display: none; }
</style>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://unpkg.com/gijgo#1.9.13/js/gijgo.js" type="text/javascript"></script>
</head>
<body>
<div class="margin-top-10">
<div class="float-left">
<form class="display-inline">
<input id="txtName" type="text" placeholder="Name..." class="gj-textbox-md display-inline-block width-200" />
<input id="txtNationality" type="text" placeholder="Nationality..." class="gj-textbox-md display-inline-block width-200" />
<button id="btnSearch" type="button" class="gj-button-md">Search</button>
<button id="btnClear" type="button" class="gj-button-md">Clear</button>
</form>
</div>
<div class="float-right">
<button id="btnAdd" type="button" class="gj-button-md">Add New Record</button>
</div>
</div>
<div class="clear-both"></div>
<div class="margin-top-10">
<table id="grid"></table>
</div>
<div id="dialog" class="gj-display-none">
<div data-role="body">
<input type="hidden" id="ID" />
<div class="form-row">
<input type="text" class="gj-textbox-md" id="Name" placeholder="Name...">
</div>
<div class="form-row">
<select id="Nationality" width="100%" placeholder="Nationality..."></select>
</div>
<div class="form-row">
<input type="text" id="DateOfBirth" placeholder="Date Of Birth..." width="100%" />
</div>
<div class="form-row">
<label for="IsActive"><input type="checkbox" id="IsActive" /> Is Active?</label>
</div>
</div>
<div data-role="footer">
<button type="button" id="btnSave" class="gj-button-md">Save</button>
<button type="button" id="btnCancel" class="gj-button-md">Cancel</button>
</div>
</div>
<script type="text/javascript">
var grid, dialog, nationalityDropdown, dateOfBirth, isActiveCheckbox;
function Edit(e) {
$('#ID').val(e.data.id);
$('#Name').val(e.data.record.Name);
nationalityDropdown.value(e.data.record.CountryID);
dateOfBirth.value(e.data.record.DateOfBirth);
isActiveCheckbox.state(e.data.record.IsActive ? 'checked' : 'unchecked');
dialog.open('Edit Player');
}
function Save() {
var record = {
ID: $('#ID').val(),
Name: $('#Name').val(),
CountryID: nationalityDropdown.value(),
DateOfBirth: gj.core.parseDate(dateOfBirth.value(), 'mm/dd/yyyy').toISOString(),
IsActive: $('#IsActive').prop('checked')
};
$.ajax({ url: '/Players/Save', data: { record: record }, method: 'POST' })
.done(function () {
dialog.close();
grid.reload();
})
.fail(function () {
alert('Failed to save.');
dialog.close();
});
}
function Delete(e) {
if (confirm('Are you sure?')) {
$.ajax({ url: '/Players/Delete', data: { id: e.data.id }, method: 'POST' })
.done(function () {
grid.reload();
})
.fail(function () {
alert('Failed to delete.');
});
}
}
$(document).ready(function () {
grid = $('#grid').grid({
primaryKey: 'ID',
dataSource: '/Players/Get',
columns: [
{ field: 'ID', width: 56 },
{ field: 'Name', sortable: true },
{ field: 'CountryName', title: 'Nationality', sortable: true },
{ field: 'DateOfBirth', sortable: true, type: 'date' },
{ field: 'IsActive', title: 'Active?', type: 'checkbox', width: 90, align: 'center' },
{ width: 64, tmpl: '<span class="material-icons gj-cursor-pointer">edit</span>', align: 'center', events: { 'click': Edit } },
{ width: 64, tmpl: '<span class="material-icons gj-cursor-pointer">delete</span>', align: 'center', events: { 'click': Delete } }
],
pager: { limit: 5 }
});
dialog = $('#dialog').dialog({
autoOpen: false,
resizable: false,
modal: true,
width: 360
});
nationalityDropdown = $('#Nationality').dropdown({ dataSource: '/Locations/GetCountries', valueField: 'id' });
dateOfBirth = $('#DateOfBirth').datepicker();
isActiveCheckbox = $('#IsActive').checkbox();
$('#btnAdd').on('click', function () {
$('#ID').val('');
$('#Name').val('');
nationalityDropdown.value('');
dateOfBirth.value('');
isActiveCheckbox.state('unchecked');
dialog.open('Add Player');
});
$('#btnSave').on('click', Save);
$('#btnCancel').on('click', function () {
dialog.close();
});
$('#btnSearch').on('click', function () {
grid.reload({ page: 1, name: $('#txtName').val(), nationality: $('#txtNationality').val() });
});
$('#btnClear').on('click', function () {
$('#txtName').val('');
$('#txtNationality').val('');
grid.reload({ name: '', nationality: '' });
});
});
</script>
</body>
</html>
Backed-Code
using Gijgo.Asp.NET.Examples.Models.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
namespace Gijgo.Asp.NET.Examples.Controllers
{
public class PlayersController : Controller
{
public JsonResult Get(int? page, int? limit, string sortBy, string direction, string name, string nationality, string placeOfBirth)
{
List<Models.DTO.Player> records;
int total;
using (ApplicationDbContext context = new ApplicationDbContext())
{
var query = context.Players.Select(p => new Models.DTO.Player
{
ID = p.ID,
Name = p.Name,
PlaceOfBirth = p.PlaceOfBirth,
DateOfBirth = p.DateOfBirth,
CountryID = p.CountryID,
CountryName = p.Country != null ? p.Country.Name : "",
IsActive = p.IsActive,
OrderNumber = p.OrderNumber
});
if (!string.IsNullOrWhiteSpace(name))
{
query = query.Where(q => q.Name.Contains(name));
}
if (!string.IsNullOrWhiteSpace(nationality))
{
query = query.Where(q => q.CountryName != null && q.CountryName.Contains(nationality));
}
if (!string.IsNullOrWhiteSpace(placeOfBirth))
{
query = query.Where(q => q.PlaceOfBirth != null && q.PlaceOfBirth.Contains(placeOfBirth));
}
if (!string.IsNullOrEmpty(sortBy) && !string.IsNullOrEmpty(direction))
{
if (direction.Trim().ToLower() == "asc")
{
switch (sortBy.Trim().ToLower())
{
case "name":
query = query.OrderBy(q => q.Name);
break;
case "countryname":
query = query.OrderBy(q => q.CountryName);
break;
case "placeOfBirth":
query = query.OrderBy(q => q.PlaceOfBirth);
break;
case "dateofbirth":
query = query.OrderBy(q => q.DateOfBirth);
break;
}
}
else
{
switch (sortBy.Trim().ToLower())
{
case "name":
query = query.OrderByDescending(q => q.Name);
break;
case "countryname":
query = query.OrderByDescending(q => q.CountryName);
break;
case "placeOfBirth":
query = query.OrderByDescending(q => q.PlaceOfBirth);
break;
case "dateofbirth":
query = query.OrderByDescending(q => q.DateOfBirth);
break;
}
}
}
else
{
query = query.OrderBy(q => q.OrderNumber);
}
total = query.Count();
if (page.HasValue && limit.HasValue)
{
int start = (page.Value - 1) * limit.Value;
records = query.Skip(start).Take(limit.Value).ToList();
}
else
{
records = query.ToList();
}
}
return this.Json(new { records, total }, JsonRequestBehavior.AllowGet);
}
[HttpPost]
public JsonResult Save(Models.DTO.Player record)
{
Player entity;
using (ApplicationDbContext context = new ApplicationDbContext())
{
if (record.ID > 0)
{
entity = context.Players.First(p => p.ID == record.ID);
entity.Name = record.Name;
entity.PlaceOfBirth = record.PlaceOfBirth;
entity.DateOfBirth = record.DateOfBirth;
entity.CountryID = record.CountryID;
entity.Country = context.Locations.FirstOrDefault(l => l.ID == record.CountryID);
entity.IsActive = record.IsActive;
}
else
{
context.Players.Add(new Player
{
Name = record.Name,
PlaceOfBirth = record.PlaceOfBirth,
DateOfBirth = record.DateOfBirth,
CountryID = record.CountryID,
Country = context.Locations.FirstOrDefault(l => l.ID == record.CountryID),
IsActive = record.IsActive
});
}
context.SaveChanges();
}
return Json(new { result = true });
}
[HttpPost]
public JsonResult Delete(int id)
{
using (ApplicationDbContext context = new ApplicationDbContext())
{
Player entity = context.Players.First(p => p.ID == id);
context.Players.Remove(entity);
context.SaveChanges();
}
return Json(new { result = true });
}
public JsonResult GetTeams(int playerId, int? page, int? limit)
{
List<Models.DTO.PlayerTeam> records;
int total;
using (ApplicationDbContext context = new ApplicationDbContext())
{
var query = context.PlayerTeams.Where(pt => pt.PlayerID == playerId).Select(pt => new Models.DTO.PlayerTeam
{
ID = pt.ID,
PlayerID = pt.PlayerID,
FromYear = pt.FromYear,
ToYear = pt.ToYear,
Team = pt.Team,
Apps = pt.Apps,
Goals = pt.Goals
});
total = query.Count();
if (page.HasValue && limit.HasValue)
{
int start = (page.Value - 1) * limit.Value;
records = query.OrderBy(pt => pt.FromYear).Skip(start).Take(limit.Value).ToList();
}
else
{
records = query.ToList();
}
}
return this.Json(new { records, total }, JsonRequestBehavior.AllowGet);
}
}
}
I am consuming wcf rest service into angular js application . I am joining three tables records into a single record and displaying it in web application . I want when i click the button with account number it should returns user account information like account number , Money In ,Money Out ,Date and Account Balance etc . But i got following errors in google chrome network tab ..
The server encountered an error processing the request. The exception message is 'The type 'HalifaxWCFProject.Transcation.AccountTransaction' appears in two structurally incompatible initializations within a single LINQ to Entities query. A type can be initialized in two places in the same query, but only if the same properties are set in both places and those properties are set in the same order.'. See server logs for more details. The exception stack trace is:
Here is the Class .
public class AccountTransaction
{
public int? Account_Number { get; set; }
public decimal? Deposit { get; set; }
public decimal? Withdrawal { get; set; }
public decimal? Account_Balance { get; set; }
public string Date { get; set; }
}
Here is the Linq Query .
public string TranscationDetails(string Account_Number)
{
var accountNumber = int.Parse(Account_Number);//It could be better to use TryParse
using (HalifaxDatabaseEntities context = new HalifaxDatabaseEntities())
{
var inOut = context.Current_Account_Deposit.Where(x => x.Account_Number == accountNumber).Select(w => new AccountTransaction
{
Account_Number = w.Account_Number,
Deposit = (decimal?)null,
Withdrawal = (decimal?)w.Amount,
Date = w.Date
}).Concat(context.Current_Account_Withdraw.Where(x => x.Account_Number == accountNumber).Select(d => new AccountTransaction
{
Account_Number = d.Account_Number,
Deposit = (decimal?)d.Amount,
Withdrawal = (decimal?)null,
Date = d.Date
})).OrderBy(r => r.Date)
.Concat(context.Current_Account_Details.Where(x => x.Account_Number == accountNumber).Select(e => new AccountTransaction
{
Account_Number = e.Account_Number,
Account_Balance = (decimal?)e.Account_Balance
}));
var js = new System.Web.Script.Serialization.JavaScriptSerializer();
return js.Serialize(inOut); // return JSON string
}
}
}
}
Here is my angular js code .
#{
Layout = null;
}
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular.min.js"></script>
<script type="text/javascript">
var app = angular.module('MyApp', [])
app.controller('MyController', function ($scope, $http, $window) {
$scope.IsVisible = false;
$scope.Search = function () {
var post = $http({
method: "GET",
url: "http://localhost:52098/HalifaxIISService.svc/TranscationDetails/" + encodeURIComponent($scope.Account_Number),
dataType: 'json',
headers: {
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Content-Type': 'application/json; charset=utf-8'
}
});
post.then(function (response) { // .success(function(data => .then(function(response
var data = response.data; // extract data from resposne
$scope.Customers = JSON.parse(data); // eval(data.d) => JSON.parse(data)
$scope.IsVisible = true;
}, function (err) {
$window.alert(err);
});
}
});
</script>
<div ng-app="MyApp" ng-controller="MyController">
Account Number:
<input type="text" ng-model="Account_Number" />
<input type="button" value="Submit" ng-click="Search()" />
<hr />
<table style="border: solid 2px Green; padding: 5px;" ng-show="IsVisible">
#*<table cellpadding="0" cellspacing="0">*#
<tr style="height: 30px; background-color: skyblue; color: maroon;">
<th></th>
<th> Account Number</th>
<th> Money In</th>
<th>Date</th>
<th> Money Out</th>
<th>Date</th>
<th>Account Balance</th>
<th></th>
<th></th>
</tr>
<tbody ng-repeat="m in Customers">
<tr style="height: 30px; background-color: skyblue; color: maroon;">
<td></td>
<td><span>{{m.Account_Number}}</span></td>
<td><span>{{m.Deposit| currency:"£"}}</span></td>
<td><span>{{m.Date}}</span></td>
<td><span>{{m.Withdrawal | currency:"£"}}</span></td>
<td><span>{{m.Date}}</span></td>
<td><span>{{m.Account_Balance| currency:"£"}}</span></td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
Here is the database
Here is the Model.
Here is the Screen Shot On Debugging mode ..
Here is the result when i run the application
Try below code, Added all the properties of AccountTransaction add use Union instead Concat
Union will return distinct values but here your comparison is with reference of your items thus all items will be considered as different. Concat is equivalent to Union All
public string TranscationDetails(string Account_Number)
{
var accountNumber = int.Parse(Account_Number);//It could be better to use TryParse
using (HalifaxDatabaseEntities context = new HalifaxDatabaseEntities())
{
var inOut = context.Current_Account_Deposit.Where(x => x.Account_Number == accountNumber).Select(w => new AccountTransaction
{
Account_Number = w.Account_Number,
Account_Balance = (decimal?)0M,
Deposit = (decimal?)null,
Withdrawal = (decimal?)w.Amount,
Date = w.Date
}).Union(context.Current_Account_Withdraw.Where(x => x.Account_Number == accountNumber).Select(d => new AccountTransaction
{
Account_Number = d.Account_Number,
Account_Balance = (decimal?)0M,
Deposit = (decimal?)d.Amount,
Withdrawal = (decimal?)null,
Date = d.Date
})).OrderBy(r => r.Date)
.Union(context.Current_Account_Details.Where(x => x.Account_Number == accountNumber).Select(e => new AccountTransaction
{
Account_Number = e.Account_Number,
Account_Balance = (decimal?)e.Account_Balance,
Deposit = (decimal?)0M,
Withdrawal = (decimal?)0M,
Date = DateTime.Now
}));
var js = new System.Web.Script.Serialization.JavaScriptSerializer();
return js.Serialize(inOut); // return JSON string
}
}
}
}
I am having problem with getting the progress bar working properly I have setup for when a file is uploaded. The progress bar works fine but however the bar doesn't work in sync with the size of the file. So if the file is 80 MB and if the file is still being processed in the back end the progress bar will always says upload 100%.
I am not sure where am going wrong in the code? Basically want the progress bar to be in sync with code being processed in the back end.
Here is progress so far
Controller:
//
// POST
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult UploadMultipleFiles(IEnumerable<HttpPostedFileBase> files)
{
int count = 0;
if (files != null)
{
foreach (var file in files)
{
if (file != null && file.ContentLength > 0)
{
FileUploadService service = new FileUploadService();
var postedFile = Request.Files[0];
StreamReader sr = new StreamReader(postedFile.InputStream);
StringBuilder sb = new StringBuilder();
DataTable dt = CreateTable();
DataRow dr;
string s;
int j = 0;
while (!sr.EndOfStream)
{
while ((s = sr.ReadLine()) != null)
{
//Ignore first row as it consists of headers
if (j > 0)
{
string[] str = s.Split(',');
dr = dt.NewRow();
dr["Postcode"] = str[0].ToString();
dr["Latitude"] = str[2].ToString();
dr["Longitude"] = str[3].ToString();
dr["County"] = str[7].ToString();
dr["District"] = str[8].ToString();
dr["Ward"] = str[9].ToString();
dr["CountryRegion"] = str[12].ToString();
dt.Rows.Add(dr);
}
j++;
}
}
// Save to database
service.SaveFilesDetails(dt);
sr.Close();
count++;
}
}
}
return new JsonResult { Data = "Successfully " + count + " file(s) uploaded" };
}
View:
#{
ViewBag.Title = "File Upload";
Layout = "~/Views/Shared/_LayoutPage.cshtml";
}
<h2>Upload a CSV File</h2>
#using (Ajax.BeginForm("UploadMultipleFiles", "File", new AjaxOptions() { HttpMethod = "POST" }, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="row">
<div class="col-md-5">
<input type="file" name="files" id="fu1" />
</div>
<div class="col-md-2">
<input type="submit" class="btn btn-default" value="Upload File" />
</div>
</div>
}
<div class="progress">
<div class="progress-bar">0%</div>
</div>
<div id="status"></div>
<div id="loading" class="loader">Loading...</div>
<style>
.progress {
position: relative;
width: 400px;
border: 1px solid #ddd;
padding: 1px;
}
.progress-bar {
width: 0px;
height: 20px;
background-color: #57be65;
}
</style>
#section scripts{
<script src="http://malsup.github.com/jquery.form.js"></script>
<script>
$(document).ready(function () {
(function () {
var bar = $('.progress-bar');
var percent = $('.progress-bar');
var status = $('#status');
$('#loading').hide();
$('form').ajaxForm({
beforeSend: function () {
status.empty();
var percentValue = '0%';
bar.width(percentValue);
percent.html(percentValue);
},
uploadProgress: function (event, position, total, percentComplete) {
var percentValue = percentComplete + '%';
bar.width(percentValue);
percent.html(percentValue);
$('#loading').show();
},
success: function (d) {
var percentValue = '100%';
bar.width(percentValue);
percent.html(percentValue);
$('#fu1').val('');
$('#loading').hide();
//alert(d);
},
complete: function (xhr) {
status.html(xhr.responseText);
}
});
})();
});
</script>
}
Your code is working fine. You have upload progress, so you only get percent of data passed to server. After that your client have no idea how long server processes your data and how much of it has been processed.
In fact the only long time running operation you have after file is uploaded is saving it to the database. As I know there is no way you can know how much time the query left to complete, so you can't get progress. So the only thing I can suggest here is to switch to some inifinite loading icon with "processing" label after file upload is 100% complete.
In case you had more than one long time running operations you could pass progress after each operation via SignalR for example. But you won't be able to get progress of each operation (of course depends on operation) only percent of operations completed.
Editable Dropdownlist working fine in .aspx page referred from this link:
http://jqueryui.com/autocomplete/#combobox
But if i use same code in master page.. i am not getting the Output(Editable dropdownlist)..
what can i do?
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.1/jquery-ui.js"></script>
<style>
.custom-combobox
{
position: relative;
display: inline-block;
}
.custom-combobox-toggle
{
position: absolute;
top: 0;
bottom: 0;
margin-left: -1px;
padding: 0;
}
.custom-combobox-input
{
margin: 0;
padding: 5px 10px;
}
</style>
<script>
(function($) {
$.widget("custom.combobox", {
_create: function() {
this.wrapper = $("<span>")
.addClass("custom-combobox")
.insertAfter(this.element);
this.element.hide();
this._createAutocomplete();
this._createShowAllButton();
},
_createAutocomplete: function() {
var selected = this.element.children(":selected"),
value = selected.val() ? selected.text() : "";
this.input = $("<input>")
.appendTo(this.wrapper)
.val(value)
.attr("title", "")
.addClass("custom-combobox-input ui-widget ui-widget-content ui-state-default ui-corner-left")
.autocomplete({
delay: 0,
minLength: 0,
source: $.proxy(this, "_source")
})
.tooltip({
tooltipClass: "ui-state-highlight"
});
this._on(this.input, {
autocompleteselect: function(event, ui) {
ui.item.option.selected = true;
this._trigger("select", event, {
item: ui.item.option
});
},
autocompletechange: "_removeIfInvalid"
});
},
_createShowAllButton: function() {
var input = this.input,
wasOpen = false;
$("<a>")
.attr("tabIndex", -1)
.attr("title", "Show All Items")
.tooltip()
.appendTo(this.wrapper)
.button({
icons: {
primary: "ui-icon-triangle-1-s"
},
text: false
})
.removeClass("ui-corner-all")
.addClass("custom-combobox-toggle ui-corner-right")
.mousedown(function() {
wasOpen = input.autocomplete("widget").is(":visible");
})
.click(function() {
input.focus();
// Close if already visible
if (wasOpen) {
return;
}
// Pass empty string as value to search for, displaying all results
input.autocomplete("search", "");
});
},
_source: function(request, response) {
var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
response(this.element.children("option").map(function() {
var text = $(this).text();
if (this.value && (!request.term || matcher.test(text)))
return {
label: text,
value: text,
option: this
};
}));
},
_removeIfInvalid: function(event, ui) {
// Selected an item, nothing to do
if (ui.item) {
return;
}
// Search for a match (case-insensitive)
var value = this.input.val(),
valueLowerCase = value.toLowerCase(),
valid = false;
this.element.children("option").each(function() {
if ($(this).text().toLowerCase() === valueLowerCase) {
this.selected = valid = true;
return false;
}
});
// Found a match, nothing to do
if (valid) {
return;
}
// Remove invalid value
this.input
.val("")
.attr("title", value + " didn't match any item")
.tooltip("open");
this.element.val("");
this._delay(function() {
this.input.tooltip("close").attr("title", "");
}, 2500);
this.input.autocomplete("instance").term = "";
},
_destroy: function() {
this.wrapper.remove();
this.element.show();
}
});
})(jQuery);
$(function() {
$("#combobox").combobox();
$("#toggle").click(function() {
$("#combobox").toggle();
});
});
</script>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<div>
<div class="ui-widget">
<%-- <select id="combobox" runat="server" >--%>
<asp:DropDownList ID="combobox" runat="server">
<asp:ListItem Text="--Select--" Value="0"></asp:ListItem>
<asp:ListItem Text="ABC" Value="1"></asp:ListItem>
<asp:ListItem Text="CBI" Value="2"></asp:ListItem>
<asp:ListItem Text="IBM" Value="3"></asp:ListItem>
</asp:DropDownList>
</div>
</div>
</asp:Content>
Anyone try this? Seems to do the job
http://xdsoft.net/jquery-plugins/editableselect/
I am trying to implement ASP.NET MVC Paging using MVC4.Paging nuget package.
Problem:
It is working in online demo and also in the download source code. However I am not able to find why it is not working in my particular project by AJAX. In my project it is working by full post back method but not Ajax.
I have even tried to copy over the Index action method and Index and _AjaxEmployeeList Views (.cshtml) files (except .js).
Note: In my solution its not bootstrap as shown in samples. Also my controller name is AdminController whereas in Samples its HomeController
In my solution I need it to work in AJAX method as in samples.
Kindly help regarding:
1. How to find the root cause for why it is not working?
2. How to make this working?
.
My Solution Code (which I tried to reproduce in my solution from the sample):
Index.cshtml
#using MvcPaging
#model IPagedList<MvcPagingDemo.Models.Employee>
#{
ViewBag.Title = "MVC 4 Paging With Ajax Bootstrap";
}
<div class="row-fluid">
<div class="span6">
<h2>
Ajax Paging With Bootstrap In MVC 4
</h2>
</div>
<div class="span6">
<div class="alert alert-info">
The pager also supports area's. #Html.ActionLink("Ajax paging in an area", "Index", "Admin", new { Area = "AreaOne" }, new { #class = "btn btn-success" })</div>
</div>
</div>
<div class="clearfix">
</div>
#using (Ajax.BeginForm("Index", "Admin",
new AjaxOptions { UpdateTargetId = "grid-list", HttpMethod = "get", LoadingElementId = "loading", OnBegin = "beginPaging", OnSuccess = "successPaging", OnFailure = "failurePaging" },
new { id = "frm-search" }))
{
<div class="input-append">
<input class="span2" id="appendedInputButton" type="text" name="employee_name" placeholder="Name" />
<button class="btn" type="submit">
<i class="icon-search"></i> Search</button>
</div>
<div id="grid-list">
#{ Html.RenderPartial("_AjaxEmployeeList", Model); }
</div>
}
<script type="text/javascript">
function beginPaging(args) {
// Animate
$('#grid-list').fadeOut('normal');
}
function successPaging() {
// Animate
$('#grid-list').fadeIn('normal');
$('a').tooltip();
}
function failurePaging() {
alert("Could not retrieve list.");
}
</script>
_AjaxEmployeeList.cshtml
#using MvcPaging
#model IPagedList<MvcPagingDemo.Models.Employee>
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>
ID
</th>
<th>
Name
</th>
<th>
Email
</th>
<th>
Phone
</th>
<th>
City
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#item.ID
</td>
<td>
#item.Name
</td>
<td>
#item.Email
</td>
<td>
#item.Phone
</td>
<td>
#item.City
</td>
</tr>
}
</tbody>
</table>
<div class="pager1">
#Html.Raw(Ajax.Pager(
new Options
{
PageSize = Model.PageSize,
TotalItemCount = Model.TotalItemCount,
CurrentPage = Model.PageNumber,
ItemTexts = new ItemTexts() { Next = "Next", Previous = "Previous", Page = "P" },
ItemIcon = new ItemIcon() { First = "icon-backward", Previous = "icon-chevron-left", Next = "icon-chevron-right", Last = "icon-forward" },
TooltipTitles = new TooltipTitles() { Next = "Next page", Previous = "Previous page", Page = "Page {0}." },
Size = Size.normal,
Alignment = Alignment.centered,
IsShowControls = true,
IsShowFirstLast = true,
CssClass = ""
},
new AjaxOptions
{
UpdateTargetId = "grid-list",
OnBegin = "beginPaging",
OnSuccess = "successPaging",
OnFailure = "failurePaging"
}, new { controller = "Admin", action = "Index", employee_name = ViewData["employee_name"] }))
<div class="well">
Showing <span class="badge badge-success">#Model.ItemStart</span> to <span class="badge badge-success">#Model.ItemEnd</span>
of <span class="badge badge-info">#Model.TotalItemCount</span> entries</div>
</div>
AdminController.cs
public class AdminController : Controller
{
private const int defaultPageSize = 3;
private IList<Employee> allEmployee = new List<Employee>();
private string[] name = new string[4] { "Will", "Johnny", "Zia", "Bhaumik" };
private string[] phone = new string[4] { "1-274-748-2630", "1-762-805-1019", "1-920-437-3485", "1-562-653-8258" };
private string[] email = new string[4] { "donec#congueelitsed.org", "neque.non#Praesent.co.uk", "et.magna#Pellentesque.ca", "enim.commodo#orci.net" };
private string[] city = new string[4] { "Wigtown", "Malderen", "Las Vegas", "Talence" };
public AdminController()
{
InitializeEmployee();
}
private void InitializeEmployee()
{
// Create a list of 200 employee.
int index = 0;
for (int i = 0; i < 200; i++)
{
var employee = new Employee();
//int categoryIndex = i % new Random().Next(1, 5);
//if (categoryIndex > 3)
// categoryIndex = 3;
index = index > 3 ? 0 : index;
employee.ID = i + 1;
employee.Name = name[index];
employee.Phone = phone[index];
employee.Email = email[index];
employee.City = city[index];
allEmployee.Add(employee);
index++;
}
}
public ActionResult Index(string employee_name, int? page)
{
ViewData["employee_name"] = employee_name;
int currentPageIndex = page.HasValue ? page.Value : 1;
IList<Employee> employees = this.allEmployee;
if (string.IsNullOrWhiteSpace(employee_name))
{
employees = employees.ToPagedList(currentPageIndex, defaultPageSize);
}
else
{
employees = employees.Where(p => p.Name.ToLower() == employee_name.ToLower()).ToPagedList(currentPageIndex, defaultPageSize);
}
//var list =
if (Request.IsAjaxRequest())
return PartialView("_AjaxEmployeeList", employees);
else
return View(employees);
}
public ActionResult Paging(string employee_name, int? page)
{
ViewData["employee_name"] = employee_name;
int currentPageIndex = page.HasValue ? page.Value : 1;
IList<Employee> employees = this.allEmployee;
if (string.IsNullOrWhiteSpace(employee_name))
{
employees = employees.ToPagedList(currentPageIndex, defaultPageSize);
}
else
{
employees = employees.Where(p => p.Name.ToLower() == employee_name.ToLower()).ToPagedList(currentPageIndex, defaultPageSize);
}
return View(employees);
}
}
JS references in the _Layout.cshtml
You have not described how exactly it is not working. but i will guess the most common issues which might be causing your issue
make sure you actually have a reference to the correct java script files. its not enough to have them in a folder, your page must link to them.
see the following link to see how you reference scripts on you page. http://www.w3schools.com/tags/att_script_src.asp
make sure you put in the correct path.
make sure you reference the *ajax.js files for ajax to work along with any other required files.
Finally I found the solution.
Since I was using jquery-1.11.1.js, in script file jquery.unobtrusive-ajax.js I had to replace calls to .live() with .on().
But simple find and replace was not right way which I found later. I found from other sources that I have to change completely those lines of code as the .on() works.
I replaced the code as below:
Non-working code with .live() function:
$("a[data-ajax=true]").live("click", function (evt) {
debugger;
evt.preventDefault();
asyncRequest(this, {
url: this.href,
type: "GET",
data: []
});
});
$("form[data-ajax=true] input[type=image]").live("click", function (evt) {
debugger;
var name = evt.target.name,
$target = $(evt.target),
form = $target.parents("form")[0],
offset = $target.offset();
$(form).data(data_click, [
{ name: name + ".x", value: Math.round(evt.pageX - offset.left) },
{ name: name + ".y", value: Math.round(evt.pageY - offset.top) }
]);
setTimeout(function () {
$(form).removeData(data_click);
}, 0);
});
$("form[data-ajax=true] :submit").live("click", function (evt) {
debugger;
var name = evt.target.name,
form = $(evt.target).parents("form")[0];
$(form).data(data_click, name ? [{ name: name, value: evt.target.value }] : []);
setTimeout(function () {
$(form).removeData(data_click);
}, 0);
});
$("form[data-ajax=true]").live("submit", function (evt) {
debugger;
var clickInfo = $(this).data(data_click) || [];
evt.preventDefault();
if (!validate(this)) {
return;
}
asyncRequest(this, {
url: this.action,
type: this.method || "GET",
data: clickInfo.concat($(this).serializeArray())
});
});
Working code with .on() function:
$(document).on("click", "a[data-ajax=true]", function (evt) {
evt.preventDefault();
asyncRequest(this, {
url: this.href,
type: "GET",
data: []
});
});
$(document).on("click", "form[data-ajax=true] input[type=image]", function (evt) {
var name = evt.target.name,
$target = $(evt.target),
form = $target.parents("form")[0],
offset = $target.offset();
$(form).data(data_click, [
{ name: name + ".x", value: Math.round(evt.pageX - offset.left) },
{ name: name + ".y", value: Math.round(evt.pageY - offset.top) }
]);
setTimeout(function () {
$(form).removeData(data_click);
}, 0);
});
$(document).on("click", "form[data-ajax=true] :submit", function (evt) {
var name = evt.target.name,
form = $(evt.target).parents("form")[0];
$(form).data(data_click, name ? [{ name: name, value: evt.target.value }] : []);
setTimeout(function () {
$(form).removeData(data_click);
}, 0);
});
$(document).on("submit", "form[data-ajax=true]", function (evt) {
var clickInfo = $(this).data(data_click) || [];
evt.preventDefault();
if (!validate(this)) {
return;
}
asyncRequest(this, {
url: this.action,
type: this.method || "GET",
data: clickInfo.concat($(this).serializeArray())
});
});
Thanks.