Interacting with Hidden Fields and Actions with Javascript - acumatica

I am trying to figure out how to get values back and forth between an external javascript library and the Acumatica back end.
Currently I have 2 fields that are hidden (set to hidden on the PXUIField Attribute) and I am picking up their values successfully as follows:
function doSomething() {
var url = px_alls['txtUrl'].value;
var clientId = px_alls['txtClientID'].value;
}
However I am not having the same luck setting a hidden fields values and then posting the data to the back end in this way:
client.on('someEvent', (data) => {
px_alls['txtId'].value = data.id;
Save();
})
How can I accomplish this?
Thanks
-Kyle

Reading form fields from px_alls works fine but I was not able to automate saving.
I use action callback to send the values from JavaScript to an action defined in the Graph.
var ds = px_alls['ds'];
ds.executeCallback('TestAction', 'parameter value');
Then In the graph you can use the parameter value to update the document:
public PXAction<PrimaryDAC> TestAction;
[PXButton]
[PXUIField(DisplayName = "Test Action")]
public virtual IEnumerable testAction(PXAdapter adapter)
{
string parameterValue = adapter.CommandArguments;
// Update document here with parameter value
return adapter.Get();
}

Related

Passing parameters to GraphAction in Acumatica from toolbar button

(Edited to better reflect the current state after help from the comments)
I have a graph extension to which I have added a PXAction and PXButton etc. The method (now) accepts parameters.
The button appears on the screen as expected an I can debug the action code in Visual Studio when the button is clicked.
// test params action.
public PXAction<InventoryItem> testParams;
[PXUIField(DisplayName = "Test Params", MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select)]
[PXButton(CommitChanges = true)]
public virtual IEnumerable TestParams(PXAdapter adapter, [PXInt] int? siteID, [PXString] string testParamStr)
{
IEnumerable ret = adapter.Get();
if (adapter.Parameters != null)
{
int a = 0;
a++;
}
return adapter.Get();
}
After adding the parameters to my C# method and re publishing etc, the parameters appeared as options in the Parameter column below and I have been able to configure parameters to send through when I press the button on my stock item screen:
However... when I debug and look at the adapter, the method arguments (siteId and testParamsStr) are null as is adapter.Parameters
and adapter.CommandArguments is an empty string.
As per Hugues Beauséjour's comment, the documentation for amending an existing action describes just this but how do we get at the values in the C# code? Looking at existing actions in Acumatica I don't think I'm missing any markup attributes etc.
Ideally I'd like a zero-code way to do what I'm trying to do but I'm not sure that's possible so I'm trying very short action code that passes values to a central class we will write to allow users to set up their own parameters that the central class will process so that they don't have to do any lengthy coding in the action code (the rest of the story is longer but that's the bit that's relevant to this question!).
Thanks!
This is how to pass parameters using code only. I'm posting it to help other people who might need it. For configuring the wizard parameters, this will not help much unfortunately.
// Graph Action
public PXAction<MyPrimaryDAC> MyAction;
[PXButton]
[PXUIField(DisplayName = "My Action")]
public virtual IEnumerable myAction(PXAdapter adapter)
{
// String value coming from JavaScript is read in adapter.CommandArguments
string payload = adapter.CommandArguments;
}
// JavaScript calls the graph action with a string parameter in payload variable
var ds = px_alls['ds'];
var actionName = 'MyAction';
var payload = 'string value passed to server';
ds.executeCallback(actionName, payload);

How can I filter records for the Generate Recurring Entries (GL504000) screen

