Create HTML table out of object array in Javascript - asp.net

I am calling a web Method from javascript. The web method returns an array of customers from the northwind database. The example I am working from is here: Calling Web Services with ASP.NET AJAX
I dont know how to write this javascript method: CreateCustomersTable
This would create the html table to display the data being returned. Any help would be appreciated.
My javascript
function GetCustomerByCountry() {
var country = $get("txtCountry").value;
AjaxWebService.GetCustomersByCountry(country, OnWSRequestComplete, OnWSRequestFailed);
}
function OnWSRequestComplete(results) {
if (results != null) {
CreateCustomersTable(results);
//GetMap(results);
}
}
function CreateCustomersTable(result) {
alert(result);
if (document.all) //Filter for IE DOM since other browsers are limited
{
// How do I do this?
}
}
else {
$get("divOutput").innerHTML = "RSS only available in IE5+"; }
}
My web Method
[WebMethod]
public Customer[] GetCustomersByCountry(string country)
{
NorthwindDALTableAdapters.CustomersTableAdapter adap =
new NorthwindDALTableAdapters.CustomersTableAdapter();
NorthwindDAL.CustomersDataTable dt = adap.GetCustomersByCountry(country);
if (dt.Rows.Count <= 0)
{
return null;
}
Customer[] customers = new Customer[dt.Rows.Count];
for (int i = 0; i < dt.Rows.Count; i++)
{
NorthwindDAL.CustomersRow row = (NorthwindDAL.CustomersRow)dt.Rows[i];
customers[i] = new Customer();
customers[i].CustomerId = row.CustomerID;
customers[i].Name = row.ContactName;
}
return customers;
}

Try to look what is the result variable value in debug mode. If the structure seems the structure that i'm imagining, something like this could work:
function CreateCustomersTable(result) {
var str = '<table>';
str += '<tr><th>Id</th><th>Name</th></tr>';
for ( var i=0; i< result.length; i++){
str += '<tr><td>' + result[i].CustomerId + '</td><td>' + result[i].Name + '</td></tr>';
}
str += '</table>';
return str;
}
And then You can do somethig like this:
var existingDiv = document.getElementById('Id of an existing Div');
existingDiv.innerHTML = CreateCustomersTable(result);
I wish this help you.

Something like this, assuming you have JSON returned in the "result" value. The "container" is a div with id of "container". I'm cloning nodes to save memory, but also if you wanted to assign some base classes to the "base" elements.
var table = document.createElement('table');
var baseRow = document.createElement('tr');
var baseCell = document.createElement('td');
var container = document.getElementById('container');
for(var i = 0; i < results.length; i++){
//Create a new row
var myRow = baseRow.cloneNode(false);
//Create a new cell, you could loop this for multiple cells
var myCell = baseCell.cloneNode(false);
myCell.innerHTML = result.value;
//Append new cell
myRow.appendChild(myCell);
//Append new row
table.appendChild(myRow);
}
container.appendChild(table);

You should pass the array as JSON or XML instead of just the toString() value of it (unless that offcourse is returns either JSON oR XML). Note that JSOn is better for javascript since it is a javascript native format.
Also the person who told you that browser other then IE can not do DOM manipulation should propably have done horrible things to him/her.
If your format is JSON you can just for-loop them and create the elements and print them. (once you figured out what format your service returns we can help you better.)

Related

Unable to check existing XML nodes in Adobe Flex 3

