Retrieve the fetchxml in grid via javascript - dynamics-crm

This might seem a bit of an odd request so I'll try to offer some background. I have a feature on my CRM which requires that user should be able to filter a view and then save the resulting records such that a separate process can pick them up and process them periodically e.g. daily.
Now here's the catch, they want this process to requery the data before it processes it, so basically what should be saved is the query or filters rather than the data in the view.
Having previously written some javascript code which dynamically sets the fetchxml on a subgrid like so
Subgrid.getGrid().setParameter("fetchXml", fetchxml);
I though it should be fairly straight forward to potentially retrieve the fetchxml in the grid
Subgrid.getGrid().getParameter("fetchXml");
However that doesn't work and I can't seem to find any documentation or anything that can point me in the right direction. I have used Developer tools to inspect the properties of Mscrm.XrmControlGridWrapper but I can't find anything useful..
If anyone knows how I can retrieve the fetchxml that powers a subgrid using javascript, it would be massively helpful?
EDIT
I have just found that I can do this
Subgrid.getGrid().getFilter().$3_1.GetParameter("fetchXml")
and that returns exactly what I want, however this just screams of hacky and unsupported.
$3_1 has a type of [object (Mscrm.TurboGridControl)]
Is there a way I can access this object in a supported way?

A few thoughts on this:
You can retrieve the SystemForm record, then parse the FormXml to get the ViewId. Then you can retrieve the view from the SavedQuery entity, and get the FetchXML. Here's an example of the ViewId in the FormXml:
You could add a boolean field to the entity and when the user saves the set they want to process you can flag those records for the later batch process to retrieve.
When the user identifies the set they want to process you could temporarily create a view (SystemQuery or UserQuery) with the the FetchXML using the "in" operator with the list of Guid's to identify the exact records to process. After using the view to retrieve and process the records, the batch process could delete the view. I would probably be comfortable using this approach up to a few dozen records.
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="account">
<filter type="and">
<condition attribute="accountid" operator="in">
<value>{A1CC84F2-BE0D-E711-8104-00155D6FD705}</value>
<value>{A3CC84F2-BE0D-E711-8104-00155D6FD705}</value>
<value>{A5CC84F2-BE0D-E711-8104-00155D6FD705}</value>
</condition>
</filter>
</entity>
</fetch>
If you want to avoid changing the Modified information by setting a boolean flag on the records to be processed, you could create an N:N linking entity and associate the selected records to an instance of that entity.

You can do:
Since you have the fetchxml that previously set as filter for SubGrid, why don't you store this variable directly. You can save this variable in localStorage or maybe even in a dummy field created for this purpose. And use it in the desired process.
Btw, the supported way of getting fetchXml: Xrm.Page.getControl(gridControlName).getFetchXml()
Hope this helps...

Related

Is there a way to sort a content query by the value of a field programmatically?