I'm trying to modify the Generate Recurring Transactions (GL504000) screen, and I want to add a user field to filter the grid. I've added a UsrRecurringClass user field to DAC extensions of both the 'Parameters' DAC for the header, and the 'Schedule' DAC for the grid. Now I want to filter that grid by the selection I've added to the header (The UsrRecurringClass field I've added to both)
The problem is, I can't add that field to the View select (Schedule_List) and have it make any difference (I did set the CommitChanges to true on the header filter field).
I've added this to graph extension of the 'ScheduleRun' BLC, as follows, but it doesn't seem to make any difference...
[PXFilterable]
public PXFilteredProcessing<Schedule, ScheduleRun.Parameters,
Where2<Where<ParametersExt.usrRecurringClass, IsNull, Or<ScheduleExt.usrRecurringClass, Equal<Current<ParametersExt.usrRecurringClass>>>>,
And2<Where<Schedule.active, Equal<True>>,
And<Schedule.nextRunDate, LessEqual<Current<ScheduleRun.Parameters.executionDate>>>>>> Schedule_List;
Maybe I'm not doing the BQL correctly, or there's a better way, using the View delegate - I'm not sure.
Any ideas?
I have done a similar customization, maybe the pattern will help you.
public class ARCreateWriteOff_Extension : PXGraphExtension<ARCreateWriteOff>
{
#region Event Handlers
// First expose the PXFilterable view in the extension
[PXFilterable]
[PX.SM.PXViewDetailsButton(typeof(ARRegisterEx.refNbr), WindowMode = PXRedirectHelper.WindowMode.NewWindow)]
public PXFilteredProcessingJoin<ARRegisterEx> ARDocumentList;
// the ARDocumentList view is a long BQL statement I just removed most of it for the example
// Over write the IEnumerabel
protected virtual IEnumerable aRDocumentList()
{
// Get the current row and its extention
ARWriteOffFilter aRWriteOffFilter = Base.Filter.Current;
ARWriteOffFilterExt aRWriteOffFilterExt = aRWriteOffFilter.GetExtension<ARWriteOffFilterExt>();
// loop the values
foreach (ARRegisterEx item in Base.ARDocumentList.Select())
{
//check if the field is Null to return all data
if (string.IsNullOrWhiteSpace(aRWriteOffFilterExt.UsrEmployeeID))
{
yield return item;
}
else
{
// Here you will check if your filter matches the row level
if (aRWriteOffFilterExt.UsrEmployeeID == bAccountExt.UsrEmployeeID)
{
yield return item;
}
}
}
}

Add note to custom data record in code

I was searching for a solution to add a note to a database row I am creating in a custom table. I found the solution below from Ruslan for accessing the noteid, but I don't understand how this would be used to add a note to the row. I have all the code to create the row, I just need the attributes or function call to actually attach the text of the note to the row.
==================================================================
To have Note record automatically created when a new parent record gets saved, one should invoke the static PXNoteAttribute.GetNoteID(PXCache cache, object data) method when the parent record is inserted in the cache.
For example, to have Note record automatically created when a new Stock Item gets saved, you should subscribe to RowInserted handler for the InventoryItem DAC and call PXNoteAttribute.GetNoteID(...):
public class InventoryItemMaintExt : PXGraphExtension<InventoryItemMaint>
{
public void InventoryItem_RowInserted(PXCache sender, PXRowInsertedEventArgs e)
{
var noteCache = Base.Caches[typeof(Note)];
var oldDirty = noteCache.IsDirty;
PXNoteAttribute.GetNoteID<InventoryItem.noteID>(sender, e.Row);
noteCache.IsDirty = oldDirty;
}
}
The code snippet above can be incorporated into almost any custom BLC with a couple simple changes to replace InventoryItem with a custom DAC.
After implementing Gabriel's suggestions:
I do not seem to get any note in the database. The code compiles and runs fine, but the notes are not generated as far as I can tell. The note id is set in my table, but no data appears in the note table. Please take a look at my code and let me know what needs to change. Also, how do I get the note column into a grid, or does it automatically become available when it is done correctly?
Database field definition:
[NoteID] [uniqueidentifier] NULL
DAC field:
#region NoteID
public abstract class noteID : PX.Data.IBqlField
{
}
protected Guid? _NoteID;
[PXNote()]
public virtual Guid? NoteID
{
get
{
return this._NoteID;
}
set
{
this._NoteID = value;
}
}
#endregion
Code to create record:
private static bool acumaticaException(Exception e, EDImportExceptionMaint excpMaint, LingoRet850 res850)
{
excpMaint.Clear();
var except = new EDImportExcept();
except.ExceptReason = "U";
except.Active = true;
<...field assignments...>
except.OrderNbr = "";
PXNoteAttribute.SetNote(excpMaint.Exception.Cache, excpMaint.Exception.Current,
((PX.Data.PXOuterException)e).InnerMessages[0] + "-" + e.Message);
excpMaint.Exception.Insert(except);
excpMaint.Actions.PressSave();
return true;
}
To set the note of a record, use the SetNote()static function of PXNoteAttribute
PXNoteAttribute.SetNote(Base.Item.Cache, Base.Item.Current, "Hello, World!");
Calling SetNote will also take care of adding the Note record if it doesn't exist, so you don't have to call GetNoteID before setting the note value as in your question.
P.S. There is also a GetNote function which allows you to retrieve the current value of the note:
string note = PXNoteAttribute.GetNote(Base.Item.Cache, Base.Item.Current);

Monotouch Dialog - Reload data list after modifying row detail not updating list when returning

When an item is clicked, a details view controller is opened that makes some webservice calls to save back the data if the user clicks save (this works fine). The issue I have is after saving the data when the user clicks back to go back to the list, the list item (ie if the name was updated) is not updated. So, perhaps the user changes the name and so the list prior should be updated, I'd like to update the value without having to make another webservice call to repopulate.
I am calling this.ReloadData() when the view appears, but this never seems to update the list names. I've checked workouts which is a list of objects, and it has been modified by the detail controller, however the reload data doesn't seem to do anything.
How do I refresh the data in the case that another controller has modified the list of objects.
public override void ViewWillAppear (bool animated)
{
InvokeOnMainThread (delegate {
this.ReloadData();
}); // call reload on main thread
base.ViewWillAppear (animated);
}
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
workouts = manager.GetWorkouts(Helpers.User.Auth);
var sections = new Section();
var root = new RootElement("Workouts"){sections};
foreach (var wo in workouts) {
var tempwo = wo;
var wodetail = new RootElement(wo.Name, delegate {
var W = new WorkoutViewModel(tempwo);
var p = new WorkoutDetailController(W, tempwo);
return p;
});
sections.Add (wodetail);
}
Root = root;
}
It seems that when you assign the value of an element from a custom object like so:
AccountDetailsSection = new Section ("Details"){
new StringElement ("Code:", _Account.Code),
new StringElement ("Name:", _Account.Name) };
You get the desired result but the element loses the pointer back to the property of the object. So if you change the value of the property later for example:
_Account.Code = "xxx";
Reloading the data doesn't do anything. You should manually update the value like so:
(AccountDetailsSection.Elements [0] as StringElement).Value = "xxx";
this.Root.Reload ( AccountDetailsSection, UITableViewRowAnimation.Fade);
Hope this Helps.

