Angular drop down - Selected values at the top of multiselect dropdown - angular5

I have a requirement to keep selected values at the top of dropdown list of a multiselect. I have kept selected values in one array (for each selected item), the original option list in another array, compared the index values and concatenated selected values to the top of array. Its working when i choose one value and not working for multiple values
html
<div>
<ng-multiselect-dropdown class ="ng-multiselect" [placeholder]="'Users'"
[data]="userList" [(ngModel)]="selectedUsers" [settings]="multiSelect"
name="user" (onSelect)="onItemSelect($event)" (click)="userSelectedAtTopOnClick()">
</ng-multiselect-dropdown>
</div>
ts
onItemSelect(user: User) {
this.userData = user;
}
userSelectedAtTopOnClick(): void {
this.isUserDropDownWidgetHidden = document.querySelector('.dropdown-list').hasAttribute("hidden");
if(this.isUserDropDownWidgetHidden ) {
this.sortUserListAfterEachSelection(this.userData);
}
}
sortUserListAfterEachSelection(user: User) {
let arrPartner: Partner[];
if(origInst) {
const index = this.userList.findIndex(element => element.partnerId === user.partnerId);
const item: Partner = this.userList[index];
if (index > -1) {
arrPartner = this.userList.splice(index, 1);
arrPartner = arrPartner.concat(this.userList);
this.userList = arrPartner;
}
}
}

Related

Calling to a method from ForEach doesn't working properly - vue.js

I'm trying to call a method from a foreach in vue, but the method is performed only one time,
No matter how many variables are in the list.
attached here the two functions I used:
CleanChips() {
this.chips.forEach((item) => {
this.RemoveRequirement(item)
})
},
RemoveRequirement(item) {
var index = this.chips.indexOf(item);
if (index > -1) {
this.chips.splice(index, 1);
this.chips = [...this.chips];
}
},
The RemoveRequirement function is performed only one time.
Any idea what's wrong here?
You modify the array itself in RemoveRequirement while running through it in CleanChips. You should create a copy of the original array to iterate in order to safely delete elements in the original array.
CleanChips() {
const chipsCopy = [...this.chips]
chipsCopy.forEach((item) => {
this.RemoveRequirement(item)
})
},
RemoveRequirement(item) {
var index = this.chips.indexOf(item);
if (index > -1) {
this.chips.splice(index, 1);
// this.chips = [...this.chips]; // you don't need this line because `splice` is reactivity-compatible.
}
},

In ag grid drop down, how to show name once selected and on save set value instead of name.?

Using this reference, I had worked ag grid drop down.
Issue : once I selected a drop down value, then getvalue() returns value instead of name. Hence it shows the number on the column and it should be text.
If I change that to name, while saving, its bind to name . But here it should be value.
Required : getValue should return name & saving the array should contain value.
agInit(params: any): void {
this.params = params;
this.value = this.params.value;
this.name = this.params.name;
this.options = params.options;
}
getValue(): any {
return this.value;
}
ngAfterViewInit() {
window.setTimeout(() => {
this.input.element.nativeElement.focus();
})
}
stackbltiz here
here
How can I achieve this.
You don't have to create new cellRenderer and cellEditor for it, ag-grid provides inbuilt select for it. **
When you using objects (for dropdown\combobox) inside single cell - you have to implement value handlers: valueParser and valueFormatter:
Value parser: After editing cells in the grid you have the opportunity to parse the value before inserting it into your data. This is done using Value Parsers.
colDef.valueParser = (params) => {
return this.lookupKey(mapping, params.newValue);
}
Value formatter: Value formatters allow you to format values for display. This is useful when data is one type (e.g. numeric) but needs to be converted for human reading (e.g. putting in currency symbols and number formatting).
colDef.valueFormatter = (params) => {
return this.lookupValue(mapping, params.newValue);
}
*where mapping represents your object and inside each of those functions you are just extracting key or value.
Original solution:
lookupValue(mappings, key) {
return mappings[key];
}
lookupKey(mappings, name) {
var keys = Object.keys(mappings);
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (mappings[key] === name) {
return key;
}
}
}
and here my little bit modified:
lookupValue(mappings, key:string) {
if(!mappings || !mappings.find(item => item.Id == key)) return null;
else
return mappings.find(item => item.Id == key).Value;
}
lookupKey(mappings, name) {
let key: any;
for (key in mappings) {
if (mappings.hasOwnProperty(key)) {
if (name === mappings[key]) {
return key.Id;
}
}
}
}
UPDATE
To populate dropdown you need yo use cellEditorParams:
colDef.cellEditor = 'selectCellEditor';
colDef.cellEditorParams = {
values: yourList,
},
** But in case when it could be required you still need to have both of renderers and store object inside, and then you would be able to choose what would be displayed on every stage.

