Adding html item to infoWindow - ArcGIS Javascript API 3.18 - javascript

This question regarding a web app built using the ArcGIS Javascript API 3.18. I am trying to add an dojo select to the title of an infoWindow. The select box is intended to be populated with the list of identified results. I'm trying two different ways:
1) Adding the combobox declaratively using html:
var template = new esri.InfoTemplate(layerName + "<br/><select id="id_select" data-dojo-type="dijit/form/Select"</select>,"<br/> FID : ${FID}");
The combobox is there, but I don't know how to access the combobox to add the options dynamically (via addOptions). I would normally do dijit.byId("id_select"), but considering it doesn't exist until it's created...I'm not sure how to go about this way.
2) Programmatically
With the code below, the title displays information regarding the dijit/form/select widget (It displays: [object HTML TableElement]), but not the widget itself. Wondering if this can be rectified using dijitStartup(), but I can't haven't figured out how to use it (currently trying something along the lines of myTemplate.startupDijits(mySelectBox)--not with these variable names). I tried using domConstruct like this example
var identifyTask, identifyParams, idPoint;
var identifyResults;
require([
"esri/dijit/Popup",
"esri/tasks/IdentifyTask",
"esri/tasks/IdentifyParameters",
"dijit/form/Select",
"dojo/dom-construct",
"dojo/promise/all",
"dojo/domReady!"
], function (
Popup, IdentifyTask, IdentifyParameters, Select, domConstruct, All
) {
var identifySelect;
//dojo.connect(window.myMap, "onLoad", mapReady);
mapReady(window.myMap);
function mapReady(map) {
dojo.connect(window.myMap, "onClick", runIdentifies);
}
function runIdentifies(evt) {
identifyResults = [];
idPoint = evt.mapPoint;
var layers = dojo.map(window.myMap.layerIds, function (layerId) {
return window.myMap.getLayer(layerId);
});
layers = dojo.filter(layers, function (layer) {
if (layer.visibleLayers[0] !== -1) {
return layer.getImageUrl && layer.visible
}
}); //Only dynamic layers have the getImageUrl function. Filter so you only query visible dynamic layers
var tasks = dojo.map(layers, function (layer) {
return new IdentifyTask(layer.url);
}); //map each visible dynamic layer to a new identify task, using the layer url
var defTasks = dojo.map(tasks, function (task) {
return new dojo.Deferred();
}); //map each identify task to a new dojo.Deferred
var params = createIdentifyParams(layers, evt);
var promises = [];
for (i = 0; i < tasks.length; i++) {
promises.push(tasks[i].execute(params[i])); //Execute each task
}
var allPromises = new All(promises);
allPromises.then(function (r) { showIdentifyResults(r, tasks); });
}
function showIdentifyResults(r, tasks) {
var results = [];
var taskUrls = [];
var resultNames = [];
r = dojo.filter(r, function (result) {
return r[0];
});
for (i = 0; i < r.length; i++) {
results = results.concat(r[i]);
for (j = 0; j < r[i].length; j++) {
taskUrls = taskUrls.concat(tasks[i].url);
}
}
results = dojo.map(results, function (result, index) {
var feature = result.feature;
var layerName = result.layerName;
var serviceUrl = taskUrls[index];
resultNames.push({
value: result.layerName,
label: result.layerName
});
feature.attributes.layerName = result.layerName;
var identifiedList = getIdentifiedList(resultNames);
console.log(identifiedList);
var template = new esri.InfoTemplate();
template.setTitle(identifiedList);
feature.setInfoTemplate(template);
var resultGeometry = feature.geometry;
var resultType = resultGeometry.type;
return feature;
});
if (results.length === 0) {
window.myMap.infoWindow.clearFeatures();
} else {
window.myMap.infoWindow.setFeatures(results);
}
window.myMap.infoWindow.show(idPoint);
identifySelect.on('change', function(evt) {
var identIndex = identifySelect.get("value");
console.log(identIndex);
window.myMap.infoWindow.select(identIndex);
});
return results;
}
function getIdentifiedList(options) {
identifySelect = new Select({
name: "identifySelect",
id: "id_select",
options: options
}, domConstruct.create("select"));
return identifySelect.domNode;
}
function createIdentifyParams(layers, evt) {
var identifyParamsList = [];
identifyParamsList.length = 0;
dojo.forEach(layers, function (layer) {
var idParams = new esri.tasks.IdentifyParameters();
idParams.width = window.myMap.width;
idParams.height = window.myMap.height;
idParams.geometry = evt.mapPoint;
idParams.mapExtent = window.myMap.extent;
idParams.layerOption = esri.tasks.IdentifyParameters.LAYER_OPTION_VISIBLE;
var visLayers = layer.visibleLayers;
if (visLayers !== -1) {
var subLayers = [];
for (var i = 0; i < layer.layerInfos.length; i++) {
if (layer.layerInfos[i].subLayerIds == null)
subLayers.push(layer.layerInfos[i].id);
}
idParams.layerIds = subLayers;
} else {
idParams.layerIds = [];
}
idParams.tolerance = 5;
idParams.returnGeometry = true;
identifyParamsList.push(idParams);
});
return identifyParamsList;
}
});

