Set marker visible with knockout JS ko.utils.arrayFilter - google-maps

Hello guys I am trying to create an app that sets the appropriate markers visible when a knockout search is being done.
Basically the app is.
When someone does a search the list that is bellow it, filters the list and makes only the markers that are associated with the filter list visible on the map.
I have created a ko.utils.arrayFilter and I am trying to set only the item.marker.setVisible(true)
My Github link is https://github.com/Aimpotis/map3
Thank you again and much respect to the community it is helping me learn a lot

All you need is to set the visibility of the marker to match whether it is found:
if (!filter) {
// this is new
ko.utils.arrayForEach(self.listLoc(), function (item) {
item.marker.setVisible(true);
});
return self.listLoc();
} else {
return ko.utils.arrayFilter(self.listLoc(), function(item) {
var result = (item.title.toLowerCase().search(filter) >= 0)
item.marker.setVisible(result); // this is a new line
return result;
});
}
Working fiddle.
Note: unless you're supporting particularly old browsers, you can use the Array filter method rather than Knockout's arrayFilter util, and .foreach instead of arrayForEach.

Related

Highlight an array of nodes in Autodesk Viewer

Problem:
I have an array of nodes that I would like to highlight when an action happens.
My Attempted Solution
I have tried using code from the model browser, but it seems to only accept one dbId at a time. I have tried to iterate over my array and call it, but the highlighting doesn't work when that is done.
for (var i = 0; i < dbIdsArray.length; i++) {
viewerApp.getCurrentViewer().impl.rolloverObjectNode(dbIdsArray[i]);
}
Any advice on how to implement this correctly would be a great help.
Thanks
If you want to highlight a couple of dbids, there are some different ways depending on your requirement.
Maybe you can use the API Viewer3D.isolate() to highlight the
selected objects by isolating them, you can just input dbId array as
follow, also, you can zoom the selected items to the viewer window
use the API Viewer3D.fitToView() to focus on them:
viewer.isolate(dbIdArray);
viewer.fitToView(dbIdArray);
If you want to highlight the selected objects with different color,
maybe you can try the new API Viewer3D.setThemingColor(), here is the
simple code sample. Remember you need to clear the color using
Viewer3D.clearThemingColors(). The simple code sample should be like:
I'm able to highlight components using following code:
viewer.addEventListener(
Autodesk.Viewing.SELECTION_CHANGED_EVENT,
function (e) {
if(e.dbIdArray.length) {
var dbId = e.dbIdArray[0];
viewer.impl.highlightObjectNode(
viewer.model, dbId, true, false)
viewer.select([])
viewer.impl.sceneUpdated(true)
}
})
This is using function:
viewer.impl.highlightObjectNode = function(model, dbId, value, simpleHighlight)

How do I format my AngularJS data model?

