How to set the display value and the value of autocompleted textbox? - c#

I've made an auto-completion in a textbox using Jquery as follows:
$(document).ready(function () {
$('#searchCollabo').autocomplete({
source: '#Url.Action("AutocompleteCollabo")'
});
});
So the data come from the method AutocompleteCollabo which looks like that:
public ActionResult AutocompleteCollabo(string term)
{
int NumDossier = StructureData.DonneNumDossier((string)Session["NumCRPCEN"], (string)Session["MotDePasse"]);
List<Contact> ListeContacts = StructureData.DonneListeElementDossier(NumDossier);
Contact[] tabContacts = new Contact[ListeContacts.Count()];
int count = 0;
foreach (Contact contact in ListeContacts)
{
tabContacts[count] = contact;
count++;
}
var collaborateurs = tabContacts;
var collaborateurFiltres = collaborateurs.Where(
item => item.Nom.Contains(term) || item.Fonction.Contains(term)
);
return Json(collaborateurFiltres, JsonRequestBehavior.AllowGet);
}
The returned json contains a list of object as below:
[{"ListeFonctions":[],"IdContact":91264,"Nom":"solecki","Prenom":"hubert","Email":"hsolecki#mail.c"}]
Now I would like to set the display name (Name + function) and the value which I want to get when I select a row of the auto-completion. Do you have an Idea ?

I found out how to do it, it may help.
The function that I'm calling throught an Ajax call:
public ActionResult AutocompleteCollabo(string term)
{
int NumDossier = StructureData.DonneNumDossier((string)Session["NumCRPCEN"], (string)Session["MotDePasse"]);
List<Contact> ListeContacts = StructureData.DonneListeElementDossier(NumDossier);
var tabContactFull = ListeContacts.Where(contact => contact.Nom.Contains(term) || contact.Prenom.Contains(term) || contact.Fonction.Contains(term));
var tabInfosUtiles = tabContactFull.Select(contact => new { label = contact.Nom + " " + contact.Prenom + " ("+contact.Fonction+") ", value = contact.Nom + " " + contact.Prenom + " ("+contact.Fonction+") ", id = contact.IdContact }).ToArray();
// We set our needed informations with a title like "Label", "Value"
// So the auto-complete can find by itself which data to display and which are for the value
return Json(tabInfosUtiles, JsonRequestBehavior.AllowGet);
}
My Ajax call and the success event:
$(document).ready(function () {
$('#searchCollabo').autocomplete({
source: '#Url.Action("AutocompleteCollabo")',
select: function (event, ui) {
$("#idElement").val(ui.item.id);
// If you want to get the value : ui.item.Value
// If you want to get the label : ui.item.Label
}
});
});
Hope it helps some of you !

Related

How to map json output from [WebMethod] to d3.js bar charts