Hi this is kinda old but i'll give it a shot. I hope this answers your question.
So if the problem is accessing the infoWindow what you need to do is set up a listener for when it is created.
on(map.infoWindow, "show", function () {
// do something
})
I have a fiddle that shows how to access infoWindow upon creation:
https://jsfiddle.net/kreza/jpLj5y4h/

Related

Modify payment lines pos odoo 8

someone have any idea how i should modify the payment-lines in the POS,I want to add a type of credit card(like a many2one, I did it) but every time I add a line my option change to the first and also when the order is finished not save the value in pos.order -> statement_id.
enter image description here
here is my code:
function POS_CashRegister (instance, local) {
var pos = instance.point_of_sale;
var _t = instance.web._t;
var QWeb = instance.web.qweb;
var round_pr = instance.web.round_precision
const ParentOrder = pos.Order;
pos.PosModel.prototype.models.push({ //loaded model
model: 'pos.credit.card',
fields: ['id', 'name'],
domain: [['pos_active','=',true]],
loaded: function(self,credit_cards){ //pass parameters
self.credit_cards = credit_cards;
},
});
pos.PaymentScreenWidget = pos.PaymentScreenWidget.extend({
validate_order: function(options) {
var self = this;
var currentOrder = self.pos.get('selectedOrder');
var plines = currentOrder.get('paymentLines').models;
for (var i = 0; i < plines.length; i++) {
if(plines[i].cashregister.journal_id[1] === 'Tarjeta de Credito (PEN)')
{
var value = plines[i].node.firstElementChild.nextElementSibling.nextElementSibling.firstElementChild.value;
plines[i].set_credit_card(parseInt(value));
//console.log(plines[i].node.firstElementChild.nextElementSibling.nextElementSibling.firstElementChild.value);
//plines[i].node
}
}
console.log(currentOrder);
self._super(options);
},
render_paymentline: function (line) {
var self = this;
if(line.cashregister.journal_id[1] !== 'Tarjeta de Credito (PEN)'){
if (line.cashregister.currency[1] !== 'USD') {
return this._super(line);
} else {
var el_html = openerp.qweb.render('Paymentline', {widget: this, line: line});
el_html = _.str.trim(el_html);
var el_node = document.createElement('tbody');
el_node.innerHTML = el_html;
el_node = el_node.childNodes[0];
el_node.line = line;
el_node.querySelector('.paymentline-delete')
.addEventListener('click', this.line_delete_handler);
el_node.addEventListener('click', this.line_click_handler);
var sourceInput = el_node.querySelector('.source-input');
var convertedInput = el_node.querySelector('.converted-input');
sourceInput.addEventListener('keyup', function (event) {
el_node.line.set_usd_amount(event.target.value);
convertedInput.value = el_node.line.get_amount_str();
});
line.node = el_node;
return el_node;
}
}else {
return this._super(line);
}
},
});
pos.Paymentline = pos.Paymentline.extend({
initialize: function(attributes, options) {
this.amount = 0;
this.cashregister = options.cashregister;
this.name = this.cashregister.journal_id[1];
this.selected = false;
this.credit_card = false;
this.pos = options.pos;
},
set_credit_card: function(value){
this.credit_card = value;
this.trigger('change:credit_card',this);
},
get_credit_card: function(){
return this.credit_card;
},
export_as_JSON: function(){
return {
name: instance.web.datetime_to_str(new Date()),
statement_id: this.cashregister.id,
account_id: this.cashregister.account_id[0],
journal_id: this.cashregister.journal_id[0],
amount: this.get_amount(),
credit_card_id: this.get_credit_card(),
};
},
});
}
any suggestions?
You can create 2 journals here too. One for visa and another for master If you don't want that drop down there. Another way is you have to store selected option in a variable and then print that variable in front.
To store selected option initially assigned ids to each values of option and after then while validating order you can get that id of that field and from that id you can get your value. By this way also you can do that.