Hi I am just beginning with angular and I am struggling to find the answer to what I'm sure is quite a simple thing to do.
I am currently getting the values of some input boxes and pushing them into my scope. This is creating one long 'array' eg:
['data-1','data-2','data-3']
I would like to format my data in the following way instead
$scope.data = [
{
'header1': 'data1-1',
'header1': 'data1-2',
'header1': 'data1-3'
},
{
'header1': 'data2-1',
'header1': 'data2-2',
'header1': 'data2-3'
}
]
This is my function as it currently is.
$scope.createRow = function(){
angular.forEach(angular.element("input"), function(value, key){
$scope.td.push($(value).val());
});
}
Any help or pointers would be greatly appreciated as I am just getting my head round the angular way
Doing this isn't hard... but before I give you a gun to shoot yourself in the foot, just to say that I think it would be beneficial to explain WHY you want structure in that other format you are mentioning. You seem to have lots of data repetition and that's always a red flag.
Now for the code, you just need to create object before pushing it to the array like:
$scope.createRow = function(){
angular.forEach(angular.element("input"), function(value, key){
var obj = {
"header1": val + "-1",
"header2": val + "-2"
};
$scope.td.push(obj);
});
}
EDIT:
OK, so you are trying to add new row to the table. First of all, you shouldn't be doing angular.forEach, but rather those input elements in HTML should bind to existing scope object, like:
// obviously use better names than Input1Value
// I am here just giving you example
$scope.bindData = {
Input1Value: null,
Input2Value: null
};
// in HTML you will do
// <input ng-model="bindData.Input1Value" />
// <input ng-model="bindData.Input2Value" />
Now that you've eliminated that nasty angular.forEach you need to have some kind of event handler, for example when user clicks the button you want to add this object to the array to which table is data bound. Just be sure to clone the $scope.bindData object when you add it to array.
$scope.createRow = function(){
var newRowData = $scope.cloneObject($scope.bindData);
$scope.td.push(newRowData);
}
// http://heyjavascript.com/4-creative-ways-to-clone-objects/
// https://stackoverflow.com/questions/728360/most-elegant-way-to-clone-a-javascript-object
$scope.cloneObject = function(objToClone) {
var newObj = (JSON.parse(JSON.stringify(objToClone)));
}
To close this answer off - keep in mind, if you ever find yourself directly referencing HTML DOM elements in Javascript with AngularJS - you are doing something wrong. It's a nasty habit to eliminate, especially if you are coming from jQuery background (and how doesn't?), where everything is $("#OhHiThere_ElementWithThisId).
Obviously the main thread on this topic on StackOverflow is this one:
“Thinking in AngularJS” if I have a jQuery background?
However I find that it's too theoretical, so Google around and you may find better overviews like:
jQuery vs. AngularJS: A Comparison and Migration Walkthrough

angularjs save rendered values in html in a variable

I hope someone can help me with this, It's a strange question maybe as I didn't find an answer online.
I call the database and retrieve a list (in json) of items.
Then in angularjs,I render this list by extracting relevant pieces of data(name,age,etc) and show it properly in a table as a list of rows.
I have then an edit button that takes me to another page where I want to put a dropdown list.
What I want to know if is possible to add to that dropdown list the rendered list I previously created in my previous page.
is it possible to save the previously rendered list in a variable and then use that variable in the dropdown?
thank you
You could store the list within a controller and make this data availablte to this dropdown, I think.
Instead of trying to query for the list, add the list to the template, get the list from the template and render somewhere else, I'd suggest query for the list, save the list in a service , and then when you want to use that list again, get it from the service. Something like:
service:
var services = angular.module('services');
services.factory('getListService',['$http',function($http){
var getListOfStuff = function(){
//call to database
return //your json
};
var extractNameAgeEtc = function(){
var myListOfStuff = //get list of stuff from $http or database
var myListOfNameAgeEtc = //make a list of tuples or {name,age,etc} objects
return myListOfNameAgeEtc;
};
return {
extractNameAgeEtc : extractNameAgeEtc
};
}]);
controllers:
angular.module('controllers',['services']);
var controllersModule = angular.module('controllers');
controllersModule.controller('tableRenderController',['getListService','$scope',function(getListService,$scope){
//use this with your table rendering template, probably with ng-repeat
$scope.MyTableValue = getListService.extractNameAgeEtc();
}]);
controllersModule.controller('dropdownRenderController',['getListService','$scope',function(getListService,$scope){
//use this with your dropdown rendering template, probably with ng-repeat
$scope.MyDropDownValue = getListService.extractNameAgeEtc();
}]);

Move Ember object from one list to another with drag-and-drop

I'm trying to drag Ember objects from one list to another. If I drag an item to a new list, the item should be removed from its current list and moved to the new one.
Thanks to Drag&Drop with Ember.js and Ember.js - drag and drop list, I figured out how to copy an item to a different list. However, I am unable to determine from which list a dragged object originated. I have dozens of lists on the page, so I'd rather not do a O(n*k) search for the original object.
Currently, I'm using Ember views and the HTML 5 API. It seems like the Handelbars action helper should achieve my goal more easily. Ember's action supports the drop event, but I can't get it to fire: {{ action foo on="drop" }}. It probably has something to do with the nuanced event propagation defaults of the HTML 5 drag-and-drop implementation.
If you know how to solve this problem using actions instead of views, I'd much prefer that solution.
Here's how I'm currently transferring objects:
// this is heavily inspired by http://jsfiddle.net/ud3323/5uX9H/
// Draggable items
App.ItemView = Ember.View.extend({
templateName: 'item',
attributeBindings: 'draggable',
draggable: 'true',
dragStart: function(event) {
var dataTransfer = event.originalEvent.dataTransfer;
// The view's context is the item to transfer
var item = this.get('context');
// Use HTML 5 API to transfer object as JSON.
// There must be a more elegant way to do this.
dataTransfer.setData('application/json', JSON.stringify(item));
}
});
// Item list drop zone
App.ItemListView = Ember.View.extend({
templateName: 'itemList',
dragEnter: function(event) {
event.preventDefault();
return false;
},
dragOver: function(event) {
event.preventDefault();
return false;
},
drop: function(event) {
event.preventDefault();
// Extract the transferred data
var rawData = event.dataTransfer.getData('application/json');
// Create a new Ember object from the data
var item = App.Todo.create(JSON.parse(rawData));
this.get('controller').send('add', item);
return false;
}
});
Check out JS Bin for the complete code.
Thanks in advance for your help. Very much appreciated.
This is maybe not the full solution to your problem, but it satisfies the need to use the action helper instead of the itemView. Here is your modified jsbin http://jsbin.com/ibufeh/15/edit?html,javascript,live, the drop event fires and is catched at the ApplicationRoute level, from where you can then redirect your function call to the appropriate controller, have a look! it's not working correctly but it solves part of your problem - using an action helper. You need still to figure out from which list the item originated, but this will be easy I guess.
hope it helps

Google Maps V3 Infobox undefined on polygons

I have a spoke in my wheels and I am not sure how to sort this out. I have been struggling with it for a couple days and it isn't like a normal infobox as it is not set to a marker rather a polygon which is something new for me. I have polygons that display with data from an XML file and they show up fine. I have searched the web and got it to have the mouseover set up to where you mouseover a polygon the opacity changes and an infobox pops up. Problem is the infobox when it pop up shows "undefined" instead of the html I have set in it to display with data from the XML file.
Here is a link to the test map for example.
http://www.mesquiteweather.net/googlemap_poly.html
Here is a link to the XML file where I am just trying to show the elements events and expires in the info box.
http://www.mesquiteweather.net/xml/warnings_test.xml
This is the code I am working with to create the infoboxes and mouseover events
function attachPolygonInfoWindow(polygon, html, event, expires)
{
var html = "<strong>" + event + "</strong>";
eventWarnings.infoWindow = new google.maps.InfoWindow({content: html});
google.maps.event.addListener(eventWarnings, 'mouseover', function(e) {
var latLng = e.latLng;
this.setOptions({fillOpacity:80});
polygon.infoWindow.setPosition(latLng);
polygon.infoWindow.open(map);
});
google.maps.event.addListener(eventWarnings, 'mouseout', function() {
this.setOptions({fillOpacity:0.35});
polygon.infoWindow.close();
});
}
var polygon = new google.maps.Polygon(/* omitted for brevity */);
attachPolygonInfoWindow(eventWarnings);
eventWarnings.setMap(map);
}
});
I am pretty sure it is something easy I am overlooking but I haven't been able to find anything that pertains to my issue. I am just lucky I got the infobox to show at all as I have learned it's tricky since polygons don't have a true center and they are not set up like you would with a marker which I can handle.
If anyone has any suggestions please let me know.
-Thanks
You defined your attachPolygonInfoWindow function with 4 argument, but only provide one when you call it:
// definition
function attachPolygonInfoWindow(polygon, html, event, expires)
...
// call
attachPolygonInfoWindow(eventWarnings);
Probably you want (I don't see the html or expires parameters being used):
attachPolygonInfoWindow(eventWarnings, "", event, null);
The other option would be to change the definition to:
// definition
function attachPolygonInfoWindow(polygon, event, expires)
and the call to (assuming you are going to use "expires" for something):
attachPolygonInfoWindow(eventWarnings, event, expires);
As it doesn't look like you need to pass in that parameter (event is serving the function that I would expect it to serve).
Also, FYI, you have a "hanging comma" in your alertColors.js which make IE unhappy...
example