Friends,
I have written the following JavaScript to ascertain which row of an tabular form the user is currently on. i.e. they have clicked a select list on row 4. I need the row number to then get the correct value of a field on this same row which I can then perform some further processing on.
What this JavaScript does is get the id of the triggering item, e.g. f02_0004 This tells me that the select list in column 2 of row 4 has been selected. So my Javascript gets just the row information i.e. 0004 and then uses that to reference another field in this row and at the moment just output the value to show I have the correct value.
<script language="JavaScript" type="text/javascript">
function cascade(pThis){
var row = getTheCurrentRow(pThis.id);
var nameAndRow = "f03_" + row;
var costCentre = $x(nameAndRow).value;
alert("the cost centre id is " + costCentre);
}
// the triggerItem has the name fxx_yyyy where xx is the column number and
// yyyy is the row. This function just returns yyyyy
function getTheCurrentRow(triggerItem){
var theRow = triggerItem.slice(4);
return theRow;
}
Whilst this works I can't help feeling that I must be re-inventing the wheel and that
either, there are built-in's that I can use or if not there maybe a "better" way?
In case of need I'm using Apex 4.0
Thanks in advance for any you can provide.
Well, what you have described is exactly what I typically do myself!
An alternative in Apex 4.0 would be to use jQuery to navigate the DOM something like this:
var costCentre = $(pThis).parents('tr').find('input[name="f03"]')[0].value;
I have tested this and it works OK in my test form.
Related
I am creating an app which will perform some simple mathematical functions. One of these functions is to sum the field on my table. However, it should sum the field based on what is selected on the drop down menu and display the sum value on an edit field component. For instance, using the attached image, when I click control total, I would like to display the sum of the numbers in the fiscal period column and display it on the edit field on the right called sum.
function ControlTotalButtonPushed(app, event)
ct = app.FieldsDropDown.Value;
total = sum(app.UITable.Data.ct);
app.EditFieldTotal.Value = total;
if total == 0
app.BalanceUnbalanceLabel.Text = 'Balance';
else
app.BalanceUnbalanceLabel.Text = 'Unbalance';
end
end
I get an error:
Unrecognized variable name 'ct'
I thought app.UITable.Data.ct would refer to the column name to sum?
Please refer to the attached picture.
I've been having trouble figuring out how to have multiple intervals used on a page. Normally, this wouldn't be a problem but I'm working to create a dynamic countdown script which uses data submitted by the user and have to abide by a few rules:
I need the interval only to clear specifically for given element.
I only need the interval to clear if there currently is an interval set in that specific element.
My idea was to count each interval and assign the number instance to each one. So something like this :
function(element, data, api) {
let intervalIds = [];
for (var i=0; i < intervalIds.length; i++){
}
intervalIds.push(setInterval(function(){
console.log(intervalIds[i]);
clearInterval(intervalIds[i]-1);
//timecalculations after
}, 1000 ));
}
This worked at first, however when I refresh the page with multiple intervals, but after I refresh the page there is only one interval.
If the element ID is the same and a interval has been set for this element then clear the previous interval
If the element ID is different just simply start a new interval
P.S with the software I'm using I can access the element id using data.elementId. ex: if (data.elementId == data.elementId) { do stuff }
I found out the answer to this riddle.
You would need to create a dynamic variable. To do this you would either need to use eval() or assign the variable to the window scope. Then assign the interval to that variable.
Luckily, the software I work with assigns a unique Id to each element added to the page. So I can use this unique Id to assign it to the variable to create the dynamic va
For example:
//unique id
var dynamicIntervalID = $(element).attr('id');
//clear interval if one exists
if (window["intervalIds"+dynamicIntervalID])clearInterval(window["intervalIds"+dynamicIntervalID])
//assign unique element id to interval
window["intervalIds"+dynamicIntervalID] = setInterval(function(){
...code here..
}, 1000 );
Hope this helps.
I have a Google Sheet where information from a Google Form is dumped. Two of the columns create a date range (columns C and G) and I would like for the sheet to automatically create a new row of information for every date of the range and copy all the other information from the original row for every row that is created. In the end, every date in the range has it's own row regardless of it being 2 days or 25 and all the the information gathered through the form be present for each day. If there is not a date in column G, it is only a one day trip and there is no need for additional rows. To make things more difficult when someone submits a form, the information is entered into the row directly beneath the last one that it filled, so these new rows filled by the date range will need to be down the sheet, possibly beginning at row 2000 or more as this sheet will have a lot of information in a few months. As you may see in the sample, there is another sheet in the workbook that performs all the sorting. Thanks for any help.
Sample Document
You will need to create a form submit event and attach the following code to it. Also you'll need to create a sheet name 'ResponseReview'.
function formSubmitEvent1(e)
{
var ss=SpreadsheetApp.openById('SpreadsheetID');
var sht=ss.getSheetByName('ResponseReview');
sht.appendRow(e.values);
}
The above code will need the SpreadsheetId in the openById Method. This code will append any new rows to the end of the ResponseReview sheet.
The code below will expand any entrees that have a date in column 3 and 7 and it will also remove the end date in column 7 from that first row. I use the fact that if column 3 is not empty and column 7 is not and column 7 is no equal to column 3 then that's a row that needs to be expanded. So I have to remove the end date so that it won't continue to get expanded when it's run again in the future. We could figure something else out if you need to keep than end date. We could add a don't expand column at the end.
function convertRangetoRows()
{
var ss=SpreadsheetApp.getActive();
var sht=ss.getSheetByName('ResponseReview');
var rng=sht.getDataRange();
var rngA=rng.getValues();
var rngB=[];
var day=86400000;
rngB.push(rngA[0]);
for(var i=1;i<rngA.length;i++)
{
rngB.push(rngA[i]);
if(rngA[i][2] && rngA[i][6] && rngA[i][2]!=rngA[i][6])
{
var row=rngA[i].slice();//returns a new copy of the array by value
rngA[i][6]='';//deletes the end date by reference so it also deletes the one thats already been pushed into rngB
var dt0=new Date(row[2]);
var dt1=new Date(row[6]);
var days=(dt1.valueOf()-dt0.valueOf())/day;
var dt=dt0.valueOf();
for(j=0;j<days;j++)
{
dt+=day;
row[2]=Utilities.formatDate(new Date(dt), Session.getScriptTimeZone(), "MM/dd/yyyy");//original array unchanged
row[6]='';//original array unchanged
rngB.push(row.slice());//push in a copy
}
}
var intermediate='nothing';
}
var outrng=sht.getRange(1,1,rngB.length,rngB[0].length);
outrng.setValues(rngB);
var end='the end is near';
}
This is what my spreadsheet looks like before running the expansion function:
And After:
And now you can leave the sheet linked to the form alone and let it be an archive for submitted data.
I am trying to mimic the functionality of the right sidebar of this example for my Angular site.
I don't know what this is called, or even how to go about it on the front end or back end!
My assumption:
Create a form with values coming straight from the DB and only show the desired parameter (i.e. db.collection.find(query, {parameter: 1}) which will be called to update each time a user modifies the form. Additionally, the results would also be updated on selection (I have over 100MB of documents, returning ALL of them would be troublesome, how can I limit the number of documents returned to let's say 20 or 50 (user input?) and paginate it (1000 documents returned / 50 per page = 20 'pages')
Each input that is selected, a { 'field' : value } would be returned -- but I am not sure how to control an empty value (i.e. what if a user doesn't pick a fuel type or transmission range?)
How do I go about designing such a feature correctly?
1) In your query, use limit statement:
var options = { "limit": 20 }
collection.find({}, options).toArray(...);
2) you can validate user empty input (for eg. with express-validator):
req.checkBody('postparam', 'Invalid postparam').notEmpty()
req.getValidationResult().then(function(result) {
if (!result.isEmpty()) {
res.status(400).send('There have been validation errors: ' + util.inspect(result.array()));
return;
}
and based on result choose default value/pass error/render ask page for user
I've got a form done in x++ (formBuild) and I managed to display different grids in different tabs. However, when I do a right-click record info on any of the grids other than the first one, the details are that of the first grid. Eg. The second row of grid 2 when I do a record info is actually the second row of grid 1.
One thing is all the grids are actually using the same table, just having different query ranges for each.
Any way to fix this?
Added code snippets
Making the grid:
for (counter = 0; counter < locations.lastIndex(); counter++)
{
formBuildDatasource = form.addDataSource(tableStr(SomeTable));
formBuildTabPageControl = formBuildTabControl.addControl(FormControlType::TabPage, locations.value(counter+1));
formBuildTabPageControl.caption(locations.value(counter+1));
formBuildGridControl = formBuildTabPageControl.addControl(FormControlType::Grid, locations.value(counter+1));
formBuildGridControl.allowEdit(0);
formBuildGridControl.dataSource(formBuildDatasource);
formBuildGridControl.height(500,-1);
formBuildGridControl.width(550,-1);
formBuildGridControl.addDataField(formBuildDatasource.id(), fieldNum(SomeTable, MachineId));
formBuildGridControl.addDataField(formBuildDatasource.id(), fieldNum(SomeTable, MachineStatus));
}
Adding the query:
for (counter = 0; counter < locations.lastIndex(); counter++)
{
fds = formRun.dataSource(counter+1);
qbds = fds.query().dataSourceNo(1);
qbr = Qbds.addRange(fieldnum(SomeTable, MachineLocation));
qbr.value(locations.value(counter+1));
}
This answer to your prior question applies here as well:
Adding view/temporary table records to Form Grid
You will have to use more than one datasource (using the same table). Remember to change the datasource attribute of the grids to match the correct one. My guess would be that they currently all reference the same datasource.
Can you make a query + view of the table, and have that as the 'child' entity?
I don't know why you can't have the same table referenced twice in the same form data sources, however. Ensure that the link between the tables are defined correctly, and you have no confusion with the datasource names that you use for them.
You actually need to set the datasource on the grid object using the id() method on the FormDataSource object, not just the full object.
Change from:
formBuildGridControl.dataSource(formBuildDatasource);
to:
formBuildGridControl.dataSource(formBuildDatasource.id());