I am getting an XML data from server (please refer to xmlData value).
I need to:
Create another XML with non-duplicates Folders
Create another XML with final count on monthly basis.
I am unable to do this with below code and getting duplicate records.
private var xmlData:XML = new XML("<root><SUMMARY_RECORD><FOLDER>Folder1</FOLDER><COUNT>100</COUNT><MONTH>Feb</MONTH><QUARTER>Q1</QUARTER><YEAR>2014</YEAR></SUMMARY_RECORD><SUMMARY_RECORD><FOLDER>Folder1</FOLDER><COUNT>100</COUNT><MONTH>Feb</MONTH><QUARTER>Q1</QUARTER><YEAR>2014</YEAR></SUMMARY_RECORD></root>");
var folderDataXML:XML = new XML("<root></root>");
var folderDGDataXML:XML = new XML("<root></root>");
private function loaded():void{
var item:XML;
folderDGDataXML.appendChild(new XML("<FOLDER_NAME><Name>ALL</Name></FOLDER_NAME>"));
for each (item in xmlData.SUMMARY_RECORD){
if (folderDGDataXML.FOLDER_NAME.(Name==item.FOLDER).toString() == ""){
folderDGDataXML.appendChild(new XML("<FOLDER_NAME><Name>"+item.FOLDER+"</Name></FOLDER_NAME>"));
}
if (folderDataXML.SUMMARY_RECORD.(Name==item.MONTH).toXMLString() == ""){
folderDataXML.appendChild(new XML("<SUMMARY_RECORD><Name>"+item.MONTH+"</Name><COUNT>"+item.COUNT+"</COUNT></SUMMARY_RECORD>"));
}else{
var count:int = Number(folderDataXML.SUMMARY_RECORD.(Name==item.MONTH).COUNT) + Number(item.COUNT);
folderDataXML.SUMMARY_RECORD.(Name==item.MONTH).COUNT = count;
}
}
}
Final output, folderDGDataXML:
<root>
<FOLDER_NAME>
<Name>ALL</Name>
</FOLDER_NAME>
<FOLDER_NAME>
<Name>Folder1</Name>
</FOLDER_NAME>
<FOLDER_NAME>
<Name>Folder1</Name>
</FOLDER_NAME>
</root>
folderDataXML:
<root>
<SUMMARY_RECORD>
<Name>Feb</Name>
<COUNT>100</COUNT>
</SUMMARY_RECORD>
<SUMMARY_RECORD>
<Name>Feb</Name>
<COUNT>100</COUNT>
</SUMMARY_RECORD>
</root>
What am I doing wrong?
After getting correct XML, I need to populate datagrid & column chart.
Try this one
In XML Checking the elements present or not with hasOwnProperty or we can use in operator anyhow our case if it is based on value try like this way folderDGDataXML.descendants("FOLDER_NAME").(Name.text() == "Folder1"); //Return always XMLList. With the help of length() we can predict element with value occur or not.
Hope this will work for you.
var xmlData:XML = new XML("<root><SUMMARY_RECORD><FOLDER>Folder1</FOLDER><COUNT>100</COUNT><MONTH>Feb</MONTH><QUARTER>Q1</QUARTER><YEAR>2014</YEAR></SUMMARY_RECORD><SUMMARY_RECORD><FOLDER>Folder1</FOLDER><COUNT>100</COUNT><MONTH>Feb</MONTH><QUARTER>Q1</QUARTER><YEAR>2014</YEAR></SUMMARY_RECORD></root>");
var folderDataXML:XML = new XML("<root></root>");
var folderDGDataXML:XML = new XML("<root></root>");
var item:XML;
folderDGDataXML.appendChild(new XML("<FOLDER_NAME><Name>ALL</Name></FOLDER_NAME>"));
for each (item in xmlData.SUMMARY_RECORD)
{
var folderName:String = item.FOLDER.text();
var monthName:String = item.MONTH.text();
var existXMLList:XMLList = folderDGDataXML.descendants("FOLDER_NAME").(Name.text() == folderName);
if (existXMLList.length() == 0)
{
folderDGDataXML.appendChild(new XML("<FOLDER_NAME><Name>"+item.FOLDER+"</Name></FOLDER_NAME>"));
}
var monthXMLList:XMLList = folderDataXML.descendants("SUMMARY_RECORD").(Name.text() == monthName);
if (monthXMLList.length() == 0)
{
folderDataXML.appendChild(new XML("<SUMMARY_RECORD><Name>"+item.MONTH+"</Name><COUNT>"+item.COUNT+"</COUNT></SUMMARY_RECORD>"));
}
else
{
monthXMLList..COUNT = Number(monthXMLList..COUNT) + Number(item.COUNT);
//If more than one node it throws error. you need to use loop operation
}
}
trace("folderDGDataXML" + folderDGDataXML);
trace("folderDataXML" + folderDataXML);