Filtering an array of Objects in javascript

I'm really new to JS, and I'm now stuck on a task, hope someone can guide me through it.
I have an Array of Objects, like this one:
var labels = [
// labels for pag 1
{pageID:1, labels: [
{labelID:0, content:[{lang:'eng', text:'Txt1 Eng'}, {lang:'de', text:'Txt1 De:'}]},
{labelID:1, content:[{lang:'eng', text:'Txt 2 Eng:'}, {lang:'de', text:'Txt2 De:'}]},
{labelID:2, content:[{lang:'eng', text:'Txt 3 Eng:'},{lang:'de', text:'Txt 3 De:'}]}
]},
// labels for pag 2
{pageID:2, labels: [
{labelID:0, content:[{lang:'eng', text:'Txt1 Eng'}, {lang:'de', text:'Txt1 De:'}]},
{labelID:1, content:[{lang:'eng', text:'Txt 2 Eng:'}, {lang:'de', text:'Txt2 De:'}]},
{labelID:2, content:[{lang:'eng', text:'Txt 3 Eng:'},{lang:'de', text:'Txt 3 De:'}]}
]}
]
What I am trying to do is write a function to return me an array of labels (Objects) for a specific page and a specific lang. By calling this function specifying pageID 1 and lang eng, I'm basically trying to build an array like this one:
var desideredArray = [
{labelID:0, text:'Txt1 Eng'},
{labelID:1, text:'Txt1 Eng'},
{labelID:2, text:'Txt2 Eng'}
]
Now, I'm trying to write the function to retrieve/build the new array:
this.getLabelsForPageAndLang = function (numPage, lang) {
// this part filters the main object and selects the object with pageID == numPage
var result = labels.filter(function( obj ) {
return obj.pageID == numPage;
});
var tempResult = result[0].labels;
var desiredResults = []; // here I want to store the new objects
for (var i=0; i<tempResult.length; i++) {
var simpleLabelObject = {};
simpleLabelObject.labelID = tempResult[i].labelID;
// simpleLabelObject.text = ?????
results[i] = simpleLabelObject;
}
console.log (results);
};
...but how can I access the right value (the one corresponding the lang selected) in the content property?
You can use the same technique as the one used to keep the matching page: the filter method.
this.getLabelsForPageAndLang = function (numPage, lang) {
// this part filters the main object and selects the object with pageID == numPage
var result = labels.filter(function( obj ) {
return obj.pageID == numPage;
});
var contentFilter = function(obj){ return obj.lang === lang};
var tempResult = result[0].labels;
var desiredResults = []; // here I want to store the new objects
for (var i=0; i<tempResult.length; i++) {
var simpleLabelObject = {};
simpleLabelObject.labelID = tempResult[i].labelID;
var matching = tempResult[i].content.filter(contentFilter);
simpleLabelObject.text = matching[0].text;
desiredResults[i] = simpleLabelObject;
}
console.log (desiredResults);
};
I didn't do bound checks because in your code you assumed there is always a matching element, but it would probably be wise to do it.
And if you want to avoid creating two closures each time the function is called, you can prototype an object for that:
var Filter = function(numPage, lang) {
this.numPage = numPage;
this.lang = lang;
};
Filter.prototype.filterPage = function(obj) {
return obj.pageID === this.numPage;
}
Filter.prototype.filterLang = function(obj) {
return obj.lang === this.lang;
}
Filter.prototype.filterLabels = function(labels) {
var result = labels.filter(this.filterPage, this);
var tempResult = result[0].labels;
var desiredResults = []; // here I want to store the new objects
for (var i=0; i<tempResult.length; i++) {
var simpleLabelObject = {};
simpleLabelObject.labelID = tempResult[i].labelID;
var matching = tempResult[i].content.filter(this.filterLang, this);
simpleLabelObject.text = matching[0].text;
desiredResults[i] = simpleLabelObject;
}
return desiredResults;
}
console.log(new Filter(1, "eng").filterLabels(labels));
Just filter again:
var getLabelsForPageAndLang = function (numPage, lang) {
// this part filters the main object and selects the object with pageID == numPage
var result = labels.filter(function (obj) {
return obj.pageID == numPage;
});
var tempResult = result[0].labels;
var desiredResults = []; // here I want to store the new objects
for (var i = 0; i < tempResult.length; i++) {
var simpleLabelObject = {};
simpleLabelObject.labelID = tempResult[i].labelID;
var lg = tempResult[i].content.filter(function (lg) {
return lg.lang == lang;
});
simpleLabelObject.text = lg[0].text;
desiredResults.push(simpleLabelObject);
}
console.log(desiredResults);
};
http://jsfiddle.net/9q5zF/
A rather 'safe' implementation for cases when pages have the same pageID and multiple contents with the same lang:
this.getLabelsForPageAndLang = function(numPage, lang) {
var result = [];
var pages = labels.filter(function( obj ) {
return obj.pageID === numPage;
});
for (var p = pages.length - 1; p >= 0; p--) {
var page = pages[p];
for(var i = page.labels.length - 1; i >= 0; i--) {
var labelId = page.labels[i].labelID;
for (var j = page.labels[i].content.length - 1; j >= 0; j--){
if (page.labels[i].content[j].lang === lang) {
result.push({labelID: labelId, test: page.labels[i].content[j].text});
}
}
}
}
console.log(result);
}
Fiddle: http://jsfiddle.net/6VQUm/

