I am making a calendar and have a dropdown with all the months in so you can pick a month from the dropdown and the lazyrow should go to that index. Now my question is how would you go about doing it the other way around so that the dropdown changes when you swipe in the calendar would you update it every time you touch the lazy row or would you do it in a side effect?
So would you do it this way
LazyRow(state = calendarViewModel.listState, modifier = Modifier.fillMaxWidth()) {
calendarYears.forEach {
items(it.months.count()) { index ->
calendarViewModel.onEvent(CalendarEvent.setMonth(index))
CalendarRowItem(
modifier = Modifier.fillParentMaxWidth(),
calendarSize = it.months[index].amountOfDays,
initWeekday = it.months[index].startDayOfMonth.ordinal,
textColor = MaterialTheme.colors.secondaryVariant,
clickedColor = MaterialTheme.colors.primary,
textStyle = MaterialTheme.typography.body1
)
}
}
}
or would you do it by a side effect and can someone in that case give me an example of how to do that?
Related
This question already has an answer here:
Iterate through selected grid data and get field values of n-th datasource
(1 answer)
Closed 2 months ago.
[ExtensionOf(formControlStr(BankReconciliation ,ClearALL))]
final class ClearAll_Extension
{
void clicked(){
next clicked();
FormRun formrunn = this.FormRun();
FormDataObject myField;
FormCheckBoxControl BankAccountTrans_Included = formrunn.design().controlName("BankAccountTrans_Included");
FormDataSource BankAccounttable_ds = formrunn.dataSource("BankAccountTable");
BankAccountTable BankTable = BankAccounttable_ds.cursor();
// BankAccountTable BankTable ;
FormDataSource BankAccountTran = formrunn.dataSource("BankAccountTrans");
myField = BankAccountTran.object(fieldnum(BankAccountTrans,Included));
BankAccountTrans Bankacc ;
/// Bankacc = BankAccountTran.getFirst();
// if(Bankacc.AccountId == BankTable.AccountID)
// {
Bankacc = BankAccountTran.getFirst();
while(Bankacc){
if (Bankacc.Included == NoYes::No)
{
BankAccountTran.object(fieldNum(BankAccountTrans,Included)).setValue(NoYes::Yes) ;
}
else
{
BankAccountTran.object(fieldNum(BankAccountTrans,Included)).setValue(NoYes::No) ;
}
BankAccountTran.write();
Bankacc = BankAccountTran.getNext();
}
I want to select all record by clicking on (clear all) button and run methods of datasource in all record selected .
this button select all records but methods of datasource run on only first record doesn't run on all record , cursor still on first record not moving to the next
Why do you need to use datasource methods?
If you're doing something on all the records in a table, it makes more sense to do it with a method on the table. Or possibly create a SysOperation and do it in the service class, just loop through all the records. Doing the changes on datasource level makes sense only if you want to change the marked records, in which case you can do it with multiselect.
I have this calendar I'm working on in jetpack compose. I have gotten some help with placement in rows and stuff like that using weight. The problem is though that I'm trying to make an item of a month in the calendar and place that in a LazyRow but i think it has to do with that lazy rows are scrollable so the weight function for the box with the text in it makes it so that no text shows up if the code looks like this...
fun CalendarRowItem(calendarSize: Int, initWeekday: Int, textColor: Color, clickedColor: Color){
var dayCounter: Int = 1
var week: Int = 1
var _initWeekday = initWeekday
Column() {
while(dayCounter <= calendarSize){
Row(modifier = Modifier.fillMaxWidth().padding(5.dp)) {
if(initWeekday > 0){
repeat(initWeekday){
Spacer(modifier = Modifier.weight(1f))
}
}
for (i in week..(7 - _initWeekday)){
if(dayCounter <= 31){
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
.padding(10.dp)
.background(clickedColor, CircleShape)
.clickable { }
) {
Text(text = dayCounter++.toString(), color = textColor )
}
}else{
Spacer(modifier = Modifier.weight(1f))
}
_initWeekday = 0
}
}
}
}
}
but without the weight i cant place the dates correctly plus i have no clue how i would make it so that only one item is visible in the screen at once?
I think using HorizontalPager instead of LazyRow may suit better in this case: it has pagination, as you probably don't need your scroll to stop in between the month, and won't have such a problem out of the box, as same modifier as I suggest you below in applied by the component.
Below is a general answer to the problem, as you still may face it in other cases.
That indeed happens because the parent is horizontally scrollable.
In such case Modifier.fillMaxWidth, as well as Modifier.weight with fill parameter set to true (it's default value) has no effect, as parent width constraint is equal to infinity.
You need to restrict parent width. In this case Modifier.fillParentMaxWidth() can be used on the container: it'll make the view width be equal to the LazyRow width - the part of scroll view which takes exactly "one screen".
As this modifier is defined on LazyItemScope, you have two options to apply it:
Define CalendarRowItem on the scope, in this case CalendarRowItem will only be available to use from lazy view item.
fun LazyItemScope.CalendarRowItem(/* ... */) {
// ...
Column(Modifier.fillParentMaxWidth()) {
// ...
}
}
Add a modifier parameter for CalendarRowItem and pass Modifier.fillParentMaxWidth from item scope:
fun CalendarRowItem(/* ... */, modifier: Modifier) {
// ...
Column(modifier) {
// ...
}
}
items(yourItems) { item ->
CalendarRowItem(
/* ... */,
modifier = Modifier.fillParentMaxWidth()
)
}
I need to Delete All the records in a list applet by a button clicked method. In order to achieve this, I have added a button to the list applet with "DeleteAllRecords" method and added a script to BC PreInvokeMethod function as below. Once clicked on the button all the records will get deleted, but the applet won't get refreshed. How Can I achieve that?
try
{
if(MethodName == "DeleteAllRecords")
{
var EmpBO = TheApplication().GetBusObject("XXXX");
var EmpBC = EmpBO.GetBusComp("XXXX");
with(EmpBC)
{
SetViewMode(AllView);
ActivateField("EmployeeID");
ClearToQuery();
SetSearchExpr("[XXXX] <> ' '");
ExecuteQuery(ForwardOnly);
var Frecord = FirstRecord();
while(Frecord)
{
Frecord = DeleteRecord();
Frecord = FirstRecord();
}
}
//BC.InvokeMethod("RefreshBuscomp");
return (CancelOperation);
}
}
catch(e)
{
throw(e);
}
finally
{
EmpBO = null;
EmpBC = null;
}
return (ContinueOperation);
You could try a few things.
1: A simple null query in the end after all deletions are done. ClearToQuery() and ExecuteQuery();
2: There is a BC method for RefreshBusComp (check documentation) which can be used with InvokeMethod(). Does pretty much the same thing as 1. I see you already tried it and probably did not work.
3: There are Business services which can refresh applets , like FINS Teller UI navigation.
4: You could also try a null query in browserscript/javascript, put that in InvokeMethod, so that it runs after the BC escript. Genb has to be run to generate bscripts.
One of these should work .
I have made this virtual inventory with buttons that copy and paste values to various sheets for different types of reports. The code might not be optimal I am not much of a programmer but I'm trying my best. now I have the same button in multiple places and I want it to copy values in cells relative to the position of the button itself but I am not sure how to reference a cell in a relative manner in the getRange fucntion.
here is the code:
function Go() {
var ss = SpreadsheetApp.getActiveSpreadsheet ();
var sheet = SpreadsheetApp.getActiveSheet();
var destSheet = ss.getSheetByName("Fiche");
var lastRow = destSheet.getLastRow();
var source = ss.getRange ('(rowid-3)(colid)');
var checkbox = sheet.getRange (3,3);
var destColumn = ss.getRange ('B10').getValues ();
source.copyTo(destSheet.getRange(lastRow + 1,1), {contentsOnly: true});
if (checkbox.getValue() == 'vrai' ) {
var source = ss.getRange ('B9');
source.copyTo(destSheet.getRange(lastRow + 1, destColumn), {contentsOnly: true});
source.copyTo(destSheet.getRange(lastRow + 1, 2), {contentsOnly: true});
}
else {
var nombre = ss.getRange ('D5').getValues() ;
destSheet.getRange(lastRow + 1, destColumn).setValue(nombre);
destSheet.getRange(lastRow + 1, 2).setValue(nombre)
}
I want all (B10),(B9), etc. format cells to be replaced with relative cell positons. I have tried with (colID)(rowID) but it doesn't seem to work
I believe your goal as follows.
You want to retrieve the cell coordinate when a button on Spreadsheet is clicked.
Modification points:
Unfortunately, in the current stage, when a button on Spreadsheet is clicked, there are no methods for directly retrieving the information where button is clicked.
So when you want to use the button on Spreadsheet, if you want to retrieve the information, it is required to prepare each script for each button. But I thought that this might be different from the direction you expect.
In this answer, in order to retrieve the information where the button is clicked, I would like to propose the following 2 patterns as the workarounds. In these patterns, the event object is used. By this, the information of the button can be retrieved. This is used.
Pattern 1:
In this pattern, a cell is used as the button using the simple trigger of OnSelectionChange. When the cell "B3" is used as the button like above image, the script is as follows.
Sample script:
In this script, for example, when you want to use the cell "B3" of "Sheet1" as the button, please set "B3" to buttonRanges. And, set sheet.getSheetName() != "Sheet1". When when you want to use the cell "B3" and "B4" as the button, please set "B3" and "B4" to buttonRanges.
function onSelectionChange(e) {
const range = e.range;
const sheet = range.getSheet();
const buttonRanges = ["B3"];
if (sheet.getSheetName() != "Sheet1" || !buttonRanges.includes(range.getA1Notation())) return;
const row = range.getRow(); // This is the row number.
const column = range.getColumn(); // This is the column number.
}
In this case, when the cell "B3" is clicked, this script is run. And row and column are the row and column number of the cell.
Because the cell is used as the button, you can put the value to the cell.
Pattern 2:
In this pattern, a checkbox is used as the button using the OnEdit trigger. When the cell "B3" is used as the button like above image, the script is as follows.
Sample script:
In this script, for example, when you want to use the cell "B3" of "Sheet1" as the button, please set "B3" to buttonRanges. And, set sheet.getSheetName() != "Sheet1". When when you want to use the cell "B3" and "B4" as the button, please set "B3" and "B4" to buttonRanges.
function onEdit(e) {
const range = e.range;
const sheet = range.getSheet();
const buttonRanges = ["B3"];
if (sheet.getSheetName() != "Sheet1" || !buttonRanges.includes(range.getA1Notation()) || !range.isChecked()) return;
const row = range.getRow(); // This is the row number.
const column = range.getColumn(); // This is the column number.
}
In this case, when the checkbox is checked, the script is run. When the checkbox is unchecked, the script is not run.
Because the checkbox is used as the button, you cannot see the text in the cell.
References:
Simple Triggers
Event Objects
Related question
Button change text display every after click
This question is for achieving the switching button.
I'm trying to make a document to manage my finances on google sheet, actually, I would like to be able to track the transactions I make between my accounts.
I made this sheet to be able to sum things up.
Actually, I would be able to tell the document i'm making a transaction from - to (in that case, from content 1 to content 3) and to add a new value.
I don't know how to tell google sheet to "move" 25 from content 1 to content 3 or any other content.
Thanks for the precious help.
You can use an Apps Script onEdit trigger so fire the transactions, and use checkboxes to track which transaction should be fired, so that the transaction takes place whenever the corresponding checkbox is checked.
First, add the checkboxes to the transaction rows by selecting the appropriate cells and click Insert > Checkbox.
Then, open the script bound to your spreadsheet by selecting Tools > Script editor, copy the following function, and save the project. Now every time a checkbox is checked, the corresponding transaction takes place in B2:E3, and when it is unchecked the transaction gets undone (the from and the to exchange places, and the money goes the other way):
function onEdit(e) {
var range = e.range;
var col = range.getColumn();
var row = range.getRow();
var checkbox = e.value;
var sheet = range.getSheet();
if (col === 6 && row > 8) {
var from = sheet.getRange(row, 3).getValue();
var to = sheet.getRange(row, 4).getValue();
var value = sheet.getRange(row, 5). getValue();
var valuesToUpdate = sheet.getRange("B2:E2").getValues();
var fromIndex = valuesToUpdate[0].findIndex(contents => contents === from);
var toIndex = valuesToUpdate[0].findIndex(contents => contents === to);
var fromRange = sheet.getRange(3, fromIndex + 2);
var toRange = sheet.getRange(3, toIndex + 2);
if (checkbox === "TRUE") { // MAKE TRANSACTION
fromRange.setValue(fromRange.getValue() - value);
toRange.setValue(toRange.getValue() + value);
} else if (checkbox === "FALSE") { // UNDO TRANSACTION
fromRange.setValue(fromRange.getValue() + value);
toRange.setValue(toRange.getValue() - value);
}
}
}
This function will fire every time the spreadsheet is edited, but you only want to update the transaction summary whenever the edited cell is a checkbox and this checkbox is checked. The function is checking for that, using the information passed to the onEdit function through the event object (e), which contains information on the edited cell (its value, its range, etc.):
Reference:
onEdit(e)
Event Objects: Edit