AngularJS forEach set object properties in ng-repeat found set - javascript

I have an ng-repeat displaying items from json, based on what the user enters into a field it can be filtered.
<tr ng-repeat="i in filteredItems = (iso3166 | filter: {alpha_2: isoQuery})">
this all works as expected.
Each item in the group ("iso3166") has 3 boolean values, "restricted", "unrestricted", and "unclassified", for each of the columns "license", "prohibited", and "size".
The user can set one of these values in each column in each row to true or false:
This works fine.
What I need to add is an "ALL" row at the top that will set every item in the filtered set to whichever button was clicked in each column.
In other words, if the user clicks the ALL rows "restricted" button in the "license" column, every row's "license" "restricted" value should be toggled to true or false. I'm not sure of the syntax to set the value.
Now I have the ng-click as
ng-click="setAll('col1','licensed')"
and the function as
$scope.setAll = function (column, value) {
angular.forEach($scope.filteredItems, function (value, key) {
??
});
};
How do I assign the correct value to each row in the loop?

At the moment your inner function shadows the value variable. Rename the local variable to something else in order to change it.
$scope.setAll = function (column, value) {
angular.forEach($scope.filteredItems, function (item, key) {
item[column] = value;
});
};

Related

Filtering array based on checkbox conditional values

So, I'm a bit stuck. I'm filtering an array based on the values of another array. When the user clicks a check box a year value gets pushed to an array (checkedBoxes), then the yearMarker array is populated from meeting the condition IF the marker.year (from mapMarkers array) entry is equal to any value in the CheckedBoxes array. This then gets passed to the getMarkers function which populates the map I'm working on. This all works perfectly. However when I click uncheck the box it doesn't work. If I log the checkedBoxes array I can see that the year is being removed as it should. The code to populate/replace yearMarkers is the same as the checked state, as with the function to create map markers. Yet it doesn't work. Any help to straighten out my thinking on this would be appreciated.
subFilter.forEach(item => {
const elm = item;
item.addEventListener('click', function () {
if (elm.checked) {
markersLayer.clearLayers();
checkedBoxes.push(elm.value);
yearMarkers = mapMarkers.filter(marker => checkedBoxes.includes(marker.year));
getMarkers(yearMarkers, markersLayer);
} else{
checkedBoxes = checkedBoxes.filter(entry => entry !== elm.value);
yearMarkers = mapMarkers.filter(marker => checkedBoxes.includes(marker.year));
getMarkers(yearMarkers, markersLayer);
console.log('unchecked');
console.log(checkedBoxes);
}
})

How to correctly remove a vue-select multiselect item

I have a vue-select multiselect (http://sagalbot.github.io/vue-select/) defined as
<v-Select label="label" multiple :on-change="updateCities" :options="cities"></v-Select>
The method updateCities is defined as
'updateCities': function (menuItem) {
var name = ''
// iterate thru the elements in the multiselect
menuItem.forEach(function (elem, i) {
name = elem.label
return name
})
// push the selected element to an array in the data model
this.state.city.push(name)
}
and the data model is defined as
'data' () {
return {
'state': {
'city': []
}
}
}
When I click on the multiselect and choose a city, both the menu and the data model array city is updated correctly but when I click on the X on the top right of the menu item to remove the element from menu and from the data model array city. as shown below
The element is correctly removed from the menu but not from the data model array city.
How do I fix this?
This was resolved by assigning the value of this.state.city to the menu item as:
'updateAdvertisers': function (menuItem) {
this.state.city= menuItem.map(elem => elem.label)
}

SlickGrid javascript get current row data

I would like to remove a row when I press the Delete key. But I can't get any data from the source below:
var selectedrows = grid.getSelectedRows();
grid.onKeyDown.subscribe(function(event) {
var item = data[selectedrows.cell];
if (event.keyCode == 46) {
alert(item.hostname);
}
});
First, the getSelectedRows() function returns an Array of the selected column numbers. The way you are trying will return undefined, since that Array doesn't contain any property called cells.
Open this official SlickGrid example demo and try the following:
Select the first row in grid.
Try issuing the following command in your JS debugger console:
grid.getSelectedRows()
Will return you an Array with the selected row number as:
Array [ 0 ]
The returned Array'sfirst element is the row number that you have just selected.
Now that we know the selected row number issue this:
data[grid.getSelectedRows()[0]]
Will return you the selected Object as:
Object { name: "Make a list", complete: true }
If you want to reach a property of the returned Object you could do it as:
var selectedRow = data[grid.getSelectedRows()[0]];
console.log(selectedRow.name);
Will return the property name's value as:
Make a list
Hope this clears up your confusion.

Getting a row from a data attribute in datatables.js

I am struggling trying to find the right method to do this. Basically, I have an array of id values that correspond to which rows have been selected in my table. To construct this list, I use the following code. this.options.ajaxId is the key that accesses my Id value in the data object passed to the table.
this.getRowData(target)[this.options.ajaxId]
where my getRowData function is:
getRowData: function (HTMLrow) {
return this.dataTable.row(HTMLrow).data();
},
This works great, but then I am stumped on my next step which is re-selecting the correct rows when the table is re-drawn via paging, sorting, or searching. My plan was to cycle through the ID's and find which table row corresponded to that ID value, but I cannot find a function to input a key value search pair and return the html row. Something like the following is what I was thinking,
this.dataTable.findRow( key, value );
// then my usage would be the following:
var that = this;
_.each(this.selectedList, function (id) {
var row = that.dataTable.findRow( that.options.ajaxId, id );
// code to select the row
});
I haven't written it yet, but I know I can cycle through each of the rows, get the data for that row, and check it against what I am looking for, but in cases where the user is viewing 100 rows and has only one selection I would like to avoid that.
Any insight?
Thanks
SOLUTION #1
You can use the following code to locate and highlight rows based on row IDs if row ID is stored in one of the fields.
// Index of column containing IDs
var colIdIndex = 0;
// List of row IDs
var rowIds = ['2', '4', '6'];
// Find indexes of rows which have IDs in the desired column
var rowIndexes = table.rows().eq(0).filter( function (rowIdx) {
return ($.inArray(table.cell( rowIdx, colIdIndex ).data(), rowIds) !== -1)
? true
: false;
});
// Select rows based on array of found row indexes
table.rows(rowIndexes)
.nodes()
.to$()
.addClass('selected');
See filter() API method for more details.
Please note that this method will work for client-side processing mode only.
DEMO
See this jsFiddle for code and demonstration.
SOLUTION #2
Alternative approach that would work both in client-side and server-side processing modes would be to use createdRow callback.
For example:
// Index of column containing IDs
var colIdIndex = 0;
// List of row IDs
var rowIds = ['2', '4', '6'];
var table = $('#example').DataTable({
createdRow: function( row, data, dataIndex ) {
if ( $.inArray(data[colIdIndex], rowIds) !== -1) {
$(row).addClass('selected');
}
}
});
DEMO
See this jsFiddle for code and demonstration.

ng-repeat elements' indexes changing on sort

I have an HTML table with rows created using an ng-repeat and data using properties of objects in an object array. They are being sorted by a name column alphabetically. I have setup some simple editing using ng-show, ng-focus, and ng-blur, so that there is no need for a save button or something similar.
However, as I am editing the name column, if I type a first letter that would cause that row to be lower in the table, it sorts the table as I am still typing. I tried creating a "temp" object array, copying the original array into it, modifying the "temp" array when editing, then copying the temp array into the original array when editing is done. That didn't work; the same thing happened anyway.
After a little research, I learned that both the temp array and the original array were probably pointing to the same data, so I tried multiple ways of cloning the array. I finally got it to work...with one exception: when I edited the object to be sorted lower, it moved. When I tried to edit it again, it did all sorts of random, unexpected stuff.
After some diagnostics, I discovered that the indexes of the objects in the table (gotten from $index) were being changed when sorted. For example:
Table
-------------------------------------
|Name |Age |Phone |Index |
-------------------------------------
|George |25 |928-7495|0 |
|John |34 |342-0673|1 |
|Megan |28 |834-1943|2 |
|Susan |19 |274-8104|3 |
-------------------------------------
If I changed George to Tim, the index of that object becomes 3 also. All the other indexes stay the same. Can anyone tell me why this is happening and/or give me suggestions on how to fix this?
So apparently I just didn't realize that the indexes changed every time I changed the data or the sorting of the data. After adding the index as a property of my objects, everything worked as expected.
This is how I use the orderBy Angularjs filter with column sorts that reverse on click. The "a" tag in the "th" is what controls the behavior. I have this in a directive, which is recommended, but the code can be in a controller.
I use the Angularjs orderBy filter as they state.
$filter('orderBy')(array, expression, reverse)
// This is the order of properties in the code below that looks like this
// $scope.rows = angularSortBy( $scope.rows, columnName, toggleOrderDirection( columnName ));
Each column has a font-awesome multi-arrow toggle called
<i class="fa fa-sort"></i>
Where columns would be something like this...
$scope.columns = { columnOne: { label: 'Column One', orderDirection: true, selected: false },
columnTwo: { label: 'Column Two', orderDirection: true, selected: false },
columnThree: { label: 'Column Three', orderDirection: true, selected: true }};
and rows could be anything you wish...
<table>
<tr>
<th>Sort By</th>
<th ng-repeat="(key, value) in columns">
{{ value.label }}
<span ng-if="value.selected">
(<i class="fa fa-sort"></i>) // font-awesome arrow font.
</th>
</tr>
<tr ng-repeat="row in rows">// stuff here</tr>
var angularSortBy = $filter( 'orderBy' ); // use Angular's built in filter to sort table.
$scope.orderBy = function( columnName ){
resetAllSelectedStates(); // sets column.selected prop to false.
setAsSelected( columnName, true );
$scope.rows = angularSortBy( $scope.rows, columnName, toggleOrderDirection( columnName ));
}
function resetAllSelectedStates(){
Object.keys( $scope.columns ).forEach( resetColumnPropertyToDefault );
}
function resetColumnPropertyToDefault( name ){
$scope.columns[ name ].selected = false;
}
function setAsSelected( name ){
$scope.columns[ name ].selected = true;
}
function toggleOrderDirection( name ){
return $scope.columns[ name ].orderDirection = !$scope.columns[ name ].orderDirection;
}

Categories