We have two forms for the case entity. The default case form is heavily customized and has become rather slow to work with. The second form, called 'fastcase', is a lightweight version of the default case form. Both forms are being used by the same users. The fastcase form is opened from a link in SharePoint. We want that the default case form is always opened when working from within CRM.
I was wondering if, and how, it is possible to force CRM to always open the default case form when working from within CRM.
The only thing I could find was this link, but I have a feeling that the solution with navigate will also force the SharePoint fastcase form to open in the default case form. Working with different user roles and groups is also not an option as suggested there.
First of all: You are not using forms they are supposed to be used. Forms are role based and you are trying to use them for something else. Anyway, I totally understand your idea and I have been in the same situation :)
You need to do a little magic trick in CRM to make a form sticky. CRM stores the Most Recently Used (MRU) forms in a special entity called UserEntityUISettings. This entity stores UI settings per entity per user in xml.
What you need to do is to prevent CRM from changing this entity whenever the user changes the form for a given entity. Basically you want to control the attribute called lastviewedformxml. You can get some inspiration from this blog post: https://community.dynamics.com/crm/b/gonzaloruiz/archive/2014/11/19/avoiding-form-reload-when-switching-crm-forms-based-on-a-field.aspx
Happy coding...
You can open CRM forms in this way:
function OpenForm()
{
var parameters = {};
var id = GetFormId("account", "FormName");
parameters["formid"] = id;
Xrm.Utility.openEntityForm("account", null, parameters);
}
function GetFormId(formEntity, formName) {
var serverUrl = Xrm.Page.context.getServerUrl();
var oDataEndpointUrl = serverUrl + "/XRMServices/2011/OrganizationData.svc/";
oDataEndpointUrl += "SystemFormSet?$top=1&$filter=ObjectTypeCode eq '" + formEntity + "' and Name eq '" + formName + "'";
var service = new window.XMLHttpRequest;
var id;
if (service != null) {
service.open("GET", oDataEndpointUrl, false);
service.setRequestHeader("X-Requested-Width", "XMLHttpRequest");
service.setRequestHeader("Accept", "application/json, text/javascript, */*");
service.send(null);
var requestResults = eval('(' + service.responseText + ')').d;
if (requestResults != null && requestResults.results.length == 1) {
var rec = requestResults.results[0];
id = rec.FormId;
}
}
return id;
}
Depends the way you are calling the form from sharepoint you call the form you need and from CRM you let it handles in the native way.
Related
I searched the whole web and I couldn't found any good topic which expose the proper way to do it.
I have a very simple web which I developed using Kentico 9 CMS. This web only contains two subpages and a header to navigate between those.
The "Home" subpage contains a custom form which remains connected to a SQL table which is populated every time you press submit with certain data.
On the other hand, the other page, shows the stored data by using a custom web part which connects to the DB by using BizFormItemProvider and this object is used as a layer to binding the data in a control.
Now is my point. If you see, there is a button to "Edit" a certain row and my intention is to Redirect to "Home" (which contains the form) and sending via QueryString the ID of the row attempted to edit.
I was unable to understand how can you re-fill the form with its data using an ID.
Maybe because I never worked with a CMS before, I'm looking the development such as pure ASP.NET and it could not be the correct one.
Custom
Given that your solution uses a custom form for entering the data, as well as a custom web part for listing the stored data, you will need to use a custom solution to handle the editing of data, as well.
In the custom webpart on the Home page, in a load event, you can retrieve the form data and set the values on the form controls.
protected void Page_Load(object sender, EventArgs e)
{
// Ensure that the form is not being posted back,
// to prevent entered data from being overwritten
if(!IsPostBack)
{
// Get the form item ID from the query string
var personId = QueryHelper.GetInteger("personId", 0);
if(personId > 0)
{
// Get the biz form item, and set form control values
var bizFormItem = BizFormItemProvider.GetItem(personId, "customFormClassName");
txtFirstName.Text = bizFormItem.GetStringValue("FirstName", string.Empty);
}
}
}
Similarly, when Submit is clicked, you can update the existing form item with the new data
protected void btnSubmit_OnClick(object sender, EventArgs e)
{
// Get the form item ID from the query string
var personId = QueryHelper.GetInteger("personId", 0);
if(personId > 0)
{
// Retrieve the existing biz form item,
// and update it from the form control values
var bizFormItem = BizFormItemProvider.GetItem(personId, "customFormClassName");
bizFormItem.SetValue("FirstName", txtFirstName.Text);
bizFormItem.Update();
}
else
{
// Your code for inserting a new form item...
}
}
The Kentico way
You should really consider using the Kentico form engine for accomplishing this task. Instead of using a custom form for entering the data, use the built-in On-line form webpart.
The benefits are numerous, such as:
Ability to set the form layout through the CMS, and use alternative layouts
Automatic confirmation email to the submitter of the form, as well as notification emails to the administrators
To accomplish your task, you can customise the On-line form webpart to support loading of existing data.
In the bizform.ascx.cs file, add code to the SetupControl method:
protected void SetupControl()
{
if (StopProcessing)
{
// Existing code...
}
else
{
// Existing code...
// Get the form item ID from the query string
var personId = QueryHelper.GetInteger("personId", 0);
if(personId > 0)
{
// Get the biz form item, and set form control values
var bizFormItem = BizFormItemProvider.GetItem(personId, "customFormClassName");
if(bizFormItem != null)
{
// Set the item ID
viewBiz.ItemID = bizFormItem.ItemID;
}
}
}
}
This will automagically switch the form to Edit mode, instead of Insert mode, as soon as you set the ItemID property. Clicking the Submit button will save changes on the existing form item.
You will not need to worry about validation in your code, and inserting data will still work.
Is this a contact form that you are using Kenticos built in form application for, or is it a custom form? If it is a custom form you can create a transformation with a link that will contain the ID. If it is a biz form, you can still create a transformation in Page Types (create a new page type and select "The page type is only a container without custom fields"), then write a custom query to get the biz form data, and use a repeater to display the data with that transformation.
I have a hierarchical relation inside an entity X, I Have parent lookup which allow to give parent to a record of this entity, and I have created a Subgrid attached to this lookup within the same form of the entity:
The problem is that the display of the button + is unstable in this subgrid, sometimes it appears sometimes no. I dont know if this problem is related to some setting or it is a bug of dynamics crm online last version?
For information, I don't have this problem with other sub-grids.
Thanks in advance,
if you want to add a custom button you may do this as follows
function CreateButton() {
var connectionSubGridPlusBtn = document.getElementById("Connections_addImageButton").parentNode.parentNode;
//Connections_addImageButton is the id of + button
if (connectionSubGridPlusBtn != null) {
//New Button
var div = document.createElement("div");
div.className = "ms-crm-contextButton";
div.innerHTML = "<button id='newButton' type='button' style='width:80px;cursor: pointer;padding:0px' >New Button</button>";
connectionSubGridPlusBtn.appendChild(addVendorDiv);
//Event and url for new
document.getElementById("newButton").onclick = function () {
//Write codefor the button click event
}
}
}
call this function on load of the form
The entity has to be created before you're able to add related entities. You can add disable all required fields, and perform a save in the onload, and you should always see the plus sign.
A slightly better solution is to override the create button for the entity, and rather than directing to the create form, perform a rest entity creation, then direct to that form. Then you don't have to perform a save in the on load.
I have a Name Picker on an XPage with a dataProvider dominoNABNamePicker with the addressBookSel = all-public and people and groups = true. With the database on a Domino server using the Notes Client it displays my local Names.nsf. If I open the DB in a brouse it selects the correct names.nsf from the server.
Can't figure out if this is the result of settings in my client, the server or XPages. Does the same thing on two different PC's.
I would think that the all-public would force it to open only public NABs but it does not appear so.
I asked the same question myself.
The answer, in the control add
addressBookDb="SERVER!!names.nsf"
From here.
Can I have the extlib name picker running in xPINC lookup the directory on the server?
After a fair bit of frustration I have this working for the Notes Client and the Web Client. Perhaps this is obvious to most of you, but it sure wasn't to me.
First on the Name Picker I created a namePickerAggregator. Then I added a dominoNABNamePicker
in the addressBookDb I put the following SSJS:
var server:String = #Name("[CN]",session.getCurrentDatabase().getServer());
var allNABs:Array = session.getAddressBooks().iterator();
var pubNABs = new Array;
var privNABs = new Array;
while (allNABs.hasNext()) {
var db:NotesDatabase = allNABs.next();
if (db.isPublicAddressBook()){
pubNABs.push(db.getFileName())
} else {
privNABs.push(db.getFileName())
}
db.recycle()
}
if (pubNABs[0] == ""){
return privNames[0];
break;
} else {
return server + "!!" + pubNABs[0];
break
}
I then added a second dominoNABNamePicker with the same block of code except the return is
if (pubNABs[1] != "") {
return server + "!!" + pubNABs[1];
break;
} else {
return "";
}
This code works for both the Notes Client and the Web client so I'm now a happy camper, unless I find a gotcha somewhere.
Here is what I eventually did. I set a limit on the maximum number of address books (not great but it works) of 4 you can create as many as you want. So I created a couple of sessionScope variable that I created in the after Page Loads event on the XPage. I used this formula.
var allNABs:Array = session.getAddressBooks().iterator();
var pubNABs = new Array;
var privNABs = new Array;
while (allNABs.hasNext()) {
var db:NotesDatabase = allNABs.next();
if (db.isPublicAddressBook()){
pubNABs.push(db.getFilePath())
} else {
privNABs.push(db.getFilePath())
}
db.recycle()
}
sessionScope.put("ssPublicNABs", pubNABs);
sessionScope.put("ssPrivateNABs", privNABs);
because I use several different Name Pickers on the same page I did not want to repeat having to cycle through the Address books.
Then I created 4 NamePicker controls and added 1, 2 , 3 and 4 dominoNABNamePickers providers to each of the successive controls. Then set the rendered property based on the number of public Address books so they would not blow up on me. The db name property on each of the providers is :
var server:String = #Name("[CN]",session.getCurrentDatabase().getServer());
var pubNABs:Array = sessionScope.get("ssPublicNABs");
return server + "!!" + pubNABs[0];
where pubNABs[n] returns the correct filePath for the NAB. It works well in both Notes Client and the Web.
Then to make it not blow up on a local disconnected replica I created 4 more controls and did the same thing but used the privNABs with appropriate rendered properties so that there is no conflict. Seems like the long way around and I'm sure that there is an easier way, but it works.
I've been trying to figure auto-complete some values from netsuite onto our custom html form.
After a bit of researching, I found this gem: nlapiGetContext (http://www.netsuite.com/portal/developers/resources/APIs/Dynamic%20HTML/SuiteScriptAPI/MS_SuiteScriptAPI_WebWorks.1.1.html)
which should do exactly what it says,
However, when doing a console.log dump of nlapigetcontext()
the following information is displayed, not my current logged in user information
Here is my current test script:
if (window.addEventListener) { // Mozilla, Netscape, Firefox
window.addEventListener('load', WindowLoad, false);
} else if (window.attachEvent) { // IE
window.attachEvent('onload', WindowLoad);
}
function WindowLoad(event) {
alert(nlapiGetContext().getCompany());
console.log(nlapiGetContext());
}
Any help or guidance is appreciated!
Thank you!
Where is this form located? Context will only work if you are logged into the system, so this won't apply for online customer forms, those are considered to be "outside the system".
You can write a Suitelet to retrieve data from an external form if you are only retrieving values.
I use this to get campaign information on an external landing page.
function getCamData(request, response){
if ( request.getMethod() == 'GET' ){
response.setHeader('Custom-Header-CamID', 'CamID');
var camid = request.getParameter('camid');
var rec = nlapiLoadRecord('campaign', camid);
var o = new Object();
o.thisid = camid;
o.promocode = rec.getFieldValue('campaignid');
o.phone = rec.getFieldValue('custevent_cam_1300num');
o.family = rec.getFieldValue('family');
var myString = JSON.stringify(o);
response.write (myString);
}}
You request something like this:
https://forms.netsuite.com/app/site/hosting/scriptlet.nl?script=188&deploy=1&compid=xxxxxx&h=fb8224b74b24907a79e6&camid=8020
And returns something like this:
{"thisid":"8020","promocode":"CAM999","phone":"1800 111 222","family":"12"}
Also you can do server-side posting from an external site to a NetSuite customer online form, it will capture and validate the data as far as it has the entry fields set in NS, this is a great way to avoid using those horrible iframes.
Use these functions
nlapiGetContext().getName()
nlapiGetContext().getUser()
nlapiGetContext().getRole()
nlapiGetContext().getRoleId()
nlapiGetContext().getRoleCenter()
nlapiGetContext().getEmail()
nlapiGetContext().getContact()
nlapiGetContext().getCompany()
nlapiGetContext().getContact()
nlapiGetUser()
nlapiGetDepartment()
For details check http://suitecoder.appspot.com/static/api.html
Anyone knows how to make attachment compulsory to the SharePoint custom list?
We are using SharePoint 2007.
There's nothing in the UI / Admin to do this AFAIK.
This arcticle explains how to achieve it with jQuery Link
Edited to correct my previous answer, which on reflection only provided a part answer. The above link is the correct way to achieve this. It shows the mechanism to query the attachments details on the NewForm, ie: before the list item is created, which is the point at which the mandatory function can be applied.
Add the below function as a script in a "Content Editor Web Part" or directly to the form via SharePoint designer. Obviously, this also requires jQuery.
function PreSaveAction(){
var hasAttachment = false;
//There are more then one fileupload inputs on the form
//and one of them will always be blank
$("input[name^='fileupload']").each(function() {
if ($(this).val() != "") {
hasAttachment = true;
}
});
if (hasAttachment){
return true; //OK to save
}else{
alert('An attachment is required!');
return false; //Prevents user from saving
}
}
Better Create a workflow
which will send a mail to last modified by + cc team lead
"if the current item has attachment = no" send mail