How to get selected rows' index in Table element in iview vue?

How to get selected rows' index in Table element in iview vue?
For example, table element is like below:
<Table ref="selection" :columns="columns4" :data="data1" #on-selection-change="updateSelectedNumber"></Table>
GET data rows item clicked.
To get the index of the item clicked, simply click on the line you want, not above the checkbox, over the item that is not the box, but that is on the same line.
add this tag
methods: {
valueRowClick(value)
console.log(value)
}
result:
position: 0 -> Object
position 1: -> Index item clicked 2
When you select an item, according to the documentation it throws the value of the selected items out.
GET data item select
<table #on-select="nameFunction">
methods: {
nameFunction (value) {
console.log(value)
}
}
DELETE ITEM EXAMPLE:
add the this tag TABLE
<table #on-selection-change="valueItemsSelected"></table>
methods: {
valueItemsSelected(value){
if(value.length > 0){
for(let y = 0, max1 = value.length; y < max1; y ++){
for(let i = 0, max = this.data1.length; i < max; i++){
if(value[y] === this.data1[i]) {
this.data1.splice(i, 1)
}
}
}
}
}
},
In your HTML template as
<Table :columns="myColumns" :data="myData" />
do nothing.
In your <script>, when you click on a row, you can get a params object to your function, with data structure like this:
{
row : {...}
index : 0 // or maybe the actual row index,
column: {...}
}
rowClicked(params.index) {
let rowIndex = params.index;
}

Filter Data Separately in Two Different DataTables

Here is what I am trying to do:
I have two DataTables on the same page with different data. One is 'sell_orders' and the other is 'buy_orders'. I want to filter the data in each table separately based on checkboxes at the top of each table. So far I have gotten that to work using the following code:
$("#sell_vis_cit").change(function() {
var checked = this.checked;
var allowFilter = ['sell-orders'];
if (!checked) {
$.fn.dataTable.ext.search.push (
function(settings, data, dataIndex) {
// check if current table is part of the allow list
if ( $.inArray( settings.nTable.getAttribute('id'), allowFilter ) == -1 ) {
// if not table should be ignored
return true;
}
return $(sell_table.row(dataIndex).node()).attr('sell-data-sec') != 'x';
}
);
sell_table.draw();
} else {
$.fn.dataTable.ext.search.pop();
sell_table.draw();
}
});
$("#buy_vis_cit").change(function() {
var checked = this.checked;
var allowFilter = ['buy-orders'];
if (!checked) {
$.fn.dataTable.ext.search.push (
function(settings, data, dataIndex) {
// check if current table is part of the allow list
if ( $.inArray( settings.nTable.getAttribute('id'), allowFilter ) == -1 ) {
// if not table should be ignored
return true;
}
return $(buy_table.row(dataIndex).node()).attr('buy-data-sec') != 'x';
}
);
buy_table.draw();
} else {
$.fn.dataTable.ext.search.pop();
buy_table.draw();
}
});
The problem I am having is when it comes time to remove the filter. If filters have been applied to each table, the removal of the filter using the pop() function becomes unreliable because there is no way to verify that it is removing the filter from the right table.
So my question is: is there a way to verify that pop() is running on the right table like I did with push()? Alternatively, is there a better way to achieve my goal?
Why push() and pop() in the first place? It seems to me you have some static filters which is turned on and off by checkboxes. You could declare a filter once globally and do the "math" inside the filter :
$.fn.dataTable.ext.search.push(function(settings, data, dataIndex) {
if ((settings.sTableId == 'sell-orders' && $("#sell_vis_cit").is(':checked')) ||
(settings.sTableId == 'buy-orders' && $("#buy_vis_cit").is(':checked'))) {
//filter code
} else {
return true
}
})
and then simply activate the filters in the click handlers :
$("#sell_vis_cit, #buy_vis_cit").change(function() {
buy_table.draw();
sell_table.draw();
})

