Microsoft Dynamics CRM run script (or something similar) in background - javascript

I wrote a script that adds the values of field A and field B. It then writes the result in field C.
My problem now is that, as I'm using a script, it only runs if I the form is open. However, I need to run it whenever field A or field B changes, regardless whether the form is open or not. For example, if a workflow changes the value of field A in the background, I need the script to calculate the new value of field C in the background as well.
I know that scripts only run on forms. That's why I'm looking for an alternative for scripts. I am aware that I could normally solve this by using a workflow, but I can't access field A through the workflow (it's a calculated field).
Are there any other possibilities?

I find that for custom calculations the following approach is effective and doesn't require much effort to implement and mantain:
Create an ACTION (let's call it new_action) without any steps
Create a PLUGIN which does the math you want, register it to the new_action message
Identify all the Simple fields involved
Create a workflow for each entity where you found the fields, set it to run on Update of the Simple fields you identified in that entity
The workflows should all be the same and the only step would be EXECUTE ACTION -> new_action
The end result is this behavior:
Simple field involved in your math changes -> Workflow starts -> Action starts -> Plugin does the math
NOTE: I usually make the action Unbound and "hand-craft" the data received by both the action and the plugin, but I glossed over this aspect because the approach itself stays the same.

Use CRM plugin. It works on server side so it will run whenever fields values will change (user interface, workflow, system process, CRM API call, etc.).
Detailed information: https://msdn.microsoft.com/en-us/library/gg328263.aspx

1.Create an update message plugin with filtering attribute as A and B,
This will fire only when your form is updated and also only when attribute A and B has changed on that form.
2.write your logic in your plugin
3. choose async and sync depending on how frequent the changes are on A and B, ideally, I will use sync so that my value of C gets updated and be in sync all the time w.r.t A and B.

Related

How to preserve userscript modifications in Chrome after an asynchronous content update on an .aspx webpage

I'm trying to automate the workflow of a webpage for my company's inventory system. The page is generated by the server-side logic of an ASP.Net page, which I don't have access to. The page has several fields on it to allow you to enter a new container barcode, the item that should go in the container, etc. Each of these fields has an onchange event listener hooked up to it which calls the page's __doPostBack() function to verify the entered data. If the data is verified, the page code is re-served with the data entered so far, and focus is set to the next field on the form.
I want to automate this page with a userscript in Chrome. I started by using ViolentMonkey to inject a custom script, but I could only get the script to trigger on the initial load, not after each data entry. After this, I tried using Chrome Local Overrides to change __doPostBack() to try to capture the data I need to automate the page. That also only works once; after a field is filled and loses focus and new HTML is served, it overwrites Chrome's local copy.
I think that my problems are being caused by an asynchronous refresh of the entire page contents, which wipes out the injected userscript and Chrome's Local Override without triggering the normal page refresh listeners in Chrome Overrides or ViolentMonkey to re-inject the modified code. Does anyone have any thoughts on how I could modify the JavaScript in such a way that it would persist after the page content is replaced with new HTML?
P.S. I don't think the code itself is relevant to this particular problem, but if anyone thinks it would be helpful to share a limited section of the client-side code, let me know.
Edit 1: Here's a more in-depth view of what I'm trying to accomplish, and the progress I've made so far. For reference, the form looks like this:
My Original Plan
The user loads the page. ViolentMonkey injects a userscript which issues a series of prompts, collecting data on the range of new barcodes that the user would like entered into the system. (Specifically, the barcode prefix, the starting barcode number, and the ending barcode number.) This values are stored in localStorage.
After this data has been collected and validated by the user, the page loads normally. For reference, the form looks something like this:
The user fills out the fields as normal. After each field is filled out (with the exception of the Container Description field), the page pushes focus to the next field. (For example: <script language="javascript"> try { document.getElementById('txtContDesc').focus() } catch (e) { } </script>. The id of the field to focus is dynamically changed via the server logic.)
I need to collect the User Badge, Container Type, and Destination Barcode values so that I can refill them later when I automate the form. My original plan was to add a onfocus event listener to the Container Description field, since focus will be shifted to it once the Destination Barcode field has been verified. I will know at this point that the user has successfully entered a valid entry for each of the fields above the Container Description field, and I would then be able to collect these values and store them in localStorage.
Once I have all the data needed for the form, I would pilot the form using the userscript in ViolentMonkey and the data stored in localStorage, to persist data across page refreshes.
Other Alternatives:
The eventListener idea on an element doesn't work, because ASP.NET updates the page with fresh code every time a field is verified, wiping out the listener. It also doesn't trigger a refresh, so ViolentMonkey doesn't rerun my userscript.
My other thought was to modify doPostBack(). The doPostBack() function looks like this (as far as I can tell):
<script type="text/javascript">
var theForm = document.forms['formNewContainer'];
if (!theForm) {
theForm = document.formNewContainer;
}
function __doPostBack(eventTarget, eventArgument) {
console.log("Form submitted");
}
</script>
It is called on verified fields with the following onchange handler:
onchange="javascript:setTimeout('__doPostBack(\'ctl00$newContPage$txtBarcode\',\'\')', 0)"
My goal would be to modify doPostBack() to save the information I need to localStorage before executing the rest of doPostBack() without changing it.
(Note: doPostBack() here looks incredibly simplistic, so I think I'm missing some information about how ASP.NET works here. This is outside of the question though, unless it's relevant for what I'm trying to do.)
I was able to successfully modify doPostBack() in this way using Chrome Local Overrides to serve myself a local copy of the page on page load, instead of the server version. But this only works for the first doPostBack() request. After the first request, the server serves me new code. Like with ViolentMonkey, the lack of a refresh trigger prevents Chrome Local Overrides from re-serving my local copy, and I'm served code without the doPostBack() modification.
So that's where I'm at. I'll try adding a global listener like #wOxxOm suggested, and see where that gets me.
I ended up using a Chrome extension called "Run Javascript" (has an elephant for it's logo), which runs the JavaScript code even on AJAX requests.
Link: https://chrome.google.com/webstore/detail/run-javascript/lmilalhkkdhfieeienjbiicclobibjao/
I don't see how this is possible at all. You need to work with the people that created that web page.
Asp.net and the server side code will be EXTENSIVE .net code (c# or vb.net). Each of those events you trigger will set variables and server side session (or viewstate) values for the code behind to run.
That's how asp.net pages work. You post back, page travels up to server, THEN the .net code behind runs. That code will modify the page, modify controls, and modify the view state for that page. And after that code runs (say on a button click), then you client side will receive a whole new fresh page - that will blow out any JavaScript you try and inject. (you would have to re-inject each time). But, it gets worse, since quite of bit of that code behind also checks and often will NOT tolerate that the page settings have been messed with, and will be rejected.
About the only way to do this would be to write some desktop software, and that software would "house" or "host" a full "com" object copy of the web page, and you thus automate that given page. (and even then, you still fighting a losing battle).
Hint:
Web development, business logic, and a functional business applcation is NOT some simple markup and JavaScript (despite what that lame 2 week HTML course tells you).
This is a application, and asp.net applcation. Trying to think of this as just some markup and JavaScript is actually quite silly here. It not how you write, or build business solutions for a company.
If you can't write and modify the code and the web server side of things then find out if that site has some kind of web api or whatever.
But, really - this is silly, and unless this is some simple college project, or some hacked up html page and some JavaScript? Forget this approach - you dealing with FAR too much server side and code behind on the server.
In fact, asp.net as noted has quite a bit built in features that check if the page being posted back been messed with, and you never really be sure that you set values and that the proper amounts of code behind that runs to setup row values, database primary key values and a WHOLE boatload of state values that are probably 100% saved in server side session() based class objects - and objects that are never exposed server side.
Tring to supposed modify or assume you can create or modify such a system with only client side tools is not going to work - its just not.
code behind runs, it re-processes the page with .net code and then sends the whole page back down - all with new state values etc. This is not some lame html + JavaScript, but is a full server side code driven system written in c# .net code.

Dynamics CRM - call javascript resource

We are in the process of migrating our data to CRM online.
I would like to run some javascript code that I have that creates the sharepoint folder for an entity when the page loads.
However as we are using an api to create the record from existing data, is there a way to call/trigger the javascript on record create?
There is no hook for JavaScript with Dynamics CRM to trigger an action when a record is created, however the following may work (although is a little messy!).
1) Create a new dummy field (hidden, but on every the form) called "SharePoint Created?", this is a two options field, default value of "No".
2) Create a new JavaScript function to execute on "Form Load", which checks the form type to ensure its in edit mode (not create), if so, checks the value for the "SharePoint Created?" field, if this field is "No", update it to "Yes", call your SharePoint creation function, then save the record.
The better option would be to the move the call to a Plugin, which can be executed on create of a record, but understand authentication is always a problem.

How to add a read/write customRestService to support editing in Dojo DataGrid?

I am trying to develop a Dojo DataGrid that returns a user's documents from the categorized BidsByDriver view and allows them to edit the Priority field in the grid. After getting past the hurdle of using the keys property to filter over the categoryFilter, this was easy to set up using an xe:viewFileItemService read/write service. However the problem with xe:viewFileItemService as a data source is it will display empty lines for each entry in the view after showing the user's documents in the grid.
To get around the blank lines I went down the path of creating an xe:customRestService that returned the jasonData for just the current user's documents. This fixes my blank lines problem but my data source is not in the correct read/write format to support the in-grid editing.
Here is the resulting Json data returned form the xe:customRestService ...
[{"Driver":"ddd","BidID":"123","Priority":"1","Trip":"644"},
{"Driver":"ddd","BidID":"123","Priority":"2","Trip":"444"},
{"Driver":"ddd","BidID":"123","Priority":"4","Trip":"344"},
{"Driver":"ddd","BidID":"123","Priority":"4","Trip":"643"}
]
Here are the Dojo modules I am loading:
<xp:this.resources>
<xp:dojoModule name="dojo.store.JsonRest"></xp:dojoModule>
<xp:dojoModule name="dojo.data.ObjectStore"></xp:dojoModule>
</xp:this.resources>
And here is the script to develop the data store for the grid:
<xp:scriptBlock id="scriptBlock2">
<xp:this.value><![CDATA[
var jsonStore = new dojo.store.JsonRest({target: "InGridCustom.xsp/pathinfo"});
var dataStore = dojo.data.ObjectStore({objectStore: jsonStore});
]]></xp:this.value>
</xp:scriptBlock>
All of this works very nicely except for the bit on providing the in-grid editing support. Any ideas appreciated.
How are you trying to save the changes? With a custom REST service, I would not expect that saving the data store would make any changes to the back-end data, which is why a refresh would revert it to the original value.
I would expect that you'd need to write a doPost method in your custom REST service to process the change on the server side, along with client-side code to call the post method and pass in the updates to process (along with the document ID).
UPDATED ANSWER:
I would try one or both of these approaches to fix your issue.
1) Have a category in your view, and use a categoryFilter and use the hack to make the service only return the correct values. Outlines in this question: XPages Dojo Grid editable cell does not save value when REST Service save() method is called
2) Change the rest service type to viewJsonService in combination with #1. If you get an error, double check the configuration document that Per mentioned. Also heed Per's comments in the linked question relating to configuration and using Firebug to make sure the correct method is used. The update must be a PUT, a POST will not work with the viewJsonService.
Original Answer (for context of comments)
Paul,
I believe that you need to have a button with code to save the changes back. Maybe you do, but you don't mention it and it isn't in your screen shots. The step that Per mentioned is very necessary so it is good that you have it taken care of. The button is necessary, to 'commit' the changes back. The act of inline editing doesn't trigger the PUT call. If you think about it, you wouldn't want an update after each change but one update when the user is finished editing.
If you don't figure out by this evening, I have working code that I can send you, but don't have access to at work.

