Microsoft Dynamics CRM 2015 – Need to have Subgrid Lookup Filter - dynamics-crm

Microsoft Dynamics CRM 2015 –
Need to filter the look up on a subgrid
Javascript code I am using:
function SetCustomLookUp() {
debugger;
lookupFieldObject = Xrm.Page.data.entity.attributes.get('account');
if (lookupFieldObject.getValue() != null) {
entityId = lookupFieldObject.getValue()[0].id;
entityName = lookupFieldObject.getValue()[0].entityType;
entityLabel = lookupFieldObject.getValue()[0].name;
}
var filterXML = [
'<filter type="and">',
'<condition attribute="parentcustomerid" value="{54BC1539-C29C-E511-80E9-3863BB2E6258}" operator="eq"/>',
'</filter>'
].join('\n');
var Subgrid = Xrm.Page.getControl("Contacts");
document.getElementById("Contacts").addEventListener("click", function () {
setTimeout(function () {
var gridControl = Xrm.Page.getControl("Contacts");
var me = gridControl.$c_0.$N_4.$Y_3;
me.addPreSearch(function () {
me.addCustomFilter(filterXML);
});
}, 2000);
});
}
Error: "Cannot read property 'addEventListener' of null"

I used this code and erro thet you present, the reason is:
the subgrid is painting at the end of paint all form, and then you must add this even of click when the sub-grid is painting
I write a small code for this:
var objSubGrid = document.getElementById("subgrid_name");
//CRM loads subgrid after form is loaded.. so when we are adding script on form load.. need to wait until sub grid is loaded.
// that's why we are adding a delay..
if (objSubGrid == null) {
setTimeout(functionxxx, 2000);
return;
} else {

Following article contains answer - http://www.magnetismsolutions.com/blog/paulnieuwelaar/2016/06/20/filter-n-n-add-existing-lookup-dynamics-crm-2016-turbo-forms
To Modarators - Yes, I know that it is recommended to retype everything that is mentioned in article but I'm pretty sure that article will be available online for a long time so I just will not retype because it has no sense for me.

Related

Refresh Parent Form after Quick Create in Dynamics CRM 2016

In Dynamics CRM 2016 we have a Quick Create Form which works well. But once the Quick Create is done, and the record is saved (and the new record appears in the sub-grid in the parent form), the roll-up field under the sub-grid doesn't get re-refreshed on the screen until the user presses F5.
(we have some C# code to update the roll-up).
Does anyone know how to force the refresh of the main form after the Quick Create has successfully run?
You may add timeout on refresh event, and after 1-2 sec refresh once more.
function OnFormLoad() //add this function onload form
{
var subGrid = window.parent.document.getElementById("id of your subgrid")
if (subGrid !== null) {
if (subGrid.control)
subGrid.control.add_onRefresh(fnOnRefresh)
else
setTimeout(OnFormLoad, 500);
} else {
setTimeout(OnFormLoad, 500);
}
}
function fnOnRefresh() {
setTimeout(function() {
Xrm.Page.ui.controls.get("id of your subgrid").refresh();
}, 2000) //after 2 sec refresh subgrid
}
I would try stopping the OOB save event using the below snippet: Read more
function onSave(context) {
var saveEvent = context.getEventArgs();
saveEvent.preventDefault();
//save explicitly here
//reload the window here
}
And then save the entity in code using:
Xrm.Page.data.entity.save();
And then refresh/reload the browser window. I haven’t tried this but very rough theory :)
We got it working ... used what Timur suggested but just changed the last function to:
function fnOnRefresh() {
setTimeout(function() {
window.parent.location.reload(true);
}, 500)
}
Thank you

How to get webHookUrl from Microsoft Teams connector

I’m building a connector for Teams and I can get my custom configuration page to load by calling the necessary functions. I have a few <span> tags in my page just to debug and I'm populating the tags with properties from my call to "getSettings()".
<script>
microsoftTeams.initialize();
var teamsSettings = microsoftTeams.settings.getSettings(); //should this not return at least something?
if (teamsSettings == null) {
$(document).ready(function () {
document.getElementById('status').textContent = "Get settings
returned null!"; //i always get null
});
} else {
document.getElementById('entityId').textContent = teamsSettings.entityId;
document.getElementById('configName').textContent = teamsSettings.configName;
document.getElementById('contentUrl').textContent = teamsSettings.contentUrl;
document.getElementById('webhookUrl').textContent = teamsSettings.webhookUrl;
document.getElementById('appType').textContent = teamsSettings.appType;
document.getElementById('userObjectId').textContent = teamsSettings.userObjectId;
}
microsoftTeams.settings.registerOnSaveHandler(function (saveEvent) {
saveEvent.notifySuccess();
});
function onClick() {
microsoftTeams.settings.setValidityState(true);
}
</script>
So I’m wondering if the getSettings() method is even running as my label element is blank. How can I troubleshoot the JavaScript interactions while configuring my connector in Teams? Is there a better way to view settings obtained from the method?
Here is the code snippet to get the webhookUrl using getSettings().
microsoftTeams.initialize();
microsoftTeams.settings.getSettings(function (settings) {
document.getElementById('webhookUrl').textContent = settings.webhookUrl;
});

Ckeditor issue calling setData during onchange event

I am trying to create a plugin that works similar to the tagging feature here on Stack Overflow. The plugin adds an onchange event to the editor and than checks the data to see if the user entered a tag and replaces any tags found with a div.
CKEDITOR.plugins.add('tagit', {
icons: '',
init: function (editor) {
var tags = ['MyTag'],
tokens = [];
editor.on('change', function (event) {
var tokenUpdated = false;
tokens = tokenize(event.editor.getData());
for (var tokenIndex = 0; tokenIndex < tokens.length; tokenIndex++) {
var token = String(tokens[tokenIndex]);
if (!token.match(/tagit/gmi) && tags.some(function (tag) { return token.indexOf(tag) >= 0; })) {
tokens[tokenIndex] = '<div class="tagit">' + tokens[tokenIndex] + '</div>';
tokenUpdated = true;
}
}
if (tokenUpdated) {
event.editor.setData(tokens.join(''));
}
});
var tokenize = function (data) {
var match = '(<div class="tagit">.*?<\/div>)';
for (var i = 0; i < tags.length; i++) {
match += '|(' + tags[i] + ')';
}
var re = new RegExp(match, "gmi");
return data.split(re);
}
}
});
The problem is when I call setData the change event is fired again and event.editor.getData() returns the html before I called setData. Is the change event fired before the data has actually been set? There's an option internal that I tried setting to true but than the data doesn't appear to be updated.
You are changing editors content so it's natural that change event will be called with editor.setData function. TBO I think that your implementation has a much important problem than circular call - you are comparing HTML content by regex. It's bad practice and you will encounter more problems during this implementation.
This feature is not obvious and requires working with document selection, not simply querying its content (also for performance reasons).
But I have a good information. With CKEditor 4.10 we are shipping new plugins which can easily be used to create feature you are talking about - especially textmatch and textwatcher. Mentioned plugins will be shipped alongside with autocomplete and mentions plugins. You can read more about our progress on GH:
Mentions: https://github.com/ckeditor/ckeditor-dev/issues/1703
Autocomplete: https://github.com/ckeditor/ckeditor-dev/issues/1751
4.10 release is set on 26 June but it could change, check GH milestones for updates.
After release, I can provide some example implementation for your feature - but I'm sure that with new plugins it will be easy as pie.

Custom Validation causing computed values to fire

For a quick view of my problem I have made a working jsFiddle here:
In KnockoutJS I have made a custom extender validator to test if the input format is in the HHMM format. If it is it returns the new value, if it doesn't it will set it back to the old value this is currently working.
ko.extenders.acValidTimeHHMM = function (target, options) {
var result = ko.computed({
read: target,
write: function (newValue) {
var re = /^([0-9]|0[0-9]|1[0-9]|2[0-3])[0-5][0-9]$/;
if (!re.test(newValue)) {
target.notifySubscribers(target());
//Time not in correct format return old time
return;
}
target(newValue);
}
}).extend({ notify: 'always' });
result(target());
return result;
};
The problem I am having is that I update my database when the value changes using a computed. However this is also firing when I reset the value back to its original using my validator. (Method based on Ryan Rahlf dirty flag technique here )
self.update = ko.computed(function () {
self.timeOne();
self.timeTwo();
alert("Fired");
});
The problem is obviously the line target.notifySubscribers(target()); in my validator. However without this line I can't reset the value to its old value and I can't find another way to do this.
So this only fires when a value actually changes rather then the validator resetting it. The jsFiddle demonstrates my problem exactly and can be used to make a working version (hopefully) I know its currently firing on page load too.
The problem I am having is that I update my database when the value changes using a computed.
I don't know all your logic, but I don't think this is a good idea to update the db each time your knockout view model has updated. May be you should look at knockout validation plugin. Using this plugin you can build the same custom validation rule and update the db only on form submit event.
About your problem...
The simplest solution I'm found is to send a success callback function to the validation extension like an option.
Something like this.
JS:
var ViewModel = function() {
var update = function () {
alert("value was successfully changed");
};
var cancel = function () {
alert("validation failed. previous value was returned");
};
var timeOne = ko.observable("1100").
extend({
acValidTimeHHMM: {
success: update,
fail: cancel
}
});
var timeTwo = ko.observable("1248").
extend({ acValidTimeHHMM: { success: update } });
return {
timeOne: timeOne,
timeTwo: timeTwo
};
};
ko.extenders.acValidTimeHHMM = function(target, option) {
var baseOptions = {
success: null,
fail: null
};
$.extend(baseOptions, option);
var result = ko.computed({
read: target,
write: function (newValue) {
var oldValue = target();
if(newValue == oldValue) return;
var re = /^([0-9]|0[0-9]|1[0-9]|2[0-3])[0-5][0-9]$/;
if (!re.test(newValue)) {
target.notifySubscribers(oldValue);
if(typeof(baseOptions.fail) == "function")
baseOptions.fail();
return;
}
target(newValue);
if(typeof(baseOptions.success) == "function")
baseOptions.success()
}
}).extend({ notify: 'always' });
result(target());
return result;
};
ko.applyBindings(new ViewModel());
HTML:
<p>Time One<input data-bind='value: timeOne' /></p>
<p>Time Two<input data-bind='value: timeTwo' /></p>

Why Doesn't Javascript DOM 2 "Click" Event Work

My question is, Why doesn't the click event work when other events do work using the same code? Consider the following code examples from http://www.pricelearman.com/__dev (2 underscores)
For Square 2 using "click" event
function showWorkPane() {
var _workID = document.getElementById("workID");
_workID.addEventListener("click", showWorkPaneHandler, false);
}
function showWorkPaneHandler(e) {
var _workPane = document.getElementById("workPane");
e.preventDefault();
_workPane.style.display = "block";
}
Clicking on the link "Work" does not show the workPane.
For Square 3 using "mouseover" event
function showAboutPane() {
var aboutID = document.getElementById("aboutID");
aboutID.addEventListener("mouseover", showAboutPaneHandler, false);
}
function showAboutPaneHandler(e) {
e.preventDefault();
var v = document.getElementById("aboutPane");
v.style.display = "block";
}
Rolling-Over the link "ABOUT" shows the aboutPane hover effect as expected
For Square 4 using "mousedown" event
function showConnectPane() {
var connectID = document.getElementById("connectID");
connectID.addEventListener("mousedown", showConnectPaneHandler, false);
}
function showConnectPaneHandler(e) {
e.preventDefault();
var v = document.getElementById("connectPane");
v.style.display = "block";
}
Holding mouse down on the link "CONNECT" shows the connectPane as expected
What am I missing about the click event. It's counterintuitive to me that it would not follow the same pattern as the other mouse events.
I'm trying to preclude interference from the link's default action by using e.preventDefault();
I know a click event is a sequence of simple events: mousedown,mouseup,click.
Is there something blocking this sequence?
The full code can be reviewed at http://www.pricelearman.com/__dev (2 underscores). The code may not be optimum, but it is functionally correct – binding is accomplished and functions are called, etc – else the above code would not be working at all.
Thanks for your time and expertise. This is a vexing question to me. It seems so fundamental and simple. I'm new to javascript and I must be missing something.
For Square 2 using "click" event
function showWorkPane() {
var _workID = document.getElementById("workID");
_workID.addEventListener("click", showWorkPaneHandler, false);
}
function showWorkPaneHandler(e) {
var _workPane = document.getElementById("workPane");
e.preventDefault();
_workPane.style.display = "block";
}
Clicking on the link "Work" does not show the workPane.
Well what I currently can find at http://www.pricelearman.com/__dev/_js/main.js is
// Show work navigation
function showWorkPane() {
var workID = document.getElementById("workID");
workID.addEventListener("mouseover", showWorkPaneHandler, false);
// ^^^^^^^^^
}
function showWorkPaneHandler(e) {
e.preventDefault();
var v = document.getElementById("workPane");
v.style.display = "block";
}
Looks quite obvious to me why click events show no effect. There are none bound.

Resources