google places api many filters by type Ex.: restaurant,cafe

I'm trying to change the radius category/type filter for a checkbox, so I changed the var type to an array.
ORIGINAL WORKING:
var type;
for (var i = 0; i < document.controls.type.length; i++){
if (document.controls.type[i].checked){
type = document.controls.type[i].value;
}
}
startBox.setBounds(map.getBounds());
var search = {
// keyword: 'comocomo', // not needed with the autocomplete / startBox
bounds: map.getBounds()
};
if (type != 'establishment'){
search.types = [ type ];
}
places.search(search, function(placesArr, status){
THE ONE WITH THE ARRAY NOT WORKING: edited:
var type=[];
for (var i = 0; i < document.controls.type.length; i++){
if (document.controls.type[i].checked){
type.push(document.controls.type[i].value)
}
}
startBox.setBounds(map.getBounds());
var search = {
bounds: map.getBounds()
};
var quotedAndCommaSeparated = "'" + type.join("','") + "'";
alert(quotedAndCommaSeparated); // 'establishment','restaurant','lodging'
search.types = [ quotedAndCommaSeparated ];
I made many tests, and I don't see what I'm doing wrong. the map doesn't even show.
What's this meant to be, doesn't look like valid Javascript to me:
var type[];
Should be
var type = [];
Fix the javascript errors in your code otherwise the map won't show up.
Update:
What you have in quotedAndCommaSeparated is a string like "'a','b','c'" that looks a bit like the contents of an array: ['a','b','c']. But it's not an array, it's just a single string. If you check the length of your search.type array, I'm guessing it equals 1.
What you can do is split your string on the comma to turn it into an array:
search.types = quotedAndCommaSeparated.split(",");

Client side sorting on ASP.NET MVC WebGrid

I have a partial view which contain an MVC WebGrid as below
<div id="grid">
#{
var grid = new WebGrid(source: Model.Items,
defaultSort: "Name",
rowsPerPage: 100);
}
#grid.GetHtml(columns: grid.Columns(
grid.Column(columnName: "Name", header: "Name", canSort:true),
grid.Column(columnName: "Code", header: "Code")
))
</div>
This partial view is loaded using Jquery ajax call and result is inserted into a DIV in the main page.
The table render fine but my problem is that the sorting always generates a callback to the server. I want the sorting to happen at the client side only. Is it possible using WebGrid without using external datatables like jQuery datatable?
Thanks in advance
You should probably implement Cline-Side Sorting by yourself according to the loaded table take a look here...
NOTE!: you could always make it more generic by using html attributes to tag your WebGrid.
Tag the table with 'data-clineSideSort=true' then add a jquery event that will attach the JS functionality to all such tables holding this property...
function SortTable(sortOn)
{
var table = document.getElementById('results');
var tbody = table.getElementsByTagName('tbody')[0];
var rows = tbody.getElementsByTagName('tr');
var rowArray = new Array();
for (var i = 0, length = rows.length; i < length; i++)
{
rowArray[i] = new Object;
rowArray[i].oldIndex = i;
rowArray[i].value = rows[i].getElementsByTagName('td')[sortOn].firstChild.nodeValue;
}
if (sortOn == sortedOn) {
rowArray.reverse();
}
else {
sortedOn = sortOn;
/*
Decide which function to use from the three:RowCompareNumbers,
RowCompareDollars or RowCompare (default).
For first column, I needed numeric comparison.
*/
if (sortedOn == 0) {
rowArray.sort(RowCompareNumbers);
}
else {
rowArray.sort(RowCompare);
}
}
var newTbody = document.createElement('tbody');
for (var i = 0, length = rowArray.length; i < length; i++)
{
newTbody.appendChild(rows[rowArray[i].oldIndex].cloneNode(true));
}
table.replaceChild(newTbody, tbody);
}
function RowCompare(a, b)
{
var aVal = a.value;
var bVal = b.value;
return (aVal == bVal ? 0 : (aVal > bVal ? 1 : -1));
}
// Compare number
function RowCompareNumbers(a, b)
{
var aVal = parseInt(a.value);
var bVal = parseInt(b.value);
return (aVal - bVal);
}
// compare currency
function RowCompareDollars(a, b)
{
var aVal = parseFloat(a.value.substr(1));
var bVal = parseFloat(b.value.substr(1));
return (aVal - bVal);
}
Have a look at jQuery Tablesorter. It can be applied to any well formed table (ie, has thead and tbodyelements. The only gotcha I can think of here is to make sure you bind table sorter once the data has been loaded in your ajax call.

how to set datarow to String array?

I have a datatable on which I am applying Select() method. After that I want to get the result into an array of String. I have tried the following code but it is not working.
Please let me know the exact solutions for this.
DataTable dtget = HttpContext.Current.Cache["Hello"] as DataTable;
string sqlFilter = "Securityid = '" + CommonClass.Encryptdata(txtSecurity.Text) + "'";
DataRow[] dr = dtget.Select(sqlFilter);
if (dr.Length > 0)
{
String[] Con;
for (int i = 0; i <= dr.Length; i++)
{
dr[i] = dr[i].ToString();
}
}
You have to create the List<T>.
Something like this:
List<String[]> list=new List<String[]>();
if (dr.Length > 0)
{
for (int i = 0; i < dr.Length; i++)
{
string []ar=new string[dtget.Columns.Count];
for(int j=0;j<dtget.Columns.Count;j++)
{
ar[j]=dr[i][j].ToString();
}
list.Add(ar);
}
}
You've declared the array, but not instantiated it. and you're also not writing anything to the actual array, you're trying to write straight back to the datatable.
String[] Con= new String[dtget.Columns.Count];
for (int i = 0; i <= dr.Length; i++)
{
Con[i] = dr[i].ToString();
}
The problem is that you are assigning values to the datarrow in stead of to your string array.
Change
dr[i] = dr[i].ToString();
to
con[i] = dr[i].ToString();
also you are missing the new statement for Con:
Con = new String[dr.Table.Columns.Count];
notice that there is no such thing as dr.Length, you have to check for the column count:
dr.Table.Columns.Count
lastly, you should probably move the string array definition up so it's available outside the IF.
Depending on your needs, what you could do is use the Datarow's ItemArray property. It is an object array in stead of a string array, but before using it's values you can do a "ToString()" and you are all set.
string a = dr.ItemArray[i].ToString();

JsonArray in silverlight to javascript

I'm creating a JsonArray such as:
JsonArray jsonValues = new JsonArray();
for( int i = 0; i < values.Count; i++ )
{
var someSingleValue = values[i];
jsonValues.Add( string.Format( "Name: {0}", someSingleValue ) );
}
After that I'm shipping json values to my javascript in .aspx page via call:
HtmlPage.Window.Invoke("call", jsonValues);
The call works and it gets there, however I have no idea how to iterate over those values, i.e extract them.
I've tried: (in javascript)
for (var x in somevalues){ alert(somevalues); }
I also tried:
for(var i = 0; i < somevalues.length; i++) {
alert(somevalues[i]);
}
but it crashes.(in both cases)
any ideas?
Are you using the eval method to serialize the string to a JSON object?
function call(somevalues){
//somevalues is currently just a string.
var results = eval("(" + somevalues +")");
//results now should contain your array as a JSON object.
//and you should be able to iterate over it at this point.
for(var i = 0; i < results.length; i++){
alert(results[i]);
}
}
Assuming somevalues is truly an array, you do it like this:
for(var i = 0; i < somevalues.length; i++) {
// do something with somevalues[i]
}
What you did was tell JavaScript to iterate over the properties of the somevalues object, which is similar, but not the same, as the iteration using a regular for loop.
EDIT: I am willing to bet your variable, somevalues is a string. Just do alert(somevalues) and see what happens.

Resources