featureId filtering in wfs openlayers - filtering

I want to define a featureId fiter for wfs layer like below:
wfs = new OpenLayers.Layer.Vector("WFS Vectore", {
strategies: [new OpenLayers.Strategy.BBOX(), saveStrategy],
projection: new OpenLayers.Projection("EPSG:4326"),
protocol: new OpenLayers.Protocol.WFS({
version: "1.1.0",
srsName: "EPSG:4326",
url: "http://localhost:8080/geoserver/iran/wms?service=WFS",
featureType: "population",
featureNS: "http://iran.kadaster.org",
geometryName: "the_geom"
}),
filter:
new OpenLayers.Filter.FeatureId({
fids: ['population.913', 'population.912']
//type: ?????
})
});
I don't know to what set 'type' variable in filtering option?

There is no 'type' property on filter type FeatureId.
API doc
This is enough.
filter:new OpenLayers.Filter.FeatureId({
fids: ['population.913', 'population.912'];
});

The problem was set fids field. When you set fids to ['population.913', 'population.912'], this means a feature that it's fids equal to 'population.913' and 'population.912'. If you set fids field to 'population.912' or 'population.913' you get correct response

Related

Use PostgreSQL data in ag-Grid

I'm new to Javascript (and web development in general) and want to display data from a PostgreSQL server on a web page using ag-Grid. I've followed some tutorials and I have successfully pulled data from postgreSQL, and successfully displayed some sample data using ag-Grid. Now I'm trying to combine the two, and I can't figure it out.
I've created a 'database.js' which pulls the data from PostgreSQL - it's modified from this tutorial (LINK):
database.js:
const {Client} = require("pg");
const client = new Client ({
host: "<IPaddress>",
user: "<username>",
port: 5432,
password: "<password>",
database: "postgres"
})
client.connect();
var Query = function(){
client.query( `select * from test1`, (err, res) => {
callback (err, res)
client.end;
})
return {
Query1: Query
}
}();
module.exports = Query;
Then in main.js I have the following which has come from ag-grid tutorials:
main.js:
var QueryResults = require('database');
var columnDefs = [
{headerName: 'Make', field: 'make', sortable: true, filter: true},
{headerName: 'Model', field: 'model', sortable: true, filter: true},
{headerName: 'Price', field: 'price', sortable: true, filter: true}
];
var gridOptions = {
columnDefs: columnDefs,
rowModelType: 'infinite',
datasource: datasource,
};
var eGridDiv = document.querySelector('#myGrid');
new agGrid.Grid(eGridDiv, gridOptions);
There are a few concerns that I have:
Is my method of referencing my query results in database.js correct.?
Is my data structure compatible?
Any advice would be greatly appreciated.
You need to understand that in this sort of application, there are two separate places where code is executed.
On the "server", e.g. the computer where the database is running, or another computer that connects to it, there is an application that that is doing operations including querying the database, and providing the web application code to the user's web browser. This is also commonly referred to as "the backend".
On the "client" (the user's web browser), commonly referred to as "the frontend", the web application will get data from the backend via HTTP/S ("API calls").
In the sample code that you provided,the functionality in database.js belongs on the backend (on the server), and the code that you have in main.js belongs on the frontend (in the user's web browser).

How to reload Loki database and collection from persistence

[UPDATE] I laterly found out some example which is like:
this.db = new Loki("viewsaving", {
autosave: true,
autosaveInterval: 5000,
autoload: true,
autoloadCallback: function(){
db_ready = true;
if(db.getCollection("namedviews") == null ){
this.namedviews = db.addCollection("namedviews");
}
if(db.getCollection("timedviews") == null ){
this.timedviews = db.addCollection("timedviews");
}
}
});
It basically works on my side. so I just use it, not sure if this is correct or not, please advise.
All:
I am pretty new to Lokijs, I wonder how can I reload the database and collection which has been persisted?
Say that I build a database and collection, then I persist it( like click a button to trigger persistence process):
var db = new Loki("mydb");
var users = db.addCollection('users');
// we bind this to a button click event
function saveUser(){
users.insert({
name: 'joe'
});
users.insert({
name: 'john'
});
users.insert({
name: 'jack'
});
db.saveDatabase();
}
Then when I refresh this page, how can I load "mydb" and "users" from persistence rather than create new one( cos it will go thru var db = new Loki("mydb"); again ), is there API to check if a database exists?
const db = new loki('example.json', {
env: 'BROWSER',
autosave: true,
autosaveInterval: 500,
autoload: true })
You need to assign the 'env' property to 'BROWSER'
As far as I can tell its not possible to persist to a clientside DB as its difficult and generally insecure for the browser to have access to the local file system. Lokijs supports persistence within the browser's local storage. Loki uses an adapter to implement persistence to the browsers local storage, this adapter defaults to 'localStorage adapter.
var db = new Loki("test.db", {
autoload: true,
autoloadCallback : databaseInitialize,
autosave: true,
autosaveInterval: 4000,
//adapter: 'default already set'
});
For more details see https://rawgit.com/techfort/LokiJS/master/jsdoc/tutorial-Persistence%20Adapters.html

OData Jaydata - odata update request returns error 404 (SAPUI5, node)

I'm building a web application with SAPUI5 which makes available a list of services, that are stored in a MongoDB and available as OData.
I followed this guide jaydata-install-your-own-odata-server-with-nodejs-and-mongodb and these are my model.js:
$data.Class.define("marketplace.Service", $data.Entity, null, {
Id: {type: "id", key: true, computed: true, nullable: false},
Name: {type: "string", nullable: false, maxLength: 50},
}, null);
$data.Class.defineEx("marketplace.Context", [$data.EntityContext, $data.ServiceBase], null, {
Services: {type: $data.EntitySet, elementType: marketplace.Service}
});
exports = marketplace.Context;
and server.js:
var c = require('express');
require('jaydata');
window.DOMParser = require('xmldom').DOMParser;
require('q');
require('./model.js');
var app = c();
app.use(c.query());
app.use(c.bodyParser());
app.use(c.cookieParser());
app.use(c.methodOverride());
app.configure(function() {app.use(app.router);});
app.use(c.session({secret: 'session key'}));
app.use("/marketplace", $data.JayService.OData.Utils.simpleBodyReader());
app.use("/marketplace", $data.JayService.createAdapter(marketplace.Context, function (req, res) {
return new marketplace.Context({
name: "mongoDB",
databaseName: "marketplace",
address: "localhost",
port: 27017
});
}));
app.use("/", c.static(__dirname));
app.use(c.errorHandler());
app.listen(8080);
The client is developed by using SAPUI5 and these are the parts of the code relative to the odata model creation:
oModel = sap.ui.model.odata.ODataModel("http://localhost:8080/marketplace", false); // connection to the odata endpoint
oModel.setDefaultBindingMode(sap.ui.model.BindingMode.TwoWay);
sap.ui.getCore().setModel(oModel);
The various services are correctly showed in a SAPUI5 table and I'm easily able to insert a new service by using the POST OData.request in this way:
OData.request({
requestUri: "http://localhost:8080/marketplace/Services",
method: "POST",
data: newEntry // json object with the new entry
},
function(insertedItem) {
// success notifier
},
function(err) {
// error notifier
}
);
and delete a service by using the SAPUI5 function oModel.remove() in this way (oParams is a json object which contains the alert notification functions):
var serviceId = oTable.getRows()[selectedIndex].getCells()[0].getText();
oModel.remove("/Services('" + serviceId + "')", oParams);
Everything works fine but the update request for a single service. I've tried with the functions provided by SAPUI5 (oModel.update or oModel.submitChanges), by using OData.request ("method: PUT"), by creating an ajax PUT request, I also tried to craft PUT request with Fiddler.
I always get error 404:
Request URL:http://localhost:8080/marketplace/Services('NTMzZDM3M2JlNjY2YjY3ODIwZjlmOTQ0')
Request Method:PUT
Status Code:404 Not Found
Where can be the problem?
I tried with Chrome, IE, and Firefox; same problem...
Thanks
Try to update with MERGE verb and pass the modified fields in JSON format inside the BODY

How to use ExtJS plugin 'Row Expander' with a MODx grid

I'm building an extra for MODx Revolution 2.2.x which uses ExtJS 3.4 as the front end. I have a grid that I need to use the "Row Expander" ExtJS plugin with, but I'm not sure how to translate the provided example http://dev.sencha.com/deploy/ext-3.4.0/examples/grid/grid-plugins.html (It's the first example grid) into MODExt syntax.
My main issue I think is the example is using a local store and is not using class templates like MODx does.
Here's the basic example grid I'm attempting to add the plug-in to:
Example.grid.Artworks = function(config) {
config = config || {};
Ext.applyIf(config,{
id: 'example-grid-artworks'
,url: Example.config.connectorUrl
,baseParams: { action: 'mgr/example/getListArtworks' }
,fields: ['id','name','description','menu']
,paging: true
,pageSize: 5
,remoteSort: true
,autoExpandColumn: 'description'
,columns: [{
header: _('id')
,dataIndex: 'id'
},{
header: _('example.artwork_name')
,dataIndex: 'name'
},{
header: _('example.artwork_desc')
,dataIndex: 'name'
}]
});
Example.grid.Artworks.superclass.constructor.call(this,config)
}
Ext.extend(Example.grid.Artworks,MODx.grid.Grid);
Ext.reg('example-grid-artworks',Example.grid.Artworks);
Any insight as to how to incorporate the plugin with MODx's connectorUrl and the baseParams would be greatly appreciated.
Thanks in advance.
Ok I managed to work it out. I'll leave this here if anyone else faces the same issue.
Example.grid.Artworks = function(config) {
config = config || {};
// ---- This gets added here ------
this.exp = new Ext.grid.RowExpander({
tpl : new Ext.Template(
'<p>{expandedcontent}</p>'
)
});
Ext.applyIf(config,{
id: 'example-grid-artworks'
,url: Example.config.connectorUrl
,baseParams: { action: 'mgr/example/getListArtworks' }
// added the expanded content field here.
,fields: ['id','name','description','expandedcontent','menu']
,paging: true
,pageSize: 5
,remoteSort: true
,autoExpandColumn: 'description'
,plugins: [this.exp] // <---- add this here
,columns: [this.exp,{ // <----- add this here
header: _('id')
,dataIndex: 'id'
},{
header: _('example.artwork_name')
,dataIndex: 'name'
},{
header: _('example.artwork_desc')
,dataIndex: 'name'
}]
});
Example.grid.Artworks.superclass.constructor.call(this,config)
}
Ext.extend(Example.grid.Artworks,MODx.grid.Grid);
Ext.reg('example-grid-artworks',Example.grid.Artworks);

Sencha ExtJS RESTful grid example confusion

I am very confused by the Sencha documentation for ExtJS. The documentation begins with a Getting Started guide which highlights and illustrates the importance on a suitable structure for the classes and source code of your application. But the provided examples then break all the conventions laid down by the Getting Started guide. Instead of code being broken down into appropriate Model, Store, View, etc. class files the examples are provided as a single file with example source code which is not easily re-usable in separate source files.
I started by following the Portal example (http://docs.sencha.com/ext-js/4-1/#!/example/portal/portal.html) as this is the sort of application I want to create. I wanted to enhance the Portal example and add in a screen which would display a grid and use a RESTful web service as the data backend. I have created the backend I just want to create the front-end. So I looked at the RESTful example (http://docs.sencha.com/ext-js/4-1/#!/example/restful/restful.html)
I have tried to copy the RESTful example into the recommended pattern of seperate classes e.g. Model, Store, View:
Model:
Ext.define('MyLodge.model.Member', {
extend: 'Ext.data.Model',
fields: [
{name: 'name', type: 'string'},
{name: 'email', type: 'string'},
{name: 'href', type: 'string'}
]
});
Store:
Ext.require('MyLodge.model.Member');
Ext.define('MyLodge.store.Members', {
autoLoad: true,
autoSync: true,
model: 'MyLodge.model.Member',
proxy: {
type: 'rest',
url: 'http://localhost:8888/rest/memberapi/members' ,
reader: {
type: 'json',
root: 'data'
},
writer: {
type: 'json'
}
},
listeners: {
write: function(store, operation){
var record = operation.getRecords()[0],
name = Ext.String.capitalize(operation.action),
verb;
if (name == 'Destroy' ) {
record = operation.records[0];
verb = 'Destroyed';
} else {
verb = name + 'd';
}
Ext.example.msg(name, Ext.String.format( "{0} member: {1}", verb, record.getId()));
}
}
});
View:
Ext.define('MyLodge.view.content.MemberGrid', {
extend: 'Ext.grid.Panel',
alias: 'widget.membergrid',
initComponent: function(){
var store = Ext.create('MyLodge.store.Members' );
Ext.apply( this, {
height: this.height,
store: store,
stripeRows: true,
columnLines: true,
columns: [{
id : 'name',
text : 'Name',
flex: 1,
sortable : true,
dataIndex: 'name'
},{
text : 'E-Mail',
width : 150,
sortable : true,
dataIndex: 'email'
},{
text : 'Href',
width : 200,
sortable : true,
dataIndex: 'href'
}],
dockedItems: [{
xtype: 'toolbar',
items: [{
text: 'Add',
iconCls: 'icon-add',
handler: function(){
// empty record
store.insert(0, new MyLodge.model.Member());
rowEditing.startEdit(0, 0);
}
}, '-', {
itemId: 'delete',
text: 'Delete',
iconCls: 'icon-delete',
disabled: true,
handler: function(){
var selection = grid.getView().getSelectionModel().getSelection()[0];
if (selection) {
store.remove(selection);
}
}
}]
}]
});
this.callParent(arguments);
}
});
But I am not sure where to put the code to control the grid row selection and enable the Delete button:
grid.getSelectionModel().on('selectionchange', function(selModel, selections){
grid.down('#delete').setDisabled(selections.length === 0);
});
Also when I press the Add button I get the following error:
Uncaught TypeError: Object [object Object] has no method 'insert'.
Any help would be appreciated.
You are having scoping issues. Basically the variable store is defined only in the initComponent function and therefore of local function scope.
Your handler function has it's own scope. It is firing in the scope of the toolbar button. So if you say this in the handler it would refer to the button. Hence you can say this.up('panel').store - and that gives you the correct reference to the store backing your grid panel.
Another advice is not to implement everything at once. Write a little bit to see if it works and then add to it little by little.
RE: the docs examples, I agree that it's frustrating, but there's not many options. Having a fully-MVC-style implementation of each example would not only be onerous to produce, but would also probably make point of the example get lost in the structure.
RE: your question about the where to "put" the code to control the grid, I would recommend setting up a controller with listeners for the events on the grid in the control() section. This will let you decouple the handling of the events that are fired by your grid from the view itself.