Vuejs2 component not updating as parent data changes

I am trying to make a simple product catalogue using vuejs2.
All my data is stored in an object array, I then have a subset of this data which is what the product catalogue uses to display each product.The subset is used for pagination.
When a user switches pages it clears and pushes the next set of data into the array.
This automatically makes the product component display the new data.
I have issues with the following, each product has multiple colours which are stored as a comma delimited string eg (white, blue, red)
I am trying to make that information appear as a drop down list of options beside each product.
This works until I switch to the next page of data, all other details update except the colour drop downs, which only reflect the previous set of data.
My product list is stored in an object array like:
var obj = {
productID: productID,
product: title,
gender: gender,
colour: colour,
cost: cost,
size: size,
description: description
}
productArray.push(obj);
I then have several components that display this array of data:
Vue.component('product-list', {
template: '<ul id="productList">'+
'<product :productID="product.productID" v-for="product in products">'+
'<h4>Colour</h4><colourSelect :colours="product.colour" :productID="product.productID"></colourSelect>' +
'<h4>Gender</h4><span class="genderSpan"><p v-bind:id="getID(product.productID)">{{product.gender}}</p></span>' +
'</product></ul>',
data: function() {
return {
products:
paginatedArray
};
},
Vue.component('colourSelect', {
props: ['productID', 'colours'],
template: '<select v-bind:id="getID()" class="form-control input-xs"><colourOption v-for="colourItem in colourArray"></colourOption></select>',
data: function () { //split string based into array
var newArray = [];
var optionsArray = this.colours.split(',');
for (i = 0; i < optionsArray.length; i++) {
var obj = {
colour: optionsArray[i]
}
newArray.push(obj)
}
return {
colourArray: newArray
};
},
methods: {
getID: function (test) {
return 'colourSelect' + this.productID;
}
}
});
Vue.component('colourOption', {
props:['options'],
template: '<option><slot></slot></option>'
});
Within the app section of vuejs I have the following methods that do the pagination:
buildPages: function () {
for (i = 1; i < this.listLength() /this.totalPage ; i++) {
this.pages.push(i);
}
var page = this.currentPage * this.totalPage;
for (i = page; i < page + this.totalPage ; i++) {
paginatedArray.push(productArray[i]);
}
},
listLength: function () {
var listTotal = productArray.length;
return listTotal
},
changePage: function (number) {
this.currentPage = number
var page = this.currentPage * this.totalPage;
//paginatedArray = [];
var count = 0;
for (i = page; i < page + this.totalPage ; i++) {
if (typeof productArray[i] !== 'undefined') {
paginatedArray.splice(count, 1, productArray[i])
}
count++
}
},
productArray is the main array storing data, paginatedArray is the subset of data that the product component works off.
The issue appears to be within the colourSelect component, within its "data" section it splits the colour data and returns it as an colourOption component into the select, but won't update when the paginatedArray changes.
The colourSelect component does however appear to actually get passed the correct data, as getID method updates correctly. Its just the data section which is not being re-rerun.
This is my first vuejs site, anyone have any ideas around this?
Thanks
You should make the colourArray as a computed property, as the data block of component gets executed only once and later change of props will not update colourArray .
Vue.component('colourSelect', {
props: ['productID', 'colours'],
template: '<select v-bind:id="getID()" class="form-control input-xs"><colourOption v-for="colourItem in colourArray"></colourOption></select>',
computed:{
colourArray: function () { //split string based into array
var newArray = [];
var optionsArray = this.colours.split(',');
for (i = 0; i < optionsArray.length; i++) {
var obj = {
colour: optionsArray[i]
}
newArray.push(obj)
}
return newArray
}
},
methods: {
getID: function (test) {
return 'colourSelect' + this.productID;
}
}
});