I'm working on a portal based on Orchard CMS. We're using Orchard to manage the "normal" content of the site, as well as to model what's essentially data for a small application embedded in it.
We figured that doing it that way is "recommended" for working in Orchard, and that it would save us duplicating a bunch of effort in features that Orchard already provides, mainly generating a good enough admin UI. This is also why we're using fields wherever possible.
However, for said application, the client wants to be able to display the data in the regular UI in a garden-variety datagrid that can be filtered, sorted, and paged.
I first tried to implement this by cobbling together a page with a bunch of form elements for the filtering, above a projection with filters bound to query string parameters. However, I ran into the following issues with this approach:
Filters for numeric fields crash when the value is missing - as would be pretty common to indicate that the given field shouldn't be considered when filtering. (This I could achieve by changing the implementation in the Orchard source, which would however make upgrading trickier later. I'd prefer to keep anything I haven't written untouched.)
It seems the sort order can only be defined in the administration UI, it doesn't seem to support tokens to allow for the field to sort by to be changed when querying.
So I decided to dump that approach and switched to trying to do this with just MVC controllers that access data using IContentQuery. However, there I found out that:
I have no clue how, if at all, it's possible to sort the query based on field values.
Or, for that matter, how / if I can filter.
I did take a look at the code of Orchard.Projections, however, how it handles sorting is pretty inscrutable to me, and there doesn't seem to be a straightforward way to change the sort order for just one query either.
So, is there any way to achieve what I need here with the rest of the setup (which isn't little) unchanged, or am I in a trap here, and I'll have to move every single property I wish to use for sorting / filtering into a content part and code the admin UI myself? (Or do something ludicrous, like create one query for every sortable property and direction.)
EDIT: Another thought I had was having my custom content part duplicate the fields that are displayed in the datagrids into Hibernate-backed properties accessible to query code, and whenever the content item is updated, copy values from these fields into the properties before saving. However, again, I'm not sure if this is feasible, and how I would be able to modify a content item just before it's saved on update.
Right so I have actually done a similar thing here to you. I ended up going down both approaches, creating some custom filters for projections so I could manage filters on the frontend. It turned out pretty cool but in the end projections lacked the raw querying power I needed (I needed to filter and sort based on joins to aggregated tables which I think I decided I didn't know how I could do that in projections, or if its nature of query building would allow it). I then decided to move all my data into a record so I could query and filter it. This felt like the right way to go about it, since if I was building a UI to filter records it made sense those records should be defined in code. However, I was sorting on users where each site had different registration data associated to users and (I think the following is a terrible affliction many Orchard devs suffer from) I wanted to build a reusable, modular system so I wouldn't have to change anything, ever!
Didn't really work out quite like I hoped, but to eventually answer the question in your title: yes, you can query fields. Orchard projections builds an index that it uses for querying fields. You can access these in HQL, get the ids of the content items, then call getmany to get them all. I did this several years ago, and I cant remember much but I do remember having a distinctly unenjoyable time with it haha. So after you have an nhibernate session you can write your hql
select distinct civr.Id
from Orchard.ContentManagement.Records.ContentItemVersionRecord civr
join civ.ContentItemRecord cir
join ci.FieldIndexPartRecord fipr
join fipr.StringFieldIndexRecord sfir
This just shows you how to join to the field indexes. There are a few, for each different data type. This is the string one I'm joining here. They are all basically the same, with a PropertyName and value field. Hql allows you to add conditions to your join so we can use that to join with the relevant field index records. If you have a part called Group attached directly to your content type then it would be like this:
join fipr.StringFieldIndexRecord sfir
with sfir.PropertyName = 'MyContentType.Group.'
where sfir.Value = 'HR'
If your field is attached to a part, replace MyContentType with the name of your part. Hql is pretty awesome, can learn more here: https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html But I dunno, it gave me a headache haha. At least HQL has documentation though, unlike Orchard's query layer. Also can always fall back to pure SQL when HQL wont do what you want, there is an option to write SQL queries from the NHibernate session.
Your other option is to index your content types with lucene (easy if you are using fields) then filter and search by that. I quite liked using that, although sometimes indexes are corrupted, or need to be rebuilt etc. So I've found it dangerous to rely on it for something that populates pages regularly.
And pretty much whatever you do, one query to filter and sort, then another query to getmany on the contentmanager to get the content items is what you should accept is the way to go. Good luck!
You can use indexing and the Orchard Search API for this. Sebastien demoed something similar to what you're trying to achieve at Orchard Harvest recently: https://www.youtube.com/watch?v=7v5qSR4g7E0

Check if Associated View is blank in Dynamic CRM Online

In CRM Online on a customer form is there anyway that you can check if the Associated View for Assets is blank? And if its blank change a field value based on it.
Using JavaScript, 2 ways:
The associated grid is showing records related to your primary record. You can perform the same query the grid is doing using REST which will tell you if there are any records. You can then count the records, and change the field value as required. This approach is better if there are records in the database but which aren't shown in the view for some reason, e.g. view filters.
Access the Grid objects data using getRows(). As above you can then count the records, and change the field value as required. The downside of this is I believe those methods only give you access to the records shown on the form (and not any hidden by filters but still in the database) - but I don't think that that will be a problem here.
Worth bearing in mind that this approach only works client side, e.g. someone has to be actually looking at the form.
If you need to cover the a non-client side approach, e.g. workflows creating records, then you should probably look at plugin development so the changes can be performed server side.
As a side if you just want a simple count shown on form you then you should probably look at Calculated Fields and in particular Rollup fields. You might also be able to run further client side JavaScript from the count.

NHibernate query mapped collection

In my ASP.NET web-application I use NHibernate to persist my "User"-Instances, where each of them has a "Entries" - collection. It is a typical one-to-many mapping and it works just fine. The mapping-code for the entries looks like this:
<bag name="Entries" cascade="all-delete-orphan">
<key column="UserID" />
<one-to-many class="MyApp.Entities.Entry, MyApp.Entities" />
</bag>
Now I have a page, where I want to display a grid with all the entries of the logged-in user. To do so, I could simply bind the "Entries" property of the current user to the Grids "DataSource" - property. This also works just fine, but this also means, that the grids built-in paging-functionality (Telerik RadGrid) doesn't have any effect on database-performance, because all the entries will be loaded each time when displaying the grid.
Therefore I could apply my custom-paging, where I only fetch the rows which I need to display the grids current page. A typical Linq2NHibernate query looks like this:
var query = from entry in Session.Linq<Entry>()
where entry.User == currentUser
select entry;
query.Skip(pageNum * pageSize).Take(pageSize).ToList();
Using this approach I need to extend my repository altough NHibernate has already done the mapping between User and Entry...
My question is: If I use LINQ to directly query the "Entries"-collection of my "User"-object - does this mean, that all the Entries will be loaded from the database and then filtered in memory or would this be translated to a real "database"-query, so that I could use this much more comfortable approach to implement paging?
Example:
myGrid.DataSource = currentUser.Entries.Skip(pageNum * pageSize).Take(pageSize).ToList();
J4I: Of course I use lazy-loading in the mapping files...
Thank you in advance!
LINQ on the collection will always be LINQ-to-objects, as they don't implement IQueryable, so you'd be loading everything in memory.
A query is the only possible approach at this moment.

MS CRM 4 - Custom entity with "regardingobjectid" functionality

I've made a custom entity that will work as an data modification audit (any entity modified will trigger creating an instance of this entity). So far I have the plugin working fine (tracking old and new versions of properties changed).
I'd like to also keep track of what entity this is related to. At first I added a N:1 from DataHistory to Task (eg.) and I can indeed link back to the original task (via a "new_tasksid" attribute I added to DataHistory).
The problem is every entity I want to log will need a separate attribute id (and an additional entry in the form!)
Looking at how phone, task, etc utilize a "regardingobjectid", this is what I should do. Unfortunately, when I try to add a "dataobjectid" and map it to eg Task and PhoneCall, it complains (on the second save), that the reference needs to be unique. How does the CRM get around this and can I emulate it?
You could create your generic "dataobjectid" field, but make it a text field and store the guid of the object there. You would lose the native grids for looking at the audit records, and you wouldn't be able to join these entities through advanced find, fetch or query expressions, but if that's not important, then you can whip up an ASPX page that displays the audit logs for that record in whatever format you choose and avoid making new relationships for every entity you want to audit.
CRM has a special lookup type that can lookup to many entity types. That functionality isn't available to us customizers, unfortunately. Your best bet is to add each relationship that could be regarding and hide the lookups that aren't in use for this particular entity.

How to programmatically hide a linq-to-sql column on a datagridview?

I'm binding a linq Query to a datagridview for the purposes of allowing a user to insert/update/delete. However I'd like to hide the Id column. but I'd rather not hard code the
datagridview.columns[id].visible=false
In the event the id column name changes. I've read that you can walk through reflection to get a run-time list of columns, but I can't have that checked at design-time for a column name. Is it possible?
If I change the query to not include the ID, then I'm hard coding the column list instead of the id column name, so if columns were added, I'd have to go manually update there instead.
If you're using Winforms, then you should have a BindingSource on your Form that is typed to your LINQ-to-SQL type. If you do this, then you'll get full designer support for all of the fields available on that class.
If you're doing a lot of data binding work with LINQ-to-SQL entities (or any other classes, for that matter), I highly recommend checking into HyperDescriptor by Mark Gravell. It speeds up the UI data binding performance considerably by bypassing repeated runtime invocations of the properties on the classes.
Couldn't you do it in the html? Or are you using ASP.NET?
<asp:BoundField DataField="id" Visible="false" />

Resources