4 Checkbox group to filter a repeater - velo

I want to create a recipe page with 3 different checkbox groups for different filters.
Currently, I have 1 checkbox group and linked it to a repeater.
Could anyone assist in guiding me on how to add 2 more checkbox groups to the repeater?
I went digging online but have yet to find a solution
import wixData from 'wix-data';
const databaseName = 'Recipes1';
const databaseField = 'tags';
$w.onReady(function() {
$w('#checkboxGroup1').onChange((event) => {
const selectedBox = $w('#checkboxGroup1').value;
addItemstoRepeater(selectedBox);
})
});
function addItemstoRepeater(selectedOption = []) {
let dataQuery = wixData.query(databaseName);
if (selectedOption.length > 0) {
dataQuery = dataQuery.hasSome(databaseField, selectedOption);
}
dataQuery
.find()
.then(results => {
const filtereditemsReady = results.items;
$w('#repeater1').data = filtereditemsReady;
})
}

What you're doing is a data query to fetch the items according to user selection.
In order to build a filter you need to use a dataset, connect the dataset to your repeater or table. View a filter example here, it shows you how to filter a dataset using multiple selections.
From my perspective, filter function for 3 checkbox groups should be like below
let checkbox1;
let checkbox2;
let checkbox3;
const filter = (ck1, ck2, ck3) => {
if(checkbox1 !== ck1 || checkbox2 !== ck2 || checkbox3 !== ck3) {
let newFilter = wixData.filter();
if(ck1)
newFilter = newFilter.hasSome('fieldKey1', ck1);
if(ck2)
newFilter = newFilter.hasSome('fieldKey2', ck2);
if(ck3)
newFilter = newFilter.hasSome('fieldKey3', ck3);
$w("#datasetId").setFilter(newFilter);
setVariables(ck1, ck2, ck3);
}
}
const setVariables = (ck1, ck2, ck3) => {
checkbox1 = ck1;
checkbox2 = ck2;
checkbox3 = ck3;
}
You will need to study the example to adapt to code according to your needs.

Related

Set the sourceRange of Data Validation to an array of values

I'm creating a social media outreach tracker. I want to create a drop-down list of the contact name. The problem is that I have two sources of names on two different sheets.
I wrote a script that pulls the names from the two different sources and combines them to a single array.
I was hoping to set the source range as that array.
Here is my code:
function setDataValid_(range, sourceRange) {
var rule = SpreadsheetApp.newDataValidation()
.requireValueInRange(sourceRange, true)
.build();
range.setDataValidation(rule);
}
function onEdit() {
var auditionsSheet = SpreadsheetApp.getActiveSpreadsheet();
var castingDirectorsTab = auditionsSheet.getSheetByName("Casting Directors");
var contactsTab = auditionsSheet.getSheetByName("Contacts");
var socialMediaOutreachTab = auditionsSheet.getSheetByName("Social Media Outreach");
var lastRowCD = castingDirectorsTab.getLastRow();
var lastRowContacts = contactsTab.getLastRow();
var activeCell = socialMediaOutreachTab.getActiveCell();
var activeColumn = activeCell.getColumn();
// get data
var castingDirectorNameData = castingDirectorsTab.getRange(2, 1, lastRowCD, 1).getValues();
var contactNameData = contactsTab.getRange(2, 1, lastRowContacts, 1).getValues();
//get name data to a single arrays
var castingDirectorName = [];
castingDirectorNameData.forEach(function(yr) {
castingDirectorName.push(yr[0]);
});
var contactName = [];
contactNameData.forEach(function(yr) {
contactName.push(yr[0]);
});
// get rid of the empty bits in the arrays
for (var x = castingDirectorName.length-1; x > 0; x--) {
if ( castingDirectorName[x][0] === undefined ) {
castingDirectorName.splice( x, 1 )
}
}
for (var x = contactName.length-1; x > 0; x--) {
if ( contactName[x][0] === undefined ) {
contactName.splice( x, 1 )
}
}
//combine two data sources for data validation
var combinedNames = [];
combinedNames.push(castingDirectorName + contactName);
Logger.log (combinedNames);
Logger.log( typeof combinedNames);
// data validation set up and build
if (activeColumn == 1 && auditionsSheet.getName() == "Social Media Outreach") {
var range = auditionsSheet.getRange(activeCell.getRow(), activeColumn +1);
var sourceRange = combinedNames;
setDataValid_(range, sourceRange)
}
}
When I enter a date in Col A on Social Media Outreach, nothing happens in Col 2.
I was using an existing working nested data validation script I have but the sourceRange pulls from a sheet based on the value in the active cell. Here is that code:
function setDataValid_(range, sourceRange) {
var rule = SpreadsheetApp.newDataValidation()
.requireValueInRange(sourceRange, true)
.build();
range.setDataValidation(rule);
}
function onEdit() {
var aSheet = SpreadsheetApp.getActiveSheet();
var aCell = aSheet.getActiveCell();
var aColumn = aCell.getColumn();
// data validation for Auditions Tab Projet Type to Project Details
if (aColumn == 9 && aSheet.getName() == 'Auditions') {
var range = aSheet.getRange(aCell.getRow(), aColumn + 1);
var sourceRange = SpreadsheetApp.getActiveSpreadsheet().getRangeByName('RefTables!' + aCell.getValue())
setDataValid_(range, sourceRange)
}
}
For this script when I select from the data validation drop-down, a new data validation comes up in the next col with the appropriate secondary data validation.
So the question is, can the source range be set to an array or do I need to put the names back into my sheet to reference a la the second script.
I've looked through the documentation and searched and can't find an answer. I'm relatively new to GAS and am not sure of all the inner workings of the data validation builder.

