Dropdown menu with OpenLayers 3 - drop-down-menu

I am using openlayers 3. From the values contained in a vector GeoJSON, I want to fill a dropdown menu. When selecting a value from the dropdown menu, I want to zoom in on the entity.
My problem now is that I want to generate my HTML from the attributes of my GeoJSON. So I tried this simple code but it doesn't work :
var menu = document.getElementById('menuDropDown');
vector2.getSource().forEachFeature(function() {
menu.innerHTML = feature.get('NOM').join(', ');
});
EDIT:
I'm able to populate a dropdown menu from a list:
var list = ['a','b','c'];
var mySelect = $('#mySelect');
$.each(list, function(val, text) {
mySelect.append(
$('<option></option>').val(val).html(text)
);
});
What i want to do it's to populate this list from the attribute of my vector
So i try this:
// vector2 it's a GeoJSON who is integrate on my map
vector2.getSource().getFeatures().forEachFeature(function(feature) {
list.push(feature.get('NOM'));
});

Firstly I'm assuming you have to pass some parameter to your callback:
vector2.getSource().forEachFeature(function(feature) {
Then you can append an item to a dropdown like so:
var item = document.createElement('option');
item.setAttribute('value', feature.get('NOM'));
var textNode = document.createTextNode(feature.get('NOM'));
item.appendChild(textNode)
menu.appendChild(item);
All together:
var menu = document.getElementById('menuDropDown');
vector2.getSource().forEachFeature(function(feature) {
var item = document.createElement('option');
item.setAttribute('value', feature.get('NOM'));
var textNode = document.createTextNode(feature.get('NOM'));
item.appendChild(textNode)
menu.appendChild(item);
});

I have resolve my problem:
vector2.getSource().on('change', function(evt){
var source = evt.target;
var list = [];
source.forEachFeature(function(feature) {
list.push(feature.get('NOM'));
});
// console.log("Ecrit moi les noms : " + list);
Thanks you to those who took the time to respond

Related

Data Validation range from different spreadsheets

I have in my main spreadsheet a dropdown with data validation of a range from another tab in the same spreadsheet with data imported from another spreadsheet or with IMPORTRANGE function or imported with a script.
In both cases the main spreadsheet is very slow cause I have a lot of tab with data imported with both methods.
There is a way to do the data validation of the dropdown in the main sheet taking the data I need directly from the other spreadsheets without import them previously in the main spreadsheet with the IMPORTRANGE function or with a script?
I have tried to write a draft script but not works:
function externalSheetDataValidation() {
var cell = SpreadsheetApp.getActiveRange();
var dataValidationSheet = SpreadsheetApp.openById("xxxxxxxxxx");
var sheet = dataValidationSheet.getSheets()[0];
var range = sheet.getRange("B2:B5000");
var rule = SpreadsheetApp.newDataValidation()
.requireValueInRange(range, true)
.setAllowInvalid(false)
.build();
cell.setDataValidation(rule);
Logger.log(dataValidationSheet.getName());
}
You want to populate a dropdown based on the values of a range from a different spreadsheet.
You are currently importing those values to a sheet in your spreadsheet in order to use them via requireValueInRange.
You would like to skip the import process.
If that's the case, you can just do the following:
Create a function that returns a simple array with the values from the source range:
function importSheetA() {
return SpreadsheetApp.openById('xxxxx')
.getSheetByName('xxxxx')
.getRange('xxxxx')
.getValues()
.flat(); // This ensures a simple array is returned
}
Populate the dropdowns with requireValueInList instead of requireValueInRange, using the values returned by importSheetA:
function populateDropdown() {
var values = importSheetA();
var rule = SpreadsheetApp.newDataValidation()
.requireValueInList(values, true)
.setAllowInvalid(false)
.build();
var range = SpreadsheetApp.getActiveRange();
range.setDataValidation(rule);
}
Note:
You could update the populated options when the source range is edited if you install an onEdit trigger, and you could also specify what range of cells should be populated with dropdowns without them being necessarily selected, but I'm not sure that's what you want.
Update:
If your data has more than 500 items, value in list criteria is not an option. Your only other option would be to use List from a range instead, but as you said, this would require the source range to be on the same spreadsheet as the dropdown, which you wanted to avoid.
As a workaround, I'd suggest you to programmatically copy the data to a hidden sheet in the target spreadsheet, and use the data in this hidden sheet as your source range when creating the dropdown. For example, this:
function copyRange() {
var cell = SpreadsheetApp.getActiveRange();
var rangeNotation = "B2:B5000"; // Change according to your preferences
var sourceData = SpreadsheetApp.openById(xxxxx)
.getSheetByName(xxxxx)
.getRange(rangeNotation)
.getValues();
var targetSS = SpreadsheetApp.getActiveSpreadsheet();
var hiddenSheetName = "Hidden source data"; // Change according to your preferences
var hiddenSheet = targetSS.getSheetByName(hiddenSheetName);
if (!hiddenSheet) hiddenSheet = targetSS.insertSheet(hiddenSheetName);
var sourceRange = hiddenSheet.getRange(rangeNotation);
sourceRange.setValues(sourceData);
hiddenSheet.hideSheet();
var rule = SpreadsheetApp.newDataValidation()
.requireValueInRange(sourceRange, true)
.setAllowInvalid(false)
.build();
cell.setDataValidation(rule);
}
Reference:
requireValueInList(values, showDropdown)
Cached Dropdown Dialog
GS:
function getSelectOptions(){
const cs=CacheService.getScriptCache();
const v=JSON.parse(cs.get('cached'));
if(v){return v;}
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('Options');
var rg=sh.getDataRange();
var vA=rg.getValues();
var options=[];
for(var i=0;i<vA.length;i++)
{
options.push(vA[i][0]);
}
cs.put('cached', JSON.stringify(vA), 300)
return vA;
}
function showMyselectionDialog() {
SpreadsheetApp.getUi().showModelessDialog(HtmlService.createHtmlOutputFromFile('ah2'), 'Selections');
}
html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<script>
google.script.run
.withSuccessHandler(function(vA) {
updateSelect(vA);
})
.getSelectOptions();
function updateSelect(vA,id){//the id allows me to use it for other elements
var id=id || 'sel1';
var select = document.getElementById(id);
select.options.length = 0;
for(var i=0;i<vA.length;i++)
{
select.options[i] = new Option(vA[i],vA[i]);
}
}
</script>
<body>
<select id='sel1'></select>
</body>
</html>

How to get Active (focused) slickgrid?

I have two slickgrid and one delete button,
When i click on delete,i want focused grid so that i will delete items.
How to get focused grid ?
This is what i have done so far....
function deleteRow(e, args){
//code to delete items from "grid"
var selectedrows = grid.getSelectedRows();
var len = selectedrows.length;
var itemNo = "";
for(var i=0;i<len;i++)
{
var data = grid.getData().getItem(selectedrows[i]);
dataView.deleteItem(data.id);
itemNo =data.id;
var url = "delete_Item_Master?itemNo="+itemNo;
$.get(url, {itemNo : itemNo},function(data) {
location.reload(true);
});
}
//code to delete items from "metalGrid"
var metalSelectedrows = metalGrid.getSelectedRows();
var mlen = metalSelectedrows.length;
var itemNo = "";
for(var i=0;i<mlen;i++)
{
var mData = metalGrid.getData().getItem(metalSelectedrows[i]);
meyalDataView.deleteItem(mData.id);
itemNo =mData.id;
var url = "delete_subItem?itemNo="+itemNo;
$.get(url, {itemNo : itemNo},function(data) {
location.reload(true);
});
}
}
But this code delete items from both grid..
I think that the correct way to do this is to write your own selection model. It should be a Singleton, and two grids should interact with it. It should know which grid was last active.
But you need to ask yourself is that behaviour is good. What if user will delete an item from another grid - because there's only one button. IMHO every grid should have it's own button. And I work for an ERP company where we got that dillemas everyday ;)

Get clicked cell on kendo ui grid change event

I am handling the change event of the kendo ui grid.
In the event handler, I would like to get the cell that was clicked that invoked the change event. I need the cell in order to scan its contents.
Any thoughts?
It's actually very well documented in the documentation: http://docs.telerik.com/kendo-ui/api/web/grid#events-change
Here's the example code if you have the grid configured for multiple cell selection (selectable: "multiple, cell"):
change: function(e) {
var item;
var selected = this.select(); //get selected cell(s)
for (var i = 0; i < selected.length; i++) {
item = this.dataItem(selected[i].parentNode); //get selected cell's dataItem
}
}
In order to select the table cell that was clicked to edit, simply use e.container. There are a number of options given from the event handler. Here's a few:
change: function (e) {
//jQuery object containing the cell
var cell = e.container;
//jQuery object containing the input
var field = cell.find("input");
//value in the input
var fieldVal = field.val();
//or, on one line:
fieldVal = e.container.find("input").val();
//also, if you happen to want the data model for that row
var model = e.model;
}

set an id at "Raphaeljs set"

i want to set an id to Raphael set because i want to display it after an event click.
this is my set:
var divResult = document.getElementById('printResult');
var space2Draw = Raphael(divResult, 1600, 900);
var st = space2Draw.set();
st.push(
space2Draw.circle(newXCoordinates, newYCoordinates, 20).click((function (valore) {
return function () {
window.open("index-point.html?id=" + (valore) + "&type=" + type + "&description=" + description + "&name=" + name);
}
}(valore))).mouseover(function () {
this.attr({ 'cursor': 'pointer' });
this.attr({ 'opacity': '.50' });
}).mouseout(function () {
this.attr({ 'opacity': '1' });
})
);
in my page i have a button:
function show(){
var element = space2Draw.getById(-1);
element.show();
}
}
Is not possible to set an id in this way : set.id = -1?
How can I set an id and then I find the set?
Thanks in advance for the help.
You can try using setAttribute() to add a CLASS for the elements you want to access later, and then modify their CSS propperties. The first step would be to change the CLASS of each element:
myElement.node.setAttribute("class", "class_name");
Unfortunately, Raphael does not allow you to handle sets as unique HTML objects, so you cannot do this for the entire set at once. Instead, you might have to do this for each element in your set, possibly with a for cycle, something like this:
for (var i=0; i<st.length; i++) {
st[i].node.setAttribute("class", "class_name");
}
Then, using JQuery, you can modify the CSS properties of the CLASS you created in order to display the elements in your set.
function show(){
$('.class_name').css('display', 'block');
}
I hope this helps.
Maybe you can use Raphael data() function to assign any data to your element/set.
Example:
// you can keep global var for your id and increment it within your code
var id = 0;
var p = Raphael(100, 100, 500, 500),
r = p.rect(150, 150, 80, 40, 5).attr({fill: 'red'}),
c = p.circle(200, 200, 70).attr({fill: 'blue'});
var set = p.set(r,c).data("id", id);
id++;
// then in your click event to get the id you can do
var whichSet = this.data("id");
// data("id") will return you the global id variable
Good Luck

Change text in Div using jQuery, MetaData and Map highlights

I'm a newbie to jQuery and I have a map with a highlight plugin, when mouse over an area I want to change the text in a div with an ID and the text I will get it from the area attribute Alt="some text"
Here is the code that used for area loops, I'm pretty sure I can add a small function here but I couldn't figure it out.
//map
clicks$(".tabs area").click(function(){
//areas loop:
$(".tabs area").each(function(){
var d = $(this).data('maphilight') || {};
if(d.alwaysOn == true){
d.alwaysOn = false;
}
});
var data = $(this).data('maphilight') || {};
data.alwaysOn = true;
$(this).data('maphilight', data).trigger('alwaysOn.maphilight');
if ($(this).hasClass("current") == false)
{
var thisTarget = $(this).attr("href");
$(this).parents(".tabs").find('area.current').removeClass('current');
$(this).addClass('current');
$(this).parents(".tabs").nextAll(".tab-content").children(":visible").fadeOut(1, function() {
$(thisTarget).fadeIn("fast");
});
}
return false;
});
Any help or suggestions on how I can get this done would be highly appreciated.
I'm not familiar with the highlights plugin, but I think you just wanna add a mouseover event to each area like so (you would place this before/after your .click declaration):
$(".tabs area").mouseover(function() {
var alt_text = $(this).attr('alt');
$("#YOUR_TEXT_DIV_ID").html(alt_text);
}).mouseout(function() {
//do something on mouseout
});

Resources