Very simple if else check in Google App Maker - google-app-maker

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.

Related

X++ assign Enum Value to a table column

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));
}
}

update edited cells within treetable after expand/collapse items

I have a treeTable with editable cells within the expanded rows. The editable cells get a dirty flag after editing (in the example the background color is set to red).
The problem i'm running into is that i found no certain way to update the dirty flag on expand/collapse (edited cells get the css class 'edited-cell').
At the moment the code looks like that:
// each editable textfield gets a Listener
textField.attachLiveChange(
var source = oEvent.oSource;
...
jQuery('#' + source.getId()).addClass(EDITED_CELL_CLASS, false)
// list with cell ids, e.g. "__field1-col1-row1"
DIRTY_MODELS.push(model.getId()) //*** add also binding context of row
)
// the table rows are updated on toggleOpenState
new sap.ui.table.TreeTable({
toggleOpenState: function(oEvent) {
...
this.updateRows() // see function below
}
})
// update Rows function is also delegated
oTable.addDelegate({ onAfterRendering : jQuery.proxy(this.updateRows, oTable)});
//http://stackoverflow.com/questions/23683627/access-row-for-styling-in-sap-ui5-template-handler-using-jquery
// this method is called on each expand/collapse: here i can make sure that the whole row has it's correct styling...
// but how to make sure that special cells are dirty?
function updateRows(oEvent) {
if (oEvent.type !== 'AfterRendering'){
this.onvscroll(oEvent);
}
var rows = this.getVisibleRowCount();
var rowStart = this.getFirstVisibleRow();
var actualRow;
for (var i = 0; i < rows; i++){
actualRow = this.getContextByIndex(rowStart + i); //content
var row = this.getRows()[i]
var obj = actualRow.getObject()
var rowId = row.getId()
updateStyleOfRows(obj, rowId, actualRow)
updateDirtyCells(rowId) //*** how to get the binding context in this function???
}
};
// update Dirty Cells in function updateRows():
function updateDirtyCells(rowId){
for (var i = 0; i < DIRTY_MODELS.length; i++){
var dirtyCellId = DIRTY_MODELS[i]
//*** make sure that only the correct expanded/collapsed rows will be updated -> depends on the bindingContext of the row
jQuery('#' + rowId).find('#' + dirtyCellId + '.editable-cell').addClass(EDITED_CELL_CLASS, false)
}
}
This doesn't work correctly, because the ids of the cells change on each layout render (e.g. collapse/expand rows). Please see attached image.
Let me know if i should provide more information.

Placing a floating info panel

I'm using Jame Ferreira's Google Script: Enterprise Application Essentials to create a product page (Chapter 5). I've created the app that displays thumbnails of the products all on a page, and then the info panel with more detail that pops up when the user mouses over. It's using CSS to achieve this styling.
Problem comes in when placing the info panel. It pops up in only one location, as opposed to being tied to the thumbnail with which it is associated.
Here's the code related to the info panel. I believe the problem exists in the placement of the last few lines, but have tried everything I can think of:
function onInfo(e){
var app = UiApp.getActiveApplication();
var id = e.parameter.source;
for (var i in productDetails){
if(productDetails[i].id == id){
var r = 50;
var c = 0;
var infoPanel = app.createVerticalPanel().setSize('300px', '300px');
var horzPanel = app.createHorizontalPanel();
var image = app.createImage(productDetails[i].imageUrl).setHeight('100px');
var title = app.createLabel(productDetails[i].title);
horzPanel.add(image);
horzPanel.add(title);
var description = app.createLabel(productDetails[i].description);
infoPanel.add(horzPanel);
infoPanel.add(description);
applyCSS(infoPanel, _infoPanel);
applyCSS(image, _infoImage);
applyCSS(horzPanel, _infoBoxSeparator);
applyCSS(title, _infoTitle);
applyCSS(description, _infoDescription);
app.getElementById('infoGrid').setVisible(true)
.setWidget(0,0, infoPanel);
break;
}
c++
if (c == 3){
c = 0;
r = r+250;
}
switch (c)
{
case 0:
c=250;
break;
case 1:
c=500;
break;
case 2:
c=250;
break;
}
}
var _infoLocation =
{
"top":r+"px",
"left":c+"px",}
applyCSS(infoPanel, _infoLocation);
return app;
}
You may get the position of the mouse using e.parameter.x and e.parameter.y based on which you can position the infoPanel
infoPanel.setStyleAttribute('top',e.parameter.y)
.setStyleAttribute('left',e.parameter.x).setStyleAttribute('zIndex','1')
.setStyleAttribute('position','fixed');
You may add some offset to x and y positions of mouse to display it according to your needs.
Position related parameter which you get in handler function are
e.parameter.x
e.parameter.y
e.parameter.clientX
e.parameter.clientY
e.parameter.screenX
e.parameter.screenY

Multiple ASP.NET DropDownLists are being set to the same value

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

Dynamically adding container to a dynamic container

I have a loop that goes through data from a book and displays it. The book is not consistent in it's layout so I am trying to display it in two different ways. First way(works fine) is to load the text from that section in to a panel and display it. The second way is to create a new panel (panel creates fine) and then add collapsable panels(nested) to that panel. Here is the code from the else loop.
else if (newPanel == false){
// simpleData is just for the title bar of the new panel
// otherwise the panel has no content
var simpleData:Section = new Section;
simpleData.section_letter = item.section_letter;
simpleData.letter_title = item.letter_title;
simpleData.section_id = item.section_id;
simpleData.title = item.title;
simpleData.bookmark = item.bookmark;
simpleData.read_section = item.read_section;
var display2:readPanel02 = new readPanel02;
//item is all the data for the new text
display2.id = "panel"+item.section_id;
//trace(display2.name);//trace works fine
// set vars is how I pass in the data to the panel
display2.setVars(simpleData);
studyArea.addElement(display2); // displays fine
newPanel = true;
//this is where it fails
var ssPanel:subSectionPanel = new subSectionPanel;
//function to pass in the vars to the new panel
ssPanel.setSSVars(item);
//this.studyArea[newPanelName].addElement(ssPanel);
this["panel"+item.section_id].addElement(ssPanel);
The error I get is: ReferenceError: Error #1069: Property panel4.4 not found on components.readTest and there is no default value.
I have tried setting the "name" property instead of the "id" property. Any help would be greatly appreciated. I am stumped. Thanks.
So here is the solution I came up with. I made the new readPanel create the sub panels. I added the else statement to help it make more sense. The readPanel creates the first sub panel, and for every subsequent need of a sub panel it references the other panel by name and calls the public function in the panel that creates the new sub panel. Here's the code to create the main panel:
else if (newPanel == false){
var display2:readPanel02 = new readPanel02;
studyArea.addElement(display2);
display2.name = "panel"+item.section_id;
display2.setVars(item);
newPanel = true;
}
else{
var myPanel:readPanel02 = studyArea.getChildByName("panel"+item.section_id) as readPanel02;
myPanel.addSubSection(item);
}
And here is the functions in the panel:
public function setVars(data:Section):void
{
myS = data;
textLetter = myS.section_letter;
textLetterTitle = myS.letter_title;
textSection = myS.section_id;
textTitle = myS.title;
myS.bookmark == 0 ? bookmarked = false : bookmarked = true;
myS.read_section == 0 ? doneRead = false : doneRead = true;
showTagIcon();
showReadIcon();
addSubSection(myS);
}
public function addSubSection(data:Section):void{
var ssPanel:subSectionPanel = new subSectionPanel;
ssPanel.setSSVars(data);
myContentGroup.addElementAt(ssPanel, i);
i++;
}

Resources