Auto sorting 2 sheets based on 1 of them

I'm running a spreadsheet which contains multiple sheets, in Sheet3 I'm inputting some data and running an auto sorting code, which sorts it ascending by column D.
Sheet3 Example | Sheet1 Example
The "name" and "location" in Sheet1 are imported from Sheet3 so they swap position when Sheet3 does the sorting, however, the problem is that the info from D to F (Sheet1) isn't swapping and it will display for wrong people.
This is the script I'm using:
Modified it slightly to work for a specific sheet, since I didn't need to auto sort the whole document at the time.
/*
* #author Mike Branski (#mikebranski)
* #link https://gist.github.com/mikebranski/285b60aa5ec3da8638e5
*/
var SORT_COLUMN_INDEX = 4;
var ASCENDING = true;
var NUMBER_OF_HEADER_ROWS = 2;
var SHEET_NAME = 'Sheet3';
var activeSheet;
function autoSort(sheet) {
var s = SpreadsheetApp.getActiveSheet();
if (s.getName() == SHEET_NAME) {
var range = sheet.getDataRange();
if (NUMBER_OF_HEADER_ROWS > 0) {
range = range.offset(NUMBER_OF_HEADER_ROWS, 0, (range.getNumRows() - NUMBER_OF_HEADER_ROWS));
}
range.sort( {
column: SORT_COLUMN_INDEX,
ascending: ASCENDING
} );
}
}
function onEdit(event) {
var s = SpreadsheetApp.getActiveSheet();
if (s.getName() == SHEET_NAME) {
var editedCell;
activeSheet = SpreadsheetApp.getActiveSheet();
editedCell = activeSheet.getActiveCell();
if (editedCell.getColumn() == SORT_COLUMN_INDEX) {
autoSort(activeSheet);
}
}
}
function onOpen(event) {
var s = SpreadsheetApp.getActiveSheet();
if (s.getName() == SHEET_NAME) {
activeSheet = SpreadsheetApp.getActiveSheet();
autoSort(activeSheet);
}
}
function onInstall(event) {
onOpen(event);
}
So basically when I edit Sheet3 and it does the auto sorting, I want the rows from D to F in Sheet1 to carry along with repositioning that comes from Sheet3. I hope I did manage to explain properly what I want.
I've tried without success to make it work; I can't figure out the proper way of doing this, especially due to the fact that Sheet1 table has different range.
I figured out how to fix the issue so I'll post the code here. Basically whenever you edit the column that you choose to sort by in Sheet3 (master sheet) it will first copy in the Sheet1 (target sheet) what changes you've made in A & B columns and then it will sort both sheets at the same time, this way the data from following columns in Sheet1 will carry along.
I used A & B columns in this example, since that's what I commented above, but can be different ranges as long as they're similar in size.
// Master Sheet Settings (Copy ranges must be similar in size)
var msName = 'Master Sheet';
var msSortCol = 4; // which column to trigger the sorting when you edit
var msSkipRows = 6; // how many rows to skip, if you have header rows
var msCopyRange = 'A7:B51'; // the range you want to copy
// Target Sheet Settings
var tsSortCol = 3;
var tsSkipRows = 10;
var tsName = 'Target Sheet';
var tsCopyRange = 'A11:B55';
var sortAscending = true;
var activeSheet;
function onEdit() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var editedCell = ss.getActiveRange().getColumnIndex();
if (ss.getSheetName() == msName) {
activeSheet = SpreadsheetApp.getActiveSheet();
if (editedCell == msSortCol) {
copyRow();
autoSort(activeSheet);
}
}
}
function copyRow() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName(msName);
var values = sheet.getRange(msCopyRange).getValues();
ss.getSheetByName(tsName).getRange(tsCopyRange).setValues(values);
SpreadsheetApp.flush();
}
function autoSort() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var msheet = ss.getSheetByName(msName);
var tsheet = ss.getSheetByName(tsName);
var mrange = msheet.getDataRange();
var trange = tsheet.getDataRange();
if (ss.getSheetName() == msName) {
if (msSkipRows > 0) {
mrange = mrange.offset(msSkipRows, 0, (mrange.getNumRows() - msSkipRows));
}
if (tsSkipRows > 0) {
trange = trange.offset(tsSkipRows, 0, (trange.getNumRows() - tsSkipRows));
}
mrange.sort({ column: msSortCol, ascending: sortAscending });
trange.sort({ column: tsSortCol, ascending: sortAscending });
}
}