Hi I am new to d3.js.I have this following [WebMethod] in .aspx file:
[WebMethod]
public static List<Product> GetProductsLINQ()
{
List<Product> lstProducts = new List<Product>();
DataTable dtProducts = new DataTable();
string sqlQuery = "SELECT Product_Name, Purchase_Price FROM tblProductMaster";
string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["BTrax"].ConnectionString;
SqlConnection conn = new SqlConnection(connectionString);
SqlDataAdapter da = new SqlDataAdapter(sqlQuery, conn);
da.Fill(dtProducts);
var productslinq = (from products in dtProducts.AsEnumerable()
select new
{
//Product_Id = products.Field<decimal>("Product_Id"),
Product_Name = products.Field<string>("Product_Name"),
Product_Code = products.Field<decimal>("Purchase_Price"),
}).ToList();
foreach (var product in productslinq)
{
//lstProducts.Add(new Product(product.Product_Id,product.Product_Name, product.Product_Code));
lstProducts.Add(new Product(product.Product_Name, product.Product_Code));
}
return lstProducts;
}
Now, how to use this output as an input to d3.js bar chart? I tried the below script by pasting it in body tag in .aspx file but it din't help.Please provide me a solution.Thanks in Advance.
<script>
var d;
var svg = d3.select("svg"),
margin = { top: 20, right: 20, bottom: 30, left: 40 },
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom;
var x = d3.scaleBand().rangeRound([0, width]).padding(0.1),
y = d3.scaleLinear().rangeRound([height, 0]);
var g = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
d3.json("WebForm1.aspx/GetProductsLINQ", function (json) {
d=json
d.Product_Code = +d.Product_Code;
return d;
}, function (error, data) {
if (error) throw error;
x.domain(data.map(function (d) { return d.Product_Name; }));
y.domain([0, d3.max(data, function (d) { return d.Product_Code; })]);
g.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
g.append("g")
.attr("class", "axis axis--y")
.call(d3.axisLeft(y).ticks(10, "%"))
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", "0.71em")
.attr("text-anchor", "end")
.text("Frequency");
g.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function (d) { return x(d.Product_Name); })
.attr("y", function (d) { return y(d.Product_Code); })
.attr("width", x.bandwidth())
.attr("height", function (d) { return height - y(d.Product_Code); });
});
</script>
I have referred d3.js with the following link,
<script src="https://d3js.org/d3.v4.min.js"></script>
Unlike d3.csv and d3.tsv, d3.json does not accept an accessor function (or row function).
According to the API, these are the arguments of a d3.csv:
d3.csv(url, row, callback);
Compare with the argument of a d3.json:
d3.json(url[, callback])
I'm pasting your function and commenting out everything that is an accessor (row) function:
d3.json("WebForm1.aspx/GetProductsLINQ", //function (json) {
//d=json
//d.Product_Code = +d.Product_Code;
//return d;
//},
function (error, data) {
if (error) throw error;
So, it should be only:
d3.json("WebForm1.aspx/GetProductsLINQ", function (error, data) {
if (error) throw error;
And then, right after it, put your accessor (row) function inside d3.json as a forEach:
data.forEach(function(d){
d.Product_Code = +d.Product_Code;
});

Grid.MVC use select fillter form list<T>

I'm a newbie in MVC. Iuse Grid.MVC to show a list. I'm trying to create custom fillter for string and date columns as [Demo1. I had read the document of Grid.MVC but it doesn't work. The select hasn't any option.
This is my script
<script>
function CustomersFilterWidget() {
/***
* This method must return type of registered widget type in 'SetFilterWidgetType' method
*/
this.getAssociatedTypes = function () {
return ["CustomCompanyNameFilterWidget"];
};
/***
* This method invokes when filter widget was shown on the page
*/
this.onShow = function () {
/* Place your on show logic here */
};
this.showClearFilterButton = function () {
return true;
};
/***
* This method will invoke when user was clicked on filter button.
* container - html element, which must contain widget layout;
* lang - current language settings;
* typeName - current column type (if widget assign to multipile types, see: getAssociatedTypes);
* values - current filter values. Array of objects [{filterValue: '', filterType:'1'}];
* cb - callback function that must invoked when user want to filter this column. Widget must pass filter type and filter value.
* data - widget data passed from the server
*/
this.onRender = function (container, lang, typeName, values, cb, data) {
//store parameters:
this.cb = cb;
this.container = container;
this.lang = lang;
//this filterwidget demo supports only 1 filter value for column column
this.value = values.length > 0 ? values[0] : { filterType: 1, filterValue: "" };
this.renderWidget(); //onRender filter widget
this.loadCustomers(); //load customer's list from the server
this.registerEvents(); //handle events
};
this.renderWidget = function () {
var html = '<p><i>This is custom filter widget demo.</i></p>\
<p>Select customer to filter:</p>\
<select style="width:250px;" class="grid-filter-type customerslist form-control">\
</select>';
this.container.append(html);
};
/***
* Method loads all customers from the server via Ajax:
*/
this.loadCustomers = function () {
var $this = this;
$.post("/QuanLySanPham/GetTenSach", function (data) {
$this.fillCustomers(data.Items);
});
};
/***
* Method fill customers select list by data
*/
this.fillCustomers = function (items) {
var customerList = this.container.find(".customerslist");
for (var i = 0; i < items.length; i++) {
alert(data);
customerList.append('<option ' + (items[i] == this.value.filterValue ? 'selected="selected"' : '') + ' value="' + items[i] + '">' + items[i] + '</option>');
}
};
/***
* Internal method that register event handlers for 'apply' button.
*/
this.registerEvents = function () {
//get list with customers
var customerList = this.container.find(".customerslist");
//save current context:
var $context = this;
//register onclick event handler
customerList.change(function () {
//invoke callback with selected filter values:
var values = [{ filterValue: $(this).val(), filterType: 1 /* Equals */ }];
$context.cb(values);
});
};
}
$(function () {
pageGrids.ordersGrid.addFilterWidget(new CustomersFilterWidget());
});
</script>
This is my Controller
QuanLyBanSachEntities db = new QuanLyBanSachEntities();
public ActionResult Index(int? page)
{
//int pageNumber = (page ?? 1);
//int pageSize = 10;
//return View(db.Saches.ToList().OrderBy(n => n.MaSach).ToPagedList(pageNumber, pageSize));
List<WebBanSach.Models.Sach> customerslist = db.Saches.ToList();
return View(customerslist);
}
public JsonResult GetTenSach()
{
List<string> customerslist = db.Saches.Select(s => s.TenSach).ToList();
return Json(customerslist, JsonRequestBehavior.AllowGet);
}
Could you give me an advice on how to fill this select tag?

autocompleteextender Null value after setting innerHtml

I have an autocompleteextender which works very fine when i set its innerHtml to text received from the webservice a i can catch the selected value of that text on selectedItem function . but when i set some HTML elements inside innerHtml of the childnode i loss the value of that node on selectedItem function (to keep on mind that i can see set value on OnClientPopulated function !).
here is OnClientPopulated
function PopulateDataForAce_Locations(sender) {
$("#tbxLocation").css("background-image", "none");
var comletionList = $find("aceYer").get_completionList();
for (var i = 0; i < comletionList.childNodes.length; i++) {
var data = JSON.parse(comletionList.childNodes[i].innerText);
var image = data[0];
var imageClass = "";
var textClass = "";
if (data[1].indexOf("##") > -1 || comletionList.childNodes[i]._value == "0000") {
imageClass = "imageStyleIlce";
textClass = "textStyleIlce";
}
else {
imageClass = "imageStyleIl";
textClass = "textStyleIl";
}
var text = data[1].replace("##", "");
var text2 = data[2];
// comletionList.childNodes[i].innerHTML = "<font class=\"" + textClass + "\">" + text + "</font>";
comletionList.childNodes[i].innerHTML = text;
}
}
when i use the comment line i lose the value of the node.
any help is appreciated
the only way that i found to get the value on selected item function was
function aceLocation_itemSelected(sender, e) {
var index = $find("aceYer")._selectIndex;
var _item = $find("aceYer").get_completionList().childNodes[index];
var hfYer = $get('<%= hfYer.ClientID %>');
hfYer.value = _item._value;
}
while e.get_value() did not work with html item.

C#: How to using global variable with Javascript

everyone!
I'm learning ASP.NET MVC and have some question.
My problem is Passing Data from View to Controller.
This my Code:
#{
string listID = "";
}
and I try to use this variable:
function SubmitDelete() {
var listId = "";
var x = document.getElementsByName("IsCheck");
for (var i = 0; i < x.length; i++) {
if (x[i].checked == true) {
listId += x[i].value + ", ";
};
}
#listID = listId;
return listId;
}
Finalize, I want to pass #listID to Controller:
#using (Html.BeginForm("DeleteChecked", "Category", new { listID }, FormMethod.Post)){ }
It is simple problem about multi delete with checkbox.
Help me, please.
You cannot pass a javascript variable to your controller.
But you can post it as part form data with the help of hidden field.
Better add a hidden field and set it in a Javascript and post
#using (Html.BeginForm("DeleteChecked", "Category", FormMethod.Post)){
Html.HiddenFieldFor(m=>m.MyList, new {#id="my-list-data"})
..other controls and your submit button
}
In a Javascript
function SubmitDelete() {
var listId = "";
var x = document.getElementsByName("IsCheck");
for (var i = 0; i < x.length; i++) {
if (x[i].checked == true) {
listId += x[i].value + ", ";
};
}
$('#my-list-data').val(listId);
}
You cannot do that.
The aspx\ascx\cshtml etc. page is built in the server side while the js is computed on the client's side.
You can add C# string to js functions but they will be hard coded when they get to the client.
All the C# expression are evaluated before they get to the client and before the js is computed.
Here's an example:
This is what you see on the aspx\ascx\cshtml file.
<%
string str = 'test';
%>
function jsFunc(){
var myVar = '<%=str%>';
}
This is what the client gets:
function jsFunc(){
var myVar = 'test';
}

Query nested objects from MongoDB (Part 2)

With some earlier help, I created a C# script in SSIS to retrieve data from MongoDB to SQL Server. While regular documents are retrieved easily, nested documents and arrays are problematic.
Problem 1: I have shipping_address.country that returns results by using
this.UserDBBuffer.SCountry = document["shipping_address"].AsBsonDocument["country"].ToString();
However, mlocation.address gives me an error '"country" not found' using the same code:
this.UserDBBuffer.Country = document["mlocation"].AsBsonDocument["country"].ToString();
Problem 2: Retrieving items from arrays. I have an array that looks like "devices -> Document -> device_data -> model" or "devices -> Document -> device_data -> brand". How do I retrieve "model" or "brand" values in my code?
Thanks a lot for your help. Below is my entire code:
public override void CreateNewOutputRows()
{
string connectionString = "mongodb://localhost";
MongoServer myMongo = MongoServer.Create(connectionString);
myMongo.Connect();
var db = myMongo.GetDatabase("UserDB");
//Declaring variables for Date Created conversions
string DateCreatedString;
DateTime DateCreatedDateUTC;
DateTime DateCreatedDateLocal;
var fields = Fields.Include("mlocation.country", "mlocation", "_id", "primary_email", "gender", "date_created");
var collection = db.GetCollection<BsonDocument>("users");
foreach (var document in collection.FindAll().SetFields(fields))
{
this.UserDBBuffer.AddRow();
this.UserDBBuffer.ID = document["_id"] == null ? "" : document["_id"].ToString();
this.UserDBBuffer.Country = document["mlocation"].AsBsonDocument["country"].ToString();
this.UserDBBuffer.PrimaryEmail = document["primary_email"] == null ? "" : document["primary_email"].ToString();
this.UserDBBuffer.Gender = document["gender"] == null ? "" : document["gender"].ToString();
//Importing Date Created as String for data manipulation
DateCreatedString = document["date_created"] == null ? "" : document["date_created"].ToString();
//First, making sure that we have a UTC datetime
DateCreatedDateUTC = DateTime.Parse(DateCreatedString).ToUniversalTime();
//Second, converting to Local Time
DateCreatedDateLocal = DateTime.Parse(DateCreatedString).ToLocalTime();
//Finally, assigning variables to rows
this.UserDBBuffer.DateTimeCreatedUTC = DateCreatedDateUTC;
this.UserDBBuffer.DateTimeCreatedLocal = DateCreatedDateLocal;
}
myMongo.Disconnect();
}
For Problem 2, I found a Java Script that someone used; if I can convert it to C#, it might help a lot:
count = 0;
function user_list(){
var cursor = db.users.find()
//var cursor = db.users.find({"devices": {"$ne":[]}})
cursor.forEach(function(user) {
var deviceInfo = "";
if (user.devices){
if (user.devices[0]){
dd = user.devices[0].device_data;
if (dd) {
deviceInfo = dd.model + "," + dd.brand + "," + dd.model + "," + dd.device + "," + dd.pixel_height + "," + dd.pixel_width + "," + dd.pixel_format;
}
}
}
var location = "";
if (user.mlocation) location = user.mlocation.country;
print(user._id + "," + location + "," + user.primary_email + "," + user.date_created + "," + deviceInfo);
count++;
});
}
user_list();
print(count);
For problem 1, are you sure all docs contain a field mlocation that is a document containing the country field. I was able to reproduce the "Element country not found" with a document that is missing the value.
e.g. with
db.users.find()
{ "_id" : ObjectId("4f04c56a0f8fa4413bed1078"), "primary_email" : "email#email.com", "shipping_address" : [ {"country" : "USA", "city" : "San Francisco" }, { "country" : "IN", "city" : "Chennai" } ], "mlocation" : { "country" : "Canada", "city" : "Montreal" } }
{ "_id" : ObjectId("4f04d1605ab5a3805aaa8666"), "primary_email" : "incorrect#email.com", "shipping_address" : [ { "country" : "MX", "city" : "Cabo San Lucas" } ], "mlocation" : { "city" : "Montreal" } }
the 2nd document throws the exception. You can either check for its existance or use the default value option
document["mlocation"].AsBsonDocument.GetValue("country", null)
For problem 2, you cannot cast a BsonArray as a document. So for the above e.g to get shipping_address.country you can do something like
foreach (var addr in document["shipping_address"].AsBsonArray)
{
var country = addr.AsBsonDocument["country"].AsString;
}
Assuming the devices element is an array, just drill your way down into the element you are looking for, like this:
BsonDocument document; // assume this comes from somewhere
var devices = document["devices"].AsBsonArray;
var device = devices[0].AsBsonDocument; // first element of array
var deviceData = device["device_data"].AsBsonDocument;
var model = deviceData["model"].AsString;
var brand = deviceData["brand"].AsString;
I've broken it down into steps for clarity, but you can combine some of these steps into longer statements if you want.
To clarify your comment to Robert's answer, you can use BsonDocument.Contains to check if a given BsonDocument contains a field of the specified name before getting its value (http://api.mongodb.org/csharp/current/html/6181f23f-f6ce-fc7d-25a7-fc682ffd3c04.htm)
Instead of:
var mlocation = document["mlocation"].AsBsonDocument;
var country = "";
if (mlocation != null && mlocation.Contains("country"))
{
country = mlocation.AsBsonDocument.GetValue("country").ToString();
}
I would write:
var mlocation = document["mlocation"].AsBsonDocument;
var country = "";
if (mlocation.Contains("country"))
{
country = mlocation["country"].AsString;
}
And instead of:
var devices = document["devices"].AsBsonArray;
if (devices.ToList().Count > 0)
{
if (devices[0].AsBsonDocument != null)
{
var deviceinfo = devices[0].AsBsonDocument;
if (deviceinfo["device_data"].AsBsonDocument != null)
{
var deviceData = deviceinfo["device_data"].AsBsonDocument;
model = deviceData.GetValue("model", null).AsString;
}
}
}
I would write:
var devices = document["devices"].AsBsonArray;
if (devices.Count > 0)
{
var deviceinfo = devices[0].AsBsonDocument;
if (deviceinfo.Contains("device_data"))
{
var deviceData = deviceinfo["device_data"].AsBsonDocument;
var model = deviceData.GetValue("model", "").AsString; // "" instead of null
}
}

Categories

Resources