Trouble using Leafletjs MarkerClusterGroup and filters with Mapbox

I've tried Mapbox and their API to create an interactive map. The purpose is to fetch points in a geojson file, and display them on the map.
They have to be filtered by their marker-icon and grouped depending on the zoom applied.
I had no trouble using the MarkerClusterGroup plugin with leaflet and Mapbox, but I can't get the filters to work.
This is my code :
https://gist.github.com/KuneStudio/5985864
And this is the content of my json with the points :
https://gist.github.com/KuneStudio/5985858
The markers are displaying correctly, the cluster part too, but I can't get the filters to work...
Any idea?
Thanks !
(Note : using the console, I tried to display a log in the map.markerLayer.setFilter(function(f) {} , before the return true, but I have nothing showing up.
Thanks again for your time
I found the solution with some help. This is the method I used :
<script type='text/javascript'>
// I suppose that the json is saved in the var dataJSON
L.MarkerClusterGroup.include({
fromGeoJSON: function (geojson) {
this._geojson = geojson;
this.filter();
},
filter: function (f) {
f = f || function (m) { return true; }
var markers = Array();
for (var i = 0; i < this._geojson.features.length; i++) {
var a = this._geojson.features[i];
if (!f(a)) { continue; }
var title = a.properties['title'];
var description = a.properties['description']
var marker = L.marker(new L.LatLng(a.geometry.coordinates[1], a.geometry.coordinates[0]), {
icon: L.mapbox.marker.icon({'marker-symbol': a.properties['marker-symbol'], 'marker-color': a.properties['marker-color']}),
title: title
});
marker.bindPopup('<b>'+title+'</b><br>'+description);
markers.push(marker);
}
this.clearLayers();
this.addLayers(markers);
}
});
var map = L.mapbox.map('map', 'mymapid', {markerLayer: false});
map.on('error', function (e) {
console.log(e);
})
var cluster = new L.MarkerClusterGroup();
map.addLayer(cluster);
cluster.fromGeoJSON(dataJSON);
map.addLayer(cluster);
var filter = L.DomUtil.get('filter');
var food = L.DomUtil.get('filter-food');
var test = L.DomUtil.get('filter-test');
var all = L.DomUtil.get('filter-all');
jQuery('.chktax').on('click', function(e) {
var allChecked = {};
var cat = [];
jQuery(".chktax:checked").each(function(i, elem){
var name = elem.name;
allChecked[name] = allChecked[name] || [];
cat = cat || []
allChecked[name].push(elem.value);
cat.push(elem.value);
});
cluster.filter(function (m) {
return superbag(m.properties['categories'], cat);
});
});
L.DomEvent.on(all, 'click', function (e) {
cluster.filter();
})
function superbag(sup, sub) {
sup.sort();
sub.sort();
var i, j;
for (i=0,j=0; i<sup.length && j<sub.length;) {
if (sup[i] < sub[j]) {
++i;
} else if (sup[i] == sub[j]) {
++i; ++j;
} else {
return false;
}
}
return j == sub.length;
}
</script>

Save values into an array from a function which is called consecutively

I have a function which is called when a file is needed to be read in a folder. In this case since i have 3 files in that folder, it is called 3 times consecutively. I need to save all files info into array mapped_data2 like that:
mapped_data2[0] = inner_data1 //first file info,
mapped_data2[1] = inner_data2 //second file info etc.
However using my code i am having just the first files information 3 times. I am a bit confused with global variables, if you can point out the problem, i would appreciate it.
here is the code:
var mapped_data = [];
var mapped_data2 = [];
function o(msg) {
if (msg.data) {
var inner_data = [];
var lines = msg.data.split('\n'); //read lines of a file
for (var i = 2; i < lines.length; i++) {
if (lines[i].length > 0) {
.. //do same data format here
inner_data.push([son, vactual, voutput]);
}
}
mapped_data = inner_data;
}
else {
if (msg.topic == "/somefolder/somefolder") {
for (var i = 0; i < msg.args.length; i++) {
var filename = msg.args[i];
aw.get(filename);
}
}
}
}
function de() { //where i wanted to use these files info
for (var i = 0; i < 3; i++) {
mapped_data2[i] = { key: "Group" + (i + 1), values: mapped_data };
}
var datam = mapped_data2;
var den = JSON.stringify(datam);
document.write(den);
};
function init() {
..//create new client called aw for the server application and start it;
..//if the connection is established:
aw.onmessage = o;
aw.get("/somefolder/somefolder"); // request list of files in a folder
};
//when html page is being onload, call the functions init() and de()
var mapped_data2 = [];
function o(msg) {
var mapped_data = []; // this doesn't need to be global
if (msg.data) {
var inner_data = [];
...
mapped_data = inner_data;
} else {
...
}
mapped_data2.push({ key: "Group" + mapped_data2.length + 1, values: mapped_data };)
// do more stuff as in den()
}

Losing object reference on lookup in Javascript

I'm working on an extension for Google Chrome and I ran into the following situation:
I'm trying to get all the existing tabs from all the opened windows in the same instance of Google Chrome. I manage to get them and construct an array of objects that contain the relevant data for me.
When I look at the constructed array using console.log (which is saved for future use also) I can see the collection of objects, but I can't reference them (when I try I get undefined).
I tried to save the array outside my object in a container, but nothing changes.
Any idea why the reference to the objects go away when I try to look them up? Thanks.
Here is the code:
(function(window){
//defining a namespace
var example = {
bmarksmaster: (function() {
var bmarksmaster = function() {
return new bmarksmaster.fn.init();
}
bmarksmaster.fn = bmarksmaster.prototype = {
debug: false,
tabs: [],
constructor: bmarksmaster,
init: function() {
return this;
},
windowParser: function(ctx, filter) {
var local = ctx;
var filter = filter;
return function(wObj) {
if((wObj !== null) && (wObj !== undefined)) {
for(var idx in wObj) {
var cw = wObj[idx];
if((cw.tabs !== null) && (cw.tabs !== undefined)) {
var cwtabs = cw.tabs;
for(var tabIdx in cwtabs) {
local.tabs.push(filter(tabIdx, cwtabs[tabIdx]));
}
}
}
}
};
},
getTabs: function() {
var returnData = [];
chrome.windows.getAll(
{
"populate": true
}, this.windowParser(this, function(i, e) {
var data = {};
if(!e.incognito) {
data["title"] = e.title;
data['url'] = e.url;
data['favicon'] = e.favIconUrl || "";
}
return data;
}));
return this.tabs;
},
getTab: function(callback) {
this.getTabs();
for (var tabIdx in this.tabs) {
if(callback(tabIdx, this.tabs[tabIdx])) {
return this.tabs[tabIdx];
}
}
},
getTabsData: function(callback) {
var data = [];
var tabs = [];
tabs = this.getTabs();
console.log(this.tabs[0]);
for (var tabIdx in tabs) {
console.log(tabs[tabIdx]);
var tabData = callback(tabIdx, tabs[tabIdx]);
if(tabData) {
data.push(tabData);
}
}
return data;
},
setDebug: function() {
this.debug = true;
},
resetDebug: function() {
this.debug = false;
}
};
bmarksmaster.fn.init.prototype = bmarksmaster.fn;
return bmarksmaster;
})()
};
window.example = example;
})(window);
//end of bmarksmaster.js file
console.log(example.bmarksmaster().getTabs()); //this works, I can see the array
console.log(example.bmarksmaster().getTabs()[0]); //this doesn't work, I get undefined, never mind the shortcut
I think the logic in your code is wrong. It is a bit convoluted and hard to follow. I would recommend rewriting it a bit to be simpler. Something like this might help get you started. It collects all the windows, putts all the tabs into the tabs var.
var tabs = [];
chrome.windows.getAll({ populate: true}, function(windows) {
var localTabs = windows.reduce(function(a, b){
return a.tabs.concat(b.tabs);
});
tabs = localTabs.filter(function(element){
return !element.incognito;
});
})

Categories

Resources