hide forms tab in a form head crm dynamics 365

I have an entity which contains 2 forms, I want to prevent navagation between these 2 forms based on the value of two option field. In other words if the value of need prescoring is yes navigation is not possible and the inverse, how can I do this ?
Is it possible to simply hide the list ?
Thanks,
No, you cannot dynamically change the forms the user can select. This can only be done statically based on security roles.
Instead I suggest using a single form, where you hide and show the relevant fields/sections/tabs based on the value of your Need Processing field.
You can decide based on your project complexity wrt number of form controls/tabs/sections. We did something like this to maintain & forced navigation based on form control value.
var taskFormOptionSet = {
Form1: 1,
Form2: 2,
};
var FormNames = {
Form1: "Form1",
Form2: "Form2",
};
var myform = Xrm.Page.getAttribute("need_Prescoring").getValue();
var currentform = Xrm.Page.ui.formSelector.getCurrentItem();
if (currentform != null) {
var formId = currentform.getId();
var formLabel = currentform.getLabel();
}
if (myform == taskFormOptionSet.Form1 && formLabel != FormNames.Form1) {
var items = Xrm.Page.ui.formSelector.items.get();
for (var i in items) {
var form = items[i];
var formId = form.getId();
var formLabel = form.getLabel();
if (formLabel == FormNames.Form1) {
form.navigate();
return;
}
}
}
As it's not supported I used another solution which is to check if the boolean is true and the name of the, if the user tries to change the form he will be redirected to the right form until he changes the value of the boolean.
DiligenceSwitch: function(){
if (Xrm.Page.ui.formSelector.getCurrentItem() != null) {
var currentform = Xrm.Page.ui.formSelector.getCurrentItem();
}
if (currentform != null) {
var formId = currentform.getId();
var formLabel = currentform.getLabel();
}
var kycId = Xrm.Page.data.entity.getId();
SDK.REST.retrieveRecord(kycId, "kyc_Kycdiligence", "kyc_Needprescoring", null, //field for searching the targeted field, entity, targeted field, ...
function (kyc) {
if (kyc != null || kyc.kyc_Needprescoring != null) {
if (formLabel != "Pre-Scoring" && kyc.kyc_Needprescoring == true) {
var windowOptions = { openInNewWindow: false };
var parameters = {};
parameters["formid"] = "4B0C88A9-720C-4BFA-8F59-7C1D5DD84F02";
Xrm.Utility.openEntityForm("kyc_kycdiligence", kycId, parameters, windowOptions);
alert("Vous devez faire le pre-scoring");
}
}
},
function (error) {
Xrm.Utility.alertDialog(error.message);
});
},

