Error throwing while loading GridPanel on button click - ext.net

I am getting a javascript error while trying to load GridPanel on a button click. The same function is working while calling on page_load event.
Code:
private DataTable GetDataTable()
{
DataTable table = new DataTable();
table.Columns.AddRange(new DataColumn[] {
new DataColumn("Company") { ColumnName = "Company", DataType = typeof(string) },
new DataColumn("Price") { ColumnName = "Price", DataType = typeof(double) },
new DataColumn("Change") { ColumnName = "Change", DataType = typeof(double) },
new DataColumn("PctChange") { ColumnName = "PctChange", DataType = typeof(double) },
new DataColumn("PctChange") { ColumnName = "LastChange", DataType = typeof(DateTime) }
});
foreach (object[] obj in this.Data)
{
table.Rows.Add(obj);
}
return table;
}
private object[] Data
{
get
{
DateTime now = DateTime.Now;
return new object[]
{
new object[] { "3m Co", 71.72, 0.02, 0.03, now },
new object[] { "Alcoa Inc", 29.01, 0.42, 1.47, now },
new object[] { "Altria Group Inc", 83.81, 0.28, 0.34, now },
new object[] { "American Express Company", 52.55, 0.01, 0.02, now },
new object[] { "American International Group, Inc.", 64.13, 0.31, 0.49, now },
new object[] { "AT&T Inc.", 31.61, -0.48, -1.54, now },
new object[] { "Boeing Co.", 75.43, 0.53, 0.71, now },
new object[] { "Caterpillar Inc.", 67.27, 0.92, 1.39, now },
new object[] { "Citigroup, Inc.", 49.37, 0.02, 0.04, now },
new object[] { "E.I. du Pont de Nemours and Company", 40.48, 0.51, 1.28, now },
new object[] { "Exxon Mobil Corp", 68.1, -0.43, -0.64, now },
new object[] { "General Electric Company", 34.14, -0.08, -0.23, now },
new object[] { "General Motors Corporation", 30.27, 1.09, 3.74, now },
new object[] { "Hewlett-Packard Co.", 36.53, -0.03, -0.08, now },
new object[] { "Honeywell Intl Inc", 38.77, 0.05, 0.13, now },
new object[] { "Intel Corporation", 19.88, 0.31, 1.58, now },
new object[] { "International Business Machines", 81.41, 0.44, 0.54, now },
new object[] { "Johnson & Johnson", 64.72, 0.06, 0.09, now },
new object[] { "JP Morgan & Chase & Co", 45.73, 0.07, 0.15, now },
new object[] { "McDonald\"s Corporation", 36.76, 0.86, 2.40, now },
new object[] { "Merck & Co., Inc.", 40.96, 0.41, 1.01, now },
new object[] { "Microsoft Corporation", 25.84, 0.14, 0.54, now },
new object[] { "Pfizer Inc", 27.96, 0.4, 1.45, now },
new object[] { "The Coca-Cola Company", 45.07, 0.26, 0.58, now },
new object[] { "The Home Depot, Inc.", 34.64, 0.35, 1.02, now },
new object[] { "The Procter & Gamble Company", 61.91, 0.01, 0.02, now },
new object[] { "United Technologies Corporation", 63.26, 0.55, 0.88, now },
new object[] { "Verizon Communications", 35.57, 0.39, 1.11, now },
new object[] { "Wal-Mart Stores, Inc.", 45.45, 0.73, 1.63, now }
};
}
}
private void createDynamicGrid()
{
Store store1 = new Store();
GridPanel grid = this.GrdPanel;
Ext.Net.Model model = new Model();
for (int i = 0; i < 2; i++)
{
ModelField modelField = new ModelField();
if (i == 0)
modelField.Name = "Company";
else
modelField.Name = "Price";
model.Fields.Add(modelField);
}
store1.Model.Add(model);
store1.DataSource = this.GetDataTable();
store1.DataBind();
grid.Store.Add(store1);
grid.SelectionModel.Add(new RowSelectionModel { Mode = SelectionMode.Single });
grid.ColumnModel.Columns.Add(new ColumnBase[] {
new Column
{
Text = "Company",
DataIndex = "Company",
Flex = 1
},
new Column
{
Text = "Price",
DataIndex = "Price"
}
});
grid.Render();
}
protected void btnSearch_Click(object sender, DirectEventArgs e)
{
createDynamicGrid();
}
Designer View:
<ext:Button runat="server" ID="btnSearch" Text="Search" Icon="FeedMagnify" X="150"
Y="10">
<DirectEvents>
<Click OnEvent="btnSearch_Click" />
</DirectEvents>
</ext:Button>
If I am calling createDynamicGrid() on page_load then it is working fine.
Error message: "Microsoft JScript compilation error: Expected identifier"

