I am implementing auto-compete textbox using MVC 4. According to the requirement the textbox can take multiple names(here EmployeeName) separated by "," (comma). I have written the following code for the controller:
public JsonResult EmployeeList(string strEmpName)
{
List<string> list = strEmpName.Split(',').ToList();
list = list.Select(s => s.Trim()).ToList();
//Extract the term to be searched from the list
string searchTerm = list.LastOrDefault().ToString().Trim();
//Return if Search Term is empty
if (string.IsNullOrEmpty(searchTerm))
{
//return new string[0];
}
List<string> excludeEmployeeName = new List<string>();
if (list.Count > 1)
{
list.RemoveAt(list.Count - 1);
excludeEmployeeName = list;
}
var query = (EmployeeDAL.GetEmployee().Where(x => x.EmployeeName.StartsWith(searchTerm.ToString().ToUpper()))).ToList();
var myList = new List<string>();
foreach (var emp in query.ToList())
{
myList.Add(emp.EmployeeName.ToString());
}
return Json(myList, JsonRequestBehavior.AllowGet);
}
The above function is returning JSON.
Data is like:
public class EmployeeDAL
{
public static List<Employee> GetEmployee()
{
var empList = new List<Employee>
{
new Employee { EmployeeId = "E001", EmployeeName = "Alex", DepartmentId = 1 },
new Employee { EmployeeId = "E002", EmployeeName = "Alan", DepartmentId = 2 },
new Employee { EmployeeId = "E003", EmployeeName = "Johny", DepartmentId = 3 },
new Employee { EmployeeId = "E004", EmployeeName = "Joe", DepartmentId = 1 },
new Employee { EmployeeId = "E005", EmployeeName = "Thomas", DepartmentId = 3 },
new Employee { EmployeeId = "E006", EmployeeName = "Sarah", DepartmentId = 3 },
new Employee { EmployeeId = "E007", EmployeeName = "Rahul", DepartmentId = 4 },
new Employee { EmployeeId = "E008", EmployeeName = "Raman", DepartmentId = 1 },
new Employee { EmployeeId = "E009", EmployeeName = "Mandy", DepartmentId = 2 },
new Employee { EmployeeId = "E010", EmployeeName = "Rohit", DepartmentId = 4 },
new Employee { EmployeeId = "E011", EmployeeName = "Sanjay", DepartmentId = 1 },
new Employee { EmployeeId = "E012", EmployeeName = "Abhi", DepartmentId = 3 },
new Employee { EmployeeId = "E013", EmployeeName = "Martin", DepartmentId = 1 },
new Employee { EmployeeId = "E014", EmployeeName = "Robin", DepartmentId = 2 },
new Employee { EmployeeId = "E015", EmployeeName = "Rohit", DepartmentId = 1 },
new Employee { EmployeeId = "E016", EmployeeName = "William", DepartmentId = 3 },
new Employee { EmployeeId = "E017", EmployeeName = "Sourav", DepartmentId = 2 },
new Employee { EmployeeId = "E018", EmployeeName = "Alex", DepartmentId = 2 },
};
return empList.ToList();
}
}
In view I have written the following script:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.1/jquery-ui.min.js"></script>
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css" rel="Stylesheet" type="text/css" />
<script type="text/javascript">
$(document).ready(function() {
SearchText();
});
function SearchText() {
$("#txtEmployeeName").autocomplete({
source: function(request, response) {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "Employee/EmployeeList",
data: "{'strEmpName':'" + extractLast(request.term) + "'}",
dataType: "json",
success: function(data) {
response(data.d);
},
error: function(result) {
alert(result.responseText);
}
});
},
focus: function() {
// prevent value inserted on focus
return false;
},
select: function(event, ui) {
var terms = split(this.value);
// remove the current input
terms.pop();
// add the selected item
terms.push(ui.item.value);
// add placeholder to get the comma-and-space at the end
terms.push("");
this.value = terms.join(", ");
return false;
}
});
$("#txtEmployeeName").bind("keydown", function (event) {
if (event.keyCode === $.ui.keyCode.TAB &&
$(this).data("autocomplete").menu.active) {
event.preventDefault();
}
})
function split(val) {
return val.split(/,\s*/);
}
function extractLast(term) {
return split(term).pop();
}
}
</script>
When I run the application and debug the json script using firebug, I can see the data is coming rightly according the letter I type in the text box (txtEmployeeName) but is not showing in the browser window. I have given the total script so that any one can run it.
Any help will be thankfully accepted.
Related
Json list -
[
{
"date": "2022-10-10T09:53:40.835519+05:30",
"value": 10
},
{
"date": "2022-10-13T09:53:40.835519+05:30",
"value": 12
},
{
"date": "2022-10-13T10:53:40.835519+05:30",
"value": 15
},
{
"date": "2022-10-15T10:53:40.835519+05:30",
"value": 20
}
]
in above list if there are multiple dateTimes for same day ( ex. 2022-10-13 )
so how to mark 2022-10-13T10:53 date in object list as isLatestDateForSameDay=true as 2022-10-
13T10:53 is latest compare to 2022-10-13T09:53.
and if there is only one dateTime then it should also marked as isLatestDateForSameDay=true
ex. (2022-10-10T09:53:40.835519+05:30 and 2022-10-15T10:53:40.835519+05:30)
DataListItem class -
class DataListItem {
String date;
int value;
bool isLatestDate;
DataListItem({
required this.date,
required this.value,
this.isLatestDateForSameDay = false,
});
}
Expected list of Objects -
[
DataListItem(date: '2022-10-10T09:53:40.835519+05:30', value: 10, isLatestDateForSameDay: true),
DataListItem(date: '2022-10-13T09:53:40.835519+05:30', value: 12, isLatestDateForSameDay: false),
DataListItem(date: '2022-10-13T10:53:40.835519+05:30', value: 15, isLatestDateForSameDay: true),
DataListItem(date: '2022-10-15T10:53:40.835519+05:30', value: 20, isLatestDateForSameDay: true),
];
Lets assume your json is jsonData with collection package you can get what you want:
var grouped = groupBy(
jsonData,
(Map item) => (item['date'] as String).substring(0, 10),
);
List<DataListItem> result = [];
for (var element in grouped.entries) {
if (element.value.length == 1) {
result.add(DataListItem(
date: element.value.first['date'] as String,
value: element.value.first['value'] as int,
isLatestDate: true));
} else {
var latesItem = findLatestDate(element.value);
element.value.remove(latesItem);
result.add(DataListItem(
date: latesItem['date'] as String,
value: latesItem['value'] as int,
isLatestDate: true));
element.value.forEach((e) => result.add(DataListItem(
date: e['date'] as String,
value: e['value'] as int,
isLatestDate: false)));
}
}
Map<String, dynamic> findLatestDate(List<Map<String, dynamic>> dateList) {
Map<String, dynamic>? result;
for (var element in dateList) {
if (result == null) {
result = element;
} else {
DateTime resultDate =
DateFormat("yyyy-MM-ddThh:mm:ss").parse(result['date'] as String);
DateTime tempDate =
DateFormat("yyyy-MM-ddThh:mm:ss").parse(element['date'] as String);
if (tempDate.isAfter(resultDate)) {
result = element;
}
}
}
return result!;
}
for (var element in result) {
print("result= ${element.date} ${element.value} ${element.isLatestDate}");
// result= 2022-10-10T09:53:40.835519+05:30 10 true
// result= 2022-10-13T10:53:40.835519+05:30 15 true
// result= 2022-10-13T09:53:40.835519+05:30 12 false
// result= 2022-10-15T10:53:40.835519+05:30 20 true
}
also use intl for DateFormat.
Try sorting the list with DateTime.parse()
List<DataListItem> dataListItemlist = [];
list.sort(
(a, b) {
return DateTime.parse(a["date"]).compareTo(DateTime.parse(b["date"]));
},
);
List<String> repeatedDate = [];
for (var i = list.length - 1; i >= 0; i--) {
Map item = list[i];
DateTime date = DateTime.parse(item["date"]);
int day = date.day;
int month = date.month;
int year = date.year;
String formatedDate = "$day-$month-$year";
if (repeatedDate.contains(formatedDate)) {
dataListItemlist.add(
DataListItem(
date: item["date"],
value: item["value"],
isLatestDateForSameDay: false,
),
);
} else {
dataListItemlist.add(
DataListItem(
date: item["date"],
value: item["value"],
isLatestDateForSameDay: true,
),
);
repeatedDate.add(formatedDate);
}
}
I have a data set as follows:
[
{
"Id": 1,
"Country": "Uruguay",
"Name": "Foo",
"Status": "Completed",
},
{
"Id": 2,
"Country": "Uruguay",
"Name": "Foo",
"Status": "Completed",
},
{
"Id": 3,
"Country": "Germany",
"Name": "Foo",
"Status": "Completed",
},
]
I want to transform and sort it by Country so that it looks as follows:
[
{
"Country": "Uruguay",
"Details": [
{
"Id": 1,
"Name": "Foo",
"Status": "Completed",
},
{
"Id": 2,
"Name": "Foo",
"Status": "Completed",
},
],
},
{
"Country": "Germany",
"Details": [
{
"Id": 3,
"Name": "Foo",
"Status": "Completed",
},
],
},
],
These are the classes in C#:
public class Countries {
public int Id { get; set; }
public string Country { get; set; }
public string Name { get; set; }
public string Status { get; set; }
}
public class Details {
public int Id { get; set; }
public string Name { get; set; }
public string Status { get; set; }
}
public class CountryList {
public string Country { get; set; }
public List<Details> Details { get; set; }
}
Some of what I have tried looks as followed:
var foo = countries
.GroupBy(x => new Details { Id = x.Id, Name = x.Name, Status = x.Status })
.Select( y => new CountryList
{
// Country = y.Key.
}
var foo = countries
.GroupBy(x => x.Country)
.Select( y => new CountryList
{
// Country = y.Key.
Details = y.GroupBy(a => new Details
{
Id = a.Id,
Name = a.Name,
Status = a.Status
}).ToList()
}
I am having trouble working out how to use LINQ to solve this. I have done a handful of GroupBy operations in the past, but I wasn't able to work this one out. How do I transform my dataset into the desired result?
You do not need second GroupBy
var foo = countries
.GroupBy(x => x.Country)
.Select(y => new CountryList
{
Country = y.Key,
Details = y.Select(a => new Details
{
Id = a.Id,
Name = a.Name,
Status = a.Status
}).ToList()
};
You can take advantage of the .GroupBy() overload that lets you define a resultSelector to create your CountryLists and populate their Details:
var countries = new List<Countries>
{
new() { Id = 1, Country = "Uruguay", Name = "Foo", Status = "Completed" },
new() { Id = 2, Country = "Uruguay", Name = "Foo", Status = "Completed" },
new() { Id = 3, Country = "Germany", Name = "Foo", Status = "Completed" },
};
List<CountryList> countryList = countries
.GroupBy(
c => c.Country,
( country, matches ) => new CountryList()
{
Country = country,
Details = matches.Select(match => new Details
{
Id = match.Id,
Name = match.Name,
Status = match.Status
}).ToList()
})
.ToList();
, ( country, matches ) => new CountryList() { ... } being the resultSelector.
Example fiddle here.
try this
var orig = JsonConvert.DeserializeObject<List<Countries>>(json);
List<CountryList> countries = orig.GroupBy(o => o.Country)
.Select(x => new CountryList {
Country = x.Key,
Details = x.Select(o => new Details {Id=o.Id,Name=o.Name,Status=o.Status} ).ToList()
}).ToList();
I am new in cakephp and my table like:
city
id | name
1 | city1
2 | city2
state
id | name | cityid
1 |state1| 2
so how do i get the city name if i having state id.
In controller i have code like this.
public function getCity()
{
if( $this->request->is('ajax') ) {
$this->autoRender = false;
}
if ($this->request->isPost()) {
$sId= $this->request->data['stateid'];
}
}
In the $sId i get value so how do i write query.
If you have a BelongsTo relationship between both Model, you just have to do a query on the States which contains City:
public function getCity()
{
if( $this->request->is('ajax') ) {
$this->autoRender = false;
}
if ($this->request->isPost()) {
$stateEntity = $this->States->find('all')
->where(['id' => $this->request->data['stateid']])
->contain(['Cities'])
->first();
// Now the State Object contains City
$cityName = $stateEntity->city->name;
}
}
To create this relationship you need to do like this:
class StatesTable extends Table
{
public function initialize(array $config)
{
$this->belongsTo('Cities')
->setForeignKey('city_id')
->setJoinType('INNER');
}
}
I have the following issue to solve.
I have an IQueryable list of Invoices, each tied to an Account. Each Account can have multiple Structures, and Accounts and Structures are tied together by a table called StructureAccount. It looks like this:
Invoice ---> Account <-----StructureAccount ----> Structure
I want to query my IQueryable list of Invoices and group by Structure.StructureID or StructureAccount.StructureID. But, because any given invoice can be tied to multiple Structures the best I can get is a LIST of StructureIDs, and therefore my GroupBy is not working.
I feel like I am missing an obvious solution to this.
I should note that I understand that the data in any one Invoice would be counted multiple times if the Invoice were tied to more than one Structure, and this is "solved" by a "PercentAllocationtoStructure" value in the table StructureAccount.
I hope I did a good enough job explaining this problem. Let me know if not.
Hmmm...I might be missing something, but doesn't the following work?
var q = from i in Invoice
join a in Account
on i.AccountID equals a.AccountID
join sa in StructureAccount
on i.AccountID equals sa.AccountID
join s in Structure
on sa.StructureID equals s.StructureID
group i by s.StructureID;
I tested it on the following dummy data:
var Invoice = new [] {
new { InvoiceID = 1, AccountID = 1 },
new { InvoiceID = 2, AccountID = 2 },
new { InvoiceID = 3, AccountID = 3 },
new { InvoiceID = 4, AccountID = 1 },
new { InvoiceID = 5, AccountID = 2 },
new { InvoiceID = 6, AccountID = 3 }
};
var Account = new [] {
new { AccountID = 1 },
new { AccountID = 2 },
new { AccountID = 3 },
};
var StructureAccount = new [] {
new { AccountID = 1, StructureID = 2 },
new { AccountID = 1, StructureID = 3 },
new { AccountID = 2, StructureID = 2 },
new { AccountID = 3, StructureID = 1 },
new { AccountID = 3, StructureID = 2 },
};
var Structure = new [] {
new { StructureID = 1 },
new { StructureID = 2 },
new { StructureID = 3 }
};
And it returns:
StructureID = 2:
InvoiceID's: 1,2,3,4,5,6
StructureID = 3:
InvoiceID's: 1,4
StructureID = 1:
InvoiceID's: 3,6
I'll assume you have the following starting point:
IQueryable<Invoice> _invoices;
First, you need to get a list of all the items that you will be iterating over:
IQueryable<Account> _accounts = _invoices.Select(myInvoice => myInvoice.Account).Distinct();
IQueryable<StructuredAccount> _structuredAccounts = _accounts.SelectMany(myAccount => myAccount.StructuredAccounts);
IQueryable<Structure> _structures = _structuredAccounts.Select(myStructuredAccount => myStructuredAccount.Structure).Distinct();
Next, you need to go back and join your Structure objects to the respective Invoice objects.
For this, you'll:
Get a set of {Structure, Account} pairs:
var structureAccountJoin = _structures.Join(_structuredAccounts, _structure => structure.StructuredID, _structuredAccount => _structuredAccount.StructuredID, (structure, structuredAccount) => new { Structure = structure, Account = structuredAccount.Account });
Get a set of {Structure, Invoice} pairs:
var structureInvoiceJoin = structureAccountJoin.Join(_invoices, myObj => myObj.Account.AccountID, invoice => invoice.AccountID, (myObj, invoice) => new { Structure = myObj.Structure, Invoice = invoice});
Finally, you can group everything by the Structure object:
IQueryable<IGrouping<Structure, Invoice>> groupByStructure = structureInvoiceJoin.GroupBy(obj => obj.Structure, result => result.Invoice);
(GroupBy documentation: http://msdn.microsoft.com/en-us/library/bb534304.aspx)
Now, you can access everything as follows:
foreach(IGrouping<Structure, Invoice> groupEntry in groupByStructure)
{
Structure currentGrouping = groupEntry.Key;
foreach(Invoice inv in groupEntry)
{
// do something;
}
}
As a note, this is a very complex script that requires a lot of steps if you don't have access to the tables directly. You may want to look into creating a StoredProcedure for this instead, as it will be more efficient and you'll be able to use SQL Joins instead. If you have only an IQueryable<Invoice> to work with and access to nothing else, there is probably a design problem somewhere in your architecture.
Nevertheless, this is the way to make it work based on your requirements, if I read them correctly.
I'm trying to move the following query to Linq-to-sql, is it possible?
select * from (
Select top (#Percent) percent with ties *
from(
Select distinct
LoanNumber as LoanNo
From CHE
Left Join RecordingInfo as Rec
On CHE.LoanNumber = Rec.LoanNo
Where Channel = 'LINX'
and CHE.Doc in ('MTG','MOD')
and Rec.LoanNo is null
and LoanNumber >= '#LoanNo'
) A
order by LoanNo #Order
) B
order by LoanNo
I have not seen anyway to do with ties in linq.
I think something like this will work for you.
public static IQueryable<T> TopPercentWithTies<T, TKey>(this IOrderedQueryable<T> query, Expression<Func<T, TKey>> groupByExpression, double percent)
{
var groupedQuery = query.GroupBy(groupByExpression);
int numberToTake = groupedQuery.Count() * percent / 100;
return groupedQuery.Take(numberToTake).SelectMany(t => t);
}
I only tested it with IEnumerable, so I don't know for sure that it'll work properly with IQueryable. I also sorted the list before calling TopPercentWithTies().
Here's the code I used to test it.
int percent = 50;
var people = new []
{
new { Age = 99, Name = "Adam" },
new { Age = 99, Name = "Andrew" },
new { Age = 89, Name = "Bob" },
new { Age = 50, Name = "Cecil" },
new { Age = 50, Name = "Doug" },
new { Age = 50, Name = "Everett" },
new { Age = 35, Name = "Frank" },
new { Age = 25, Name = "Greg" },
new { Age = 15, Name = "Hank" }
};
var sortedPeople = people.AsQueryable().OrderByDescending(person => person.Age);
var results = sortedPeople.TopPercentWithTies(person => person.Age, percent);
foreach (var person in results)
Console.WriteLine(person);
Hope it helps or at least gets you in the right direction. You may want to tweak the logic for calculating numberToTake.