firebase sort reverse order

var playersRef = firebase.database().ref("team_mapping/");
playersRef.orderByChild("score").limitToFirst(7).on("child_added", function(data) {
}
Using this query, I can sort it in ascending order. But, I wanted to sort in descending order. Can any body suggest me with some way to do this. Any help will be appreciated.
Thanks in Advance!!
just use reverse() on the array , suppose if you are storing the values to an array items[] then do a this.items.reverse()
ref.subscribe(snapshots => {
this.items = [];
snapshots.forEach(snapshot => {
this.items.push(snapshot);
});
**this.items.reverse();**
},
You can limit to the last 7 which will give you the highest scores since the query is in ascending order. Then all you have to do is reverse the last 7 you get for them to be in descending order.
var playersRef = firebase.database().ref("team_mapping/");
var playersData = [];
var pageCursor;
playersRef.orderByChild("score").limitToLast(7).on("child_added", function(data) {
playersData = [data] + playersData;
}
UPDATE
Here is an example of how you could paginate by score.
const query = firebase.database().ref("team_mappings").orderByChild('score');
var snapshots = [];
function reversedChildren(snapshot) {
var children = [];
snapshot.forEach(function (child) { children.unshift(child); });
return children;
}
function addPlayerToLeaderBoard(snapshot) {
var key = snapshot.key;
var place = snapshots.indexOf(snapshot) + 1;
var score = snapshot.child('score').val();
$('#leaderboard').append(`<li><b>${key}: ${score}</li>`);
}
function parsePage(snapshot) {
var children = reversedChildren(snapshot);
children.forEach(function (child) {
players.push(child);
addPlayerToLeaderBoard(child);
});
pageCursor = children[children.length - 1];
}
function reloadPlayers() {
players = [];
pageCursor = null;
query.limitToLast(5).once('value').then(parsePage);
}
function loadMorePlayers() {
query.endAt(pageCursor).limitToLast(5).once('value').then(parsePage);
}
reloadPlayers();
$('#reload').on('click', reloadPlayers);
$('#load_more').on('click', loadMorePlayers);
Unfortunatelly, there is not a shortcut for this yet. However, if you are using Listview or Recyclerview as UI, you could simply solve this issue by reversing the UI,by reversing Listview or Recyclerview
For Recyclerview you could reverse as follows:
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
layoutManager.setReverseLayout(true);
layoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(layoutManager)
For Listview:
listView.setStackFromBottom(true);

Devexpress Gridview Hide Editform in asp.net mvc

If my CustomerName FieldName equals to "MyCustomer" , i want to hide editing for that row.
If customername == "MyCustomer , hide column editing.
How can i hide column editing according to "MyCustomer"?
settings.Columns.Add(s =>
{
s.FieldName = "CustomerName";
s.Caption = "Customer";
s.Name = "CustomerColumn";
s.ColumnType = MVCxGridViewColumnType.ComboBox;
var comboBoxProperties = s.PropertiesEdit as ComboBoxProperties;
comboBoxProperties.DataSource =Model.CustomerList;
comboBoxProperties.TextField = "Customer_Name";
comboBoxProperties.ValueField = "Customer_Id";
comboBoxProperties.ValueType = typeof(int);
comboBoxProperties.ClientInstanceName = "CustomerColumn";
});
Any help will be appreaciated with points.
settings.CommandButtonInitialize = (s, e) => {
if (e.ButtonType == ColumnCommandButtonType.Edit) {
MVCxGridView g = s as MVCxGridView;
var value = (int)g.GetRowValues(e.VisibleIndex, "RowFieldName"); //use a correct field name and cast a resultant value to a correct value type
e.Visible = value > 10; // for example, only
}
};
Fortunately , i have myself.I found a solution.
It works.Hope this helps who has the same problem in the future.

Resources