Trying to pass checkbox list enum value to my view

Just trying to do some quick and dirty testing. I am passing fake data through my controller to a view just to see how the UI looks.
In my controller which I set up just to "test" this I have, for example:
MyViewModel = new MyViewModel
{
MyModel= new Models.MyModel
{
FirstName = "Homer", //This works
SomeDecimal = 10000, //This works
SomeRadioButton = Models.MyModel.Enum.Selection, //This works
SomeCheckBox = Models.MyModel.OtherEnum.OtherSelection, //This doesn't
}
}
I am getting the Cannot implicitly convert type ... to 'System.Collections.Generic.List<string>' error.
My radio buttons and check boxes share similar convention for using enums, but the checkbox uses public List<string> SomeCheckBox { get; set; } whereas radio buttons use public Enum? SomeRadioButton { get; set; }
Please note, I am not using a testing framework. I am just trying to figure out quickly how to pass some fake data to see how the UI is shaping up. Can anyone share a sample of how to accomplish what I want (to pass a checkbox value so my UI can show data that would have been selected by a user)?
The other problem I forsee is in passing more than one selection from the checkbox, but once I get the code down I think I should be able to figure that out.
Thanks.
Your error message makes total sense. Try this
var testViewModel = new TestViewModel
{
SomeCheckBox = new List<string> {TestViewModel.RadioButtonValues.Value1.ToString() }
};

Resources