Maybe the following examples will be helpful: http://examples.ext.net/#/XRender/Basic/Add_Items/
<%# Page Language="C#" %>
<%# Register assembly="Ext.Net" namespace="Ext.Net" tagprefix="ext" %>
<!DOCTYPE html>
<html>
<head runat="server">
<title>Ext.NET Examples</title>
<script runat="server">
public void Button_Click(object sender, DirectEventArgs e)
{
CreateGrid().Render(this.Container1, RenderMode.AddTo);
}
public GridPanel CreateGrid()
{
// string id = parameters["id"];
List<object> data = new List<object>();
for (int i = 1; i <= 10; i++)
{
data.Add(new { ID = "P" + i, Name = "Product " + i });
}
GridPanel grid = new GridPanel
{
Height = 200,
EnableColumnHide = false,
Store =
{
new Store
{
Model = {
new Model {
IDProperty = "ID",
Fields =
{
new ModelField("ID"),
new ModelField("Name")
}
}
},
DataSource = data
}
},
ColumnModel =
{
Columns =
{
new Column { Text = "Products's Name", DataIndex = "Name" }
}
}
};
return grid;
}
</script>
</head>
<body>
<ext:ResourceManager runat="server" />
<ext:Container runat="server" ID="Container1"></ext:Container>
<ext:Button runat="server" Text="Create grid" OnDirectClick="Button_Click"></ext:Button>
</body>
</html>

Related

Can we add text field dynamically