Enable a Custom Action button depending on current user

In essense I am trying to run a Javascript synchronized in order to make a query on a Sharepoint task list item to determine whether the current user is the same as the task asigned user. If 'true' this should enable the custom action button. But so far only being able to run the code asynchronized makes it fail, as the queries('Task Assigned To' & 'Current User') are not completed before the code returns the comparison (boolean) of the two users :-( Help anyone??
If your custom action is ribbon button after computing the value for EnabledScript cache it to some variable and call RefreshCommandUI(). This will cause second call to EnabledScript and here you can return cached value. Moreover you need to write your own state machine for that computing to avoid using expired non valid value. Real hard may appear if you have 2+ of such custom actions.

communicating between javascripts and struts2 action

I have the following scenarios:
User will input some value , and this values will be validated against the value from DB in the action class.
If if the value is invalid, want to show a confirm box to the user whether he still want to proceed with the invalid value.
Depend on user's answer YES or NO, which is brought back to the action class, the process of the action class will be different.
For the above scenarios, step 1 is OK.
But how do I achieve to bring the value from the action class to the javascripts and getting user's confirmation and bring back the value to the action class?
The second approach can be done by using Ajax. Struts 2 provides many ways to use Ajax:
Use the "stream" result type to send data back to your JS code.
Use the JSON plugin to get JSON back.
Consider the Struts 2 jQuery plugin.
A Google search will give you a lot of examples as how to use Ajax with Struts 2.

Categories

Resources