I'm working with ordered data and ran into this problem:
I add items to a location with push() and set their priority to their creation date in milliseconds so they are ordered by date. When I try to change the order of the items I find the next, or previous (if there's no next) item and get it's priority, then I add or substract one and set the priority of the moved item to the result. I fetch the priority ok, but when I call setPriority() the item loses the priority. Exporting the item with the graphical debugger returns no priority for each item moved. Returns correct priority for unmoved items.
Some code:
/* id is the id of the div being moved
using jquery ui's sortable
div id's are formed like "item_" + firebaseref.name()
*/
name = id.substr(id.indexOf('_') + 1);
id2 = $('#' + id).next().attr('id');
if(id2){
name2 = id2.substr(id2.indexOf('_') + 1);
itemRef = rootRef.child('path/to/my/items/'+name2);
itemRef.once('value', function (dataSnapshot){
var pr = Number(dataSnapshot.getPriority()),
myRef = rootRef.child('path/to/my/items/'+name);
myRef.setPriority(pr - 1); // tried this or toString as below
});
} else {
// try previous item
id2 = $('#' + id).prev().attr('id');
if(id2){
name2 = id2.substr(id2.indexOf('_') + 1);
itemRef = rootRef.child('path/to/my/items/'+name2);
itemRef.once('value', function (dataSnapshot){
var pr = Number(dataSnapshot.getPriority()) + 1,
myRef = rootRef.child('path/to/my/items/'+name);
myRef.setPriority(pr.toString());
});
}
}
I had a 'child_moved' listener but I'm not using it now. Any ideas?
This is a bug in Firebase. I'm not sure of the cause at this point but it appears that numbers larger than a certain size are not being properly saved. We'll investigate and update this answer when complete.
Update: This bug has been resolved. Give it another try!
Related
I am trying to pull the Enum chosen from a dialog and assign the label to a table's column.
For example: Dialog opens and allows you to choose from:
Surface
OutOfSpec
Other
These are 0,1,2 respectively.
The user chooses OutOfSpec (the label for this is Out Of Spec), I want to put this enum's Name, or the label, into a table. The column I'm inserting into is set to be a str.
Here's the code I've tried, without success:
SysDictEnum dictEnum = new SysDictEnum(enumNum(SDILF_ScrapReasons));
reason = dialog.addField(enumStr(SDILF_ScrapReasons),"Scrap Reason");
dialog.run();
if (!dialog.closedOk())
{
info(reason.value());
return;
}
ttsBegin;
// For now, this will strip off the order ID from the summary fields.
// No longer removing the Order ID
batchAttr = PdsBatchAttributes::find(itemId, invDim.inventBatchId, "OrderId");
orders = SDILF_BreakdownOrders::find(batchAttr.PdsBatchAttribValue, true);
if (orders)
{
orders.BoxProduced -= 1;
orders.update();
}
// Adding a batch attribute that will include the reason for scrapping
select forUpdate batchAttr;
batchAttr.PdsBatchAttribId = "ScrapReason";
//batchAttr.PdsBatchAttribValue = any2str(dictEnum.index2Value(reason.value()));
batchAttr.PdsBatchAttribValue = enum2str(reason.value());
batchAttr.InventBatchId = invDim.inventBatchId;
batchAttr.ItemId = itemId;
batchAttr.insert();
Obviously this is not the whole code, but it should be enough to give the issue that I'm trying to solve.
I'm sure there is a way to get the int value and use that to assign the label, I've just not been able to figure it out yet.
EDIT
To add some more information about what I am trying to accomplish. We make our finished goods, sometimes they are out of spec or damaged when this happens we then have to scrap that finished good. When we do this we want to keep track of why it is being scrapped, but we don't want just a bunch of random reasons. I used an enum to limit the reasons. When the operator clicks the button to scrap something they will get a dialog screen pop-up that allows them to select a reason for scrapping. The code will then, eventually, put that assigned reason on that finished items batch attributes so that we can track it later in a report and have a list of all the finished goods that were scrapped and why they were scrapped.
I'm not entirely sure of your question, but I think you're just missing one of the index2[...] calls or you're not getting the return value from your dialog correctly. Just create the below as a new job, run it, make a selection of Open Order and click ok.
I don't know the difference between index2Label and index2Name.
static void Job67(Args _args)
{
Dialog dialog = new dialog();
SysDictEnum dictEnum = new SysDictEnum(enumNum(SalesStatus));
DialogField reason;
SalesStatus salesStatusUserSelection;
str label, name, symbol;
int value;
reason = dialog.addField(enumStr(SalesStatus), "SalesStatus");
dialog.run();
if (dialog.closedOk())
{
salesStatusUserSelection = reason.value();
// Label
label = dictEnum.index2Label(salesStatusUserSelection);
// Name
name = dictEnum.index2Name(salesStatusUserSelection);
// Symbol
symbol = dictEnum.index2Symbol(salesStatusUserSelection);
// Value
value = dictEnum.index2Value(salesStatusUserSelection);
info(strFmt("Label: %1; Name: %2; Symbol: %3; Value: %4", label, name, symbol, value));
}
}
This is likely embarrassingly easy but I'm new and I've been beating my head against the wall on this for a while now. What I am attempting to do is basically a modified version of the "Hello App Maker!" If else test.
The necessary info I have the following widgets attached to the appropriate data sources:
Dropdown widget called source_name (string - list)
Label widget I've called name (string)
Text Box widget called qty_duration (number)
Label widget I've called hours (number)
I have a dropdown widget called source_name with 5 options. On selection I have the value appear in a label widget I've called name. If the option selected from the drop down widget is ever LABOUR I am trying to then have the value of a Text Box widget called qty_duration appear in a label widget I've called hours
On the source_name dropdown event - onValueChange I have the following code:
// Define variables for the input and output widgets
var nameWidget = app.pages.Apex_job_details.descendants.name;
var outputWidget = app.pages.Apex_job_details.descendants.hours;
var techhours = app.pages.Apex_job_details.descendants.qty_duration;
var nothing = 0;
// If a name is LABOUR, add the qty to the output widget Else output 0.
if (nameWidget == 'LABOUR') {
outputWidget.text = techhours;
} else {
outputWidget = nothing;
}
It's not giving me any errors, but it's also not outputting to the hours label. If I edit the code as follows just to muck with it:
// Define variables for the input and output widgets
var nameWidget = app.pages.Apex_job_details.descendants.name;
var outputWidget = app.pages.Apex_job_details.descendants.hours;
var techhours = app.pages.Apex_job_details.descendants.qty_duration;
var nothing = 0;
// If a name is LABOUR, add the qty to the output widget Else output 0.
if (nameWidget == 'LABOUR') {
outputWidget.text = techhours;
} else {
outputWidget.text = nothing;
}
I'm not sure what I'm doing wrong.
Assuming all labels and input widgets are inside a table row you will want to adjust your code as follows:
var tablerow = widget.parent;
var nameWidget = tablerow.descendants.name.text;
var outputWidget = tablerow.descendants.hours;
var techhours = tablerow.descendants.qty_duration.value;
if(nameWidget === 'LABOUR') {
outputWidget.text = techhours;
} else {
outputWidget.text = null;
}
By using widget.parent in the onValueChange event of the dropdown you will automatically reference the table row and then by using descendants you are referencing only the descendants of that table row. This will bridge the error by using an absolute reference when using table rows. If it still doesn't work let me know.
Scenario:
I have a calculated SQL that returns 100 results.
Added a table (from this calculated SQL) and limited the size of the page by 25 results.
This will generate 4 pages.
Pager form AppMaker works well (navigates between pages) but i need a button that navigates directly from page 1 to the page 4.
is this possible?
Anyone got a solution for this?
Regards
If you need to know how many entries your table has (in your case it's seems fixed to 100, but maybe it could grow), you can still do what you want:
E.g. say your table on YOURPAGE depends on a datasource called Customers.
Create a new Data item called CustomerCount, with just one field, called Count (integer).
Its data source would be a sql query script:
Select count(CustomerName) as Count from Customers
on the page you are having the table on, add a custom property (say called
Count of type integer)
In the page attach event, set the property asynchronously with this custom action:
app.datasources.CustomerCount.load(function() {
app.pages.YOURPAGE.properties.Count = app.datasources.CustomerCount.count;
app.datasources.Customers.query.pageIndex = #properties.Count / 25;
app.datasources.Customers.datasource.load();
});
I tried similar things successfully in the past.
Found a solution for this:
ServerScript:
function CandidateCountRows() {
var query = app.models.candidate.newQuery();
var records = query.run();
console.log("Number of records: " + records.length);
return records.length;
}
in the button code:
var psize = widget.datasource.query.pageSize;
var pidx = widget.datasource.query.pageIndex;
var posicao = psize * pidx;
var nreg = posicao;
google.script.run.withSuccessHandler(function(Xresult) {
nreg = Xresult;
console.log('position: ' + posicao);
console.log('nreg: ' + nreg);
console.log('psize: ' + psize);
console.log('pidx: ' + pidx);
var i;
for (i = pidx; i < (nreg/psize); i++) {
widget.datasource.nextPage();
}
widget.datasource.selectIndex(1);
}).CandidateCountRows();
This will allow to navigate to last page.
If you know for a fact that your query always returns 100 records and that your page size will always be 25 records then the simplest approach is to make sure your button is tied to the same datasource and attach the following onClick event:
widget.datasource.query.pageIndex = 4;
widget.datasource.load();
I'm using the angular-ui ui-scroll and it's great when I scroll down, keeps adding items as expected. However when I scroll up, it stops at the top of the last batch that I loaded. For example if I have 100 items and my buffer size is 10, and I've scrolled down so that items 61-70 are showing, when I scroll back up I want to see items 51-60. However I can't scroll up past item 61. I don't know what I'm doing wrong.
Here's the html:
<div row="row" ui-scroll="row in transactionSource" buffer-size="10" >{{row.data}}</sq-transaction>
Here's the script:
$scope.transactionSource = {
get: function (index, count, callback) {
if (index < 0) {
callback([])
}
else {
var buffer = 10;
var end = ctrl.nextIndex + buffer;
if (end > ctrl.transactions.length) end = ctrl.transactions.length;
var items = ctrl.transactions.slice(ctrl.nextIndex, end);
ctrl.nextIndex = end;
callback(items);
}
}
};
If it's related, when I console.log the index and count values received, after the first load of 10 I get an index of -9 (in which case I return an empty array - if I don't do this, the entire array gets loaded). When I scroll up, I don't get a console.log message at all so it's like the 'get' only gets called when scrolling down.
Thanks in advance for any and all help.
Your datasource looks wrong. Items retrieving (slicing in your case) should be based on index and count parameters that you have from the datasource.get method arguments. I'd like to post an example of datasource implementation where the result items array is limited from 0 to 100 and should be sliced from some external data array:
get: function(index, count, success) {
var result = [];
var start = Math.max(0, index);
var end = Math.min(index + count - 1, 100);
if (start <= end) {
result = externalDataArray.slice(start, end + 1);
}
success(result);
};
Hope it helps!
I have 6 dropdown lists (with identical options), and I am manually setting them in my codebehind. All six should have different values. When I log the values I am setting them to, I get the correct assumed values to be set to. However, when the page renders, all six of them are set to the same freaking value.
I have tried setting the values with all of the following:
// set index, find by text
dd1.SelectedIndex = dd1.Items.IndexOf(dd1.Items.FindByText(val1));
// set with selected value
dd2.SelectedValue = val2;
// set index, find by value
dd3.SelectedIndex = dd3.Items.IndexOf(dd3.Items.FindByValue(val3));
// set list item, selected = true
((ListItem)dd4.Items.FindByValue(val4)).Selected = true;
The dropdown lists' set of options are generated prior to me trying to set them:
foreach (Station st in stations) {
ListItem li = new ListItem() { Text = st.fromto, Value = st.fromto};
dd1.Items.Add(li);
dd2.Items.Add(li);
dd3.Items.Add(li);
dd4.Items.Add(li);
dd5.Items.Add(li);
dd6.Items.Add(li);
}
I then look in the database to see if any values exist for a specific reference id in my app. If so, it indicates that I need to set one or more (up to 6) dropdowns:
var existingStations = db.LOGOPS_STATIONs.Where(x => x.XREF_LOGOP_MAIN_ID == logopRefId);
if (existingStations.Count() > 0) {
int i = 1;
foreach (LOGOPS_STATION s in existingStations) {
if (i < 7) {
string text= s.FROM_STATION;
if (i == 1) dd1.SelectedIndex = dd1.Items.IndexOf(dd1.Items.FindByText(text));
// for the heck of it, set the next one manually...
else if (i == 2) dd2.SelectedIndex = 2;
// try and set one with forcing select
else if (i == 3) ((ListItem)dd3.Items.FindByText(text)).Selected = true;
// good ol normal
else if (i == 4) dd4.SelectedValue = text;
... and so on ...
}
}
}
So, the dropdowns are all populated (when I log in the codebehind they're fully populated). And when I log the actual values when they're being set, they're set to the value as expected. However, when the page loads, they're all set to the same thing
At any rate, not sure what else to do. I have turned on and off different event validation hookups. I have disabled all JS to see if that was manipulating values, and it's not. I have tried explicitly setting like this
dd1.SelectedIndex = 2;
dd2.SelectedIndex = 8;
Oddly enough, that doesn't work either. For real, when does setting SelectedIndex to a unique control with a unique id not set the item?
I had to create a separate list item for each dropdown instead of them all sharing the same li in the foreach loop. And then a step further, had to set Selected = false in the constructor of the ListItem
I assumed that you could 'reuse' code for each instance of the dropdown population, but each dropdown needed it's own unique ListItem
Maybe there's a better way, but this solution seems to have solved the problem