I've created an adaptive card(using json) in my chatbot that takes input from users. I want to add a button that enables the user to add a new text field every time the user clicks on the insert field. (i.e., the user can click on insert button to enter details of education (school, college etc.))
Can this be achieved in adaptive cards?
I also wanted to know, can adaptive cards be designed in any other language (excluding json)
The easiest way to do this is with Action.ShowCard:
{
"type": "AdaptiveCard",
"body": [
{
"type": "Input.Text",
"placeholder": "Placeholder 1",
"id": "text1"
}
],
"actions": [
{
"type": "Action.ShowCard",
"title": "Add field",
"card": {
"type": "AdaptiveCard",
"body": [
{
"type": "Input.Text",
"placeholder": "Placeholder 2",
"id": "text2"
}
],
"actions": [
{
"type": "Action.ShowCard",
"title": "Add field",
"card": {
"type": "AdaptiveCard",
"body": [
{
"type": "Input.Text",
"placeholder": "Placeholder 3",
"id": "text3"
}
],
"actions": [
{
"type": "Action.ShowCard",
"title": "Add field",
"card": {
"type": "AdaptiveCard",
"body": [
{
"type": "Input.Text",
"placeholder": "Placeholder 4",
"id": "text4"
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json"
}
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json"
}
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json"
}
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.0"
}
You may not like the way that looks, but there is an alternative. Microsoft Teams allows you to update messages, so you can update the card with more input fields in response to a submit action. First, you'll need a way of saving state for your card so you can update the card's activity. In C# you can declare a state property accessor like this:
public IStatePropertyAccessor<Dictionary<string, (string ActivityId, int InputCount)>> InputCardStateAccessor { get; internal set; }
Then you can instantiate it like this:
InputCardStateAccessor = _conversationState.CreateProperty<Dictionary<string, (string, int)>>("cardState");
In Node.js you won't need to declare anything but you can instantiate it like this:
this.inputCardState = this.conversationState.createProperty('cardState');
You'll want a consistent way to generate your card that you can use when you send the card initially and when you update the card. I'm using the AdaptiveCards NuGet package in C#:
public static IActivity GenerateAdaptiveCardActivityWithInputs(int inputCount, object valueObject)
{
var cardData = JObject.FromObject(valueObject);
var cardId = Convert.ToString(cardData[KEYCARDID]);
var card = new AdaptiveCard(new AdaptiveSchemaVersion(1, 0))
{
Body = Enumerable.Range(0, inputCount).Select(i =>
{
var inputId = $"text{i}";
return new AdaptiveTextInput
{
Id = inputId,
Value = Convert.ToString(cardData[inputId]),
};
}).ToList<AdaptiveElement>(),
Actions = new List<AdaptiveAction>
{
new AdaptiveSubmitAction
{
Title = "Add field",
Data = new Dictionary<string, string>
{
{ KEYCARDID, cardId },
{ KEYSUBMITACTIONID, ACTIONSUBMITADDFIELD },
},
},
new AdaptiveSubmitAction
{
Title = "Submit",
},
},
};
return MessageFactory.Attachment(new Attachment(AdaptiveCard.ContentType, content: JObject.FromObject(card)));
}
Node.js:
generateAdaptiveCardActivityWithInputs(inputCount, cardData) {
var cardId = cardData[KEYCARDID];
var body = [];
for (let i = 0; i < inputCount; i++) {
var inputId = `text${i}`;
body.push({
type: "Input.Text",
id: inputId,
value: cardData[inputId]
});
}
var card = {
type: "AdaptiveCard",
$schema: "http://adaptivecards.io/schemas/adaptive-card.json",
version: "1.0",
body,
actions: [
{
type: "Action.Submit",
title: "Add field",
data: {
[KEYCARDID]: cardId,
[KEYSUBMITACTIONID]: ACTIONSUBMITADDFIELD
},
},
{
type: "Action.Submit",
title: "Submit",
}
]
};
return MessageFactory.attachment(CardFactory.adaptiveCard(card));
}
Using this function, you can send the card initially like this in C#:
var inputCount = 1;
var cardId = Guid.NewGuid().ToString();
var reply = GenerateAdaptiveCardActivityWithInputs(inputCount, new Dictionary<string, string> { { KEYCARDID, cardId } });
var response = await turnContext.SendActivityAsync(reply, cancellationToken);
var dict = await InputCardStateAccessor.GetAsync(turnContext, () => new Dictionary<string, (string, int)>(), cancellationToken);
dict[cardId] = (response.Id, inputCount);
Node.js:
var inputCount = 1;
var cardId = Date.now().toString();
var reply = this.generateAdaptiveCardActivityWithInputs(inputCount, { [KEYCARDID]: cardId });
var response = await turnContext.sendActivity(reply);
var dict = await this.inputCardState.get(turnContext, {});
dict[cardId] = {
activityId: response.id,
inputCount: inputCount
};
await this.inputCardState.set(turnContext, dict);
And you can update the card in response to the card's "add field" submit action like this in C#:
private async Task AddFieldAsync(ITurnContext turnContext, CancellationToken cancellationToken)
{
var activity = turnContext.Activity;
if (activity.ChannelId == Channels.Msteams)
{
var value = JObject.FromObject(activity.Value);
var cardId = Convert.ToString(value[KEYCARDID]);
var dict = await InputCardStateAccessor.GetAsync(turnContext, () => new Dictionary<string, (string, int)>(), cancellationToken);
if (dict.TryGetValue(cardId, out var cardInfo))
{
var update = GenerateAdaptiveCardActivityWithInputs(++cardInfo.InputCount, value);
update.Id = cardInfo.ActivityId;
update.Conversation = activity.Conversation;
await turnContext.UpdateActivityAsync(update, cancellationToken);
dict[cardId] = cardInfo;
}
}
}
Node.js:
async addField(turnContext) {
var activity = turnContext.activity;
if (activity.channelId == 'msteams') {
var value = activity.value;
var cardId = value[KEYCARDID];
var dict = await this.inputCardState.get(turnContext, {});
var cardInfo = dict[cardId];
if (cardInfo) {
var update = this.generateAdaptiveCardActivityWithInputs(++cardInfo.inputCount, value);
update.id = cardInfo.activityId;
update.conversation = activity.conversation;
update.serviceUrl = activity.serviceUrl;
dict[cardId] = cardInfo;
await this.inputCardState.set(turnContext, dict);
await turnContext.updateActivity(update);
}
}
}
yes this is possible you can look about the addRow in javascript

js grid and autocomplete

I am able to create a custom field with jsGrid and jquery autocomplete. All ajax CRUD calls are working for all other fields. The below code activates autocomplete and shows the available options in the input field as expected.
var tags = ["tag1", "tag2", "tag3"];
MyDescriptionField.prototype = new jsGrid.Field({
insertTemplate: function(value) {
return this._editPicker = $("<input>").autocomplete({source : tags});
},
editTemplate: function(value) {
return this._editPicker = $("<input>").autocomplete({source : tags});
},
........... (more code)
So far so good. However to actually capture the value so it can be inserted into the db, I also need to define insertValue and editValue.
The code below is NOT working
insertValue: function(){
return this._insertPicker = $("<input>").val();
},
...........(more code)
this one is not working eiter:
insertValue: function(){
return this._insertPicker.autocomplete({
select: function(event, ui) {
$("<input>").val(ui.item.value);
}
});
},
reference: jsGrid. http://js-grid.com/demos/
autocomplete: https://jqueryui.com/autocomplete/
Try this snippet:
$(function() {
var myTagField = function(config) {
jsGrid.Field.call(this, config);
};
myTagField.prototype = new jsGrid.Field({
sorter: function(tag1, tag2) {
return tag1.localeCompare(tag2);
},
itemTemplate: function(value) {
return value;
},
insertTemplate: function(value) {
return this._insertAuto = $("<input>").autocomplete({source : tags});
},
editTemplate: function(value) {
return this._editAuto = $("<input>").autocomplete({source : tags}).val(value);
},
insertValue: function() {
return this._insertAuto.val();
},
editValue: function() {
return this._editAuto.val();
}
});
jsGrid.fields.myTagField = myTagField;
$("#jsGrid").jsGrid({
width: "100%",
inserting: true,
editing: true,
sorting: true,
paging: true,
fields: [
{ name: "Name", type: "text" },
{ name: "Tag", type: "myTagField", width: 100, align: "center" },
{ type: "control", editButton: false, modeSwitchButton: false }
],
data: db.users
});
});
var tags = ["tag1", "tag2", "tag3"];
var db = {};
db.users = [
{
"Name": "Carson Kelley",
"Tag": ""
},
{
"Name": "Prescott Griffin",
"Tag": "tag1"
},
{
"Name": "Amir Saunders",
"Tag": "tag3"
},
{
"Name": "Derek Thornton",
"Tag": "tag2"
},
{
"Name": "Fletcher Romero",
"Tag": ""
}];
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script><script src="//code.jquery.com/ui/1.11.2/jquery-ui.js"></script>
<script src="//rawgit.com/tabalinas/jsgrid/master/dist/jsgrid.min.js"></script>
<link href="//code.jquery.com/ui/1.11.2/themes/cupertino/jquery-ui.css" rel="stylesheet"/>
<link href="//rawgit.com/tabalinas/jsgrid/master/dist/jsgrid.min.css" rel="stylesheet"/>
<link href="//rawgit.com/tabalinas/jsgrid/master/dist/jsgrid-theme.css" rel="stylesheet"/>
<div id="jsGrid"></div>
or this codepen: https://codepen.io/beaver71/pen/rpaLEo
Thanks #beaver. Your pen helped my understand custom fields better. I extended it a bit to add filtering with autocomplete. https://codepen.io/obrienje/pen/aQKNry
$(function() {
var myTagField = function(config) {
jsGrid.Field.call(this, config);
};
myTagField.prototype = new jsGrid.Field({
autosearch: true,
sorter: function(tag1, tag2) {
return tag1.localeCompare(tag2);
},
itemTemplate: function(value) {
return '<span class="label label-primary">' + value + '</span>';
},
insertTemplate: function(value) {
return this._insertAuto = $("<input>").autocomplete({
source: tags
});
},
filterTemplate: function(value) {
if (!this.filtering)
return "";
var grid = this._grid,
$result = this._filterAuto = $("<input>").autocomplete({
source: tags
});
if (this.autosearch) {
$result.on("change", function(e) {
grid.search();
});
}
return $result;
},
editTemplate: function(value) {
return this._editAuto = $("<input>").autocomplete({
source: tags
}).val(value);
},
insertValue: function() {
return this._insertAuto.val();
},
filterValue: function() {
return this._filterAuto.val();
},
editValue: function() {
return this._editAuto.val();
}
});
jsGrid.fields.myTagField = myTagField;
$("#jsGrid").jsGrid({
width: "100%",
filtering: true,
inserting: true,
editing: true,
sorting: true,
paging: true,
fields: [{
name: "Name",
type: "text"
},
{
name: "Tag",
type: "myTagField",
width: 100,
align: "center"
},
{
type: "control",
editButton: false,
modeSwitchButton: false
}
],
data: db.users,
controller: {
loadData: function(filter) {
return $.grep(db.users, function(item) {
return (!filter.Tag || item.Tag.toLowerCase().indexOf(filter.Tag.toLowerCase()) > -1);
});
}
}
});
});
var tags = ["tag1", "tag2", "tag3"];
var db = {};
db.users = [{
"Name": "Carson Kelley",
"Tag": ""
},
{
"Name": "Prescott Griffin",
"Tag": "tag1"
},
{
"Name": "Amir Saunders",
"Tag": "tag3"
},
{
"Name": "Derek Thornton",
"Tag": "tag2"
},
{
"Name": "Fletcher Romero",
"Tag": ""
}
];
<html>
<head>
<link href="https://rawgit.com/tabalinas/jsgrid/master/dist/jsgrid.min.css" rel="stylesheet"/>
<link href="https://rawgit.com/tabalinas/jsgrid/master/dist/jsgrid-theme.css" rel="stylesheet"/>
<link href="//code.jquery.com/ui/1.11.2/themes/cupertino/jquery-ui.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css"/>
</head>
<body>
<h1>Custom Grid DateField filtering with autocomplete</h1>
<div id="jsGrid"></div>
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.2/jquery-ui.js"></script>
<script src="https://rawgit.com/tabalinas/jsgrid/master/dist/jsgrid.min.js"></script>
</body>
</html>
Thanks #beaver. Your pen helped my understand custom fields better. I extended it a bit to add filtering with autocomplete. https://codepen.io/obrienje/pen/aQKNry

Unable to use OpenLayer

I'm very new with web language and I have to integrate a map in a page. I'm using cshtml with Visual Studio 2015
To do this I have take a code using ol.js. The map have to be displayed, and for each value in my table I localize the city/country from IP and I display for each countries, the number of item.
There is my Index.cshtml
<script type="text/javascript">
var map;
var countriesLayer;
var citiesLayer;
function newCountriesLayer(start, end, item, result) {
return new ol.layer.Vector({
minResolution: 2500,
source: new ol.source.GeoJSON({
projection: 'EPSG:3857',
url: '#Url.Action("GetCountries")'
+ '?StartDate=' + start
+ '&EndDate=' + end
+ '&Item=' + item
+ '&Result=' + result
}),
style: function (f, r) {
return [
new ol.style.Style({
text: new ol.style.Text({ text: f.get("title"), fill: new ol.style.Fill({ color: '#673B8F' }), scale: 1.2 }),
image: new ol.style.Circle({ radius: 10, fill: new ol.style.Fill({ color: 'white' }) }),
})
];
}
});
}
function newCitiesLayer(start, end, item, result) {
return new ol.layer.Vector({
maxResolution: 2500,
source: new ol.source.GeoJSON({
projection: 'EPSG:3857',
url: '#Url.Action("GetCities")'
+ '?StartDate=' + start
+ '&EndDate=' + end
+ '&Item=' + item
+ '&Result=' + result
}),
style: function (f, r) {
return [
new ol.style.Style({
text: new ol.style.Text({ text: f.get("title"), fill: new ol.style.Fill({ color: '#673B8F' }), scale: 1.2 }),
image: new ol.style.Circle({ radius: 10, fill: new ol.style.Fill({ color: 'white' }) }),
})
];
}
});
}
$(document).ready(function () {
var start = $('#startDate').val();
var end = $('#endDate').val();
var item = $('#item').val();
var result = $('#resultat').val();
countriesLayer = newCountriesLayer(start, end, item, result);
citiesLayer = newCitiesLayer(start, end, item, result);
map = new ol.Map({
target: 'map',
renderer: 'canvas',
layers:
[
new ol.layer.Tile({
//source: new ol.source.TileWMS({
// url: 'http://maps.opengeo.org/geowebcache/service/wms',
// params: { LAYERS: 'openstreetmap', VERSION: '1.1.1' }
//})
source: new ol.source.OSM(),
}),
countriesLayer, citiesLayer
],
view: new ol.View2D({
center: ol.proj.transform([0, 0], 'EPSG:4326', 'EPSG:3857'),
zoom: 1,
})
});
});
</script>
In my Controller.cs I have 2 functions:
public ContentResult GetCities(string StartDate, string EndDate, string Item, string Result){...}
public ContentResult GetCountries(string StartDate, string EndDate, string Item, string Result){...}
both return :
return new ContentResult()
{
Content = geoJson.ToString(),
ContentEncoding = System.Text.Encoding.ASCII,
ContentType = "text/json"
};
Value for geoJson is :
{
"type": "FeatureCollection",
"crs": {
"type": "name",
"properties": {
"name": "urn:ogc:def:crs:OGC:1.3:CRS84"
}
},
"features": [
{
"type": "Feature",
"properties": {
"id":"CN-30-Guangzhou",
"title":"2",
},
"geometry": {
"type": "Point",
"coordinates": [113.25,23.1167]
}
},
{
"type": "Feature",
"properties": {
"id":"CN-23-Shanghai",
"title":"1",
},
"geometry": {
"type": "Point",
"coordinates": [121.3997,31.0456]
}
},
]}
In the project that I took this code, it works. The map contain 2 points in china : a "1" is displayed in Shanghai and a "2" in Guangzhou.
In my project I have an error :
Uncaught TypeError: Cannot read property 'a' of null
at xl (ol.js:266)
at wl (ol.js:265)
at Bl (ol.js:268)
at Al (ol.js:269)
at nr (ol.js:471)
at pr.mr.f (ol.js:470)
at td (ol.js:38)
at N (ol.js:37)
at Xq.q (ol.js:467)
As I said, I'm very new to web and I lost with that error. If try to check ol.js but it is unreadable. Maybe I'm missing a library or a package but I don't know how to know.

jqwidgets bind Model to Grid

I'm using ASP.NET MVC5 and i'm trying to bind my #Model to jqgrid. I already found samples with xml and json, but they're kinda old for me, because i'm using ActionResult to pass data to the view. The problem is that i don't know how to set my model to source of the grid. The #Model is 100% working since it's tested on another view with table.
I wont post any pictures of javascript error, because it's not showing anying that would be helpful. I'm sure that the only problem is mapping the #Model.Employees to the source variable in the View. Here is my code.
Model:
public class EmployeesTownsViewModel
{
public EmployeesTownsViewModel()
{
Towns = new List<SelectListItem>();
}
public List<Employee> Employees { get; set; }
public IList<SelectListItem> Towns { get; set; }
public int Id { get; set; }
public string EmployeeName { get; set; }
public int TownId { get; set; }
public string PhoneNumber { get; set; }
public string Identitycard_num { get; set; }
public string Address { get; set; }
}
Controller:
[HttpGet]
public ActionResult Worker()
{
var employee = new EmployeesTownsViewModel()
{
Employees = this.Data.Employees.All().Where(x => x.IsWorkerDeleted == false).ToList(),
Towns = this.Data.Towns.All().Select(x => new SelectListItem { Text = x.TownName, Value = x.Id.ToString() }).ToList()
};
employee.Towns.Insert(0, new SelectListItem() { Text = "---Choose---", Value = "0" });
return View(employee);
}
View:
#model LogisticsEngineeringLTD.ViewModels.Employees.EmployeesTownsViewModel
#{
ViewBag.Title = "Worker";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<!DOCTYPE html>
<html lang="en">
<head>
<title id='Description'>
This demo illustrates the basic functionality of the Grid plugin. The jQWidgets Grid plugin offers rich support for interacting with data, including paging, grouping and sorting.
</title>
<meta name="description" content="JavaScript Grid with rich support for Data Filtering, Paging, Editing, Sorting and Grouping" />
#*<link rel="stylesheet" href="~/Content/jqx.base.css" type="text/css" />*#
<script type="text/javascript">
$(document).ready(function () {
//How to set this variable 'source' to my Model properties
var source =
{
datatype: "array",
datafields: [
{ name: 'Id', type: 'number' },
{ name: 'EmployeeName', type: 'string' },
{ name: 'PhoneNumber', type: 'string' },
{ name: 'Address', type: 'string' },
{ name: 'TownId', type: 'number' },
{ name: 'Identitycard_num', type: 'string' },
],
localdata: #Model,
};
var dataAdapter = new $.jqx.dataAdapter(source);
var cellsrenderer = function (row, columnfield, value, defaulthtml, columnproperties, rowdata) {
if (value < 20) {
return '<span style="margin: 4px; float: ' + columnproperties.cellsalign + '; color: #ff0000;">' + value + '</span>';
}
else {
return '<span style="margin: 4px; float: ' + columnproperties.cellsalign + '; color: #008000;">' + value + '</span>';
}
}
// initialize jqxGrid
$("#jqxgrid").jqxGrid(
{
width: 850,
source: dataAdapter,
pageable: true,
autoheight: true,
sortable: true,
altrows: true,
enabletooltips: true,
editable: true,
selectionmode: 'multiplecellsadvanced',
columns: [
{ text: "Name", datafield: "EmployeeName" },
{ text: "Number", datafield: "PhoneNumber" },
{ text: "Address", datafield: "Address" },
{ text: "Town", datafield: "TownId" },
{ text: "Id Card Number", datafield: "Identitycard_num" }
],
columngroups: [
{ text: 'Product Details', align: 'center', name: 'ProductDetails' }
]
});
});
</script>
</head>
<body class='default'>
<div id='jqxWidget' style="font-size: 13px; font-family: Verdana; float: left;">
<div id="jqxgrid">
</div>
</div>
</body>
</html>
Thank you in advance ^^

Google Fusion Tables: Two layers, one with style

I'm trying to create a map using Google Fusion Tables with two layers, one of which I want to add a style to. I also have multiple columns, and I want to switch between these columns using a drop-down menu. So far I managed to do the latter, but I'm stuck trying to add a second layer.
The map I have now shows the ratio of girls:boys in schools in the 170 districts in Ghana. With the drop down menu I can switch between primary school and junior high. Now I want to add a layer with the regional borders.
In the documentation I saw this:
You can use the Maps API to add up to five Fusion Tables layers to a
map, one of which can be styled with up to five styling rules.
Which is pretty much exactly what I want, but I also keep the drop-down menu. I've recently started using Fusion Tables and was hoping someone could help me.
The ID of the layer I want to add: 1_0rcifQnnNpLV1VjTPyzDZSF3LHp-7rowzrXM78
And the code of the working map:
PS: I'm a total newbie and used this map made by the Guardian as a basis. I got rid of everything I didn't think I needed, but there might be some unnecessary stuff left in the code.
<!DOCTYPE html>
<html lang="en" itemscope itemtype="http://schema.org/Article">
<head>
<title>Gender Parity Index | Education | 2011</title>
<meta charset="utf-8" />
<style type="text/css">
body { font-family: Arial, sans-serif; }
#map_canvas { height: 600px; width:575px; }
</style>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" id="script">
var center = new google.maps.LatLng(7.972198, -0.716284);
var zoom = 7;
var legend_width = '150px';
var tableid = '12GLQaH4wvwByxBk4W7UHkJTr99vsxymCTYHmkXs';
var location_column = 'geometry';
var colors = ['#CA0020','#F4A582','#F7F7F7','#92C5DE','#0571B0'];
var columns = {
'Gender parity index at primary education': [
{
'min': 0.6,
'max': 0.8,
'color': '#CA0020'
},
{
'min': 0.8,
'max': 0.95,
'color': '#F4A582'
},
{
'min': 0.95,
'max': 1.05,
'color': '#F7F7F7'
},
{
'min': 1.05,
'max': 1.2,
'color': '#92C5DE'
}
],
'Gender parity index at junior high school education': [
{
'min': 0.6,
'max': 0.8,
'color': '#CA0020'
},
{
'min': 0.8,
'max': 0.95,
'color': '#F4A582'
},
{
'min': 0.95,
'max': 1.05,
'color': '#F7F7F7'
},
{
'min': 1.05,
'max': 1.2,
'color': '#92C5DE'
},
{
'min': 1.2,
'max': 1.6,
'color': '#0571B0'
}
]
}
var map, layer, geocoder;
function initialize() {
map = new google.maps.Map(document.getElementById('map_canvas'), {
center: center,
zoom: zoom,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var style = [ { stylers: [ { invert_lightness: true } ] },{ featureType: "road.highway", stylers: [ { hue: "#00e5ff" } ] },{ featureType: "poi.park", stylers: [ { visibility: "off" } ] },{ featureType: "landscape.natural", stylers: [ { visibility: "on" } ] },{ featureType: "water", stylers: [ { color: "#080808" } ] },{ featureType: "landscape.natural", stylers: [ { color: "#202020" } ] },{ featureType: "administrative.province", elementType: "labels", stylers: [ { visibility: "on" } ] },{ featureType: "administrative.locality", elementType: "labels", stylers: [ { visibility: "on" } ] },{ featureType: "administrative.country", elementType: "labels", stylers: [ { visibility: "off" } ] },{
featureType: 'road',
elementType: 'all',
stylers: [
{ saturation: -99 }
]
} ];
geocoder = new google.maps.Geocoder();
var styledMapType = new google.maps.StyledMapType(style, {
map: map,
name: 'Styled Map'
});
map.mapTypes.set('map-style', styledMapType);
map.setMapTypeId('map-style');
layer = new google.maps.FusionTablesLayer({
query: {
select: location_column,
from: tableid
}
});
layer.setMap(map);
init_selectmenu();
addStyle(getKey());
}
function getKey() {
for(key in columns) {
return key;
}
}
// Initialize the drop-down menu
function init_selectmenu() {
var selectmenu = document.getElementById('selector');
for(column in columns) {
var option = document.createElement('option');
option.setAttribute('value', column);
option.innerHTML = column;
selectmenu.appendChild(option);
}
}
function addStyle(column) {
var defined_styles = columns[column];
var styles = new Array();
for(defined_style in defined_styles) {
var style = defined_styles[defined_style];
styles.push({
where: generateWhere(column, style.min, style.max),
polygonOptions: {
fillColor: style.color,
fillOpacity: 0.9,
strokeOpacity: 0.50,
strokeColor: "#f3f3f3"
}
});
}
layer.set('styles', styles);
updateLegend(column);
}
// Create the where clause
function generateWhere(column_name, low, high) {
var whereClause = new Array();
whereClause.push("'");
whereClause.push(column_name);
whereClause.push("' >= ");
whereClause.push(low);
whereClause.push(" AND '");
whereClause.push(column_name);
whereClause.push("' < ");
whereClause.push(high);
return whereClause.join('');
}
// Create the legend with the corresponding colors
function updateLegend(column) {
var legendDiv = document.createElement('div');
var legend = new Legend(legendDiv, column);
legendDiv.index = 1;
map.controls[google.maps.ControlPosition.RIGHT_TOP].pop();
map.controls[google.maps.ControlPosition.RIGHT_TOP].push(legendDiv);
}
// Generate the content for the legend
function Legend(controlDiv, column) {
controlDiv.style.padding = '10px';
var controlUI = document.createElement('div');
controlUI.style.backgroundColor = 'white';
controlUI.style.borderStyle = 'solid';
controlUI.style.borderWidth = '1px';
controlUI.style.width = legend_width;
controlUI.title = 'Legend';
controlDiv.appendChild(controlUI);
var controlText = document.createElement('div');
controlText.style.fontFamily = 'Arial,sans-serif';
controlText.style.fontSize = '12px';
controlText.style.paddingLeft = '4px';
controlText.style.paddingRight = '4px';
controlText.innerHTML = legendContent(column);
controlUI.appendChild(controlText);
}
function legendContent(column) {
var defined_styles = columns[column];
// Generate the content for the legend using colors from object
var controlTextList = new Array();
controlTextList.push('<p><b>');
controlTextList.push(column);
controlTextList.push('</b></p>');
for(defined_style in defined_styles) {
var style = defined_styles[defined_style];
controlTextList.push('<div style="background-color: ');
controlTextList.push(style.color);
controlTextList.push('; height: 20px; width: 20px; margin: 3px; float: left;"></div>');
controlTextList.push(style.min);
controlTextList.push(' to ');
controlTextList.push(style.max);
controlTextList.push('<br style="clear: both;"/>');
}
controlTextList.push('<br />');
return controlTextList.join('');
}
</script>
</head>
<body onload="initialize();">
<select onchange="addStyle(this.value);" id="selector" style="font-size: 16px"></select>
<div id="map_canvas"></div>
</div>
<script>
// send the query string to the iFrame
(function() {
var interactive = jQ('#interactive iframe');
if (interactive.length > 0) {
var qs = window.location.search;
interactive[0].src = interactive[0].src + qs;
}
})();
</script>
</div>
<div id="related">
</script>
</script>
</body>
</html>
Just add the second layer at the end of your initialize() method like that:
function initialize() {
// ... all the other stuff ...
borderLayer = new google.maps.FusionTablesLayer({
query: {
select: 'geometry',
from: '1_0rcifQnnNpLV1VjTPyzDZSF3LHp-7rowzrXM78'
}
});
borderLayer.setMap(map);
}
See the working example of your code with the second layer on jsFiddle.

Resources