This page has been closed for comments.
We encurage you to use the M3 development at Infor Community for questions, or the H5 SDK git for development of web applications in H5, but please try and avoid posting at multiple locations at the same time.
A lot of the readers of this blog are also interested in H5 Scripting. It’s a bit off topic for this blog, but since we are all in the same team, we have started to answer questions. If you have a specific question on H5 Scripting make sure that you have read the developers guide and then you can ask questions here and if we have time we will try and help out.
M3 H5 Scripting Guide for M3 UI Adapter 10.3.1.0 (always search for the latest version when you are on the support portal).
You can also use the M3 development at Infor Community for questions, or the H5 SDK git for development of web applications in H5, but please try and avoid posting at multiple locations at the same time.
Hi Gerard… Below is whole code of my script. Not sure where did I do wrong but once I switch to othere transaction, the script is not working correctly anymore.
Hi Len,
Thank you for posting on the H5 Scripting page.
But may be you can try this first. I think this line may be causing your script to not work. Try to remove this line on the method H5SampleRequestTracer3.prototype.run().
This method prevents the script from attaching to the reqesting, etc events on the next reloading of the script.
If this does not work, can you please provide me the detailed steps on how to replicate your scenario? I will try to run your script.
Thanks and regards,
Gerard
Hi Gerard,
Everything’s working fine now. Thanks for your help. 🙂
Hi!
Is there anyway to catch the when the user closes a tab from a web mashup sdk? I imagine from a H5 js, it’s just a matter of catching button close/F3, but would that also catch the tab close? Can web mashup sdk session also catch the same?
Thanks!
Jonathan
From using script, you can find the class of the selected tab using “$(“.ui-tabs-selected”)” and navigate through the close button, then you must attach your own listener for the close functionality.
Regards,
Reggie
Hi, for people who still need to solve similar problems: In the actual browser versions, there is an object called “MutationObserver” which can be used to monitor changes; a method is automatically called when the observed object changes:
const config = { childList: true };
this.observer = new MutationObserver(this.onTablistChanged); // <= the H5 program tabs
this.observer.observe(this.headerTabsList, config);
In my case the mashup opened an external tab via bookmark. After closing that tab, the mashup needed to refresh itself
On another subject. Can you do Program Automation scripts like you can in Smart Office?
Theoretically you should be able to use automation mforms:// links in H5 as they support that format and the Automation is taking place in the server but I haven’t tried it myself.
You can use a URL like this to open CRS610 and press F13:
https://yoursampleserver.com:xxxxx/mne/?TASK=mforms%3A//_automation?data=%3c%3fxml+version%3d%221.0%22+encoding%3d%22utf-8%22%3f%3e%3csequence%3e%3cstep+command%3d%22RUN%22+value%3d%22CRS610%22+%2f%3e%3cstep+command%3d%22KEY%22+value%3d%22F13%22+%2f%3e%3c%2fsequence%3e
Hi.
Thanks for a very helpful blog!
Where do I find the developers guide for H5 scripting?
I have tried to search for it on Xtreme, but did not find anything.
Could you provide a download link?
Christian
Hi,
I’m currently investigating where to find it. In the meanwhile I’m going to send it directly to you but I plan to update this blog with the answer – once I get it from the H5 development team.
Hi,
I tried looking for the H5 developer’s guide as well, and you can search it from Infor Extreme. Just type “H5 Development Guide” in the Search texbox on the upper right, make sure to check Search Documentation, and you will be able to see the file in the result. Although, the file may not be updated because it’s last updated 2014. Maybe we should wait for the H5 Development Team to upload an updated one..
I think you should start with the existing one. I don’t know when the document will be updated.
Thank you!
The h5 scripting dev guide suggests using $content.Add(…)
but that (or rather the absolute positioning) does not play nice with the various expanders, I now found that there is also a $content.AddElement that works more like in the “old JScript” days, and plays nicer with the expanders. Any particular reason why the documentation does not suggest using that instead ?
Hi,
The H5 scripting guide as not been updated for a few years. I’ll forward your comment to the development lead for H5. All the examples needs to be updated but I don’t know when an updated version is planned for.
Hi Guys,
Can you please help me with Requesting, Requested and Request Completed in H5 script?
I had a read of the H5 develop guide but it doesn’t mention those events.
I am on H5 Client v10.2.2.0
I’ve got an exception when I call controller.Requested.On(function(args){});
VM910:13 Uncaught TypeError: Cannot read property ‘On’ of undefined(…)
This is my code.
Thanks for your help.
Regards,
Jasper
Hi Jasper,
This is not supported in MUA 10.2.2.0. I’d like to clarify if you’re using this version of MUA. Thanks.
Reah
Hi rdespiritu
Thanks for clarifying.
Can I please ask if that’s possible to handle Requesting, Requested and Request Completed event?
If that’s possible, can I please get some sample code?
Thanks.
Regards,
Jasper
Hi rdespiritu,
Sorry, forgot to mention my previous post is still about MUA 10.2.2.0.
Thanks.
Regards,
Jasper
Hi.
I am trying to do something as simple as adding a Label and a Textbox in my H5 script, but i cant figure out how to do it.
I have dowloaded the H5 dev guide, but it only covers how to add a button, using the “new ButtonElement();”. However, it seems to me that there exists no “TextboxElement()” or “LabelElement()”. Does anyone know where this is documentet, or how you do it?
I see in the comments above that Simon is mentioning a “h5 scripting dev guide” that suggests using $content.Add(…). My copy of the H5 dev guide says nothing about $content.Add, so is this a different guide that is not on Infor Extreme?
Thanks in advance for any help!
Hi, Cheggen.
I got your script guide from the development team. You can download the guide on Infor extreme to compare. As for details it’s best if I forward your request.
it would be nice if you could forward my question to the development team. I am really stuck on this.
Thank you.
Hi Cheggen,
The content.Add function is used in the guide in crs020_PreviewListHeader.js and other examples. We’re currently updating the dev guide including the examples; we’ll post here when we can make it available. Anyway, here’s a sample script for adding elements.
Hi Guys,
Can I please ask if it is possible to add a column in listview in H5 client?
That would be good if I can get some sample code.
Thanks.
Regards,
Jasper
Thank you!:)
Hi Jasper,
It is possible to add a column by directly manipulating the grid.
We will be creating a wrapper for this in the future.
Yes, I have already done that.
Hello,
How to create Hyperlink in data grid for custom column , It means I want to add custom column and want to add data as a hyperlink.
Thank you.
Hello,
I want to extract an information from selected row in a ListView (sub-file), Have you any idea how to do it?
Thanks in advance for any help
Using the name of the column and a reference to the ListControl (which you can get from PanelState or RenderEngine you can use String value= getColumnValue(string columnName). I’ll try to do a new post with an example when I have some spare time.
We would like to know how to build a script in H5 for a M3 list pgm, that adds a button in the header, and when selecting a transaction line in the list, click the button, another M3-program is called with parameters/data from the selected line.
In Jscript for SO this is rather easy, but we lack good examples for this in H5.
Thanks in advance!
Hi Mikael,
You can use ContentElement.AddElement() to add a button and ScriptUtil.Launch() to open a program. Here’s an example which uses the MFormsAutomation utility to create the automation XML to open MMS002 and set the value of W1OBKV.
Hello,
I took this and am trying to modify it to run an automation that uses a related option, and then press enter twice and then F3 to be back in the list, but I keep receiving a message that the program was terminated due to an error. I thought instead of using “ActionType.Run” it would be “ActionType.LSTOPT” is this not correct? If i want to use a related option do I need to define the data that the next screen needs? If not, is there a way to select the entire row, instead of data out of individual columns in the row?
I was also hoping there was a way to have the automation repeat n-times, based on how many rows were selected; is that possible?
Hi Ian,
It should be “ActionType.ListOption”.
Hi Reah,
I have added the button using your script as above. I have also used mforms automation . Everything works fine. But the button is not visible for very first session of the day when I start.
I need to refresh the screen of OIS101/H where this script is added. And after the first refresh for all other sessions my button appears. Can you guide me please what may be the issue.
Actually I have two scripts in OIS101/H one without button and second with Button. Is this causing any issue just because I have two scripts in one program?
Hi,
I was trying to create some customized scripts in H5. I was wondering how can I customize the list by adding a column with editable cells in it? Hope anyone can help. Thanks!
Hi Sam, here’s an example:
Thanks so much! 🙂
Hi! I tried using the TextCellEditor in my script but it is giving me an error “Cannot find name ‘TextCellEditor'” do I need to declare it somewhere first? Thanks!
Hi Jennifer,
I think the function “TextCellEditor” is only a part of H5 and not inside the Scripting SDK that’s why you were having errors in your ts file. I think it should work if the transformed js file is uploaded in H5.
Regards,
Reggie
Hi! Has anyone encountered an issue with the editable cell wherein you have to hold the left click so that the cursor will stay inside the cell so that you can type inside the cell? Any ideas on how to fix that issue? Thanks!
Hi,
I was working on migrating a jScript to a typescript and got stuck. I was trying to open a second dialog after a first.
– Enter pressed
– Show dialog
– Yes
– Do something
– No
– Show Dialog 2
The first Dialog opens with no problem and the doing something works fine too. However, the second Dialog on cancel/no nether shows. Would be nice if you could help find the mistake.
Thank you for your time! 🙂
Hi Marlene,
The ConfirmDialog API currently does not support nested dialogs; only one dialog can exist at a time.
One thing you can do is set a timeout when opening the second dialog. This makes sure the first dialog is removed before the creation of the second is triggered.
Another option is to create your own dialog, instead of using ConfirmDialog. Please note that while this gives you more control, this entails handling forward compatibility on your part. You may have to modify your script should the Infor control library be updated.
Hope this helps.
For cross-reference, another post: https://m3ideas.org/2017/06/02/developing-h5-client-scripts/
Hi again,
There used to be the possibility in jScript to set the MaxLenght of an element.
e.g.
public function Init(element: Object, args: Object, controller : Object, debug: Object){
this.controller = controller;
this.content = controller.RenderEngine.Content;
var element = ScriptUtil.FindChild(content, "WFORNO");
element.set_MaxLength(9);
}
Is there a way to do this with H5ScriptSDK?
Thank you for your help! 🙂
Hi Marlene,
ScriptUtil.FindChild() returns a JQuery object; you can use the library functions for this.
Hi,
I added a button in OIS300 B panel and want do disable the button until a row is selected. To do so I copied the onSelectedRowsChanged event from the “H5SampleSelectionChanged” example of the H5ScriptSDK.
Unfortunately, the “onSelectedRowsChanged” event does not trigger on the first selection of a row. Once I have selected a row and I change the selection, the event triggers as expected.
Due to this behaviour of the event, I am not able to enable the button on the first selection of a row. Is there a way to achieve the described behaviour with a H5 Script?
Thank you for your help
Hi,
This seems like a bug and I think that it might already been reported. Let me check with the developers.
Hi Georg,
This is a bug and an internal ticket has been filed to fix this.
As a workaround, you can set the selected rows after subscribing to the event so the succeeding selections will work.
Tjena Karin,
In H5 Client script (not H5 Script SDK), how can we get the current Option value? 1-Create, 2-Change, 3-Copy, 4-Delete, 5-Display? I tried controller.Response.ControlData.Bookmark.Opt but it returns 1 for both Create/Change. How to tell these two apart?
Tack,
–Thibaud
I don’t want to presume but if what you’d like is to get the current operation the user did before proceeding with your code, i believe you can check this in the OnRequesting(). You can console.log the commandType and commandValue to get the correct condition. In your case commandType should be LSTOPT.
Hi Thibaud,
Please try using controller.GetMode().
Hi Reah,
In the JavaScript console, it throws “controller.GetMode is not a function”.
Grid 11.1.13.0 77
mne 10.3.1.0.147
Foundation 10.1.4.4.1
PPS300/E
[INFO] [PageController.showContainer] Version: 10.3.1.0.147
var controller = getActiveController(); // InstanceController {OPTION_LIST_ACC_WE: “listAccWE”, taskName: “PPS300”, SID: “1EA9F2E40FAA9B85079B91B8F78258E3”, IID: “557691F89A07CF6C11E9FC6B3F56615F”, lastFocus: Object…}
controller.Response.ControlData.Bookmark.Opt // “2”
controller.GetMode()
VM136:1 Uncaught TypeError: controller.GetMode is not a function
These are the available controller.Get* as per code completion, no GetMode, lowercase or uppercase:
GetCachedSelRows
GetContent
GetContentElement
GetElement
GetElementValue
GetGrid
GetInstanceId
GetPanelElement
GetPanelName
GetProgramName
GetSortingOrder
GetValue
GetView
I’m developing a script for H5 Client, no SDK. Why does it throw the exception?
–Thibaud
Hi Reah, did you see my response? I get an exception on GetMode().
GetMode is not available in your version. It has been included since Version: 10.3.1.0.161. We recommend getting the latest version 10.3.1.207.
Hi 🙂 here again with another issue/question,
I was trying to set a value in the Requesting.On event.
I notice it being set for a second to the new value but for the request the original value is used and after the request, the value in the M3 Mask is reset to the old value.
e.g.
controller.Requesting.On((e) => { this.onRequesting(e);
...
private onRequesting(args: CancelRequestEventArgs): void {
this.controller.SetValue("WTEXIN", "012345678");
}
Thank you for your help
Regards,
Marlene
Hi Marlene,
This is currently not supported. The panel field values have already been collected when the Requesting handlers are executed, so the new value is not used in the request.
Any idea for a workaround? Because this was a common use in jScript.
Hi Marlene,
I would try something like the following in your case:
// Define a class member called continue, set it to false by default
if (!this.continue) {
args.cancel = true;
this.setFieldValueAndPressEnter(“WTEXIN”, “012345678”);
}
// Create a method which will set the value, this.continue to true and then then press the enter
// key
private setFieldValueAndPressEnter(field, value) {
this.controller.SetValue(field, value);
this.continue = true;
this.controller.PressKey(‘ENTER’);
}
Hi,
I have a new problem 🙂 when deploying a script in PPS170, the method ListControl.Columns() returns a wrong string array. The array has the correct length (the length of the array equals the number of columns) but the problem is that it contains at any index the string “MVX/” instead of the field name. In further consequence the method ListControl.GetColumnIndexByName() returns always -1. Is this a bug or am I doing something wrong?
Further, the typing for the method GetColumnIndexByName is missing in the SDK. Therefore, a cast to any of the ListControl object is necessary. Would be great if you could add the typing within the next release 🙂
Thank you for your help.
Regards,
Georg
This seems like an M3 BE issue. I would check the response XML (using Fiddler for example) and check which column names are returned from the MUA server. If the list column names contains “MVX/” in the response XML the issue is in either M3 BE or the MUA server and needs to be resolved there. Are there any customer modifications for PPS170? If not you might need to create a support ticket.
Hi,
I have two feature requests for ScriptUtil.ApiRequest. I see it invokes $.ajax() for the HTTP request.
1) Can you return the promise, so that we can use the promise’s functions, such as then()?
instead of:
ScriptUtil.ApiRequest = function (…) { $.ajax({ … }) … }
do this:
ScriptUtil.ApiRequest = function (…) { return $.ajax({ … }) … }
2) Can you add support for ES2017 async/await? It is already implemented in Chrome, Firefox, Safari.
Thank you,
–Thibaud
Hi, ScriptUtil.ApiRequest has been deprecated in favor of MIService. I’m afraid we won’t be able to accommodate this request.
Reah,
Do you know in what version MIService was introduced? I scanned the JavaScript in mne 10.3.1.0.147, and the only declaration of MIService I found was at fashionmatrix\odin\odin-m3.js inside the declaration of object M3, but none are in the scope of H5 Scripts. The M3 Core Administration Guide mentions the Mashup Administration Client, and “Toggle the button enable MI service.” I see the Administration Tools menu with Net Extension Manager, but I don’t see the Mashup Administration Client either. And I read Chapter 7 MI Service in the M3 H5 Development Guide Version 10.3.1.0 Published May 2017, but it looks like TypeScript. Is it available for H5 Scripts in JavaScript?
I appreciate any help.
Thank you,
–Thibaud
Reah, I found the Mashup Administration Client at /mashup/admin/ui . It shows MI Service is toggled to enabled, and the BaseURL is correctly set to some https://host:16107/m3api-rest/ , but it shows Has keystore: False. If I fix the keystore, will I finally see M3 or MIService in the Chrome DevTools JavaScript Console? Thanks. –Thibaud
Hi, Thibaud. MIService was made available in version 10.3.1.0.195. No need for other settings to enable it. Yes, you can use this with JavaScript. TypeScript compiles to JavaScript, so there should be no difference in functionality. If you look in the Samples directory included in the H5ScriptSDK package, you will find both the TypeScript and the transpiled JavaScript files for the examples in the documentation. I suggest you still check out TypeScript to see its advantages over plain JavaScript.
Great. Thank Reah!
Hi!
Does this mean we will have to update all scripts that use ScriptUtil.ApiRequest? Is it a simple replacement or does the syntax need to change as well? So if I have this line what would it look like using MIService?
ScriptUtil.ApiRequest(“/execute/CRS610MI/GetBasicData;returncols=YRE2?CUNO= ” + cuno”, response =>{
var yre2 = response.MIRecord[0].NameValue[0].Value.trim();
For cross-reference, more about my experience with H5 scripts, https://m3ideas.org/2017/06/22/developing-h5-client-scripts-part-2/
FYI: I’ve finished developing the new Infor Education course called M3 13.4 Developing H5 Personalized Script. Check out on Infor Campus. For those of you like I was transitioning from JScript in Smart Office to TypeScript in H5 Client, this course is a good starter to get you going on personalized scripts in the H5 Client.
Another FYI: I’ve also finished developing the new Infor Education course called M3 13.4 Programming in the Web[Mashup] SDK. Check out on Infor Campus. For those of you like I was transitioning from the SDK in Smart Office to Web/Mashup SDK in H5 Client, this course is a good starter to get you going on writing custom applications and Mashup controls in the H5 Client.
Hi Matt, How do I find this course on the campus? I have tried searching for M3 13.4 but no hits.
Hi Daniel,
Infor Education had both new 13.4 courses scheduled in July. It is about time to schedule another round of H5 Scripting and H5 Web SDK training sessions. Watch for on Infor Campus’s calendar soon.
Here are the official Infor Campus course names:
M3 13.4 Developing H5 Personalized Script
M3 13.4 Programming In The Web Software Development Kit
Hi there,
I ran into a problem while trying to migrate an old JScript to H5: how do I implement radio-group behaviour? There is no RadioElement and for some reason it seems impossible to uncheck a CheckBox from code after it has been added:
Hi Matt,
Here’s an example for adding a radio group:
As for the checkbox, if you try to get the value after setting it with the jQuery function prop(“checked”, false), you will find that it works. However, the change in the value is not reflected in the UI. The following code toggles a checkbox:
Let me get back to you so I can verify what needs to be done on our side.
Hi Reah,
the second solution works perfectly fine and I am going to use that. The first one may be implemented as an h5.script.RadioElement later on? I would like to avoid writing HTML in code and layouting in absolute measurements.
Greeting
Hi Reah,
I tried implementing the first way to add radio buttons in “ConfirmDialog.ShowMessageDialog” but its not working. It just prints Object:object.
How can we add radio buttons on “ConfirmDialog.ShowMessageDialog” window and then pick up the value of radio option checked by user.
Regards,
Bhumika
Hi Matt,
You can manipulate the checkbox this way:
Hi Reah,
thanks for your fast reply. This works but it will trigger the change() eventhandler of #randomCheckBox1. To get radiogroup boxes I had to add a simple flag so toggling the other one back gets skipt when trigger occurs from code otherwise we’ll end up in an infinity loop 😉
Hi again,
There used to be the possibility of using templates in jScripts
eg. var uri = new Uri(“mforms://_automation?template=PPS310REPNR1&REPN=” +REPN);
Can you still use them? If yes were should the template files be placed and how can they be included in the H5 Script?
Thank you 🙂
Marlene
Hi,
Template can still be used. They are uploaded in the Data Files tool found under Adminstration in the H5 client. I don’t know the syntax of the URI but check the documentation or if you can find an example on this blog. The template is an .xml file.
ah okay so you can still use the old .xml files. I looked through the documentation again but was not able to find a hint on how to include it… the only thing I could find was on how one looks (pg. 55 – Automation XML)
Did some more testing and trying. I uploaded the .xml file to the H5 client and tried some versions of calling but none did work 😦
e.g.
var uri = “mforms://_automation?template=TestTemplate”;
ScriptUtil.Launch(uri);
//like in the Developer Guide
var uri = “mforms://_automation?data=TestTemplate”;
ScriptUtil.Launch(uri);
The only way so far that I got it to work was by calling ?data with the xml code just following it
e.g.
mforms://_automation?data=%3c%3fxml+version%3d%221.0%22+encoding%3d%22utf-8%22%3f%3e%3csequence%3e%3cstep+command%3d%22RUN%22+value%3d%22MMS001%22+%2f%3e%3c%2fsequence%3e
Sadly, this is not what I am looking for 😦
Hi,
I’ve looked at the code and it seems to me like this should work:
var uri = “mforms://_automation?template=TestTemplate.xml”;
ScriptUtil.Launch(uri);
Can you see the request to MUA in a network tool like Fiddler?
Anything in the Smart Office log?
I would expect a call to the main servlet with the following parameters. CMDTP=RUN&CMDVAL=TEMPLATE&TEMPLATE_NAME=TestTemplate.xml. I can’t find an example I would have to wait until “norpe” is back and ask him.
If there is a request to MUA also check the MUA grid log to see if there is any trace of what happens.
Maybe i should have also posted the Error i get…
in every version i tried so far it gives me the error:
“The program was terminated due to an error.”
now i checked in the chorme developer tools – Netlog – the From Data that gets passed is:
used “mforms://_automation?template=TestTemplate.xml”
result “CMDTP=RUN&CMDVAL=ate%3DTestTemplate.xml&BMREQ=&SID=97fd73ef5c629d607573b8e870d52706”
so it cuts off a lot that it would need 😦 wenn passing the information.
wenn will norpe be back?
He’s back on Monday. But I forgot that this is in the H5 client. It seems to me that the CMDVAL corrupted. It should also forward any values that you pass in. I’ll ask the H5 Developers to have a look.
thank you 🙂
Any news?
Hi, this is not yet available in H5. A ticket has been filed to support this feature.
Hi Karin and Co,
with Smart Office we were able to retrieve the addresses of grid components like MWS, is there an equivalent method in H5 yet?
Following on from that question, how is it envisaged that the authentication to MWS would work?
Cheers,
Scott
Hi Scott,
With web development this is considerably harder. There is no method to get other URLs and there is no plans to provide it in H5. The reason is simple. You can only access resources on the same server so there is no point in using full URLs, you need to have MWS on the same machine and then a relative path can be used /MWS/xxxx. The reason is that there is no way to authenticate against another grid service using Ajax calls. For good reasons the browser does not allow it. And even if you can call it most services does not allow Cross domain calls (CORS).
I’m not saying that it is impossible, you can to crazy stuff like showing an overlay where you load a secured web resource on the other server and then if the other server has the same SAML SP and the same IDP in the background it could potentially get authenticated automatically but then you would need to know when to close the overlay and so on and it’s just crazy and not something that you would ever do in production.
Hi Karin,
would there be scope for Infor to add essentially a proxy or helper for the calls to MWS? Even if it was a method that we could submit a SOAP envelope and receive the response where the H5 framework handles the user rights as it does with the API calls?
Essentially we want to avoid having to handle usernames and passwords when making MWS calls, relying instead that the H5 client is already authenticated.
Cheers,
Scott
Hi Scott, If MWS is located on the same grid the user is already authenticated via the grid cookie. There is no plan to create a proxy. With web we don’t have the users credentials. We have been forced to create a proxy for IDM since it has moved to the teckstack grid compared to previous versions but tunneling traffic is adds complexity and server load. In the case of IDM we had no other options but to provide a proxy as infor applications in H5 needed IDM.
If you have a strong case for MWS proxy I suggest that you officially request a solution for your scenario via support.
The current option is to install MWS on the same server has H5, it can be another node in the same grid but it needs to be in the same grid so that the user is already authenticated. Where is MWS normally installed?
User names and passwords cannot be used in scripts. It’s a major security risk. You have to rely on the authentication in the browser.
Hi! Is there any documentation of the properties and methods for each class available somewhere? When doing JScript in Smart Office I usually rely on https://msdn.microsoft.com/en-us/library/mt468159(v=vs.110).aspx to know what I can do with each object, but I can’t find any equivalent documentation for H5 elements. Is there one? Or is there another way to see what kind of properties and object has?
In my particular case I’m fetching a textfield in a panel by doing “content.GetElement(‘WEITNO’)[0]”, and I now want to know what kind of different properties and methods that are available to me. My end goal is to make the field read-only.
Hi, Jonatan. The GetElement function returns a jQuery element; you can use the library functions to set its attributes:
The H5ScriptSDK documentation is available in Infor Xtreme. You can also check the h5.script.d.ts declaration file in Samples and the project template included in the SDK package, for the available functions and properties.
For your reference:
The PDF file can be found on the Infor Extreme Documentation repository: https://www.inforxtreme.com/esknowbase/root/DLPublic/52175/H5ScriptDevelopersGuide_10.3.1.0.pdf
The zip for the H5 Scripting documentation (with samples and templates) are found in a KB Article: https://www.inforxtreme.com/espublic/EN/answerlinkdotnet/SoHo/Solutions/SoHoViewSolution.aspx?SolutionID=1909067
Thanks a lot for the link to the zip-file!
With TypeScript-template project, this is a must for us developers with C# (and Java)-experience and less JavaScript-experience.
Unlimited upvote 🙂
Thanks! I’m unable to find the H5ScriptSDK documentation containing all the available functions and properties for all classes though. Could yo u please tell me where I can find it?
Will that documentation also contain the available attributes for the jQuery element, like “readonly” and such?
Apparently setting the “readonly” attribute to true doesn’t work if the field has a browsing (F4) functionality. Because you can still press F4 and pick a value there.
Thanks a lot for your help!
Regards,
Jonatan
Hi Jonatan,
If you download the zip-file from the last link in Reah’s answer, you will find most of what you want there.
The zip-file contains template-projects with samples and documentation. If you use Visual Studio with Typescript, you will get Intellisense-support so that it is a lot easier to see which methods and properties that are available.
You can even debug with breakpoints, watch etc. in Visual Studio.
For standard javascript, jQuery etc., you will probably have to look elsewhere (but even here, Visual Studio gives you some hints).
If I didn’t ask for it in my previous question. Where can I find the available attributes for e.g. a TextBoxElement?
The attributes you can set through jQuery are basically the HTML attributes. For more information, you can refer to the jQuery website.
You can find the properties of H5 elements in the declaration file in the H5ScriptSDK package. If you develop scripts in TypeScript and use this file, the listed properties and functions should be listed as suggestions as you type in your IDE.
Hi Karin,
I am migrating a ISO-Jscript to H5-Javascript that is calling a M3 API for each line in a listview.
In JScript, we could tag the api-request with the current line and this tag was passed on to the response, so that when reading the output from the api-call we could update the correct listivew-line.
Is that possible to do in H5 Javascript as well?
In ISO-Jscript, we could do something like this:
var request = new MIRequest();
request.Program = api;
request.Transaction = apiTransaction;
request.Tag = rowIdx;
In H5, we are using the ScriptUtil.ApiRequest, but this has only the url as inputparameter and we cannot pass on any other data (like linenumber from the listview)?
E.g:
ScriptUtil.ApiRequest(url, CustomColumns.onApiSuccess, CustomColumns.onApiFail);
Thanks.
Hi, here’s an example:
Thanks a lot Reah!
Much appreciated 🙂
Hi Reah,
I have had a look at your suggestion.
It can work in some instances, but unfortunately it is not the same as the “Tag”-solution from SmartOffice-JScript and does not solve my issue.
In my case, I have a JScript that loops over all rows in a listview and calls an api based on the data in the list (and updates a new column).
This was done in SmartOffice (Jscript) by passing the linenumber in the “Tag”-property of the Request-object and interpret the Tag in the response-object to update the correct row.
This does not seem to work in your suggested solution, as the rowIdx will be the LAST linenumber in the loop (loop finishes before the response-function is run – because of Javascript Closure).
I also found that the ScriptUtil.ApiRequest is deprecated – so I tried to switch to using the MIService. I see that the IMIResponse actually DO have a tag-property, but the IMIRequest does not.
Maybe this is a bug in the H5-implementation, where the tag-property of the IMIRequest is forgotten?
I actually do not see any way that one can successfully loop over the rows in the listview and know which row to update in the response-function.
(I could tag the row itself, but I still cannot map to this row in the response-function as I do not have any of the same information there).
interface IMIRequest extends IMIOptions {
program?: string;
transaction?: string;
record?: any;
outputFields?: string[];
}
interface IMIResponse {
program?: string;
transaction?: string;
item?: any;
items?: any[];
metadata: any;
tag?: any;
errorField?: string;
errorType?: MIErrorType;
error?: any;
errorMessage?: string;
errorCode?: string;
hasError(): boolean;
}
I have filed a ticket to support the tag property in MIService.
If I understand correctly, the issue you encounter with the rowIdx value is due to the scope of variables in JavaScript. If you are using TypeScript, you can simply make the variables block-scoped by using ‘let’ instead of ‘var’ when you loop through the rows. The following code should log the id for each row and request.
This is transpiled to the following JavaScript code:
The same can be done for ScriptUtil.ApiRequest.
Please note that ‘let’ is available in JavaScript but is not yet supported by some browsers.
Hi Tjalve,
Did you ever find a solution for this? I have the same issue in an H5 Cloud M3 script I am trying to write whereby I highlight a number of rows in a function, call an API for each, but am struggling to match the API responses back up to the rows that call it. Occasionally, they come back in a different sequence. Unfortunately, I don’t really have a unique identifier in the M3 data per row that I can cross check the API response against so was hoping there was a solution whereby the call and the response each have a unique identifier that aligns them.
Thanks,
Joe Walker
Hi Joe!
My question above was years ago and my memory is not that good 🙂
But I believe I managed to fix this issue.
Can’t remember exactly which script I had the issue with, but found a simular script I can share with you (that works).
If this doesn’t help, feel free to send me your script and I can have a look.
Here is the code that may put you in the right direction:
for (let i = 0; i {
let foundInvoice = false;
let invoice = “”;
for (let j = 0; j {
this.log.Error(“Feil i APS251MI-api: ” + response + ” : ” + response.errorMessage);
});
}
}
The use of “hasExtensionData” is only to tag lines when they have been updated – to avoid updating the same line(s) again if the user scrolls up and down on the same lines. (This code is to retrieve extra information in a list – and it only needs to be done once per line).
I don’t think I had any “syncronization-issues” with this piece of code.
Kind Regards,
Tjalve.
Ooops!
Pasting the code did not work very well…
Trying again:
for (let i = 0; i {
let foundInvoice = false;
let invoice = “”;
for (let j = 0; j {
this.log.Error(“Feil i APS251MI-api: ” + response + ” : ” + response.errorMessage);
});
}
}
Pasting the code didn’t work.
But you can download the code-snippet here:
https://ln.sync.com/dl/27de8dbd0/9hi7e2wy-hsqcds5b-ink5ta62-ujv5g58h
Thanks for the reply Tjalve. Your reply and code helped and I’ve got it working. Similar to you, in the API response I compare back to check if its a match. The key bit for me was I had to remove duplicate items in the array before calling the API transactions, such that I know an item will only get processed once and then when the API response is returned for that item I can compare it to all selected rows and calculate the new quantity accordingly. That is because from my calling B panel the item can be in there multiple times.
Thanks again,
Joe
Would it be possible to have some guidance regarding the development of custom components for the H5 Client?
My situation is migrating customizations from SmartOffice to the H5 Client. These are primarily comprised of custom, streamlined interfaces built using Windows Presentation Foundation (Microsoft .NET) that are shown in separate dialogs, typically invoked by choosing a button from the M3 program or the grid context menu.
From what I can see the H5 Client SDK (Infor M3 H5 Development Guide Version 10.3.1.0) does not include any examples showing a modal window whose content is a custom, interactive HTML template. I’m referring to the implementation of an advanced template, where the content is multiple different HTML input elements with event handlers that update the content of the HTML template when values change. (For instance, a template with a drop-down that, when a value is selected, populates a grid that lets the user select one or more values, and then invoking the MIService multiple times for the user’s selections).
While the SDK doesn’t provide a sample, this can technically be accomplished by hand-rolling the HTML/event-sinks using JQuery and then showing the content using inforDialog(), but this approach doesn’t seem optimal.
Is using the H5 Client for these kinds of customizations even recommended? If so, is there any examples that Infor can provide of an implementation? Otherwise, should I be approaching this at a different angle, perhaps using Mongoose or the Infor App Builder?
Hi Anthony,
There is no out of the box answer for your question. Developing for web with HTML5 and jQuery is that much harder than WPF. This all comes down to how much integration you have between the panel and the application. There are a few options I and I think that you have listed them all, except for perhaps using the M3 Mashup SDK to build a stand alone web app that you can deploy to the MUA server. It might be easier to use that and just have the script open a dialog with an IFrame than using JQuery for everything. The M3 Mashup SDK is using AngularJS so you would have templating support (which you don’t have if you just use JavaScript in the H5 client.)
Mongoose and Infor App Builder are also options that are available for you where Mongoose is the most powerful framework which can include server logic. There is no official recommendation as it “depends” but I would say that writing everything in JavaScript within the H5 is a bit hard since there is no public documentation of the H&L Xi SoHo HTML controls that H5 uses. You would pretty much try and figure things out by reading this blog and looking at the H5 client and the examples it provides. Of course you can ask questions on this blog and via support for specific examples but we don’t have any more examples than the scripting examples already provided. But if you require tight integration with the M3 panel – eg returning data to the panel – this is the only option. If you just need input from the panel to your application you can always pass those as parameters on the URL to another application. If I were you I would spend some time looking at: M3 Mashup SDK, Mongoose, Infor App Builder and then compare those. Smaller things can be done in H5 directly with JavaScript and JQuery.
Thanks for the very detailed response, karin! SmartOffice did offer us a lot of latitude to develop our customizations and it seems that we may have been attempting to fit too much into this approach. We’ll definitely be looking into Infor’s other application/platform options in Mongoose, App Builder and the Mashup SDK to determine if they offer the functionality we need, but it’a also good to know that we can approach the problem by developing custom web-base applications that can be exposed through IFrames and/or browser windows. Thanks again for your assistance.
Hi Guys,
I am trying to invoke MI program via H5 scripting but while executing that script I am getting below error.
Uncaught ReferenceError: MIRequest is not defined
Below is the simple snippet which I am using.
const myRequest = new MIRequest();
myRequest.program = “MNS150MI”;
myRequest.transaction = “GetUserData”;
Any help will be highly appreciated.
Regards, Salman
Hi, Salman. Can you please check your MUA version? MIService was added in 10.3.1.0.195.
Hi Reah, Thank you so much for your reply. Indeed I upgraded MUA and BE as well and MIService is working now. With previous version even GetMode wasn’t working but its working perfectly OK.
Once again Thank you for your reply 🙂
Regards, Salman
Using Typescript for H5-scripting is wonderful, but where do you guys keep the ts-files?
H5 only need the js-files, but I guess everybody wants the ts-files to be the “source” and make sure nobody is modifying the js-files generated from a ts.
Are you using Version-Control (e.g. GitHub) – and how do you make sure nobody is changing the js-files directly?
Recommendations, suggestions?
Hi Tjalve,
We in the M3 Demo Services team are using Git and Gitlab as version control and to store all of our demo solution scripts. On thing that you could to in order to prevent others from updating the transpiled .js-file could be to also minify the script. No one likes to modify minified files… 🙂
Hi!
Apparently setting the “readonly” attribute to true doesn’t work if the field has a browsing (F4) functionality. Because you can still press F4 and pick a value there.
How do I make a field like that read-only? I.E. so that the user can’t write anything in the field and can’t prompt for a value using F4.
Thanks in advance!
Hi, here’s an example on how to handle key/mouse events. You can find more information on RequestCompleted and other request events in the scripting guide.
Hi again!
Is there something like a text area element which you can add to a panel?
I basically need to display text with several rows. So the normal TextBoxElement is not sufficient, since it seems like you can’t change the amount of rows of the TextBoxElement.
But I can’t find anything like a text area element. Not in the samples or anything.
Thanks in advance,
Jonatan
Hi, you can use TextAreaElement and set the length, rows, and columns in Contraint.
Hi!
I’ve been trying to get the cursor to automatically go to a desired field during order entry (from the A panel to the next panel, it stays in the field the cursor was in in the A panel. I’ve set the tab order to have it be first, but it doesn’t seem to want to go to that field. Is there a way to create a script to make the cursor default to the field I want?
Hi,
There are a number of different things that control the focus and the tab order. You can configure the tab order, M3 can return the panel with information on where to put the focus etc. You can try with a script but you can’t do it when the script is initialized because the UI isn’t rendered yet and you even if you dispatch to the UI-thread to do it later, the other logic might also dispatch and change it after your code is run. You can try and use field.setFocusAsync(), but after you receive the response with the panel that comes after the B-panel. I don’t know all the details so I’ll ask norpe to see if he can give you a more detailed (and correct) answer.
Thanks! I’ll give that a try and check back for Norpe’s answer too.
Hi!
There’s some documentation on how to extract data from selected rows in a list, but I can’t find any info anywhere on how to just extract data from lets say all rows (without them being selected).
I guess this is possible somehow?
Thanks,
Jonatan
Hi!
Is there any plans on implementing this functionality if it isn’t there yet?
This is the most common request from my customers that needs H5 scripts, and right now I have to tell them that it isn’t possible in H5 yet.
Hi Jonatan,
The following snippet iterates through the currently loaded rows in the grid:
Hi,
I am migrating some older ISO scripts to H5 scripts and I am struggling with the datepicker element. Is it possible to add a datepicker with a H5 script?
Thanks,
Georg
Hi Georg,
You can use the inforDateField from the Infor control library with a TextElement.
I have filed a ticket to create an API function for this.
Thank you for the example. It works great
Hi Reah,
Is there a way to add a datepicker to dialog box?
I use the below dialgoContent to create the dialog html, but I can’t figure out how to include the above javascript into this sort of implementation:
var dialogContent = $(“”);
dialogButtons = [ //Dialog box button Ok and Cancel
{ //”Ok” button to call submit for approval
text: “Ok”,
isDefault: true,
width: 80,
click: function () {
}
}
},
{ //Close dialog box
text: “Cancel”,
width: 80,
click: function () {
$(this).inforDialog(“close”);
}
}
];
var dialogOptions = {
title: “Selection”,
dialogType: “General”,
modal: true,
width: 400,
minHeight: 200,
icon: “info”,
closeOnEscape: true,
close: function () {
dialogContent.remove();
},
buttons: dialogButtons
};
dialogContent.inforMessageDialog(dialogOptions);
Regards,
Jonathan
Hi Jonathan,
You can add the text field manually in the custom dialog. Just make sure to add the css class ‘inforDateField’ to the element.
Thanks Reah!
Hi,
Do you know how to change date format from a list?
Thanks.
No I don’t know. I don’t think you should be changing the format. It will use whatever applies according to User settings etc.
Hi Reah!
When I just copy-paste your example, the text in my date picker is displayed as MM/DD/YYYY, even though the date format is set to YYMMDD. So it looks likes this DateFormat property on the text element doesn’t actually change the date format.
This becomes looks very strange to the user if the rest of the dates in a panel is displayed in YYMMDD. Is it possible to change date format somehow? Preferably I would like to be able to set the date format however I’d like, to match the date format of the M3 user.
Best regards,
Jonatan
Hi! See my question above. I would really need a solution to this. Many of our customers need custom date pickers in H5.
Hi Reah,
I wonder if it is possible to change date format? I can’t change date format by using textElement.DateFormat = “DDMMYY” or textElement.DateFormat = “DMY”. Do you know how I can get it to work?
Thanks in advance!
/Johanna
Hi Jonatan and Johanna,
The fields date format is completely tied up to the business engines format, I think the date format is limited for “YMD”, “DMY”, “MDY”, “YWD” respectively. You may change the date format of the field if you hijack the elements’ attribute, but it doesn’t change the value coming from BE, you will always need to re-format the values coming from BE to your desired format. but it will not change the true date format in the backround.
Regards,
Reggie
Hi Reggie,
Thank you for your response regarding date format. I could set the date format though when doing that I found some problem with the calendar. If I use and set “dateFormat”, the calendar will open with January. If I don’t set any “dateFormat” the calendar will open with todays date defaulted (which I wan’t). Do you have any idea of how I can get the calendar to open with todays date and also sets the the dateFormat?
$dateElem.inforDateField({
hasInitialValue: true,
openOnEnter: false,
startDate: new Date(),
dateFormat: ‘yymmdd’,
beforeShow: function () {
if ($(this).val() == “”) {
$(this).datepicker(“setDate”, new Date());
}
},
})
Hi Johanna,
Try to simplify first the inforDateField initialization.
ex.
$(“#dateInput1”).inforDateField({
dateFormat: “yyMMdd”
});
I used this and it opens up the date today with the format “200706”.
Regards,
Reggie
Hi again Reggie,
Thank you for your answer, though there still are problems. What you say works at first but as soon as I select a date in the calender the selcted date displayed in the date field is wrong. I selected 6th of July and the display date is then “200006”. Then when opening the calendar again it is back to January… Can you see if you get the same error when you select a date in the date picker after you have set the date format?
Hi,
How to disable date picker field during display?
Thanks.
Hi
How call h5 personalization script (javascript) using web mashup. Web mashup was developed using smart office mashup tool and export as web mashup.
Tx
Hi priyanthahet,
You can only access the personalization script tool inside the regular form and not in web mashup. Any customizations should be done inside the regular forms.
Regards,
Reggie
Hi,
Is it possible to ge any example on how to use the “ComboBoxElement” ? How to add “options” to the list and also on how to get the selected values.
I have made some tests and can’t get it to work. I can add the box on the screen but I can’t manage to add any “options” to the list or open the dropdown.
Thanks in advance!
Hi,
I have a requirement to automate ‘select all rows’ in a B panel and hit an existing related option. There is the code this.controller.ListOption(buttonInfo.option) to call the related option. But I can’t find a working equivalent to do the same as a ‘ctrl-a’ key press to select all rows.
I’ve tried :
$(“.slick-row”).addClass(“selected”);
But it only highlights all rows. They are not added to the selected list. So the related option thinks you didn’t select a row.
Do you have any suggestions here?
Thanks,
Jonathan
The underlying grid is an instance of a SlickGrid that exposes a method for setting the row selection.
In your TypeScript you’ll need a reference to the IInstanceController (from your Init method the IScriptArgs parameter exposes this through its controller property). From there the following snippet will set the selected rows:
let controller = … // Assume this references your IInstanceController
this.controller.GetGrid().setSelectedRows([1, 3, 5, 7]); // setSelectedRows expects an array of the row indeces to be selected
Thanks Anthony.
I’ve also found another option:
this.controller.GetGrid().selectAllRows();
I can’t seem to post new comments in this forum any more. I just get “sorry, this comment could not be posted”. Do you know why this is?
I’ve tried to post a question in this forum multiple times, but I just get “this post already exists”, or something like that. However, I can’t find the post here on the forum, so it apparently hasn’t been posted.
Best regards,
Jonatan
Hi,
I haven’t seen any issues on my end but I’m going to have a closer look around. This comment came through 😁
Thanks! Today I at least don’t get any “this comment could not be posted” message, but instead I get the “Duplicate comment detected; it looks as though you’ve already said that!” (I’ve copied my question into a text document so that I could try to re-post it when it didn’t work).
But I can’t find my question anywhere in this thread. Is it stuck somewhere?
I’m looking for an H5 script that would serve as an input mask for phone numbers in H5 CRS610 / customer telephone number. Is this something that could be achieved through a script?
I can’t seem to change the value of a LabelElement. Whatever method or property I try to change, the text that is shown in the label remains the same.
I have tried both changing the text using the JQuery method:
this.label.val(“testing”);
… and the LabelElement method:
this.label.Value = “testing”;
But none of them changes the actual text in the label.
Hi Jonatan,
You can use the jQuery method .text().
Hi,
I have just begin the process of converting my Smart Office scripts to H5 client and have ran into two problems I am stuck on. I wonder if anyone has an answer for them please:
1. On buttons you add to a panel, is there the ability to add a tooltip such that when you hover over the button you get a longer amount of text than just shows on the button itself? I often use this for a description of what the button does. This was done with button.ToolTip in Smart Office but there does not seem to be an H5 equivalent from what I can see. It is not mentioned in the developers guide and visual studio does not seem to suggest one.
2. For scripts in detail panels, whereby an error message dialog is shown and then the user is left in the panel and focus is placed on a particular field (the one in error), I have been trying to use ScriptUtil.FindChild(host, “MMECVE”).focus(). However, this only works when the focus is on the panel, if you show a dialog box instead the focus is on that and therefore it does not work. Infor support suggested setting the focus on closing the dialog box and that might work – which was not something you had to do in smart office. Has anyone coded this before or have an alternative solution?
Thanks,
Joe
Hi Joe,
1. Adding tooltips is currently not possible using the API, but you can do this directly with the Infor control library that H5 uses. Please note, however, that this entails handling forward compatibility on your part as this not part of the API.
2. You can set the focus of the element on close of the message dialog by specifying it in the dialog options.
Hi Reah,
I have an additional question if you don’t mind please. I am using the standard supplied script H5SampleImageFromList to show an image in MMS001 of the item. However, when I try and run it I get the following error in the console log:
SCRIPT438: Object doesn’t support property or method ‘GetContentBody’
I get this in both IE and Chrome but I am on H5 client 10.3.1 which the documentation states is the version where this should be available. So I don’t think its a case of my H5 client version being behind which the odd issue like this has been in the past.
Any ideas please?
Thanks in advance,
Joe
Hi! Is there a way to – and is it necessary – to clear script cache in H5?
I’ve had several situations where some old script is cached somewhere and loaded, even though I can see that the new script is imported in “Administrator tools” -> “Data files”.
At those occasion I’ve just logged out and then tried a few days later, and the problem has fixed itself. But I guess I missed something somewhere.
Thanks,
Jonatan
The file should be updated when it’s uploaded. The H5 version that I tested added generated query parameter to the script, eg https://server.infor.com/mne/scripts/Demo.js?_=1527829053795
It is possible that the version you are using does not have a cache busting parameter like that which means that it is probably stored in the browser (clear browser cache) but it is also possible that it is stored in the web server that is sending the files.
I would try and download the script directly – with an extra parameter (could be anything, ?hepp=hej). Just to verify that the upload works OK.
If your version does not have a cache busting parameter then see if you can upgrade to the latest fix pack. Generally you would need to login and out again to get the updated scripts (if you have already loaded it during the session).
If you still have this issue after that please report it to support.
Hi
I have my script in ois101 and I need to check in the script if the user browsed thru Ois100 or ois300 to Ois101. Is there a controller method to check the calling program in OIS101?
Thanks
Hi sid,
The application call stack is not available to scripts. You would have to have scripts running on all locations that a user can browse from and store it in the global cache to do this manually. E.g. save a “OIS101Source”, but it would be tedious and I can’t recommend it.
You can submit an enhancement request to support to request that we provide an API for the call stack information.
Hi,
Is there a way add ToolTips to the List in Browse panel? (i.e. MMS080).
HI,
May I know how to add Combobox to a panel using H5 script. I have tired couple of ways and any of that did now work ,
Thanks
BULITH
Hi, here’s an example in TypeScript:
Hi
Using H5 script I have added text box to a MMS001 B panel . However when user press the enter button, contents in the text get cleared up(not the refresh) . So how to avoid that ?.
Thanks
Pra
Hi, The M3 UI is driven from the M3 server. The M3 server has a view definition that defines the UI and since you have pressed enter the panel has been submitted and the server will give you the next panel, in your case it is the same panel with a fresh set of rows as you have positioned yourself in the list. Your script will run again. You can keep the script running for a longer time and add the textbox back (with content) as long as the reply from the server says that you are still on MMS001B, if you are on another panel after the request has completed then you must disconnect the script. There should be some examples of the events and how to subscribe to them on the blog. Use a tool like Fiddler to see the communication between Smart Office and the M3UIAdapter for a deeper understanding.
Basically:
– before the request is made save the text box value in a variable in the script, but don’t disconnect
– on the response. Check the panel in the reply. Anything else than MMS001B – disconnect. If you are still on MMS001B – Add the text box and if you have a value add the text box. There might be scenarios like after a page down where the textbox is still there so if you have it a name you can search for it on the panel to see if it remains in the visual tree.
Something like that would do the trick – but I don’t have an example for it.
Hi ,
I am developing a H5 script . I have introduce textbox. when user press enter button , it gives waning message.
I have two issue.
1. How can I retrieve M3 Error or waning message.
2. Textbox is clear when user press enter and show waning message.
please help me to resolve above issues .
Thank you
Priyantha
Hi Priyantha,
There is currently no API function to easily retrieve this. One workaround is to parse the server response. You might want to do this inside your RequestCompleted instance event handler – there are examples in the H5ScriptSDK package if you need more information on how to do this.
Hi
When Button is clicked on a panel i want to show to popup form and user should be able to feed some values to that form .(Simple popup with 3 text boxses and ok cancel button) .Based on form inputs i want to do some actions in panel .
Can anyone share a code to add popup for a panel?
I have tired with jquery popup and it didn’t work
THanks
Pra
Hi Pra,
Here’s a simple example:
Sorry, but how do you insert the code into your question so you get the line numbers and everything?
I add a sourcecode tag sourrounded with brackets. See this link https://en.support.wordpress.com/code/posting-source-code/
It says code but I use sourcecode. I think that works in comments as well.
Hi! Would something like this be possible in H5 also:
https://smartofficeblog.com/2014/04/25/hyperlink-columns-in-m3-lists/
Thinking especially on the link part.
Have made the column and presenting all my data in right row’s. But need to make them clickable links.
Hello Frode,
I have aso exact same reqirement, have you found solution for that?
Thank you.
I have a requirement to change the value of one of the field ALQT in sub-file in MMS120 screen using H5 Script. Please advice me how can I change the value of a field in subfile?.
Hi Kat,
Here is an example:
If the field is not editable, this can also be achieved without a script using conditional styles as a personalization in the panel.
Hi,
In the Script sample H5SampleCustomDialog.js the comment text is referring to open a webSDK application from the script in a dialog window, as far as I can understand(?).
We have a webSDK on the following path:
Path: /mne/apps/mashupintegration
But im struggling how to set the dialogContent to the webSDK we deployed.
Would it be possible to get an example how to set the dialogContent to a webSDK?
// Create the dialog content
// Change the dialog content to the webSDK. Save the local data to the cache and use on open and close.
var dialogContent = $(“Custom dialog content”);
Thank you.
Regards
Ken Eric
Hi Ken,
I don’t have such an example but it should be a matter of creating an IFrame and setting the URL. But I think there could be issues with the size of the dialog as the SoHo dialog by default tries and adjust to content.
Hi Ken,
You can create the iframe this way:
Thank you, it worked perfectly fine!
Hi!
controller.PressKey(“ENTER”) does for some reason not do anything in my code. Below is my code. On row 80 in the checkDate() method I do “this.controller.PressKey(this.lastCommand);”, where I’ve checked that this.lastCommand is indeed ENTER, but nothing happens in the environment when this line of code is executed.
class APS100_DateControl {
private args;
private controller;
private content;
private log;
private detachRequested: Function;
private detachRequesting: Function;
private lastCommand;
private checked;
private dateField = "";
private maxInterval;
constructor(args: IScriptArgs) {
this.args = args.args;
this.controller = args.controller;
this.log = args.log;
}
public static Init(args: IScriptArgs): void {
return new APS100_DateControl(args).run();
}
private run() {
const panel = this.controller.GetPanelName()
this.log.Info("Panel: " + panel);
if (panel == "APA100EC" || panel == "E") {
this.dateField = "WWIVDT";
this.maxInterval = 200;
} else if (panel == "APA100F0" || panel == "F") {
this.dateField = "WWDUDT";
this.maxInterval = 300;
} else {
ConfirmDialog.ShowMessageDialog({
dialogType: "Information",
header: "Script error",
message: "Script can only be added to APS100/E or APS100/F. Aborting."
});
}
// Attach events.
this.attachEvents(this.controller);
this.log.Info("APS100_DateControl initiated2");
}
private checkDate () {
try {
const ivdt = this.controller.GetValue(this.dateField);
var dt = new Date();
var currentDate = dt.getFullYear() + "" + this.leftPad(dt.getMonth()+1,2) + "" + this.leftPad(dt.getDate(), 2);
var currentDate = currentDate.substring(2, 8);
const ivdtNum = parseInt(ivdt);
const dateNum = parseInt(currentDate);
// If IVDT - today's date i more than 200, ivdt is more than 2 months ahead of today's date.
if (ivdt - dateNum > this.maxInterval) {
let months = (this.maxInterval == 200 ? 2 : 3);
//Retrieving the user response in a Question dialog
ConfirmDialog.ShowMessageDialog({
header: "Date check",
message: "Invoice date is more than " + months + " months after current date, do you want to proceed?",
dialogType: "Question",
closed: (ret) => {
if (ret.ok == true) {
this.checked = true;
this.controller.PressKey(this.lastCommand);
this.lastCommand = null;
}
}
});
} else {
this.checked = true;
this.controller.PressKey(this.lastCommand);
this.log.Info("Check OK, proceed with command " + this.lastCommand);
}
} catch (ex) {
this.log.Error("checkDate(): " + ex);
}
}
private leftPad(num, length) {
var result = '' + num;
while (result.length {
this.onRequesting(e);
});
this.detachRequested = controller.Requested.On((e) => {
this.onRequested(e);
});
}
private detachEvents(): void {
this.detachRequesting();
this.detachRequested();
}
private onRequesting(args: CancelRequestEventArgs): void {
this.log.Info("Command type: " + args.commandType + "; Command value: " + args.commandValue);
if ((args.commandType == "KEY" && args.commandValue == "ENTER") && !this.checked) {
this.log.Info("Doing check!");
args.cancel = true;
this.lastCommand = args.commandValue;
this.checkDate();
} else {
this.log.Info("Check already done!");
}
}
private onRequested(args: RequestEventArgs): void {
this.detachEvents();
}
private splitAndTrimArguments (args: string) {
return args.split(',').map(arg => arg.trim());
}
}
You cannot call the PressKey method directly from an event handler for the Requesting event. After you cancel the Requesting event by setting the Cancel property to true you need to delay the call to PressKey. One way to do this is using the BeginInvoke method in the dispatcher.
Example:
private CallPressKey() {
this.controller.PressKey(this.lastCommand);
}
…
var action : Action = CallPressKey;
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Input, action);
Thank you for the quick response!
However, it doesn’t seem like Action, Application or DispatcherPriority are types available in TypeScript, because I just get “[ts] Cannot find name ‘Action’.”.
Did you write this solution in javascript or something?
Thanks again,
// Jonatan
Hi!
So it seems like you can’t call controller.PressKey() directly from an event handler for the requesting event. So how do you do it instead? It seems like you somehow need to delay the call to the PressKey() method, how can you do that?
It was suggested to me that you use Application.Current.Dispatcher.BeginInvoke. However, it doesn’t seem like Action, Application or DispatcherPriority are types available in TypeScript.
Thanks,
Jonatan
Hello Karin
We still use JScript.NET on our 13.4 ISO Smart Office. I am currently working on moving over those scripts to H5. I have my first h5 script working in my current H5 client. I have successfully deployed the data file via the H5 Administation Tool. I have added to my own user personalization script and it works fine. However when I copy the personalization over to Global personalizations with the H5 Administration Tool I can no longer view/execute the H5 script. Is it possible that JScript and H5 scripting do not play nicely in the same Global personalization?
Hi Eric,
You cannot combine a user personalization with a global personalization of the same type. That means that if you have a personal personalization of a specific type, like JScript then the Global would not be applied. It’s the same with a personalization on a role for example. The first personalization that is found user, role or global will be used. It does not matter if you have multiple roles with different personalizations. We never merge personalizations of the same type. So you will have to think about and plan for how to deploy the scripts.
So remove the user personalization and try again. If you still have issues check with Fiddler of the JScript file is loaded in the browser and check the server log for M3 UI Adapter on the grid server to see any message related to loading the script.
Hi,
considering my script consists of following two lines of code in the run method:
ScriptUtil.SetFieldValue(“W1OBKV”, “99999999”, this.controller);
this.controller.ListOption(“1”);
For test purpose I deployed it in MMS001. I can see that the value “99999999” gets set in field “W1OBKV”. But this.controller.ListOption(“1”) creates an empty item with item number blank. I can use:
setTimeout(() => { this.controller.ListOption(“1”);}, 1000);
then it works as expected.
But this is not a good solution since I can’t be sure that the timeout is long enough. Depending on the PC it can take 500-1500ms. Is there a way to check if UI is loaded and perform the List option after this?
Thanks,
Georg
Hi Georg,
You can make use of request events and set the field value on the RequestCompleted handler:
If you need more information on request instance events, please have a look at the documentation and the H5SampleRequestTracer and H5SampleCancelRequest scripts included in the SDK package.
For your reference:
The PDF file can be found in the Infor Extreme Documentation repository: https://www.inforxtreme.com/esknowbase/root/DLPublic/52175/H5ScriptDevelopersGuide_10.3.1.0.pdf
The zip for the H5 Scripting documentation (with samples and templates) are found in a KB Article: https://www.inforxtreme.com/espublic/EN/answerlinkdotnet/SoHo/Solutions/SoHoViewSolution.aspx?SolutionID=1909067
Hi Reah,
thank you for your answer. Unfortunately, it does not work as expected. I have tried already to call this.controller.ListOption(“1”); first and then set the value in the onRequesting or requestCompleted method. But the value I set gets ignored. I have also seen that in the developer console of the browser following error is displayed
jquery-1.10.2.min.js?v=MTAuMy4xLjAuMzUz:5 Uncaught TypeError: Cannot read property ‘nodeType’ of undefined
at Function.acceptData (jquery-1.10.2.min.js?v=MTAuMy4xLjAuMzUz:5)
at R (jquery-1.10.2.min.js?v=MTAuMy4xLjAuMzUz:5)
at Function._data (jquery-1.10.2.min.js?v=MTAuMy4xLjAuMzUz:5)
at RenderEngine.InitializeListHeaderContextMenu (mforms.min.js?v=MTAuMy4xLjAuMzUz:1)
at mforms.min.js?v=MTAuMy4xLjAuMzUz:1
This error is only thrown if this.controller.ListOption(1); is called directly in the run method. Do you have any idea on this error? Thanks.
Georg
Hi,
We been working on a websdk for H5/IOS.
The requirement was to use multiple CMS010 list panels as part of the solution.
After failing to bookmark and run a standard listpanel in javascript, we used the “mashup everywhere” and created mashups to be opened directly in the websdk to get the ListPanels working.
However, when running this in H5 directly it works fine, but when running it in H5/IOS we lose the company/divi when the websdk closes.
This causes an error when trying to open any M3 standard programs afterwards, until the cono/divi is set again.
This only happends when we run a bookmarked listpanel through the mashup. And it seems to clear the userContext everytime.
Does anyone have any experience with the same kind of issue? Or know how to run a bookmarked ListPanel in native javascript for H5?
Thank you.
Regards
Ken Eric
Hi,
I think that you should report this issue.
But please note that you need to be extremely clear with the scenario that fails by providing a sample as well as a step by step instruction. For example: Is the bookmarks running in a Mashup, is the webSDK application running mashups, is the webSDK opened within H5 or in it’s own tab? What is the step by step flow? What do you mean with “websdk closes”. I assume that you are executing a bookmarks in the webSDK and at some time the dono/divi on the user context is lost. It appears that you have a fixed scenario that fails so please create a repro and report it. We generally does not support coding issues but if this is something in the webSDK or in Mashups we should have a look at it. Just describe the scenario and provide a repro so that it is clear.
It needs to be clear what versions you are using; H5, Mashups, WebSDK.
One of limitations with a shared browser session like we have in H5 is that if you run a webSDK outside of H5, launch H5 and then close H5, the H5 client will logout and the webSDK application will not be able to continue as the session is no longer valid.
Hi.
Does anoyone know if it possible to detect how many programs that are open in the H5 session?
Hi Christian, this information is only available on the server and there is no method that the client can call to get the full list of open programs. It gets more complicated as there can potentially be Mashups, WebApplications created with the SDK, as well as the H5 client that are containing open programs.
Regards
Karin
Hi! Is there a way to call REST APIs in H5?
Best regards,
Jonatan
Hi Jonatan,
You can use the helper class MIService for executing M3 API requests. Please refer to the dev guide for examples.
For other REST endpoints, you can easily perform AJAX requests.
Hello,
I am trying to set a value for dropdown field OAOPRI in OIS100/I , using ScriptUtil.SetFieldValue(“OAOPRI”, “9-Low priority”); but it blanks the field value. I also tried this $(“#OAOPRI”).val(“9-Low priority”).change(); but still no luck. is there any another way to set the dropdown field value? Thank You.
Regards,
Kathir
Hi Kathir,
Can you please verify that the value you are setting to is available in the list? Also that “9-Low priority” is the option val, not the text.
Thanks.
Hi Reah,
Thank You for your help.
Hello,
I have a requirement that when we click a button it should open the browse window(with the pagination and select option) like in standard F4 browse window in M3 and on selecting a row from browse window it should populate the selected value on a screen field. is there any way we can achieve this requirement in H5 script / jquery ?
Thank You.
Best Regards,
Kat
Hi,
I am developing a H5 (Typescript) solution which runs on a M3CE Multitenant environment. What is the correct Start Url in Visual Studio ? I assume that I am not able to access the ..\mne folder due to security reasons. When I use the mingle/portal-logon, I can log into M3, but debug is not enabled.
Best regards
Heiko
Hi,
Have you able to sort this out?
I’m facing the same issue, When i set the mne path it will open the H5 client from visual studio but debug is not enabled.
Please advice.
Regards
Rajitha
Hi,
When I’m using H5Scripts in M3 Cloud Environments, I use VS Code as my IDE and installed a “Debugger for Chrome”.
Here are the steps I do:
1. Run M3CE Mingle – > Open H5 Client
2. Open Stand alone of M3CE H5 Client (open in new browser tab, don’t close Mingle)
-attach the localscript parameter ex. (https://m3devapp.m3cedev.awsdev.infor.com/mne/?localScript=http://localhost:8085/H5SampleHelloWorld.js“)
3. Run Webserver of my H5Scripts then Run chrome debugger in my VS Code
4. It will now work
Here is my configuration in “launch.json” of debugger for chrome:
“configurations”: [
{
“type”: “chrome”,
“request”: “attach”,
“name”: “Launch Chrome”,
“url”: “https://m3devapp.m3cedev.awsdev.infor.com/mne/?localScript=http://localhost:8085/H5SampleHelloWorld.js”,
“port”: 9222,
“sourceMaps”: true,
“webRoot”: “${workspaceFolder}”
}
]
*I hope it will work for you too
Regards,
Reggie
@Reginald Thank you for your response.
I have configured the “launch.json” as you described below and place my .js file under the folder structure. Once I launch it from debug mode it will open the H5 but again not hit the debug points.
Can you please clarify point no : 3 (Run Webserver of my H5Script) further more.
Thanks
Hi raji,
Maybe you were using “launch” type of chrome debugger.
My configuration is set to “attach” and needed to open the mingle H5 Client first and also open the stand alone H5 client version.
When using attach, the url you set needs to be open before running “debugger for chrome in VS Code”
/Reggie
Hi Reggie,
Thanks for your guidance.
This worked for me with below configuration.
Now debugger is enabled.
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
“version”: “0.2.0”,
“configurations”: [
{
“type”: “chrome”,
“request”: “launch”,
“name”: “Launch Chrome against localhost”,
“url”: “https://m3use1.m3.inforcloudsuite.com/mne/?scriptCache=false&localScript=http://localhost:8085/H5AddButton.js”,
“sourceMaps”: true,
“webRoot”: “${workspaceFolder}”
}
]
Thanks
Rajitha
Hi All,
i have a requirement to highlight a cell from grid(subfile) on some conditions. Can anyone help me in this?
Hi Deepak,
The conditions required to highlight the cell, are they outside the scope of what can be handled by the tool found in the menu option “Tools -> Personalize -> Conditional Styles…” in the H5 panel? In case you have missed that option I recommend that you have a look at it.
Thank you Peter. I was wondering if we could do that by scripting itself.
Hi,
I have a problem when trying to validate project numbers in OIS100 on the E-panel with the help of a script, the problem seem to be that the program does not wait for the results of my validations before continuing to the F-panel. Error messages and everything is displayed but the program still continues to the next panel.
To stop the program if the validation fails I use args.cancel as used in the H5SampleRegexValidator sample code that comes with the H5ScriptSDK, it works just fine as long as I do not include values fetched from MIService. When doing this the execution of the main program simply ignores my args.cancel, I have tried using async/await and different variations of Promis but nothing seem to work.
Anyone else having this type of problem?
Current version of the UI adapter: 10.3.1.0.369
Thanks / Marcus
Hi Marcus,
The way you describe it you would have to set cancel directly, before doing any other calls. If it does not work when you call a MI Service that is because that call is asynchronous. You need to make sure you call cancel even if you don’t know yet that you need to cancel. Does that make sense?
Hi Karin,
Thanks for your quick reply, it does make sense in a way even though it would have made more sense for the application to support the async/await. I’ll do some more tests with the cancel call at the beginning before anything else is called.
Thanks / Marcus
Hi again,
Still in OIS100 on the E-panel.
Is there any way to capture the event on the next button other than command value Enter, I have encountered an issue where my script is overriding the standard project number validation for the order type. It is the initial args.cancel = True that is causing that validation to not work any longer, it seems as the panel gets stuck in a status where the basic validation of the field should have displayed an error message but now isn’t and that the validations from the script is not triggered because the project number added does not exist.
Optionally if there is a way in the script to determine if the basic validations on the program and its fields are done before the validations in the script are triggered, I have gone through the documentation and cannot seem to find any examples on what I am looking for.
Thanks / Marcus
Hi Marcus,
You may do whatever you like in the script BEFORE the Enter-key sends the control to the BE-program behind the panel – the program doesn’t know what goes on in the script until you press the Enter-key (or a F-key, open related etc).
When the program does it’s validation, it also takes control over what happens next (like showing another panel).
So you have to do “your stuff” before the program takes control (by cancelling the Enter-key event).
To avoid getting in a situation where “nothing happens”, you have to simulate the Enter-key after your validation-logic (if you don’t show an error-message and want the process to stop).
Hi Tjalve,
Thank you for the answer, I got it working by returning true from the validation functions in those cases where validations where not suppose to be taking place. By doing that the validation in BE triggered as expected so the two could be combined.
Thanks / Marcus
Hi Marcus,
If you have an attached “Requesting” event on the controller, you can always capture/override the event that needs to be cancelled, just as Tjalve said, you should first validate and do your stuff before that program takes control.
Regards,
Reggie
Hi Marcus,
as the MI call is asynchronous as Karin stated, you need to synchronize background call and user activity. Before the MI call is started, set a global flag. When the user presses a key, check if the MI call is still executing. If so, cancel the requesting event and set a second flag and the action that the user has chosen – probably you only have to react to “ENTER”. When the MI call finishes, do your validation. If the entry was correct, and your second flag indicates that the user has already pressed ENTER before the MI call finished, do it now programmatically. If the entry was not correct, you have already cancelled the event, so present a message to the user. If the user presses enter at a time where the MI call already finished (indicated by the flag that you have removed), everything runs as usual.
Hi Heiko,
Thanks for you r quick reply.
The thing is that I only calling the validation function when the user is pressing enter, I have that as a condition because the user can change the project number so I can only validate the field when he tries to move forward. I therefore have the validation call inside the onRequesting function where I am verifying that the user mode, this.controller.GetMode(), is 1, 2 or 3. If that is the case and the user has pressed Enter, args.commandValue === “ENTER”, I then call the actual validation which also includes the async MI calls.
All logic is in other words only triggered when the user is hitting Enter, not really sure how to check the status of the validation function (including MI calls) inside the onRequesting function, the only way in there to the logic is for the correct mode to be used and that the user has pressed Enter. Because the user can change the project number I cannot trigger the validation unless he is trying to move forward via Enter or Next and in the user mode to do so.
Am I approaching this all wrong, I do not want anything validated or cancelled if the user is only viewing the information on the E panel.
Thanks / Marcus
Hi Marcus,
I think I understand. In that case you must cancel the request, wait for the API having finished, and then press enter programmatically if the validation is ok.
Of course this must only be done if the user changed the project number. Buest guess is to read the project number from the screen when the panel opens and compare it to the value when the “Requesting” event is fired. And of course you must check the mode as well and do this validation only on Create, Change and Copy.
This event’s argument (of type CancelRequestEventArgs) has a “Cancel” property which can be set to “true”.
The H5 Development Guide has sample code for controller event handling.
Logik:
in “Requesting”:
if the mode is “display” or “delete” => do nothing
if flag detects “pressed by script” => do nothing, but reset the flag
if the user did not change the project number => do nothing
if new project number => cancel the event and run the API
in your “API completed” handler:
if valid project number => set flag “pressed by script” and press enter
if invalid => message to user
the flag can be stored in the InstanceCache. After pressing enter programmatically, your script will reload and lose all variables.
It is also a good idea to save valid project numbers in the cache (Session cache, if they are immutable, otherwise Instance Cache) and compare the values. If it is a valid project number which has been validated in a previous API call, no new API call is required.
br
Heiko
Hi again,
It is now working by the looks of it when using the cancellation right at the gate and then passing the Enter after the validations, thanks for the help it was really helpful.
Thanks / Marcus
Hi
Can anyone give me a code sample to file open dialog and read some text files ?
I could not find any solution on web.
Help is appreciated .
Thanks
PRA
Hi,
I’m not sure what the scenario is. SoHo Xi has a file upload control that would allow you to browse to a file. It’s used in the H5 admin tool to import files.
But the content of the file can only be posted to a server. You can’t just write JavaScript and access files on the computer. You can only upload data as a form post for example.
Hello!
I’m trying to populate editable fields in a listview with data. Unfortunately it is not the first row. Is there a way to move to say the third row to populate the data and column XXXX?
Hi Ian,
This piece of script will change the text in the editable cells of a list.
import System;
import System.Windows;
import System.Windows.Controls;
import MForms;
package MForms.JScript {
class EditableCellUpdate {
public function Init(element: Object, args: Object, controller: Object, debug: Object) {
var listControl = controller.RenderEngine.ListControl;
var items = listControl.ListView.Items;
debug.WriteLine(“Script Initializing.”);
for (var r = 0; r < items.Count; r++) {
var row = items[r];
for (var c = 0; c < row.Items.Length; c++) {
var cellText = "Cell " + r + ", " + c;
row[c].Text = cellText;
debug.WriteLine("Set value for editable " + cellText);
}
}
}
}
}
HI
How to populate editable fields in a listview with data using H5 scrpits .
I have tired one way but to update date in the cell i want to click the cell .
Thanks
PA
Can somebody please help me with programatically entering CTRL+27 in a type script?
Thanks
Hi,
check the controller’s “ListOption()” function.
/Heiko
Thank you very much, that worked! Is there any way to declare a global variable within an H5 script that will be seen from within an MIService execution block? Meaning, when I exit the MIService block it will retain the value set within the block:
MIService.Current.executeRequest(myRequest).then(
(response: IMIResponse) => {
//Read results here
for (item of response.items) {
asid = item.ASID;
if (asid !== “” && asid !== “undefined”) {
ConfirmDialog.ShowMessageDialog({ dialogType: “Error”, header:
“ERROR”, message: “my message” });
}
else {
//send CTRL+27 programmatically
//SET A GLOBAL HERE THAT WILL BE ACCESSIBLE OUTSIDE OF THIS REQUEST
this.controller.ListOption(“27”);
}
}
})
Thanks!
Hi Promethius,
Yes, this is absolutely possible.
But the “trap” here is that the api is run asyncroneously, meaning that the rest of the code will continue while your codeblock is waiting for the response from M3.
Thus there is a possibility that you will try to access your global variable before it is set inside your MIService-block.
One way to solve that, is to use async and await (calling the async method and waiting for it to finish before continuing with the rest of the code).
This way you are guaranteed that the MIService-block is finished before you try to access the global variable.
Kind Regards,
Tjalve.
Thanks TJalve, I’ve got it working you’re awesome!
How can I read from the environment profile some parameters like the smart office Jscript using H5 scripts
Hi Ahmed,
You mean the UserContext?
If so, you can e.g. write:
const userContext = ScriptUtil.GetUserContext();
let cono = userContext.CurrentCompany
And so on for all parameters of the Usercontext.
Hi Tjalve, I meant the application services which is under the environment profile for smart office where you read the parameters related to some application components like PF and Mashup web services configuration
Hi Ahmed,
Do you mean how to access profile in Smart Office or in H5? There are no such values for the H5 JavaScript.
Hi Tjalve,
I meant the application services which stored in the environment profile for the smart office where you retrieve the parameters related to the application components like PF, Mashup or web services
here an example for what I am trying to have
validAgreementType =ApplicationServices.SystemProfile.GetProperty(ApplicationGroupType.PF, “PFlow”, “ValidAgTypes”);
H5 does not have any PF configuration data. You will need to have the base URL as a parameter to your script. I don’t think that you will be able to call PF if that is your goal. The cookies the browser has are not valid for PF and you can’t have user credentials in the script. What is the scenario? Where is PF installed? Is it in the same grid? If it is then you should just have a relative path. If it is not on the same grid you have an issue and am not sure how you would be able to access it. Also unless PF supports CORS (cross domain calls) then you would not be able to call them from a browser loaded from another server than the PF server.
I am trying to generate IPA workflow using HTTP request but it doesn’t recognize the user and password and I don’t know the parameters that I should send as per the below example
let uri = ‘http://pztjhipa.zahid.com/sso/SSOServlet?_ssoUser=IPA_EJAR^&_ssoPass=”Password”&_action=LOGIN^&_fromLoginPage=TRUE^&_language=en-us^&_locale=en_US^&_ssoOrigUrl=http://ppzjhipa.zahid.com:80/bpm/trigger?triggerType=ServiceAsync&triggerName=IPA-PPW-004-Serv&dataArea=lpa_data_psu&workTitle=’ + data + ‘&varName\[0\]=DONO&varValue\[0\]=’ + data + ‘&varName\[1\]=Originator&varValue\[1\]=’ + encodeURI(this.usid.toUpperCase()) + ‘&varName\[2\]=ToWHS&varValue\[2\]=Y30&varName\[3\]=strCompany&varValue\[3\]=’ + encodeURI(this.Company);
ScriptUtil.Launch(encodeURI(uri));
Hi,
I don’t know how to integrate with IPA. NEVER pass a user and password. You need to solve this in another way. I suggest using the enhancement request process or contact the product owner Ole Rasmussen for a discussion. Never have secret information in a JScript or JavaScript. It’s visible to everyone. Passing information over http is also visible to everyone. It’s not acceptable do do these kind of tricks. You shouldn’t even have sensitive information in the Smart Office profile.
Sorry.
Hi,
I am trying to develop type script so M3 H5 can call external(another domain) Web Service API to retrieve data and push them back to M3 using $.ajax()…got the error:
No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘https://xxx.domain.com:20110’ is therefore not allowed access.
Where to setup M3 Grid and so it can allow CORS request?
It is the other server that has the service that prevents the call. Is that an Infor Grid? CORS is not configured grid wide but on a context root. Contact support for the application you are trying to access.
Regards
Karin
Thanks for the information Karin.
Hi
Is there a way to create a button that lets users select an excel file? and then the records in that file gets sent as input parameters to an MIService call?
Help much appreciated. Thanks!
Hi,
No. JavaScript don’t have access to the client’s disk.
I would only work if the Excel file is accessible through a URL (https/http) and CORS script access is allowed. In order to access a file on a client’s machine you will need to post it to a server, which you don’t have if this is a H5 script. The only workaround would be to copy and paste the content of the excel file into a dialog where you have a text area, but that is not good user experience.
Hi,
Is there a way to use in an h5 script?
The reason I’m asking is because I need to convert a jscript which is used for importing excel data into a db table. In that jscript, they use System.Windows.Forms.OpenFileDialog().
Is this still possible in h5 script?
Thanks!
Hi,
Is there a way to use “input type=file” in an h5 script?
The reason I’m asking is because I need to convert a jscript which is used for importing excel data into a db table. In that jscript, they use System.Windows.Forms.OpenFileDialog().
Is this still possible in h5 script?
Thanks!
Hi,
I’m asking about the “input type=file” here.
Thanks!
Hi Dax,
I thought of this some more it’s possible to load a file in Chrome, but I don’t know if an excel file could be opened or not. Generally we don’t develop something that would only work in Chrome. In web there is a corresponding Infor Dialog control that you can use to create your own dialog, search for dialogOptions in the comments on this page.
You can’t import anything into a DB table, you can call MIPrograms but you are not allowed to have any sensitive information which means calling a DB is not an option.
Basically what you are looking for would need an endpoint which you could post the excelfile too that would then return it’s data to the script. That would work in all browsers as long as that endpoint allow cross site scripting.
Hi Karin,
I call M3 API in H5 script like this:
MIService.Current.execute(program, transaction, record).then(function (response) {
console.log(“API works fine”);
}, function(err) {
console.log(“oops, something is wrong err”);
});
Is there a way to see error message returned by API?
Thanks,
Hi,
I’m not sure exactly what you mean? Do you mean in case of a NOK? It’s part of the response. If you debug in the browser dev tools you can check the object in the debugger. I don’t remember if we have typings right n place for the response, but I think we do, I’ll check tomorrow.
Hi Karin,
Yes, in case of NOK.
Regards,
Hi
Is there anyway to hide a column in a grid dynamically or make the editable cells as read only
Thanks
Prabodha
Hi
Is there any way to hide column in grid dynamically using J script?
Or disable editable cell
Thanks
Prabodha
Hi,
When opening a modal window using dialog options, how do you get the properties declared in the parent window and use the value in this modal window? I’m always getting ‘undefined’.
Thanks!
Hi,
You should always get the value you want to pass from the instance controller and get the parent window/host.
Hi,
Is there anyway to add a dropdown or combobox in H5 which will be populated by fetching records from API(MI)?
Hi,
Yes it is possible. It’s a matter of adding the correct control. What is the user case? Replacing an existing input field? Because that might not be possible.
Yes there is a textbox and that needs to be replaced by combobox. Can you provide the script for adding a combobox/dropdown field?
Hi Deepak,
You can do like this.
let buttonElement = new CheckBoxElement();
let contentElement = this.controller.GetContentElement();
contentElement.AddElement(buttonElement);
You can also create an instance of CheckBoxElement like the textbox and add it using “.AddElement”
Hi,
Looking around I see values on M3 panels retrieved both with ScriptUtil and this.controller. What are the pros and cons? When is it better to use one rather than the other?
Examples which both work for me:
let DAField1 = ScriptUtil.GetFieldValue(“WWALVL”)
let keyField1 = this.controller.GetValue(“WHITNO”)
Hi Jessika,
Technically you can use both, because it goes to the same code base, but it is best to use the ScriptUtil because the utility is made primarily for scripts, plus it can carry an instance controller parameter that is “mandatory” to pass when using scripts in webmashups.
Thanks!
Hi
Is there a way to know if the user is in display mode or change mode in H5 ?
Thanks
SP
Hi Sunny,
You can check the panel response if the mode is “2” for change and mode “5” for display.
//Reggie
Is it possible to change entire row text color or background color based on certain cell value in grid list using H5 script?
Thanks
Kev
Hi. Did you ever find out how to do this?
// Christian
how do i create a function to get the selected row in gridview?
Thanks,
Len
Hi,
I’m looking for a way to read the M3 error/ Warning messages while MForms automation running.
Seeking your ideas is this possible or if there any work around.
Thanks
Hi,
There is no way to do this with automation.
What are you using the automation for? I checked with my colleagues as well. Will you ever present a screen from the automation? Perhaps a bookmark would be a better option?
Hi,
Thanks for your prompt response.
My requirement is to upload excel file and based on number of lines in excel file, I have to create lines in M3.
Automation has proposed because there are no standard M3 API to fulfill my need.
So as I mentioned before while creating the lines via automation, I need to keep a track if any error occurred.
Thanks
Hi,
Basically you need to have an API for this. There is also a lot of limitations with the actual file upload in a browser when you are not actually posting the file to the server, that I have written comments about in the past.
Hi,
Basically the JavaScript File-API allows to access files from the local machine after the user has selected it or it has been dropped to a special region on the HTML5 UI.
Then GLS840MI can be used to process finance data which are defined in GLS850 as a template (interface type 1; takes a 900 char parm field which holds the input data in a structure which is described in the GLS850 input record) or, in M3CE, even as interface type 2, where each M3 field is exposed as parameter which can be passed to the REST API call.
An alternative is to run the solution standalone outside the browser or as Excel AddIn.
/Heiko
Hi,
In H5 you can show programs “side by side”.
(Start two programs, then drag one tab over the other and they are shown “side by side”).
A lot of the functionality in scripts seem to stop working in the “second tab” when using this functionality.
E.g. ScriptUtil.GetFieldValue and SetFieldValue does not find the fields in scripts on the second tab.
It looks like the error is because the “Active controller” always points to the controller in the first tab (even for scripts in the second tab/program).
Is this drag/drop of tabs offisially supported in H5 – and in that case: is this an error in the H5 ScriptUtil functionality?
/Tjalve.
Hi, This should be corrected. It is possible that a new ScriptUtil that takes the controller as a parameter is needed in this case, eg, it can’t be static. The ScriptUtil was created when there could only be one instance. I’ll create a ticket to add a new method on the ScriptUtil and ask that the other methods are deprecated.
If you would like to track this please add a ticket through support and we can connect those tickets.
Thank you Karin!
Have reported it (Incident 13589562).
This is not a bug that we can just fix. Code changes in the scripts will also be needed as the ScripUtil needs to resolve using the current instanceController as a parameter or similar.
Yes, of course.
A parameter with the current instanceController sounds like a good idea (and deprecate the current function)
Hi there,
I’m really new to H5, M3 and JS but just started as developer and got asked if I could write a script that launches an URL to a mashup. Now I’ve figured that part out but I’d like to make it a bit better. When the mashup is launched I’d like to select a field in the DataGrid (Slick-grid). I can’t seem to get that working and I don’t know why. Could anyone help me with that? If my question is unclear please tell me, I’m really new to it all.
Hi Siemen,
I just need to clarify if the script that you attached in a program launches/opens a mashup and have a different tab? and you are hoping to select something after that mashup loads?
note*
For every program there will be an instance, which mean even if you have a set of mashup, those mashups that run different programs will also have different controllers.
/Reggie
Hi Reggie,
The mashup loads in a different tab and I would like to select something after the mashup is loaded. So the script is attached to a shortcut in a program (lets say mms001). When the shortcut is clicked it should fire an URL to a mashup of mms001 and some other stuff. Is it possible to make the mashup launch in the same window/tab?
Thanks for the quick reply by the way! 🙂
Hi, I’m trying to call infor webservices via H5 script, but we are getting a CORS policy issue.
I’m getting “Access to XMLHttpRequest from origin has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.”
Is there any way to work around this issue?
Hi Dax,
Is Infor Web services and H5 in the same Grid? This is in a JavaScript right? I would not call it work around but you need to configure Infor web services so that it allows Ajax calls from the domain that is loading the script you are writing. This has to be the external address that you use to access the application. What exactly is the scenario here? It’s possible that there is configuration that you can do, some domain whitelist in Infor Web Services. Have you checked it’s documentation?
Hi Karin,
Yes, this is in a javascript. I’m using XMLHttpRequest to call the webservice, instead of AJAX.
We’ve already tried to add the domains in mi.cors.allowed.domains property in the Grid settings, but still facing same issue.
Do we need to add/do something to the infor webservices to allow requests coming from the origin?
Thanks!
Hi,
mi.cors.allowed.domains Sounds like a setting för MI-WS (M3 API) and not Infor web services. Yes, a configuration is beredd but I’m afraid I don’t know explicitly what to set.
Hi,
I’ve checked and Grid 1.13 and Infor Web Services (MWS / LWS) does not have CORS support. So you can only call it from client code running in an application on the same host. Your only option would be to create a M3 MI Program and all MI-WS as it supports CORS.
Where are you executing the script call from?
Hi,
I also suggested to create a M3 MI program for it instead. But they said that they are using IWS because they have complicated SQL queries which require to join multiple tables. DO we have any alternative for querying into multiple tables?
Hi Dax,
You can consider setting up an information category in CMS010 and its related tables. This can be used in CMS015 to setup a transaction in CMS100MI. Returned fields are setup in CMS010->views, which are also selected in CMS015.
Cheers,
Jonathan
Hi,
Why is it that when I use this.controller.GetContentElement().GetElement(‘XXXX’).readOnly() it also disables the field? I’m asking because I need to set a field as readonly and pass the value for that field to the next panel. But what happens is readOnly() also disables the field, thus the value doesn’t get passed.
Any thoughts on this?
Hi Dax,
When using “this.controller.GetContentElement().GetElement(‘XXXX’)”, you are selecting an element from your current panel, and if you’re going to get the value from that element(textbox), you need to add “.val()”
ex.
this.controller.GetContentElement().GetElement(‘XXXX’).readOnly()
-This will only disable the field
this.controller.GetContentElement().GetElement(‘XXXX’).val()
-This will get the value from the selected element
/Reggie
So in the hope someone can still help me I’ll post my question again. I’m trying to launch a mashup in a different tab and to get a value in a field en make it so that the value entered in the field is also selected from the Slick-Grid that is part of the mashup. Can anyone help me in a direction?
Hi,
I’m having H5 (Typescript) debugging issue on M3CE Multitenant environment.
Following is the sample URL I’m configured on visual studio.
https://XXX.m3.inforcloudsuite.com/mne/?scriptCache=false&localScript=http://localhost:49482/H5SampleHelloWorld.js
When I run the project from visual studio M3 will popup but debug is not enabled.
I assume this could be URL issue.
Any thoughts on this?
Hi,
Has anyone tried uploading a file from a H5 javascript of web SDK to IDM?
From what I understand, the user has to select the file via the browser will pass it to the javascript, and then converted to a stream to send to an IDM API, with appropriate tags in XML.
Is this correct and does anyone have details?
– Jonathan
Since one of the last updates of H5 it seems no longer possible to format text in dialog windows that can be called with “ConfirmDialog.ShowMessageDialog()”.
For example earlier it was possible to control line break and add bold text. Now with the new H5 version the whole HTML code is written to screen. It would be really good if it was possible to at least do a line break to be able to format the text that the user is shown.
Any suggestions?
Example code:
ConfirmDialog.ShowMessageDialog({
header: “Test of dialog”,
message: “This is an example test with BOLD text and a line break here second line”,
dialogType: “Information”
});
This is actually a security correction. The message should only be text and since the content can’t be trusted it’s now escaped. You can add an enhancement request to support something like wiki syntax in the text for formatting of this component or you would need to create your own message dialog by using the Infor Design Control and if you know that the text is completely hard coded and does not contain anything that is dynamically created or input from a user then you can add your own HTML and handle it as HTML.
Cross Site Scripting vulnerabilities should be taken extremely seriously and it is something that you need to think about in your code as well if you are handling any type of data based on user input.
Where can I find Infor Design Control?
Thanks Karin for the answer!
I understand the reason behind the correction and I like the idea around the wiki syntax. I will investigate if I can implement a custom message dialog instead.
I have a problem, my code is as follows:
var populateData = function(list, columnNum){
var columnID = “C” + columnNum;
for(var i = 0; i {
/* LOGS SECTION:
console.log(“Response Request “);
console.log(response);
*/
userStatus = response.items[0].USTA;
console.log(userStatus); // Shows the right value
});
var newData = {};
newData[columnID] = “DUMMY DATA ” + i + ” ” + userStatus; // Shows “unknown”
newData[“id_” + columnID] = “R” + (i+1) + columnID;
$.extend(list.getData().getItem(i), newData);
/* LOGS SECTION:
console.log(“newData”);
console.log(newData);
*/
}
var columns = list.getColumns();
list.setColumns(columns);
};
I was wondering if anyone has a tip on how to get the userStatus in the later part of the code assigned the value retrieved with the API call. Any other comments on my code are also greatly appreciated since I don’t have much experience.
It seems certain parts of my post have been scrubbed, forgot about sanitization. Here’s the right version i hope:
/*var populateData = function(list, columnNum){
//var columnID = “C” + columnNum;
//for(var i = 0; i {
/* LOGS SECTION:
console.log(“Response Request “);
console.log(response);
userStatus = response.items[0].USTA;
console.log(userStatus);
});
var newData = {};
newData[columnID] = “DUMMY DATA ” + i + ” ” + userStatus;
newData[“id_” + columnID] = “R” + (i+1) + columnID;
$.extend(list.getData().getItem(i), newData);
/* LOGS SECTION:
console.log(“newData”);
console.log(newData);
}
var columns = list.getColumns();
list.setColumns(columns);
};*/
Apperently parts of my code are blocked/sanitized. I have the following problem:
variable userStatus = “unknown”
API-call
userStatus = response.items[0].USTA // gives me the right values.
newData[columnID] = userStatus // contains the value “unknown” instead
Could it be that you API-call is async and newData[columnID] is executed before the API finishes? That is not clear from your snippet.
Hi HeikoM, thanks for your quick reply. The API-calls are async but I thought that I fixed that with:
/*
async function executeRequest(APIRequest){
var response = await MIService.Current.executeRequest(APIRequest);
return response;
}
*/
The snippet is not complete since it has been scrubbed of certain functions, my bad.
It would seem that the newData[columnID] is executed before the API finishes. If this is not the way to go about it, do you have a suggestion?
The async execution means that you MUST carry on in the same thread of the MIRequest, the main thread does not know that you called something in the function which runs in the background, it continuoes directly with the next statement. In theory you could use promises in the main thread, but I was not capable to got it working in H5. So, alternatively, you need to finish your main routine after “executeRequest”, and move the remaining code to a new routine which you call as last action inside “executeRequest”. This avoids the “Pyramid of Doom” which was a problem in JavaScript before Promises have been invented.
I am trying to run mforms automation to open OIS103 from OIS100/F panel. it works but the order number with which it opens is a wrong one and not the current one. Maybe it caches one order number and after that only uses that order number to open OIS107. How do I use the current order number? The order number and customer number on the OIS107 is greyed out. Is that the issue? But how does it come correctly the first time?
My code –
const auto = new MFormsAutomation();
auto.addStep(ActionType.Run, “OIS103”);
auto.addField(“ZZORNO”, orno);
auto.addField(“OKCUNO”, cuno);
auto.addStep(ActionType.Key, “ENTER”);
const uri = auto.toEncodedUri();
ScriptUtil.Launch(uri);
Thanks a lot for the help!
Sanyukta
Hi all,
I am trying to call OIS103 from OIS100/F panel. OIS103 successfully opens but with a wrong order number. The first time I did this, it worked but after that its the same order number OIS103 is opening with. Looks like this number is cached.My code is
const auto = new MFormsAutomation();
auto.addStep(ActionType.Run, “OIS103”);
auto.addField(“ZZORNO”, orno);
auto.addField(“OKCUNO”, cuno);
auto.addStep(ActionType.Key, “ENTER”);
const uri = auto.toEncodedUri();
ScriptUtil.Launch(uri);
Order number is greyed out in OIS103. Is that a problem?
Appreciate quick help!
Thanks and regards,
Sanyukta
Hi,
MFormsAutomation will not work on protected fields. You will need to call OIS103 from the calling program. Your automation should either start with OIS100 or OIS300 and then call related option 12 (Charges)
Hello Macalat,
Thank you for the response. You are right. I did this in another way which worked.
I used the bookmark URI to launch OIS103. Here is my code.
let bookmark = “bookmark?PROGRAM=OIS103&TABLENAME=OOCHRG&KEYS=OECONO%2C” + CONO + “%2COEORNO%2C” + orno + “%2COECRID%2CSHPFEE%2B%2B%2COEDLIX%2C0%2COEWHLO%2C%2B%2B%2B&OPTION=1&PANEL=E&SORTINGORDER=null”;
ScriptUtil.Launch(bookmark);
Sanyukta
Hi,
When I attach a script to a program, how can I use this same script in the other panels of the program without having to attach the script for every panel?
For example, I attach a script in MMS001/B -> I go to Change mode which will trigger a specific function in the script -> program goes to E panel -> I press ENTER which will trigger a different function in the same script -> program goes to F panel -> script is unloaded.
Is this possible in H5 script? Because this works in LSO jscript.
Thanks!
Hi,
H5 script and LSO jscript should have the same event lifecycle (i.e. OnRequesting, OnRequested and OnRequestCompleted), so if you managed to make this work before in Smart Office via Jscript then it should also be possible in H5.
I wouldn’t personally advice this approach, though. A script’s activity should only be on the panel on where it was attached. Once it is out of that panel, all event listeners for that script should be terminated. Memory leaks and a lot of unwanted behavior would happen if you don’t managed the proper detaching or unloading of the script. It would be better if you create one script for Panel E and another for Panel F.
Hi all,
I am looking to create a script for double confirmation when user trying to print a report.
The closest thing I have found is H5SampleCancelRequest.
However when i tried to use ConfirmDialog, the onRequesting method proceed without waiting the dialog to popup. However thing works when I changed to use window.confirm, but since the window pop up box design is different with ConfirmDialog, so I am looking for chance to use ConfirmDialog to achieve the same thing.
The code is as follows:
private onRequesting(args: CancelRequestEventArgs): void {
this.log.Info(“onRequesting”);
if (args.commandType === “KEY” && args.commandValue === “F12”) {
return; // The user should be allowed to go back
}
if (args.commandType === “KEY” && args.commandValue === “ENTER”) {
ConfirmDialog.Show({
header: “Question”,
message: “Please confirm to proceed”,
dialogType: “Question”,
closed: respond => () => {
args.cancel = respond.cancel;
}
});
}
}
Thanks!
Hi!
I did a lot of different methods, but I only came up using this work around code.
let _this = this;
if (args.commandType === “KEY” && args.commandValue === “ENTER”) {
args.cancel = true
ConfirmDialog.Show({
header: “Question”,
message: “Please confirm to proceed”,
dialogType: “Question”,
closed: (respond) => {
if(respond.ok){
_this.unsubscribeRequesting();
_this.controller.ExecuteFunction({CMDTP:args.commandType, CMDVAL: args.commandValue});
}
}
});
}
Firstly we need to cancel the current event and re-issue the event after pressing the “ok” button inside the dialog. You also need to unsubscribe the listener first because it you will have an infinite loop if you don’t.
//Reggie
Hello,
How to user inforListBox, can you please share some sample code.
Thank you in advance.
Hi!
First you need to create a select element for the listbox.
ABC Manufacturing
Acme Industrial
Then on your script file, you need to initialize the listbox.
$(“.inforListBox”).inforListBox({showCheckboxes:true});
Then when doing an event it should look like this.
For example when deleting all the options inside the listbox, of course you need a button for it to work.
$(“#listbox1”).inforListBox(“clear”);
//Reggie
Hi! Is there a way to make the text in a column act as hyperlinks? In my case I want the user to press the text in the column and then display some kind of dialog with information I’m fetching with an API.
Thanks!
Jonatan
Hi Jonatan,
Yes of course there is a way to make it act as hyperlink, but you will use extensive coding for it to happen, and that is not what we want.
As for a work around you may use a script that acts a shortcut to display the dialog.
//Reggie
Hi,
In SmartOffice we have a script that is checking the validity of VAT numbers using a SOAP call ec.europa.eu (http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl), the plan was now to transform this script using Typescript and implementing it in H5.
If the call is made using async true I get no changes in readyState or status, and of course then no response. If I instead use async false I get the below network error:
Error: NetworkError: Failed to execute ‘send’ on ‘XMLHttpRequest’: Failed to load ‘http://ec.europa.eu/taxation_customs/vies/services/checkVatService’.
The problem is that I do not seem to get it to work, I have tried different approaches with the latest being XMLHttpRequest but the readyState and status does not change when trying to call the external web service. Is it even possible to do in H5, I have been reading about problems with CORS and the availability to only call API’s on the same domain?
I have used SoapUI to verify that the the information I am sending is working and is returning the response i require.
Thanks / Marcus
Hi,
If you have a CORS issue that is shown by a log in the browser tools, so it’s not that in this case.
You have to use async true. There has to be some issue with how you are making the call. Have you verified that the call is actually triggered? Use the Network tab in the browser or a tool like Fiddler to see that you are actually triggering the request. Then double check that you are using a post, that the data submitted is correct and so on. If you can run it in SoapUI you can compare the request/response data.
Hi Karin,
Thanks for your quick reply, it seems as I have a mixed content issue where we are trying to call a http service from an https site. You where in other words correct stating that the fault is in how the actual call is made, or made from in this case. I need to investigate this initial hurdle a bit more and see if there are any other on-line checks for this using https.
/Marcus
Hello
I am trying to run the H5SampleShowOnMap sample script that we can find on the H5 scripting manual, but I get this error:
Refused to display ‘https://maps.google.com/maps?z=…&output=embed’ in a frame because it set ‘X-Frame-Options’ to ‘sameorigin’.
Why is this happening? Does this have anything to do with “Cross domain calls are not allowed by default” issue that is mentioned in 3 H5 limitations? How can we solve this?
Regards
Nuno
Hi,
I’m afraid google maps no longer supports being framed. We should remove that example. There is no work around.
Hi Karin.
Thanks for your reply.
But what about other sites? I am trying to make a script that shows tracking details from forwarding agents. Something like this (for testing purposes):
var url = “http://www.logimat-delegaciones.net/SEGUIMIENTOEXPEDICIONES.ASPX?EMPRESA=RIOLOGISTIC&ANIO=2019&SERIE=01&NUMERO=00002676&REFERENCIA=2102763”
ScriptUtil.Launch(url);
However, this throughs the following error:
jquery-1.10.2.min.js:5 Mixed Content: The page at ‘https://s65ff…. localScript=http://localhost:8080/MWS410B_Transportista.js’ was loaded over HTTPS, but requested an insecure resource ‘http://www.logimat-delegaciones.net/SEG…’. This request has been blocked; the content must be served over HTTPS.
How can I solve this?
Regards
Hi! How do I disable a drop-down in the best way?
I’m trying to set the value and then making the drop-down read-only/disabled. I’ve tried doing it this way:
this.controller.SetValue(“WRSTAT”, “10”);
this.controller.GetElement(“WRSTAT”)[0].disabled = true;
But then M3 doesn’t think that this field has a value, and since this field is mandatory the user gets stuck. If I remove the “disabled” part of the code, M3 detects the value. So SetValue works.
Setting the “readonly” property as I would do with normal text fields does not seem to work for drop-downs. You can still pick a value in the drop-down.
So is there a better way to disable a drop-down?
// Jonatan
Hi Jonatan,
You may set it up like this.
this.controller.SetValue(“WWQTTP”, “3”);
this.controller.GetElement(“WWQTTP”).attr(“disabled”, “disabled”);
//Reggie
Hi Reggie!
Thank you for your answer, but this still gives me the same error actually. M3 complains about WRSTAT being empty, even though the value is set. If I remove the disable-code, the value is accepted.
The value I’m trying to set is WRSTAT in CRS610/E, if that makes any difference.
// Jonatan
Hi Jonatan,
How are you moving forward in the code from the panel that you are in, I had a similar problem where the actual value was ignored by M3 because the field was disabled. What I did was to set a value to the field, disabled it and then enabled the field the absolut last thing I did before sending the user on to the next panel. This only works though if you programmatically is sending the user forward, if not then the user will have the field enabled.
/Marcus
Hi,
After digging deep into our code, it seems like H5 doesn’t want to include the fields to be changed that are readonly/disabled, that’s why it always goes back to its previous value.
You may re-enable the field right after clicking next like Marcus’ said.
//Reggie
Okay I finally managed to figure it out…
As you said you have to enable the field right before the user is sent to the next panel. But as Marcus pointed out, it doesn’t work if the user presses “next”/ENTER, but only if you send the user through programmatically. Since I need to able to be able to navigate through the panels as usual, I found a way to get around that. I simply did it by catching the ENTER click, enable the field, and then invoke that same command programmatically.
if (!this.statEnabled) {
if (args.commandType == “KEY” && args.commandValue == “ENTER”) {
this.controller.GetElement(“WRSTAT”)[0].disabled = false;
this.statEnabled = true;
args.cancel = true;
setTimeout(() => {
this.controller.PressKey(“ENTER”);
}, 100);
}
}
Hi,
Is there anyway can we Refresh-F5 , Close -F3 M3 screens example: OIS110 from H5 script?
Thank You.
this.controller.PressKey(“F3”); should automate the action for you. Make sure you add some delay if required.
Thanks
Sanyukta
Okay sure Sanyukta , i will try it, Thank You so much for your help.
Hello
I am trying to make a script that shows tracking details from forwarding agents, opening up another web page. Something like this (for testing purposes):
var url = “http://www.logimat-delegaciones.net/SEGUIMIENTOEXPEDICIONES.ASPX?EMPRESA=RIOLOGISTIC&ANIO=2019&SERIE=01&NUMERO=00002676&REFERENCIA=2102763”
ScriptUtil.Launch(url);
However, this shows the following error:
jquery-1.10.2.min.js:5 Mixed Content: The page at ‘https://s65ff…. localScript=http://localhost:8080/MWS410B_Transportista.js’ was loaded over HTTPS, but requested an insecure resource ‘http://www.logimat-delegaciones.net/SEG…’. This request has been blocked; the content must be served over HTTPS.
How can I solve this?
Thanks in advance
Nuno
Hi,
It will not be possible to open a HTTP url within the H5 frame set. That is a security limitation. You have two options:
1. Open with window.open(url,’_blank’);
2. Check if that page can support HTTPS
Hi,
I try to re-use the example provided in H5SampleRegexValidator script, in OIS260 to validate that the “From Customer order number” (WFORNO ) and “To customer order number” (WTORNO) have same value before validating panel E. I though I can do this defining in the argument of the script, “regex” that both field has the same value:
{ “names”: [“WFORNO”], “regex”: ” WFORNO = WTORNO”, “message”: “From and To value shoul be the same” }
Could someone help on this one?
Thanks
Stéphane
Hi,
That script only works for a regular expression match check. It takes the value for the WFORNO and applies the regular expression. It’s not possible to compare values at it is a standard regex and not a string that supports variable substitution.
Eg. H5SampleRegexValidator is not for you scenario.
You would need to create a new script that takes two arguments (field names) and verifies that their values are equal. It’s a simple script and you can use the sample as a starting point. Your script would only need the following input: { “names”: [“WFORNO”,”WTORNO”], “message”: “From and To value should be the same” } and then validate fields could look like this with only two values supported:
private validateFields(): boolean {
try {
var validation= this.validations[0];
if(!validation){
return true;
}
let name1 = validation.names[0];
let name2 = validation.names[1];
let value1 = this.controller.GetValue(name1);
let value2 = this.controller.GetValue(name2);
// TODO check for null / undefined etc
const result = value1!==value2;
if(result){
this.controller.ShowMessage(validation.message);
return false;
}
return true;
} catch (ex) {
this.log.Error(“Failed to validate fields”, ex);
// Return true if the script crashes to avoid getting stuck on a panel.
return true;
}
}
Hi
I am quite new to H5 scripting.
For my development environment I’m using Visual Studio Code and Node.js
So, I write my script in TypeScript, compile it using TSC command and then I get the corresponding JavaScript. I also use the StarWebServer cmd.
Two questions:
1. I get a lot of compiling errors, even though the script works fine in H5. So, I guess some “import” kind of stuff is missing in the compiler. How can I fix it?
2. Is it possible to debug the script in the browser? How?
Regards
Nuno Monteiro
Hi Nuno,
After running the web server, could you please try to open the corresponding javascript in the browser and see if your webserver is working (ex. localhost:8085/H5SampleCancelRequest.js), also try to change the port for the server.
1. The installer should import all what you need when running the webserver using node.js
2. Yes it is possible to debug the script in the browser, attach it on your desired H5 environment and using the browsers developers tools.
Regards,
Reggie
Hi! Is it possible to manually filter a list in H5? I would like to remove some rows in a B-panel depending on some condition. Is this possible?
Best regards,
Jonatan
Hi Jonatan,
I would say that it is not possible for the rows, due to how the inforDataGrid works, the items on the rows are added by column by cell one by one.
/Reggie
Hi,
I use MIService in the following way:
let myRequest = new MIRequest();
myRequest.program = “MMS200MI”;
myRequest.transaction = “GetItmWhsBasic”;
myRequest.record[“WHLO”] = “D03”;
//myRequest.record[“WHLO”] = this.controller.GetValue(‘VHWHLO’);
myRequest.record[“ITNO”] = “101438”;
//myRequest.record[“ITNO”] = this.controller.GetValue(‘WWPRNO’);
var myPromise = MIService.Current.executeRequest(myRequest);
Promise.all([myPromise]).then(response =>{
}).catch(response =>{
console.log(response.message);
console.log(response.errorMessage);
for(var item in response[0].items){
value = item.WHSL;
}
});
The script falls into error on the line:
myRequest.record [“WHLO”] = “D03”;
I do not understand why
The error is :
15:40:58,926] [ERROR] Failed to call Init function for script H5InitField Cannot set property ‘WHLO’ of undefined TypeError: Cannot set property ‘WHLO’ of undefined
at H5InitField_WHSL.run (eval at (https://sd180001.xxxxxxx.local:19008/mne/controls/jquery/jquery-1.10.2.min.js?v=MTAuMy4xLjAuNDM5:4:4994), :91:33)
at Function.H5InitField_WHSL.Init (eval at <anonymou
Thanks in advance
Best regards
Yvonnick
Hi Yvonnick,
Looks like you have a blank between record and [“WHLO”]?
(Try to remove the blank and see if that works)
Kind Regards,
Tjalve.
Hi,
Thanks for your response.
I’m not a blank beetween record and [“WHLO”]
Kind Regards,
Yvonnick
Hi Tjalve,
Thanks for your response. I m not the blank between record.
Kind Regards
Yvonnick
Hi Yvonnick,
I tried to do the below way and it works. Can you please try this way and check?
var orno = this.controller.GetValue(“OAORNO”)
var myRequest_1 = new MIRequest()
myRequest_1.program = “OIS100MI”
myRequest_1.transaction = “LstLine”
myRequest_1.record = {
CONO: CONO,
ORNO: orno
}
myRequest_1.outputFields = [‘ORST’, ‘ITNO’, ‘PONR’]
MIService.Current.executeRequest(myRequest_1).then(function (response) {
_this.responseAvailable = true
// Check the item type CFI4/CIF5 of the new item which is being added
for (var _i = 0, _a = response.items; _i 33 && item.ORST != 99) {
_this.showError(“Line cannot be added as the highest”, ” order line status is greater than 33.”)
return
}
}
Hi
There is a standard M3 Add button in OIS101 to add line item. My script in OIS101 has a new button to perform some validations, I want to automatically click the standard Add button when validation is successfull. Can we do it from script to click the standard M3 Add button? Can you provide some example?
Hi SD, We can do it. When a user clicks on the validation button and when it is successful you can write a command to press enter.
Something like this –
_this.controller.PressKey(‘ENTER’);
I have done a very similar thing in OIS101. But I did not create another button for validations! What if the user forgets to click on the validation button? What I did was –
1) When a user clicks on the Add button, the script disconnects the action and performs the validations and when the validiation is successful I explicitly press the Enter key. Check out the example.
var OIS101_Validations = (function () {
function OIS101_Validate(args) {
this.checked = false
this.args = args.args
this.controller = args.controller
this.log = args.log
}
OIS101_Validate.Init = function (args) {
return new OIS101_Validate(args).run()
}
OIS101_Validate.prototype.run = function () {
this.attachEvents(this.controller)
}
OIS101_Validate.prototype.addLine = function () {
var _this = this
_this.checked = false
//all your validations here!!
//if successful then do the below otherwise throw an error msg
setTimeout(function () {
_this.controller.PressKey(_this.lastCommand)
if (_this.lastCommand == ‘ENTER’) {
_this.checked = true
}
}, 100)
}
OIS101_Validate.prototype.showWarning = function (header, message) {
console.log(‘header’ + header)
console.log(‘message’ + message)
ConfirmDialog.ShowMessageDialog({
dialogType: “Warning”,
header: header,
message: message
})
}
OIS101_Validate.prototype.showError = function (header, message) {
ConfirmDialog.ShowMessageDialog({
dialogType: “Error”,
header: header,
message: message
})
}
OIS101_Validate.prototype.attachEvents = function (controller) {
var _this = this
this.detachRequesting = controller.Requesting.On(function (e) {
_this.onRequesting(e)
})
this.detachRequested = controller.Requested.On(function (e) {
_this.onRequested(e)
})
}
OIS101_Validate.prototype.detachEvents = function () {
this.detachRequesting()
this.detachRequested()
}
OIS101_Validate.prototype.onRequesting = function (args) {
this.log.Info(“Command type: ” + args.commandType + “; Command value: ” + args.commandValue)
console.log(‘this.checked is in main func’ + this.checked)
if ((args.commandType == “KEY” && args.commandValue == “ENTER”) && !this.checked) {
args.cancel = true
this.lastCommand = args.commandValue
this.addLine()
}
}
OIS101_Validate.prototype.onRequested = function (args) {
this.detachEvents()
}
return OIS101_Validate
}())
Thank you Sanyukta.. this is exactly what I was trying to do. I appreciate you response.
Regards..//SD
Hi Sanyukta,
I have a similar case with you where i need to perform some validation on program OIS101 for ‘Change’ key.
I have the similar logic as your code:
OSI101.prototype.onRequesting = function (e) {
// Validation on Change option.
var self = this;
if ((e.commandType === “LSTOPT” && e.commandValue === “2”) && !this.checked) {
e.cancel = true;
this.lastCommand = e.commandValue // 2
this.validation();
}
OSI101.prototype.validation = function () {
var self= this;
self.checked = true;
// validation here then
setTimeout(() => { self.controller.PressKey(‘2’); }, 400);
}
My problem is the PressKey(‘2’) will navigate me back to OIS300 instead of navigating me to ‘Change’ panel (OIS101/E).
Can I know why it didn’t bring me to the correct panel and instead to bring me backward to OIS300?
Thanks in advance!
Hi,
Press key can be used only for Enter or F3. For changing the mode try using this.controller.ListOption(“2”).Also, make sure you select the line before executing listoption. Because there is a possibility that OIS101/B has many lines and we need to let the system know which lines need to be changed.
You will find an example of selecting the lines in H5 development guide.
Thanks,
San
Hello
I am trying to read all items in OIS101/H panel using Listcontrol but looks like I just cannot use for loop to read thru all items since lines are not selected. I am giving a button for users to click which will read each item from the list and after doing some validation will update the UOM in the subsequent text box next to it. My struggle is how to read the item from the OIS101/H panel list. Any help greatly appriciated.
Thanks
SD
Hi SD,
Have you achieved this through a button.? Can you share the entire script.
I am having the similiar requirement in OIS101/H panel.
And I am new to H5 scripting
Hello
How do I read thru listcontrol all items listed in OIS101/H panel without selecting all rows? Can we read thru 1st column all items without highlighting or selecting the rows? I want to do some validation reading all items in column 1 on button click but not able to figure out how to read all items. Anyone have tried it before.
Thanks
TN
Hi SD/TN,
I run a For loop to select the lines first (one by one) and then read it. Check out the below code if it makes sense.
var ExtendedWeight = (function () {
function ExtendedWeight(args) {
this.checked = false;
this.args = args.args;
this.controller = args.controller;
this.log = args.log;
}
ExtendedWeight.Init = function (args) {
return new ExtendedWeight(args).run();
};
ExtendedWeight.prototype.run = function () {
const list = this.controller.GetGrid();
const customColumnNum = list.getColumns().length + 1;
this.appendColumn(list, customColumnNum);
this.populateData(list, customColumnNum);
this.attachEvents(this.controller, list, customColumnNum);
};
ExtendedWeight.prototype.appendColumn = function (list, columnNum) {
const columnId = “C” + columnNum;
let columns = list.getColumns();
let newColumn = { id: columnId, field: columnId, name: “Extended weight “, width: 100 };
if (columns.length < columnNum) {
columns.push(newColumn);
}
list.setColumns(columns);
}
ExtendedWeight.prototype.populateData = function (list, columnNum) {
var _this = this;
const columnId = "C" + columnNum;
for (let i = 0; i {
//Populate additional data on scroll
if (e.commandType === “PAGE” && e.commandValue === “DOWN”) {
this.populateData(list, columnNum);
}
else {
this.detachEvents();
}
});
}
ExtendedWeight.prototype.detachEvents = function () {
this.unsubscribeReqCompleted();
}
return ExtendedWeight;
}());
Thankyou sanyukta for the example I was able to get it working. Appreciate your response.
SD
Hi SD/TN,
Yes you may read all the items from the panel, since you have the controller after the button click, you need to navigate the items like this “controller.Response.Panel.List.Rows”, there you will see the loaded data on your screen with the corresponding row id and column id, take note that there will only be 33 lines “on load” of each list, you need to scroll down/page down on the list if you wish to load the next 33 lines.
Regards,
Reggie
Thank you Reggie for the response, I tried as you suggested and was able to get it working.
SD
Hi TN,
Have you achieved this.? Can you share the script please.
I am having the similiar requirement in OIS101/H panel.
And I am new to H5 scripting
Hi Shashank Sorry for delay in responding had some issues with my email account I am able to read the row element using the for loop but i am still having issues with displaying the response from the api in the 3rd column text for each row. The data is updated in the 3rd column text but I have to switch to another tab and come back to see it in the column text fields. Staying on OIS101/H panel the data is not visible but shows up after I click on another tab. Here is the code snippet /** * MIService utility used here is still in development. * H5 Script SDK sample. */ /** * Executes M3 API calls to retrieve UOM */ var HpanelUOMAdd = (function () { function HpanelUOMAdd(scriptArgs) {
var debug = scriptArgs.debug; this.log = scriptArgs.log; var controller = scriptArgs.controller; var content = controller.GetContentElement(); var userContext = ScriptUtil.GetUserContext(); // var CCONO = userContext[“CONO”]; var CCONO = userContext.CurrentCompany; var DIVI = userContext[“DIVI”]; var DTFM = userContext[“DTFM”]; var USER = userContext[“USID”]; debugger; var cupa; //for ( var it = 0; it 0; itm++) { //for ( var itm = 0; itm 0) //_this.controller.Response.Panel.List.Rows[itm – 1].C3 = cupa;
if(OHITNO != “”) {
//if(itm != “0”) //_this.controller.Response.Panel.List.Rows[itm – 1].C3 = cupa; var autp = “1”; var dxit = “1”; var itm2 = “0”; cupa= “”;
if(OHORTP == “OMS” || OHORTP === “OMS”) OHCUNO = “000”+OHCUNO.substring(0,2); _this.log.Info(“OHCUNO: ” +OHCUNO); _this.log.Info(“OHWHLO: ” +OHWHLO); _this.log.Info(“OHITNO: ” +OHITNO); _this.log.Info(“OAORTP: ” +OHORTP);
//MMS015 var myRequest2 = new MIRequest(); myRequest2.program = “MDBREADMI”; myRequest2.transaction = “SelMITAUN00”; myRequest2.outputFields = [“AUS2,ALUN”]; myRequest2.record = { ITNO: OHITNO,AUTP : autp }; MIService.Current.executeRequest(myRequest2).then(function (response1) { for (var _k = 0, _a = response1.items; _k < _a.length; _k++) { var item2 = _a[_k]; if(item2.AUS2.trim() === "1" || item2.AUS2 == "1") { cupa = item2.ALUN; _this.log.Info("CUPA MMS015:"+cupa); _this.log.Info("ITNO MMS015:"+OHITNO); _this.controller.Response.Panel.List.Rows[itm2].C3 = cupa; _this.log.Info("ITM MMS015:"+itm2); itm2++; _this.log.Info("ITM MMS015 plus:"+itm2); } } }).catch(function (response1) { //MPACIT10 var myRequest3 = new MIRequest(); myRequest3.program = "MDBREADMI"; myRequest3.transaction = "GetMPACIT10"; myRequest3.outputFields = ["CUPA"]; myRequest3.record = { WHLO:OHWHLO,DXIT: dxit,PACT: vPACT,ITNO: OHITNO}; MIService.Current.executeRequest(myRequest3).then(function (response2) { for (var _l = 0, _a = response2.items; _l < _a.length; _l++) { var item3 = _a[_l]; cupa = item3.CUPA; _this.log.Info("CUPA WITHOUT CUST:"+cupa); //_this.controller.Response.Panel.List.Rows[itm].C3 = item3.CUPA; _this.controller.Response.Panel.List.Rows[itm2].C3 = cupa; itm2++;
}
}).catch(function (response2) { debugger; //MPACIT00 //this.controller.Response.Panel.List.Rows[itm].C3 = "EE"; var myRequest1 = new MIRequest(); myRequest1.program = "MDBREADMI"; myRequest1.transaction = "GetMPACIT10_1"; myRequest1.outputFields = ["CUPA"]; myRequest1.record = { WHLO:OHWHLO,DXIT: dxit,PACT: vPACT,ITNO: OHITNO,CUNO: OHCUNO }; MIService.Current.executeRequest(myRequest1).then(function (response) { for (var _j = 0, _a = response.items; _j < _a.length; _j++) { var item1 = _a[_j]; cupa = item1.CUPA; _this.log.Info("cupa:"+cupa); //this.controller.SetValue("OBALUN",cupa); _this.controller.Response.Panel.List.Rows[itm2].C3 = cupa; itm2++; // } }).catch(function (response) { console.error("Error in MDBREADMI GetMPACIT10_1 Api:" + response.errorMessage); _this.controller.Response.Panel.List.Rows[itm].C3 = cupa; debugger;
//Handle errors here //_this.controller.PressKey("ENTER"); });
//_this.controller.Response.Panel.List.Rows[itm].C3 = cupa; console.error("Error in MDBREADMI GetMPACIT10 Api:" + response2.errorMessage);
});
//Handle errors here // debugger; //console.error("Error in MDBREADMI SelMITAUN00 Api:" + response1.errorMessage); });
//MMS015 //_this.controller.Response.Panel.List.Rows[itm].C3 = cupa;
}
}//end of main for loop
};
return HpanelUOMAdd; }()); //# sourceMappingURL=HpanelUOMAdd.js.map
On Tue, May 26, 2020 at 3:42 AM Developing for Infor Smart Office wrote:
> Shashank Malali commented: “Hi TN, Have you achieved this.? Can you share > the script please. I am having the similiar requirement in OIS101/H panel. > And I am new to H5 scripting” >
Hi Sidh,
Thanks for your reply. I was able to move ahead. But is was just a demo script. After customer approval I will once again begin to develop the script. I have posted my script below in this blog. Its yet to be approved by customer before i go ahead and develop it.
Hi, Based on the script H5SampleIonApiService , created a h5 script in that When i click a button i am trying to call IonApiService.Current.execute() to POST data as below, but getting error message as “Message Text is missing” , also tried JSON.Stringfy() but still its not working . what am i doing wrong?.
$run.click(function () {
var request = {
url: IonApiService.Current.getBaseUrl() + “/” + _this.mingleEndpoint + “/SocialService.Svc/User/” + _this.userGUID + “/ColleagueFeeds/” + colleagueUserGUID,
method: “POST”,
data: {
“MessageText”: “thisMessage”
}
};
IonApiService.Current.execute(request).then(function (response) {
if (!response.data.ErrorList) {
}
else {
for (var _i = 0, _a = response.data.ErrorList; _i < _a.length; _i++) {
var error = _a[_i];
_this.log.Error(error.Message);
}
}
}).catch(function (response) {
_this.log.Error(response.message);
});
});
Hi , Quick update on IONApiservice after setting content-type in headers object it was successfully calling the mingle endpoint url from H5 script. Thank You.
var request = {
url: IonApiService.Current.getBaseUrl() + “/” + _this.mingleEndpoint + “/SocialService.Svc/User/” + “b8580b50-71d5-4cb8-bec8-5cc761f55f18” + “/Feeds”,
method: ‘POST’,
headers:{
“content-type”: ‘application/json’
},
data: JSON.stringify({“MessageText”: “GH5Test1”})
};
Thank you for updating here as well. I answered this in the Infor Community.
Hi,
How to disable multiselect on M3H5 list (datagrid) and set it to be single row selection? I’ve try to do the following setting in my script however it doesn’t work. When user hold CTRL + select on row or Shift + click on row, with the following setting user still able to do multiselect (multiple selected rows are highlighted).
ExampleCode.prototype.run = function () {
var _this= this;
var grid = this.controller.GetGrid();
grid.setOptions({ multiSelect: false }); // to disable multiselect
var handler = function handler(e, args) { _this.onSelectionChanged(e, args); };
grid.onSelectedRowsChanged.subscribe(handler);
this.attachEvents(this.controller);
};
What I want to achieve is :
When user hold CTRL + select on row / Shift + click on row, there is always one row is being selected (this.controller.GetGrid().getSelectionModel().getSelectedRows() only show one item in its return array) and only one row (the selected row) being highlighted.
Can anyone help on this? Thanks in advance.
Best regards,
Bas
I’ve checked and it’s not possible to change the data grid to single select. But you can prevent navigation until all validation is passed. Just be sure to unregister the script when the user is allowed to pass through to the next panel.
As part of the script you can unselect the rows with status 22, and in the dialog have the message that some of the rows are unselected, but if there are still rows that are OK in the selection they can press OK to continue.
That is actually a better approach then changing the select behavior on the list. How to add validation and add a cancel event please compare to the script code for Smart Office https://smartofficeblog.com/2012/03/30/validating-m3-panels-using-jscript-and-mi-programs-before-a-request/. There might be some H5 script examples in the questions section for H5 as well.
This question was also asked here https://community.inforxtreme.com/infor-developers/f/m3-development/14013/infor-m3h5—disable-multiselect-on-list-datagrid/39509
Regards
Karin
Hi,
Is it possible to use a script in a H5 mashup? If so, do you have any examples or any information about this somewhere?
In our case we want to connect a script to a button in the mashup.
/Johanna
I think that it’s possible but I would have to check. Have you tried it?
Hi
I have added the additional customized columns through H5 Script in OIS101/H panel SortingOrder 9. And I want to display the data in the additional columns corresponding to the item no which is first column as per the std m3 view. Trying to make it like a dashboard. And Std M3 already has some fields for that items like Qty, UOM. How can I read this fields and enter into my custom columns. For e.g There is a Lst column in standard and I want the same values to be displayed in Lst column which I created through Script and its last date uom etc. Mainly I want to do this on pressing Enter or Panel load or Refresh. Or is it necessary to have a button.?
Below is my script and looking for logic in populate data function but not able to achieve.
/**
* H5 Script SDK sample.
*/
/**
* Appends a column to the current grid
*/
var H5SampleCustomColumns = (function () {
function H5SampleCustomColumns(scriptArgs) {
this.controller = scriptArgs.controller;
console.log(“Running1…”);
}
/**
* Script initialization function.
*/
H5SampleCustomColumns.Init = function (args) {
new H5SampleCustomColumns(args).run();
};
H5SampleCustomColumns.prototype.run = function () {
var list = this.controller.GetGrid();
var customColumnNum = list.getColumns().length + 1;
this.appendColumn(list, customColumnNum, “Lst”);
this.populateData(list, customColumnNum);
customColumnNum = customColumnNum + 1;
this.appendColumn(list, customColumnNum, “Date”);
this.populateData(list, customColumnNum);
customColumnNum = customColumnNum + 1;
this.appendColumn(list, customColumnNum, “Ord No”);
this.populateData(list, customColumnNum);
customColumnNum = customColumnNum + 1;
this.appendColumn(list, customColumnNum, “Price”);
this.populateData(list, customColumnNum);
customColumnNum = customColumnNum + 1;
this.appendColumn(list, customColumnNum, “UOM”);
this.populateData(list, customColumnNum);
customColumnNum = customColumnNum + 1;
this.appendColumn(list, customColumnNum, “1st”);
this.populateData(list, customColumnNum);
customColumnNum = customColumnNum + 1;
this.appendColumn(list, customColumnNum, “Date”);
this.populateData(list, customColumnNum);
customColumnNum = customColumnNum + 1;
this.appendColumn(list, customColumnNum, “Ord No”);
this.populateData(list, customColumnNum);
customColumnNum = customColumnNum + 1;
this.appendColumn(list, customColumnNum, “Price”);
this.populateData(list, customColumnNum);
customColumnNum = customColumnNum + 1;
this.appendColumn(list, customColumnNum, “UOM”);
this.populateData(list, customColumnNum);
customColumnNum = customColumnNum + 1;
this.appendColumn(list, customColumnNum, “2nd”);
this.populateData(list, customColumnNum);
customColumnNum = customColumnNum + 1;
this.appendColumn(list, customColumnNum, “Date”);
this.populateData(list, customColumnNum);
customColumnNum = customColumnNum + 1;
this.appendColumn(list, customColumnNum, “Ord No”);
this.populateData(list, customColumnNum);
customColumnNum = customColumnNum + 1;
this.appendColumn(list, customColumnNum, “Price”);
this.populateData(list, customColumnNum);
customColumnNum = customColumnNum + 1;
this.appendColumn(list, customColumnNum, “UOM”);
this.populateData(list, customColumnNum);
customColumnNum = customColumnNum + 1;
this.appendColumn(list, customColumnNum, “3rd”);
this.populateData(list, customColumnNum);
customColumnNum = customColumnNum + 1;
this.appendColumn(list, customColumnNum, “Date”);
this.populateData(list, customColumnNum);
customColumnNum = customColumnNum + 1;
this.appendColumn(list, customColumnNum, “Ord No”);
this.populateData(list, customColumnNum);
customColumnNum = customColumnNum + 1;
this.appendColumn(list, customColumnNum, “Price”);
this.populateData(list, customColumnNum);
customColumnNum = customColumnNum + 1;
this.appendColumn(list, customColumnNum, “UOM”);
this.populateData(list, customColumnNum);
customColumnNum = customColumnNum + 1;
this.attachEvents(this.controller, list, customColumnNum);
};
H5SampleCustomColumns.prototype.appendColumn = function (list, columnNum,columnName) {
var columnId = “C” + columnNum;
var columns = list.getColumns();
var newColumn = {
id: columnId,
field: columnId,
name: columnName,
width: 100
};
if (columns.length < columnNum) {
columns.push(newColumn);
}
list.setColumns(columns);
};
H5SampleCustomColumns.prototype.populateData = function (list, columnNum) {
var columnId = "C" + columnNum;
for (var i = 0; i < list.getData().getLength(); i++) {
var newData = {};
newData[columnId] = "" //+ i;
newData["id_" + columnId] = "R" + (i + 1) + columnId;
$.extend(list.getData().getItem(i), newData);
console.log("Running…");
}
var columns = list.getColumns();
list.setColumns(columns);
};
H5SampleCustomColumns.prototype.attachEvents = function (controller, list, columnNum) {
var _this = this;
this.unsubscribeReqCompleted = controller.RequestCompleted.On(function (e) {
//Populate additional data on scroll
if (e.commandType === "PAGE" && e.commandValue === "DOWN") {
_this.populateData(list, columnNum);
}
else {
_this.detachEvents();
}
});
};
H5SampleCustomColumns.prototype.detachEvents = function () {
this.unsubscribeReqCompleted();
};
return H5SampleCustomColumns;
}());
Hi,
I have a requirement from customer to check if date is on a weekend. How do check that on H5 typescript?
Thanks.
Oh, that is a tricky one. Probably you need to check public holidays as well. If you don’t need that check if the SoHo date picker has a method for that. Best would be if there is an API for that, like an M3 API or if you can create an M3 extension.
Maybe consider using CRS900MI (M3 System Calendar Interface).
This will give you the day of week (so that you know that it is in a weekend).
But in addition, you will also know if it is a bank day (to catch moving holidays), goods receiving day, production day etc.
Try CRS900MI/LstSysCalendar with input FRDT and TODT (may be set to same date if you only need to check one date).
Hi,
I’ve follow the development guide and created a basic drillback customise script. This script has apply to MMS120/B.
Problem:
– When I press on the button, the Ming.le drillback API seem not getting invoke which I didn’t get navigate to CRS610/E, instead I’m still staying on MMS120/B.
– ** I’m able to see the log message in browser console and I’ve use program MTS043/A to test the bookmark parameters
Why the drillback API didn’t get fire (doesn’t work)?
var DrillbackSample = (function () {
function DrillbackSample(scriptArgs) {
this.controller = scriptArgs.controller;
this.args = scriptArgs.args;
}
DrillbackSample.Init = function (args) {
new DrillbackSample(args).run();
}
DrillbackSample.prototype.run = function () {
this.addButton();
}
DrillbackSample.prototype.addButton = function () {
let self = this;
let buttonElement = new ButtonElement();
buttonElement.Name = 'btnBookmark';
buttonElement.Value = "Shortcut"; // name of button
buttonElement.Position = new PositionElement();
buttonElement.Position.Top = 4;
buttonElement.Position.Left = 52;
buttonElement.Position.Width = 1;
buttonElement.Position.Height = 20;
let contentElement = this.controller.GetContentElement();
let button = contentElement.AddElement(buttonElement);
ScriptUtil.AddEventHandler(button, 'click', function (event) {
self.invokeDrillback();
});
}
DrillbackSample.prototype.invokeDrillback = function () {
const drillback = `?LogicalId=lid://infor.m3.1&AccountingEntity=900_100&ViewId=Program=CRS610;TableName=OCUSMA;Option=5;Panel=E;KeyNames=OKCONO,OKCUNO&ID1=100000`;
//Fire the drillback message using the Infor Ming.le CE JavaScript API
infor.companyon.client.sendPrepareDrillbackMessage(drillback);
console.log('click')
}
return DrillbackSample;
}());
Thank you.
Hi All,
Currently in OIS061 we have sorting based on Item number and Start Date combination (Both fields part of the sub file) in B panel subfile, based on the index used in the view defination indicators. And OIS061 has only Sorting order no views.
I have a requirement from Customer where they want Sorting based only on start date in the Subfile. Along with this I also need to add two more custom fields in subfile but all should be sorted on start date. Is this possible through H5 script or anybody worked on this kind of requirements?
The above requirement is in the multitenant cloud env
Hi, Since the item number is the primary key I don’t think so. This is not something that you should be doing in script.
This question has also been posted in the Infor community forum (https://community.infor.com/infor-m3/f/h5-scripting/14220/how-to-create-sorting-in-subfile-through-h5-script).
Hi Karin,
Thank you for the information. Yes I only asked this same question on Infor community forum.
Greetings,
A script has been installed on PPS250/E and its launching an automation to PMS020/E when ENTER is being pressed (PO line tied to MO). The problem is there may be several warning messages from the M3BE (purchase order line already in status 35, PO line tied to reference order…) before M3 validates the screen with the entered data (confirmed quantity + confirmed date)… resulting in several PMS020/E being launched by the automation. Question is : can we monitor such warning messages to launch only once the automation ? I don’t think this is doable but i ask in case. Thank you.
Hi,
I have added columns in the list view/ sub file through H5 script. One of the column fields is the Qty of each item in last six months. I want to highlight the field added with a color or entire record with a color of the particular row.column which has a sum (qty) greater than 100
Is this color highlight possible through H5 script the way we use for M3 fields through personalization ?
Hi Shashank,
Since the custom columns are not part of the list coming from BE, it is not possible to add personalizations to it.
Regards,
Reggie
Hi Reggie,
Thanks for your reply. I was looking for the possibility of applying css to the custom field added by H5 script.
I have conveyed this to customer that its not possible. Thanks again
Hi Reggie,
There is a possibility to highlight the values with a color through H5 script.
Here is the code which I got help from Community.infor.com for my question there.
1554226
Hi,
I would say thank you very much. The code you shared above worked.
I have modified your code as follows while adding my eighth column
//Create eighth column header
var columnId8 = “C” + (columnNum + 7);
this.columnAppended = true;
var columns8 = list.getColumns();
//Create a custom formatter
function MyCustomFormatter(row,cell,value)
{
console.log(row);
console.log(cell);
console.log(value);
var color = “black” ;
if (parseFloat(value)> 100){
color = “red”;}
var html = “” + value + “”;
return html;
}
var newColumn8 = {
id: columnId8,
field: columnId8,
name: “Last six months quantity”,
width: 100,
formatter: MyCustomFormatter //set the formatter to be used
};
if (columns.length < (columnNum + 7)) {
columns.push(newColumn8);
}
//add the eighth column header
list.setColumns(columns);
It highlights the value according to my condition greater than 100 and it also highlights the entire column values as below.
Hi Shashank,
I thought you will want to use the H5 personalization to color the customized columns, using that is not possible since the customized columns are not being read or is not part of the entire list coming from BE, but you may always use a custom code formatter to add color to any elements/columns you want, because you have a total control of the script.
Regards,
Reggie
Hi Reggie,
Thank you very much. I have one more small issue can you help me please?
I have added the button using one script as above in this smartofficeblog. I have also used mforms automation . Everything works fine. But the button is not visible for very first session of the day when I start.
I need to refresh the screen of OIS101/H where this script is added. And after the first refresh for all other sessions my button appears. Can you guide me please what may be the issue.
Actually I have two scripts in OIS101/H one without button and second with Button. Is this causing any issue just because I have two scripts in one program?
Hi Reggie,
Please ignore my above comment. I have changed the position of the button and its working fine.
Hi
We have requirement to develop an H5 Script for the OIS200 program. My requirement is when user enters alias number in OIS200 item number column, I need to call MMS025 API and retrieve relevant item number.
I was able to retrieve all the information and replace the relevant item number in Item number cell, but when I set the value item number cell doesn’t change till click on inside the cell. Below is my code sample.
private ValidateAndUpdateData(index: number) {
const list = this.controller.GetGrid();
let myCompany = ScriptUtil.GetUserContext(“CurrentCompany”);
let popn: string = list.getData().getItem(index).C1;
if (popn != “”) {
const program = “MMS025MI”;
const transaction = “GetItem”;
//const record = { CONO: myCompany, ALWT: “02”, POPN: popn, ALWQ: “GTIN” };
const record = { CONO: myCompany, ALWT: “02”, POPN: popn, ALWQ: “DU14” };
const outputFields = [“POPN”, “ITNO”];
MIService.Current.execute(program, transaction, record, outputFields).then(
(response: IMIResponse) => {
//Read results here
let POPN: string = response.items[0].POPN;
let ITNO: string = response.items[0].ITNO;
list.getData().getItem(index).C1 = ITNO;
I have a few questions,
1). How can I set the value to editable cells?
2). Can refresh the entire grid to overcome this issue?
3). Can anyone help us to register a cell click event?
Anyone has any idea about these questions please help us.
Thank you
Hi Nusran,
Unfortunately the editable cells of H5s Grid has limitations when it comes to adding values, and adding the values directly to the cell data will not work, however there is one workaround that you may do to actually change the values inside the cells.
First is to subscribe an on requesting listener to interrupt the post data (example inside the H5 Scripting document) before it applies, then you may add your M3 Api inside your listener function to fetch your data in MMS025MI.
Then since you have full control of the instance controller, there is an object name “editedCells” inside it, that is the exact object that has the exact Row/Column index for the current edited cells right after you press keyboard “Enter”, then you may change the value.
I hope it helps.
Regards,
Reggie
Hi Reggie,
Could you please share sample code, how can I access editedCells in instance controller.
Thank you
Regards
Priyantha
Hi,
It is like accessing the GetGrid() function in your script.
ex.
this.controller.editedCells
*since it is an object you just need to access it like this.
*you must capture it inside the OnRequesting listener, I think it is written in the H5 Scripting document and we also have it as a sample script named “H5SampleCancelRequest”
public static Init(args: IScriptArgs): void {
new H5SampleCancelRequest(args).run();
}
private run(): void {
this.unsubscribeRequesting = this.controller.Requesting.On((e) => {
this.onRequesting(e);
});
this.unsubscribeRequested = this.controller.Requested.On((e) => {
this.onRequested(e);
});
this.unsubscribeReqCompleted = this.controller.RequestCompleted.On((e) => {
this.onRequestCompleted(e);
});
}
private onRequesting(args: CancelRequestEventArgs): void {
this.log.Info(“onRequesting”);
let _this = this;
//Add the api here and capture the editedCells object here
}
Regards,
Reggie
Hi Reggie,
I checked this code in run time. I added this code to Visual studio watch, it displays all edit cells. unfortunately, when I add some code typescript, it gives below error message.
Error TS2339 (TS) Property ‘editedCells’ does not exist on type ‘IInstanceController’.
I appreciate your advice.
Hi priyanthahet,
Yes it will have an error on TS file since it is really not a part of IInstanceController, it is only a part of H5 Client and it should not have an error if you attach the JS file of the script.
Using the object name is just a workaround because of how the grid editable cells are made due to the data grids limitation.
Regards,
Reggie
Hi Nusran,
Unfortunately the editable cells of H5s Grid has limitations when it comes to adding values, and adding the values directly to the cell data will not work, however there is one workaround that you may do to actually change the values inside the cells.
First is to subscribe an on requesting listener to interrupt the post data (example inside the H5 Scripting document) before it applies, then you may add your M3 Api inside your listener function to fetch your data in MMS025MI.
Then since you have full control of the instance controller, there is an object name “editedCells” inside it, that is the exact object that has the exact Row/Column index for the current edited cells right after you press keyboard “Enter”, then you may change the value.
I hope it helps.
Regards,
Reggie
Hi Reggie,
Thank you very much for your quick response.
Appreciate, If you can share sample code for this.
Thank you
Nusran
Hi Nusran,
You may use the sample code inside H5SampleCancelRequest.ts.
So right before it sends the post data, you need to provide the exact Row and Column and the value, in this case you need to use “onRequesting”.
private run(): void {
this.unsubscribeRequesting = this.controller.Requesting.On((e) => {
this.onRequesting(e);
});
}
private onRequesting(args: CancelRequestEventArgs): void {
this.log.Info(“onRequesting”);
this.controller.editedCells = {R1C3: “TESTING”}
}
Regards,
Reggie
Hi Reggie,
Thank you very much for the quick response,
Appreciate it if can you share sample code for this
Hi,
I am using IonApiService class to call an ION Api from H5 script. But I couldn’t call an ION REST API with POST method where I need to the pass the data as a JSON object to the API.
this is the sample code I have implemented
const request: IonApiRequest =
{
url: this.IONAPI,
method: “POST”,
record:
{
logicalId : “lid://infor.m3.m3”
},
data:
{
“workflowName”: “Test”,
“instanceName”: “Test”,
“inputVariables”: [
{
“name”: “ITGR”,
“dataType”: “STRING”,
“value”: “123”
}
],
“inputStructures”: []
},
headers:
{
contentType:”application/json”
}
};
IonApiService.Current.execute(request).then((response: IonApiResponse) =>
{
console.log(“myscript: success callback”)},
function(err){
console.log(“myscript: there was an http error”);
})
But when executing, we are getting the error as “Failed to load resource. the server responds with a status 415”. So when when we checked the network option in the developers tool, we found that the default header content-type ( which is application /x-www-form-urlencoded) is not getting overridden by the header content-type (application/json) that I am passing to the API.
Can you please advise on this please?
Thank you
Regards
Mayuran
Hi mayuran05,
Could you please try this header.
headers:{
“content-type”: ‘application/json’
},
Regards,
Reggie
Hi,
I want to call the UPS address validation api from an H5 script and display the response that would be multiple lines in a popup box for the user to select the correct address from, Can anyone help me with the sample code,if its possible to do via H5 Scripting.
Thanks.
Hi,
I want to call the UPS address validation api from an H5 script and display the response that would be multiple lines in a popup box for the user to select the correct address from, Can anyone help me with the sample code,if its possible to do via H5 Scripting.
Thanks.
Hi,
Assuming UPS allow cors request to their API from a browser and the endpoint is public and without having to pass credentials it’s possible. I don’t have an example but perhaps readers of this blog has.
Hi Karin/Reggie,
In multi-tenant for H5 Scripts , do we need to Include CSRF token when we make an M3 api call using MIService.Current.executeRequest()? If yes, could you please advise how we need to implement it? .
Thank you,
Regards,
Avven.
Hi Avven,
MIService handles the csrf token, the execute request scripting usage does not need any changes.
Regards,
Reggie
Hi Reggie, Thank you so much for the clarification.
Thank You,
Regards,
Avven.
Hi, We have a requirement that in OIS101/H panel to populate the ALUN editable sub-file grid field, i am able to populate the ALUN editable field with the value properly but when i click “Enter” on the screen then its not taking the value that are populated on the ALUN field unless we get the focus on it for every line. I see multiple post here on regarding OIS101/H , has anyone faced similar scenario? is there any way to update the sub file grid to point the latest value after adding the value to the editable cell for all the lines?.i use the following standard approach to populate the value,
var newData = {};
newData[ALUNId] = ALUN;
newData[“id_” + columnALUNId] = “R” + (i + 1) + ALUNId;
$.extend(list.getData().getItem(i), newData);
var columns = list.getColumns();
list.setColumns(columns);
Thank you,
Regards,
Avven
Can someone help me please? Is there anyone who developed H5 script creating new window including window properties and structure like grid, list view, columns and rows like what we used to do via Jscript
Please provide me with a sample for this code in order to get the idea of the syntax
Hi, I am able to set up a Visual Studio (2017) environment which allows to develop, execute and debug TypeScript, as it is briefly described in the “Infor M3 H5 Development Guide”. I can also develop in Visual Studio CODE, but cannot debug, and their is no explicit hint in the manual; debugging is no problem when I develop H5 Mashups with Angular and Odin in VS CODE, so I think there is only a small piece of connection missing. Can you help?
Hi Heiko,
First you have to download the Debugger for Chrome extension inside VS Code, then create a “launch.json” file to configure the chrome debugger and save it inside the .vscode folder (in my case .vscode folder is inside my Samples folder).
*Take note that this will only work when using the stand-alone version of H5 (Cloud or On-prem)
launch.json file configuration example (attach)
*if your using attach, you need to run first the exact URL of the stand alone version plus the script you want to use, then click the debug button on the side panel and run the “Attach Chrome”.
It should say that the connection is successful on the bottom part of VS Code
{
“version”: “0.2.0”,
“configurations”: [
{
“type”: “chrome”,
“request”: “attach”,
“name”: “Attach Chrome”,
“url”: “https://m3devapp.m3cedev.awsdev.infor.com/mne?localScript=http://localhost:8085/H5SampleCancelRequest.js”,
“port”: 9222,
“sourceMaps”: true,
“webRoot”: “${workspaceFolder}”
}
]
}
Regards,
Reggie
Hi,
I am looking for a way to capture an eventual warning message from BE that is displayed in the status bar and to have it displayed as a dialog window instead, in other words to override the user setting for this via a script.
Is this possible to do?
Thanks / Marcus
Hi Marcus,
I don’t think we currently have the support for this, when the default setting is set to display in status bar and override it using scripts to display in a dialog.
Regards,
Reggie
Hi Reggie,
I thought so but it was worth a shot, thanks for the answer though.
/Marcus
Hi,
where can I found any documentation about the Infor components, i.e. inforMessageDialog?
best regards
Heiko
Hi, The only resources I know of is: https://design.infor.com/code/ids-enterprise/latest/message. (Note that this is latest version, start going back for previous version).
Then there is the git, https://github.com/infor-design/enterprise. But I don’t know if the version you are looking for is there.
Hi,
I tried to execute a drillback, but nothing happens. I try to launch panel PMS080/E with the following (decoded) drillback:
lid://infor.m3.1&AccountingEntity=100_100&ViewId=Program=PMS080;TableName=MWOMAT;Option=2;Panel=E;&Keys=VMMFNO,ID1,VMPRNO,ID2,VMMSEQ,ID3,VMCONO,ID4,VMFACI,ID5&ID1=4201901980&ID2=86701-04&ID3=81&ID4=100&ID5=100
The full encoded drillback, which is executed by the function as argument, is::
?LogicalId=lid://infor.m3.1&AccountingEntity=100_100&ViewId=Program=PMS080;TableName=MWOMAT;Option=2;Panel=E;Keys=VMMFNO%2CID1%2CVMPRNO%2CID2%2CVMMSEQ%2CID3%2CVMCONO%2CID4%2CVMFACI%2CID5&ID1=4201901980&ID2=86701-04&ID3=81&ID4=100&ID5=100
Problem: The function does nothing. I can’t see anything in the Chrome developer console log.
Can you help?
Hi HeikoM,
Are you using a script to perform a drillback to H5? Performing a drillback to H5 need to have certain mandatory parameters to work.
example:
“bookmark?program=MMS001&tablename=MITMAS&keys=MMCONO,880,MMITNO,7200000002 &option=2&panel=E&name=MMS001/E&LogicalId=lid://infor.m3.1”
If it is a drillback issue from a bookmark, I think it is better to file a ticket about this so that it could be further investigated by the developers.
Regards,
Reggie
Hi Reggie, regarding the drillback problem – I got confused by the Script Development Guide which states that “drillback” is the way to execute a bookmark; but from this blog thread, I took the information that simply ScriptUtil.Launch(…) can be used. Going that way it is an easy task. Thank you!
Best Regards
Heiko
Hi,
I have a requirement as below:
When we press F4 on a textbox of M3 program, it prompts the browse window which displays list of records. I need to iterate through each of those records and highlight the record which met certain condition.
I wanted to know how can we get the controller of Browse window on click of F4 so that the record from prompted window can be read. Can someone guide me how this can be accomplished using H5 scripting.
Hi, comments have to be approved before they are visible. I’ve forwarded the question to H5 team.
Hi Bhumika,
You may use the H5 scripting sample in H5SampleCancelRequest, I think you could use the on requested listener or on request complete listener.
On script load, it will automatically attach the listener to the current controller of the program, and on browse “F4” you will receive the dialog controller and can now manipulate the data on the current dialog controller and set the rows to be selected/highlighted.
Regards,
Reggie
Example:
SampleTestScript.prototype.run = function () {
var _this = this;
this.unsubscribeReqCompleted = this.controller.RequestCompleted.On(function (e) {
_this.onRequestCompleted(e);
});
};
SampleTestScript.prototype.onRequestCompleted = function (args) {
var _this = this;
this.log.Info(“onRequestCompleted”);
var cont = args.controller; //this is the controller of the dialog
if (cont.IsDialog() && cont.CMDVAL == “F4” || (cont.CMDVAL == “DOWN” || cont.CMDVAL == “UP” && cont.CMDTP == “PAGE”)) {
_this.IterationAndHighlighting(cont); //pass the dialog controller
} else if (cont.CMDVAL == “F12”) { //on close dialog
this.unsubscribeReqCompleted(); //unsubscribe requested complete
}
};
SampleTestScript.prototype.IterationAndHighlighting = function (inst) {
//Do your iteration here
//get active grid of controller and set selected rows to highlight the rows depending on your condition
inst.ActiveGrid.setSelectedRows([1]);
};
Hi Reggie
Thanks a lot for your response. I will try it out for sure. However, i already able to implement it by reading the F4 window based on div id and then looped through all the records one by one.
Regards,
Bhumika
Hi,
Can I know, how to import 3rd party library to h5 script?(Need to add an excel reader).
Hi,
3:rd party scripts should not be loaded in a H5 script. It may compromise the application.
How to add cdn and use it in h5script, any one can describe it step by step
Hi,
This is the same question as before, you should not be loading any other scripts. It can break the application.
This is general web development. https://aaronsmith.online/easily-load-an-external-script-using-javascript/
Hi,
I have created my own custom dialog to add radio button in it as it was not possible to include radio button in ConfirmDialog.
Can someone assist me on how can I get the user selected radio button value from custom dialog back to the Infor M3 program panel where this custom dialog has been added.
Regards,
Sharad
Hi, have you tried and looked at the corresponding documentation for SoHo controls? http://design.infor.com
Hi Karin,
Thanks for your response. I have not used it ever. There are lot of things on that page you suggested, not sure what should be used exactly.
Basically, i have added my own custom dialog in H5 scripting to show the radio button which is getting populated without any issue. I am just wandering how can I fetch the radio button value which user will select/check and bring it to display on Infor M3 program panel.
Regards,
Sharad
Hi Sharad,
I assume you have a button that confirms your choice, so before initializing your custom dialog, you should attach the controller in your dialog element as data (example dialogDiv.data(“cont”, this.controller) ), so whenever you click the button, the controller data is passed down in the event data on click of the button and you may use it to navigate the element in the current panel you wish to write the value.
Regards,
Reggie
Hi Reggie,
I am wandering how can I implement the idea you suggested in below piece of code which is used to to implement custom dialog box. This code is getting executed on ENTER button on M3 program panel:
$(“body”).append(” +
‘Converted Line Qty ‘+decimal.toFixed(2)+”+baseUnit+’
Round Down ‘+Math.floor(decimal)+”+baseUnit+’=’+down1.toFixed(2)+”+altunit+’
Round Up ‘+Math.ceil(decimal)+”+baseUnit+’=’+up1.toFixed(2)+”+altunit+”);
//Invoke the dialog on it
$(‘#dialog1’).inforMessageDialog({
title: “M3”,
dialogType: “General”,
close: function (event, ui) {
$(this).remove();
},
buttons: [{
text: “Ok”,
click: function () {
// Do something…
var ele = document.getElementsByName(‘r1’);
//var SelectedValue;
for(i = 0; i {
$(“#dialog1”).inforDialog(“close”);
}, isDefault: true
}]
});
console.log(“Final selected value out of custom dialog: “+SelectedValue); //failed to work
I have marked “failed to work ” things in above code. I am able to print radioBtn SelectedValue in the Console.Log but unable to assign it to the WBORQA field which is available on M3 program panel.
Also i am not able to print that SelectedValue out of the custom dialog in console.log or unable to assign it to any other field available on M3 program panel.
Hi Reggie,
Sorry, my earlier comment cut some content hence adding it here again,
I am wandering how can I implement the idea you suggested in below piece of code which is used to to implement custom dialog box. This code is getting executed on ENTER button on M3 program panel:
$(“body”).append(‘
‘ +
‘Converted Line Qty
‘+decimal.toFixed(2)+”+baseUnit+’
Round Down ‘+Math.floor(decimal)+’
‘+baseUnit+’=’+down1.toFixed(2)+’
‘+altunit+’
Round Up ‘+Math.ceil(decimal)+”+baseUnit+’=
‘+up1.toFixed(2)+”+altunit+”);
//Invoke the dialog on it
$(‘#dialog1’).inforMessageDialog({
title: “M3”,
dialogType: “General”,
close: function (event, ui) {
$(this).remove();
},
buttons: [{
text: “Ok”,
click: function () {
// Do something…
var ele = document.getElementsByName(‘r1’);
//var SelectedValue;
for(i = 0; i {
$(“#dialog1”).inforDialog(“close”);
}, isDefault: true
}]
});
console.log(“Final selected value out of custom dialog: “+SelectedValue); //failed to work
I have marked “failed to work ” things in above code. I am able to print radioBtn SelectedValue in the Console.Log but unable to assign it to the WBORQA field which is available on M3 program panel.
Also i am not able to print that SelectedValue out of the custom dialog in console.log or unable to assign it to any other field available on M3 program panel.
Regards,
Sharad
Hi Sharad,
Before invoking the dialog, you must set the data to the element.
$(“#dialog1”).data(“cont”. this.controller);
then initialize …. $(“#dialog1”).inforMessageDialog..
After setting the data, when clicking Ok button set the function to:
buttons: [{
text: “Ok”,
click: function() {
//here you now have a control to the instance controller
var dialogData = $(this).data();
//then check/get the value of the radio button
//and since you already have control to the instance controller, you may navigate through the host which is in dialogData.cont.ParentWindow, and set the value
//dialogData.cont.ParentWindow.find(“#WBORQA”).val(“Insert value from radio button here”)
$(this).inforDialog(“close”);
},
isDefault: true
}
]
});
Regards,
Reggie
Hi Sharad,
Based on the solution you provided, my script worked as expected.
Thanks a lot:)
Regards,
Sharad
Hi, in a Web Mashup (developed with the SmartOffice Mashup Designer), is there an equivalent for the event syntax “Target=”{mashup:SetProperty ElementName=xx, Path=yyy}”> ? On this page: https://wiki.lawson.com/pages/viewpage.action?pageId=223019704
I find that markup “SetProperty” is enabled, but I don’t find a way to do this in H5 without writing JavaScript code.
Hi HeikoM,
Currently Target is not implemented in H5 web mashups, but my colleague said that we could make a workaround on this just by editing the XAML form of the mashup. I think we need the business process/requirement to investigate this further and in order to do that, this needs to be filed as a ticket so we could help you more in fixing the forms for H5 mashups.
Regards,
Reggie
Hi Reggie,
thank you; this issue was basically raised by a customer, who wants to create an application which he can use to confirm stock movements. His Smart Office version works perfect, it performs an “Update” API call in M3 and displays a confirmation message to the user if the transaction was executed (or an error message). It was no option for him to create a M3 H5 SDK app, which requires a totally different skillset. If there is no other option to achieve this goal in an Enterprise Mashup, I can ask the customer to create the incident.
Best regards
Heiko
Hi,
Can someone assist me on below.
I was thinking to use MForms automation to copy value from a different panel to the current one.
Here both panels are of same program. Is it really possible with Mforms automation?
Below is the syntax to call different program but how can we call specific panel here?
var auto = new MFormsAutomation();
auto.addStep(ActionType.Run, “OIS101”);
Regards,
Bhumika
Hi,
You should not use automation for this. With automation you would have to edit the panel sequence and then add returns to pass through. You should use a stateless bookmark to load the panel data for a specific panel. So start searching for how to run a bookmark.
Hi Karin,
Thanks for your response.
I will try it out.
Regards,
Bhumika
Hi,
I am relatively new to scripting and in the learning phase. My requirement is to call an API after the User clicks ‘Next’ button on panel. Among below two options, which would be a better approach to do so. Also appreciate if you could please share some code for it.
1. Capture the onclick of the Next button using it’s div id or class and call the MI in that click event.
2. To use the Requested, requesting methods to get access of Next button and API call
Awaiting your response,
Thanks,
Priyanka
Option 2. There are examples on the site, search for request for example. Perhaps Regie has some samples. Is it a fire and forget type of call? To add stuff on the button does not work if they just press enter so avoid that.
Thank you so Karin for your prompt response. I understand your point, will keep this mind. Will use the second approach.
Hi Priyanka,
Yes, it is better to use option 2, you may use on requesting, on requested or on request completed methods written in the document.
Regards,
Reggie
Example from the document.
H5SampleCancelRequest.prototype.run = function () {
var _this_1 = this;
this.unsubscribeRequesting = this.controller.Requesting.On(function (e) {
_this_1.onRequesting(e);
});
this.unsubscribeRequested = this.controller.Requested.On(function (e) {
_this_1.onRequested(e);
});
this.unsubscribeReqCompleted = this.controller.RequestCompleted.On(function (e) {
_this_1.onRequestCompleted(e);
});
};
H5SampleCancelRequest.prototype.onRequesting = function (args) {
this.log.Info(“onRequesting”);
var _this = this;
if (args.commandType === “KEY” && args.commandValue === “ENTER”) {
console.log(“CALL API here”)
}
};
H5SampleCancelRequest.prototype.onRequested = function (args) {
this.log.Info(“onRequested”);
};
H5SampleCancelRequest.prototype.onRequestCompleted = function (args) {
this.log.Info(“onRequestCompleted”);
this.unsubscribeRequested();
this.unsubscribeRequesting();
this.unsubscribeReqCompleted();
};
Thank you so much for this Reggie. Appreciate it. Will try this out. 🙂
Regards,
Priyanka
Hi,
Using H5 scripting, I have created a custom textbox named “CONum” in a B panel.I am trying to fetch value of same the textbox inside onRequestCompleted method but it is failed. I have tried multiple ways like using ScriptUtil, this.controller etc but none of them worked.
Can anyone suggest me in finding what went wrong in the code written below:
this.controller.RequestCompleted.On(function (e) { this.onRequestCompleted(e); });
onRequestCompleted = function (e){
if (e.commandType === “KEY” && e.commandValue === “ENTER”) {
console.log(“INSIDE ENTER”);
var inputORNO=ScriptUtil.GetFieldValue(“CONum”, this.controller);
var inORNO = this.controller.GetValue(“CONum”);
}
}
Hi, I have a requirement that to create a new related option under Related menu or new option under Action menu using H5 Script. Is it possible to create using H5 Script or is there any alternative solution?
Thanks,
Avven.
Hi Avven,
We haven’t tried doing that on our side since those menus are created based on what is received from the business engine side and H5’s core functionalities.
We have this shortcut space where you can add a functionality for related option, link for any URL, links for document archive and sorting order, I don’t know if it will be sufficient for your requirement.
If the shortcuts won’t help, you may create your custom set of dropdown list.
Regards,
Reggie
Hi Reggie,
Thank you so much for replying. I think shortcut will be helpful approach for my requirement, I will try it out.
Regards,
Avven
Hi!
I looking for a solution to create a custom browse window (F4 prompt) where I will have a list of values based on an API call. In the browse window it should be possible to search and select a record and populate the field in the panel with the selected record from the list.
I know it was possible in Smart Office, but is this possible to do via typescript in H5? If it is, do you have any example code of this or could give me a hint of what element to use?
Thanks in advance
Johanna
Hi,
Can anybody tell me how can I do role based personalizations in M3 on -prem both in smart office and H5.
In smart office if I open personalizations manager i see four sequences Global, Role, User and Program. same in H5.
I want to add the roles under “Role” tab but I can’t see any option (button or tab) to add new role.
Do I need any access?
My H5 scripts with arguments same as smart office used as shortcuts have wiped out the arguments of smart office scripts (Used as shortcut) when I deployed the Shortcuts with the H5 script along with its personalization files.
I did this for Global role which caused the issue.
Our Customer is migrating on cloud. So they are currently in on-prem they want to give H5 to users for hands on but at the same time they want to keep smart office also active for the users
Hi,
Can anybody tell me if we can use Session.Cache(key,value) across multiple programs in the same session?
In continuation to above question, my concern is that can we retrieve values stored in the first program (where we enter the values) on the last program in the flow using Session.Cache.
Thanks in advance!
Hi Priyanka,
You mean the Session Storage? yes you may use it to share across the current session just create a unique key for it.
Regards
Hi,
The new UI in Cloud that was available from January is according to KB 2164523 using the latest Infor Design System components.
I have tested some scripts that worked in the old H5 UI but in the new UI they are no longer working as expected.
How do I know how to rewrite/adjust these script to get them to work? Do you have any documentation?
Thanks in advance
Johanna
Hi Johanna,
You can check out the Scripting Guide and samples in this link: https://support.infor.com/espublic/EN/AnswerLinkDotNet/SoHo/Solutions/SoHoViewSolution.aspx?SolutionID=1909067&FromWP=1&kb_is_archived=0&kb_accessed_from=KBFavorites
The attachment H5ScriptSDK_10.4.1_20201210.zip contains the documentation and scripting samples supporting the new H5 UI.
Hope it helps.
Regards,
Sheila
Hi,
I have to implement some validation on focusin and focusout events for Grid cell’s editable input (Ex: “R1C6”) in H5 Script. I Need to know how could achieve this.
Hi,
I have to implement some validation on focusin and focusout events for Grid cell’s editable input (Ex: “R1C6”) in H5 Script. I Need to know how could achieve this.
Hi ,
i have to implement checkbox in h5 scripting.
I have used above Matt code of checbox but its not working.
I My function is not callling.
var $rbtnGroup = $(“” +
“Option 1” +
“Option 2” +
“”);
//$rbtnGroup.find(“inforCheckbox”).inforCheckbox();
var contentElement = this.controller.GetContentElement();
contentElement.Add($rbtnGroup);
function selectOnlyThis(id) {
for (var i = 1;i <= 4; i++)
{
document.getElementById(i).checked = false;
}
document.getElementById(id).checked = true;
}
}
ERROR—VM12644:1 Uncaught ReferenceError: selectOnlyThis is not defined
at HTMLInputElement.onclick (VM12638:1)
Thanks,
Hi,
I think a lot of your code is missing because it’s not formatted in a code block for WordPress. My guess is that you need to create the radio button group as a JQuery element and then assign the function to the click method. You can search how to do that online, it’s not specific to H5.
Hi,
I have developed a H5 script on one of the Infor M3 program to add a Textbox and a button to perform action on the value entered in the same textbox.
In the same program i have enabled an enterprise search. On running the enterprise search, my textbox and button added using H5 scripting gets disabled(Textbox becomes not editable).
Can someone assist me on how can we allow script to run without having an any impact of an enterprise search.
Regards,
Sharad
Hi Sharad,
Would you mind sharing the code, this is the first I have heard this kind of issue, I would like to test it on my end.
Thanks,
Reggie
Hi Reggie,
Thanks a lot for your quick response.
Just to give you quick idea, my script is not doing anything complex. Its simply used to add new textbox and a button. It is working as expected.
Only the worry started when we activated Infor enterprise search on the same panel. On executing enterprise search, my textbox and button becomes un-editable(Meaning i can edit textbox and can not click on button). Then, to make to make them editable, i need to refresh panel again which reloads script.
Basically what I want to understand is that how can we make H5 script work even after the enterprise search without refreshing the panel.
Sorry but i don’t know how to paste screenshots here to show . Can I get your mail ID, i can share details there.
Regards,
Sharad
Hi Sharad,
You may copy the code code snippet and paste it here, I’ll just create a copy of that on my side.
Regards,
Reggie
Hi,
I would like to set an editable cell to be NOT editable. May someone assist me to achieve this?
The grid option “editable” where will disabled the whole grid cell which doesn’t suit to me case.
Thanks in advance!
Best regards,
YS
Hi YS,
You may remove the class “editable-cell” for a specific cell.
Regards,
Reggie
Hi,
I have created a custom dialog box in one of my script, Dialog is getting prompted as expected.
After returning from dialog box, I wanted to execute the statement this.controller.PressKey(“ENTER”);
as shown in the script code given below but this statement is not getting executed.
Instead, getting an error “Uncaught TypeError: Cannot read property ‘PressKey’ of undefined”.
Can someone assist me to make this statement work. Below is the code:
$("body").append('' +
'Converted Line Qty '+Qty+''+bas_Unit+'
Down Qty '+TotalVal+''+bas_Unit+'='+down1+''+unit+'
Up Qty '+TotalVal+''+bas_Unit+'='+up1+''+unit+'');
$("#dialog1").data("cont",this.controller);
//Invoke the dialog on it
$('#dialog1').inforMessageDialog({
title: "M3",
dialogType: "General",
close: function (event, ui) {
$(this).remove();
},
buttons: [{
text: "Ok",
click: function () {
// Do something...
debugger;
var dialogData = $(this).data();
var ele = document.getElementsByName('r1');
for(i = 0;i {
//this.openDialog2();
$("#dialog1").inforDialog("close");
}, isDefault: true
}]
});
Quick assistance would be really appreciated.
Regards,
Bhumika
this.controller is not in the scope when you try to call it so it’s undefined.
$(“body”) seems strange to me as well.
Declare a varaible for the controller and use that instead of “this” is a standard solution for when this is something else than what you expect.
So as you add the dialog in the script that has the controller just add var m3Controller and make sure that you use that variable in the callback handler, it should be scoped on then. The code that you have is not enough to actually see what you are trying to do since it does not have the this.controller. mentioned anywhere.
Hi Karin,
I am trying to add full code but it is getting cut automatically, not sure why is that. Anyways, again I am pasting the full code again here, hopefully that would work.
$(“body”).append(” +
‘Converted Line Qty ‘+Qty+”+bas_Unit+’
Down Qty ‘+TotalVal+”+bas_Unit+’=’+down1+”+unit+’
Up Qty ‘+TotalVal+”+bas_Unit+’=’+up1+”+unit+”);
$(“#dialog1”).data(“cont”,this.controller);
//Invoke the dialog on it
$(‘#dialog1’).inforMessageDialog({
title: “M3”,
dialogType: “General”,
close: function (event, ui) {
$(this).remove();
},
buttons: [{
text: “Ok”,
click: function () {
// Do something…
debugger;
var dialogData = $(this).data();
var ele = document.getElementsByName(‘r1’);
for(i = 0;i {
//this.openDialog2();
$(“#dialog1”).inforDialog(“close”);
}, isDefault: true
}]
});
Hi Karin,
Thanks for your quick response.
Again the code did not get added properly on the portal, so let me add here only the required things, I have added this.controller.PressKey(“ENTER”) right after the for loop.
This for loop is inside the custom dialog box.
buttons: [{
text: “Ok”,
click: function () {
// Do something…
debugger;
var dialogData = $(this).data();
var ele = document.getElementsByName(‘r1’);
for(i = 0;i {
//this.openDialog2();
$(“#dialog1”).inforDialog(“close”);
}, isDefault: true
}]
});
Hi Karin,
Below is piece of code where has been added. This statement is added inside the custom dialog box.
ScriptUtil.SetFieldValue(“WBORQA”,SelectedValue);
$(this).inforDialog(“close”);
this.controller.PressKey(“ENTER”);
return;
}
}, {
text: “Cancel”,
click: () => {
//this.openDialog2();
$(“#dialog1”).inforDialog(“close”);
}, isDefault: true
}]
});
Hi,
It is feasible to create a shortcut in Toolbox area for related options. But,
can someone confirm if it is possible to create a shortcut in Toolbox area for Option like ‘Display(CTRL+5)’ which is not a related option.
If possible then how it can be done.
Regards,
Sharad
Hi,
No that is not supported. Create an enhancement request
Hi,
No that is not supported. Please create an enhancement request for the development team to consider.
Hi Karin,
Thanks a lot for your response.
Regards,
Sharad
Hi,
I am updating a table from API call inside OnRequesting (Enter) method. But once the user press enter, there can be validation from M3 and it can throw warning message. Since the user have pressed Enter, my script is getting executed regardless of the warning msg thrown by M3. I want to stop executing the OnRquesting method in my script, if there is a warning message.
Regards
Mayuran
Hi,
I think you can use the OnRequested handler, since you need the validation first from H5, and if it goes well without the warning, push through with your API call.
Regards,
Reggie
Hi,
I’m having the same problem as well. I have an input box in panel e then I will validate in an API. When there is an error in the API a dialog box will be displayed, which is ok. But after pressing ok on the dialog box(without changing the value on the input field) then press enter again script was not able to catch the error.
How can OnRequested be use if there is a dialog box?
Thanks.
Can we have an autimatic migration tool? JScript from SO 2 H5 javascript…
Or perhaps an advisor or any sort of help with it.
Thank
Cheers
//Asaf
Hi,
No, as you can imagine a migration tool from one language to another would require too much investment and would not be realistic. It’s not just a matter of one language vs another – it’s the security model that is very different in a browser as well. You might not even be allowed to call endpoints that you can call in .Net.
I built and imported the js file with the administration tool as described but can’t the find my script when I’m trying to add a shortcut to it (on any program) – what Am I doing wrong
Hi Asaf,
Please try logging off first and then log on again, the script is being populated on log on.
Regards,
Reggie
Hi,
I am trying to call Infor M3 IPS service from H5 scripting.
Can someone assist me in knowing, how to use ION API service account in H5 scripting to call the .
Here, ideally I wanted to execute XML SOAP request through H5 scripting.
Endpoint for IPS service is https://mingle-ionapi.inforcloudsuite.com/Client_TST/M3/ips/service
Your suggestion on using ‘ION API service account- oauth2 token in H5 scripting’ would be really appreciated.
Thanks in advance!
Regards,
Bhumika
Hi,
I am trying to call Infor M3 IPS service from H5 scripting.
Can someone assist me in knowing, how to use ION API service account in H5 scripting to call the . Here, ideally I wanted to execute XML SOAP request through H5 scripting.
Endpoint for IPS service is https://mingle-ionapi.inforcloudsuite.com/Client_TST/M3/ips/service
Your suggestion on using ‘ION API service account- oauth2 token in H5 scripting’ would be really appreciated.
Thanks in advance!
Hi,
This is possible in M3 CE. There is a way to call ION API. Please check the Script development guide.
Hi,
I have added one of the script on OIS101/B panel, purpose of the script is to to hide an already existing standard button. The code to hide a button has been written in run method of the script.
When I open OIS101 program once, it hides the button as expected. At the same time if I open another instance again then it fails to hide the button.
Can I know what could be the reason for such behavior.
Can’t we open 2 instances of the same program/panel at a time?
Regards,
Sharad
Hi,
This should be possible without any issues as long as the scrip is deployed.
You need to investigate the code and debug or add logging to see what happens the second time.
Hi Karin,
Thanks for your immediate response.
Below is the piece of code I do have in my H5 script,
OIS101_B_OrderLine.prototype.run = function () {
this.log.Info(“in run…..”);
var _this = this;
$(‘#WAD74C0’).hide();
}
I am trying to hide a standard button here, which is working fine when I run first instance of OIS101/B, while keeping this instance open if I open another instance of OIS101/B panel, control goes to the piece of code written above still it fails to hide the button.
Not sure why it fails to hide button even if the script executes the code.
Could you please suggest.
Regards,
Sharad
Hi,
Im trying to validate 3 custom fields in h5. I am using a script and validating it against MNS150MI. When field 1 is correct and field is invalid, it will validate the invalid field but when you press enter again it will eventually accept invalid value. How can can I aolve this?
Thanks.
.
Hi JC,
In this case on requesting listener is used to capture the “Enter” key and validate before proceeding, but since you were validating it using an MI call, the codes work asynchronously and if the custom field MI call does accept the invalid value (meaning no parsing errors), it will still be saved because custom field has a different process.
If it doesn’t hurt your process flow, I suggest for a work-around, attach your script to the shortcuts panel, then on click of the shortcut you will first validate the fields and after validating, the script will manually trigger a press key event for enter.
Regards,
Reggie