public ConnectionsViewModel(EntityReference parentRecordId, Dictionary<string, string> connectToTypes) { ParentRecordId = parentRecordId; ObservableConnection connection = new ObservableConnection(connectToTypes); connection.Record2Id.SetValue(ParentRecordId); ConnectionEdit = (Observable<ObservableConnection>)ValidatedObservableFactory.ValidatedObservable(connection); Connections.OnDataLoaded.Subscribe(Connections_OnDataLoaded); ConnectionEdit.GetValue().OnSaveComplete += ConnectionsViewModel_OnSaveComplete; ObservableConnection.RegisterValidation(Connections.ValidationBinder); }
private static void CheckForSaved() { // Check if we have the id yet EntityReference parent = new EntityReference(new Guid(ParentPage.Data.Entity.GetId()), ParentPage.Data.Entity.GetEntityName(), null); if (ParentPage.Ui.GetFormType() != FormTypes.Create && parent.Id != null) { vm.ParentRecordId.SetValue(parent); vm.Search(); } else { Window.SetTimeout(CheckForSaved, 1000); } }
private static void InitLocalisedContent() { Dictionary<string, string> entityTypes; string id; string logicalName; #if DEBUG id = "C489707F-B5E2-E411-80D5-080027846324"; logicalName = "account"; entityTypes = new Dictionary<string, string>(); entityTypes["account"] = "name"; entityTypes["contact"] = "fullname"; entityTypes["opportunity"] = "name"; #else entityTypes = PageEx.GetWebResourceData(); // The allowed lookup types for the connections - e.g. account, contact, opportunity. This must be passed as a data parameter to the webresource 'account=name&contact=fullname&opportunity=name id = ParentPage.Data.Entity.GetId(); logicalName = ParentPage.Data.Entity.GetEntityName(); #endif EntityReference parent = new EntityReference(new Guid(id), logicalName, null); vm = new ConnectionsViewModel(parent, entityTypes); // Bind Connections grid GridDataViewBinder contactGridDataBinder = new GridDataViewBinder(); List<Column> columns = GridDataViewBinder.ParseLayout(String.Format("{0},record1id,250,{1},record1roleid,250", ResourceStrings.ConnectTo, ResourceStrings.Role)); // Role2Id Column XrmLookupEditor.BindColumn(columns[1], vm.RoleSearchCommand, "connectionroleid", "name", ""); connectionsGrid = contactGridDataBinder.DataBindXrmGrid(vm.Connections, columns, "container", "pager", true, false); connectionsGrid.OnActiveCellChanged.Subscribe(delegate(EventData e, object data) { OnCellChangedEventData eventData = (OnCellChangedEventData)data; vm.SelectedConnection.SetValue((Connection)connectionsGrid.GetDataItem(eventData.Row)); }); // Let's not use a hover button because it get's n the way of the editable grid! //RowHoverPlugin rowButtons = new RowHoverPlugin("gridButtons"); //connectionsGrid.RegisterPlugin(rowButtons); ViewBase.RegisterViewModel(vm); OverrideMetadata(); jQuery.Window.Resize(OnResize); jQuery.OnDocumentReady(delegate() { OnResize(null); vm.Search(); }); }
void jobsViewModel_OnSelectedRowsChanged() { // Get the selected bulk delete SelectedRange[] selectedRows = JobsViewModel.GetSelectedRows(); if (selectedRows.Length > 0) { ScheduledJob job = SelectedJob.GetValue(); dev1_ScheduledJob item = (dev1_ScheduledJob)JobsViewModel.GetItem(selectedRows[0].FromRow.Value); job.RecurrancePattern.SetValue(item.dev1_RecurrancePattern); RecurrancePatternMapper.DeSerialise(job, item.dev1_RecurrancePattern); job.ScheduledJobId.SetValue(item.dev1_ScheduledJobId); job.Name.SetValue(item.dev1_Name); job.StartDate.SetValue(item.dev1_StartDate); job.RecurrancePattern.SetValue(item.dev1_RecurrancePattern); EntityReference entityName = new EntityReference(null,null,item.dev1_WorkflowName); job.WorkflowId.SetValue(entityName); // Update the dependant data grid string fetchXml = @"<fetch version='1.0' output-format='xml-platform' mapping='logical' returntotalrecordcount='true' no-lock='true' distinct='false' count='{0}' paging-cookie='{1}' page='{2}'> <entity name='bulkdeleteoperation'> <attribute name='name' /> <attribute name='createdon' /> <attribute name='asyncoperationid' /> <filter type='and'> <condition attribute='name' operator='like' value='%" + item.dev1_ScheduledJobId.Value + @"%' /> </filter> <link-entity name='asyncoperation' to='asyncoperationid' from='asyncoperationid' link-type='inner' alias='a0'> <attribute name='postponeuntil' alias='asyncoperation_postponeuntil' /> <attribute name='statecode' alias='asyncoperation_statecode' /> <attribute name='statuscode' alias='asyncoperation_statuscode' /> <attribute name='recurrencepattern' alias='asyncoperation_recurrencepattern' /> </link-entity>{3} </entity> </fetch>"; bulkDeleteJobsViewModel.FetchXml = fetchXml; bulkDeleteJobsViewModel.Reset(); bulkDeleteJobsViewModel.Refresh(); } }
/// <summary> /// When an activity row is selected in the /// </summary> /// <param name="entityReference"></param> public void SetCurrentActivity(EntityReference entityReference, int day) { bool hasChanged = (entityReference!=null && entityReference.Id!=null? entityReference.Id.Value : null) != (this.SelectedActivity!=null && this.SelectedActivity.Id!=null? this.SelectedActivity.Id.Value : null); hasChanged = hasChanged || (day != GetSelectedDayIndex()); if (!hasChanged) return; if (day > 0) this.SelectedDay = DateTimeEx.DateAdd(DateInterval.Days, day - 1, this.WeekStart); else this.SelectedDay = null; this.SelectedActivity = entityReference; if (entityReference != null && entityReference.Id != null) this.SelectedActivityID = entityReference.Id; else this.SelectedActivityID = null; RefreshActivityView(); }
/// <summary> /// Checks for an existing N:N relationship between two records by executing a fetch against the relationship /// association table. /// </summary> /// <param name="relationship">The Relationship to evaluate.</param> /// <param name="Entity1">EntityReference for the one of the entities to test.</param> /// <param name="Entity2">EntityReference for the second entity to test.</param> /// <returns>Boolean true if Entity1 and Entity2 have an existing relationship.</returns> public static bool DoesNNAssociationExist(Relationship relationship, EntityReference Entity1, EntityReference Entity2) { string fetchXml = "<fetch mapping='logical'>" + " <entity name='" + relationship.SchemaName + "'>" + " <all-attributes />" + " <filter>" + " <condition attribute='" + Entity1.LogicalName + "id' operator='eq' value ='" + Entity1.Id.Value + "' />" + " <condition attribute='" + Entity2.LogicalName + "id' operator='eq' value='" + Entity2.Id.Value + "' />" + " </filter>" + " </entity>" + "</fetch>"; EntityCollection result = OrganizationServiceProxy.RetrieveMultiple(fetchXml); if (result.Entities.Count > 0) return true; return false; }
public ConnectionsViewModel(EntityReference parentRecordId, string[] connectToTypes, int pageSize, FetchQuerySettings view) { Connections = new EntityDataViewModel(pageSize, typeof(Connection), true); if (view != null) { _viewFetchXml = QueryParser.GetFetchXmlParentFilter(view, "record1id"); // Set initial sort _defaultSortCol=new SortCol(view.OrderByAttribute, !view.OrderByDesending); } ParentRecordId.SetValue(parentRecordId); ObservableConnection connection = new ObservableConnection(connectToTypes); connection.Record2Id.SetValue(parentRecordId); ConnectionEdit = (Observable<ObservableConnection>)ValidatedObservableFactory.ValidatedObservable(connection); Connections.OnDataLoaded.Subscribe(Connections_OnDataLoaded); ConnectionEdit.GetValue().OnSaveComplete += ConnectionsViewModel_OnSaveComplete; ObservableConnection.RegisterValidation(Connections.ValidationBinder); AllowAddNew = Knockout.DependentObservable<bool>(AllowAddNewComputed); }
public static EntityReference GetOppositeRole(EntityReference role, EntityReference record) { EntityReference oppositeRole = null; int? etc = GetEntityTypeCodeFromName(record.LogicalName); // Add the opposite connection role string getOppositeRole = String.Format(@"<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='true' count='1'> <entity name='connectionrole'> <attribute name='category' /> <attribute name='name' /> <attribute name='connectionroleid' /> <attribute name='statecode' /> <filter type='and'> <condition attribute='statecode' operator='eq' value='0' /> </filter> <link-entity name='connectionroleassociation' from='connectionroleid' to='connectionroleid' intersect='true'> <link-entity name='connectionrole' from='connectionroleid' to='associatedconnectionroleid' alias='ad'> <filter type='and'> <condition attribute='connectionroleid' operator='eq' value='{0}' /> </filter> </link-entity> <link-entity name='connectionroleobjecttypecode' from='connectionroleid' to='connectionroleid' intersect='true' > <filter type='or' > <condition attribute='associatedobjecttypecode' operator='eq' value='{1}' /> <condition attribute='associatedobjecttypecode' operator='eq' value='0' /> <!-- All types--> </filter> </link-entity> </link-entity> </entity> </fetch>", role.Id.ToString(), etc); EntityCollection results = (EntityCollection)OrganizationServiceProxy.RetrieveMultiple(getOppositeRole); if (results.Entities.Count > 0) { oppositeRole = results.Entities[0].ToEntityReference(); } return oppositeRole; }
public UserOrTeam GetUserOrTeamReference(EntityReference userOrTeamId) { UserOrTeam user; // Add to the list of users if not already if (!userOrTeamIds.ContainsKey(userOrTeamId.Id.ToString())) { user = new UserOrTeam(); user.Id = userOrTeamId.Id.ToString(); user.IsTeam = (userOrTeamId.LogicalName == "team"); user.LogicalName = user.IsTeam ? "team" : "systemuser"; user.FullName = null; user.Parties = new Dictionary<string, EntityReference>(); userOrTeamIds[user.Id] = user; } else { user = userOrTeamIds[userOrTeamId.Id.ToString()]; } return user; }
private bool IsAlsoAUserFromEntityReference(EntityReference record) { Entity entityRecord = new Entity(record.LogicalName); entityRecord.Id = record.Id.Value; return IsAlsoAUser(entityRecord); }
private PendingLink AddPendingLink(EntityNode newNode, EntityReference pendingEntity) { Trace("Add Pending Link {0} {1} -> {2} {3}", new object[] { ((Entity)newNode.SourceData).LogicalName, newNode.Name, pendingEntity.LogicalName, pendingEntity.Id }); PendingLink pending = new PendingLink(); pending.Source = newNode; pending.Target = pendingEntity; if (!pendingLinks.ContainsKey(pendingEntity.LogicalName)) { pendingLinks[pendingEntity.LogicalName] = new Dictionary<string, PendingLink>(); } if (!IsAlsoAUserFromEntityReference(pendingEntity)) { pendingLinks[pendingEntity.LogicalName][pendingEntity.Id.ToString()] = pending; } return pending; }
public override void LoadValue(Dictionary<string, object> item) { _originalValue = (EntityReference)item[_args.Column.Field]; if (_originalValue != null) { _value = new EntityReference(_originalValue.Id, _originalValue.LogicalName, _originalValue.Name); _input.Value(_originalValue.Name); } }
/// <summary> /// When an activity row is selected in the /// </summary> /// <param name="entityReference"></param> public void SetCurrentActivity(EntityReference entityReference, int day) { if (day > 0) this.SelectedDay = DateTimeEx.DateAdd(DateInterval.Days, day - 1, this.WeekStart); else this.SelectedDay = null; this.SelectedActivity = entityReference; if (entityReference != null && entityReference.Id != null) this.SelectedActivityID = entityReference.Id; else this.SelectedActivityID = null; RefreshActivityView(); }
/// <summary> /// Gets an instance of a <c>EntityReference</c> type that has its type property set. /// </summary> /// <param name="field">The current <c>DefinitionField</c> being mapped. This determines the type property when creating a <c>Lookup</c> instance.</param> /// <returns>A new instance of a <c>EntityReference</c> type object.</returns> private EntityReference GetReferenceInstanceType(FieldDefinition field) { // set the returned reference to a Lookup initialy, since that is the most common crm reference entity EntityReference reference = new EntityReference(); this.SetLookupType(field, reference); return reference; }
/// <summary> /// Sets the type property on a given <c>Lookup</c> instance. /// </summary> /// <param name="field">The field who's name will determine that type of the <c>Lookup</c>.</param> /// <param name="returnedLookup">The <c>Lookup</c> to set the type property on.</param> protected virtual void SetLookupType(FieldDefinition field, EntityReference returnedLookup) { if (field == null || returnedLookup == null) { throw new AdapterException(string.Format(CultureInfo.CurrentCulture, Resources.ArgumentNullExceptionMessage)) { ExceptionId = AdapterException.SystemExceptionGuid }; } returnedLookup.LogicalName = field.FindAttribute(CRM2011AdapterUtilities.LookupType).Value; }
public static string getCurrencySymbol(EntityReference currencyid) { if (currencyid != null && currencyid.Id!=null && currencyid.Id.Value!=null) { return NumberEx.GetCurrencySymbol(currencyid.Id); } return string.Empty; }
public XrmLookupEditor(EditorArguments args) : base(args) { XrmLookupEditor self = this; _args = args; _container = jQuery.FromHtml("<div><table class='inline-edit-container' cellspacing='0' cellpadding='0'><tr><td><INPUT type=text class='sparkle-input-inline' /></td><td class='lookup-button-td'><input type=button class='sparkle-lookup-button' /></td></tr></table></div>"); _container.AppendTo(_args.Container); jQueryObject inputField = _container.Find(".sparkle-input-inline"); jQueryObject selectButton = _container.Find(".sparkle-lookup-button"); _input = inputField; _input.Focus().Select(); _autoComplete = inputField.Plugin<AutoCompleteObject>(); AutoCompleteOptions options = new AutoCompleteOptions(); options.Position = new Dictionary<string, object>("collision", "fit"); options.MinLength = 100000; options.Delay = 0; // TODO- set to something that makes sense XrmLookupEditorOptions editorOptions = (XrmLookupEditorOptions)args.Column.Options; bool justSelected = false; options.Select = delegate(jQueryEvent e, AutoCompleteSelectEvent uiEvent) { if (_value == null) _value = new EntityReference(null,null,null); // Note we assume that the binding has added an array of string items AutoCompleteItem item = (AutoCompleteItem)uiEvent.Item; EntityReference itemRef = (EntityReference)item.Value; if (itemRef.LogicalName == "footerlink") { XrmLookupEditorButton button = editorOptions.footerButton; button.OnClick(item); } else { string value = item.Label; _input.Value(value); _value.Id = itemRef.Id; _value.Name = itemRef.Name; _value.LogicalName = ((EntityReference)item.Value).LogicalName; justSelected = true; } Script.Literal("return false;"); }; options.Focus = delegate(jQueryEvent e, AutoCompleteFocusEvent uiEvent) { // Prevent the value being updated in the text box as we scroll through the results Script.Literal("return false;"); }; options.Open = delegate(jQueryEvent e, jQueryObject o) { self._searchOpen = true; if (editorOptions.showFooter && totalRecordsReturned>0) { WidgetObject menu = (WidgetObject)Script.Literal("{0}.autocomplete({1})", _input, "widget"); AddFooter(menu,totalRecordsReturned); } }; options.Close = delegate(jQueryEvent e, jQueryObject o) { self._searchOpen = false; WidgetObject menu = (WidgetObject)Script.Literal("{0}.autocomplete({1})", _input, "widget"); jQueryObject footer = menu.Next(); if (footer.Length > 0 || footer.HasClass("sparkle-menu-footer")) { footer.Hide(); } }; // If there multiple names, add them to the columnAttributes string[] columns = editorOptions.nameAttribute.Split(","); if (columns.Length > 1) { editorOptions.columns = columns; editorOptions.nameAttribute = columns[0]; } // wire up source to CRM search Action<AutoCompleteRequest, Action<AutoCompleteItem[]>> queryDelegate = delegate(AutoCompleteRequest request, Action<AutoCompleteItem[]> response) { // Get the option set values editorOptions.queryCommand(request.Term, delegate(EntityCollection fetchResult) { if (fetchResult.TotalRecordCount > fetchResult.Entities.Count) { totalRecordsReturned = fetchResult.TotalRecordCount; } else { totalRecordsReturned = fetchResult.Entities.Count; } int recordsFound = fetchResult.Entities.Count; bool noRecordsFound = recordsFound == 0; XrmLookupEditorButton button = editorOptions.footerButton; bool footerButton = (button != null); AutoCompleteItem[] results = new AutoCompleteItem[recordsFound + (footerButton ? 1 : 0) + (noRecordsFound ? 1 :0) ]; for (int i = 0; i < recordsFound; i++) { results[i] = new AutoCompleteItem(); results[i].Label = (string)fetchResult.Entities[i].GetAttributeValue(editorOptions.nameAttribute); EntityReference id = new EntityReference(null, null, null); id.Name = results[i].Label; id.LogicalName = fetchResult.Entities[i].LogicalName; id.Id = (Guid)fetchResult.Entities[i].GetAttributeValue(editorOptions.idAttribute); results[i].Value = id; XrmLookupBinding.GetExtraColumns(editorOptions.columns, fetchResult, results, i); string typeCodeName = fetchResult.Entities[i].LogicalName; // Get the type code from the name to find the icon if (!string.IsNullOrEmpty(editorOptions.typeCodeAttribute)) { typeCodeName = fetchResult.Entities[i].GetAttributeValue(editorOptions.typeCodeAttribute).ToString(); } if (editorOptions.showImage) { results[i].Image = MetadataCache.GetSmallIconUrl(typeCodeName); } } int itemsCount = recordsFound; if (noRecordsFound) { AutoCompleteItem noRecordsItem = new AutoCompleteItem(); noRecordsItem.Label = SparkleResourceStrings.NoRecordsFound; results[itemsCount] = noRecordsItem; itemsCount++; } if (footerButton) { // Add the add new AutoCompleteItem addNewLink = new AutoCompleteItem(); addNewLink.Label = button.Label; addNewLink.Image = button.Image; addNewLink.ColumnValues = null; addNewLink.Value = new Entity("footerlink"); results[itemsCount] = addNewLink; } response(results); // Disable it now so typing doesn't trigger a search AutoCompleteOptions disableOption = new AutoCompleteOptions(); disableOption.MinLength = 100000; _autoComplete.AutoComplete(disableOption); }); }; options.Source = queryDelegate; inputField = _autoComplete.AutoComplete(options); RenderItemDelegate autoCompleteDelegates = ((RenderItemDelegate)Script.Literal("{0}.data('ui-autocomplete')", inputField)); autoCompleteDelegates._renderItem = delegate(object ul, AutoCompleteItem item) { if(item.Value==item.Label) { return (object)jQuery.Select("<li class='ui-state-disabled'>"+item.Label+"</li>").AppendTo((jQueryObject)ul); } string itemHtml = "<a class='sparkle-menu-item'>"; // Allow for no image by passing false to 'ShowImage' on the XrmLookupEditorOptions options if (item.Image != null) { itemHtml += "<span class='sparkle-menu-item-img'><img src='" + item.Image + "'/></span>"; } itemHtml += "<span class='sparkle-menu-item-label'>" + item.Label + "</span><br/>"; if (item.ColumnValues != null && item.ColumnValues.Length > 0) { foreach (string value in item.ColumnValues) { itemHtml += "<span class='sparkle-menu-item-moreinfo'>" + value + "</span>"; } } itemHtml += "</a>"; return (object)jQuery.Select("<li>").Append(itemHtml).AppendTo((jQueryObject)ul); }; // Add the click binding to show the drop down selectButton.Click(delegate(jQueryEvent e) { AutoCompleteOptions enableOption = new AutoCompleteOptions(); enableOption.MinLength = 0; _autoComplete.AutoComplete(enableOption); _autoComplete.AutoComplete(AutoCompleteMethod.Search, inputField.GetValue()); }); // Bind return to searching _input.Keydown(delegate(jQueryEvent e) { if (e.Which == 13 && !justSelected) // Return pressed - but we want to do a search not move to the next cell { if (inputField.GetValue().Length > 0) selectButton.Click(); else { // Set value to null _value = null; return; } } else if (e.Which == 13) { return; } if (self._searchOpen) { switch (e.Which) { case 9: case 13: // Return case 38: // Up - don't navigate - but use the dropdown to select search results case 40: // Down - don't navigate - but use the dropdown to select search results e.PreventDefault(); e.StopPropagation(); break; } } else { switch (e.Which) { case 13: // Return e.PreventDefault(); e.StopPropagation(); break; } } justSelected = false; }); }
private void UnSelectEntity(EntityReference entity) { string key = GetID(entity.Id.ToString()); EntityNode node = vm.idIndex[key]; D3.Select("#" + key).SelectAll(".entityImage").Attr("filter", "url(#no-glow)"); D3.Select("#" + key).SelectAll(".entityImage").Transition().Attr("transform", "scale(1)"); }
private void SelectEntity(EntityReference entity) { string key = GetID(entity.Id.ToString()); D3.Select("#" + key).SelectAll(".entityImage").Attr("filter", "url(#selected-glow)"); D3.Select("#" + key).SelectAll(".entityImage").Transition().Attr("transform", "scale(0.6)").Transition().Attr("transform", "scale(2)"); }
public override void Init(System.Html.Element element, Func<object> valueAccessor, Func<System.Collections.Dictionary> allBindingsAccessor, object viewModel, object context) { jQueryObject container = jQuery.FromElement(element); jQueryObject inputField = container.Find(".sparkle-input-lookup-part"); jQueryObject selectButton = container.Find(".sparkle-input-lookup-button-part"); EntityReference _value = new EntityReference(null, null, null); AutoCompleteOptions options = new AutoCompleteOptions(); options.MinLength = 100000; // Don't enable type down - use search button (or return) options.Delay = 0; options.Position = new Dictionary<string, object>("collision", "fit"); bool justSelected = false; // Set the value when selected options.Select = delegate(jQueryEvent e, AutoCompleteSelectEvent uiEvent) { // Note we assume that the binding has added an array of string items AutoCompleteItem item = (AutoCompleteItem)uiEvent.Item; if (_value == null) _value = new EntityReference(null, null, null); string value = item.Label; inputField.Value(value); _value.Id = ((Guid)item.Value); _value.Name = item.Label; _value.LogicalName = (string)item.Data; justSelected = true; TrySetObservable(valueAccessor, inputField, _value); Script.Literal("return false;"); }; // Get the query command Action<string, Action<EntityCollection>> queryCommand = (Action<string, Action<EntityCollection>>)((object)allBindingsAccessor()["queryCommand"]); string nameAttribute = ((string)allBindingsAccessor()["nameAttribute"]); string idAttribute = ((string)allBindingsAccessor()["idAttribute"]); string typeCodeAttribute = ((string)allBindingsAccessor()["typeCodeAttribute"]); string[] columnAttributes = null; // If there multiple names, add them to the columnAttributes string[] columns = nameAttribute.Split(","); if (columns.Length > 1) { columnAttributes = columns; nameAttribute = columnAttributes[0]; } // wire up source to CRM search Action<AutoCompleteRequest, Action<AutoCompleteItem[]>> queryDelegate = delegate(AutoCompleteRequest request, Action<AutoCompleteItem[]> response) { Action<EntityCollection> queryCallBack = delegate(EntityCollection fetchResult) { AutoCompleteItem[] results = new AutoCompleteItem[fetchResult.Entities.Count]; for (int i = 0; i < fetchResult.Entities.Count; i++) { results[i] = new AutoCompleteItem(); results[i].Label = (string)fetchResult.Entities[i].GetAttributeValue(nameAttribute); results[i].Value = fetchResult.Entities[i].GetAttributeValue(idAttribute); results[i].Data = fetchResult.Entities[i].LogicalName; GetExtraColumns(columnAttributes, fetchResult, results, i); string typeCodeName = fetchResult.Entities[i].LogicalName; // Get the type code from the name to find the icon if (!string.IsNullOrEmpty(typeCodeAttribute)) { typeCodeName = fetchResult.Entities[i].GetAttributeValue(typeCodeAttribute).ToString(); } results[i].Image = MetadataCache.GetSmallIconUrl(typeCodeName); } response(results); // Disable it now so typing doesn't trigger a search AutoCompleteOptions disableOption = new AutoCompleteOptions(); disableOption.MinLength = 100000; inputField.Plugin<AutoCompleteObject>().AutoComplete(disableOption); }; // Call the function with the correct 'this' context Script.Literal("{0}.call({1}.$parent,{2},{3})",queryCommand, context, request.Term, queryCallBack); }; options.Source = queryDelegate; options.Focus = delegate(jQueryEvent e, AutoCompleteFocusEvent uiEvent) { // Prevent the value being updated in the text box we scroll through the results Script.Literal("return false;"); }; inputField = inputField.Plugin<AutoCompleteObject>().AutoComplete(options); // Set render template ((RenderItemDelegate)Script.Literal("{0}.data('ui-autocomplete')", inputField))._renderItem = delegate(object ul, AutoCompleteItem item) { string html = "<a class='sparkle-menu-item'><span class='sparkle-menu-item-img'><img src='" + item.Image + "'/></span><span class='sparkle-menu-item-label'>" + item.Label + "</span><br>"; if (item.ColumnValues != null && item.ColumnValues.Length > 0) { foreach (string value in item.ColumnValues) { html += "<span class='sparkle-menu-item-moreinfo'>" + value + "</span>"; } } html += "</a>"; return (object)jQuery.Select("<li>").Append(html).AppendTo((jQueryObject)ul); }; // Add the click binding to show the drop down selectButton.Click(delegate(jQueryEvent e) { AutoCompleteOptions enableOption = new AutoCompleteOptions(); enableOption.MinLength = 0; inputField.Focus(); inputField.Plugin<AutoCompleteObject>().AutoComplete(enableOption); inputField.Plugin<AutoCompleteObject>().AutoComplete(AutoCompleteMethod.Search); }); // handle the field changing inputField.Change(delegate(jQueryEvent e) { if (inputField.GetValue() != _value.Name) TrySetObservable(valueAccessor, inputField, null); }); Action disposeCallBack = delegate() { if ((bool)Script.Literal("$({0}).data('ui-autocomplete')!=undefined", inputField)) { //inputField.Plugin<AutoCompleteObject>().AutoComplete(AutoCompleteMethod.Destroy); Script.Literal("$({0}).autocomplete(\"destroy\")", inputField); } }; //handle disposal (if KO removes by the template binding) Script.Literal("ko.utils.domNodeDisposal.addDisposeCallback({0}, {1})", element, (object)disposeCallBack); Knockout.BindingHandlers["validationCore"].Init(element, valueAccessor, allBindingsAccessor, null, null); // Bind return to searching inputField.Keydown(delegate(jQueryEvent e) { if (e.Which == 13 && !justSelected) // Return pressed - but we want to do a search not move to the next cell { selectButton.Click(); } else if (e.Which == 13) { return; } switch (e.Which) { case 13: // Return case 38: // Up - don't navigate - but use the dropdown to select search results case 40: // Down - don't navigate - but use the dropdown to select search results e.PreventDefault(); e.StopPropagation(); break; } justSelected = false; }); //Script.Literal("return { controlsDescendantBindings: true };"); }
public override void Init(System.Html.Element element, Func<object> valueAccessor, Func<System.Collections.Dictionary> allBindingsAccessor, object viewModel, object context) { XrmLookupEditorButton footerButton = (XrmLookupEditorButton)allBindingsAccessor()["footerButton"]; bool showFooter = (bool)allBindingsAccessor()["showFooter"]; jQueryObject container = jQuery.FromElement(element); jQueryObject inputField = container.Find(".sparkle-input-lookup-part"); jQueryObject selectButton = container.Find(".sparkle-input-lookup-button-part"); EntityReference _value = new EntityReference(null, null, null); AutoCompleteOptions options = new AutoCompleteOptions(); options.MinLength = 100000; // Don't enable type down - use search button (or return) options.Delay = 0; options.Position = new Dictionary<string, object>("collision", "fit"); bool justSelected = false; int totalRecordsReturned = 0; Action<AutoCompleteItem,bool> setValue = delegate(AutoCompleteItem item,bool setFocus) { if (_value == null) _value = new EntityReference(null, null, null); string value = item.Label; inputField.Value(value); _value.Id = ((Guid)item.Value); _value.Name = item.Label; _value.LogicalName = (string)item.Data; justSelected = true; TrySetObservable(valueAccessor, inputField, _value, setFocus); }; // Set the value when selected options.Select = delegate(jQueryEvent e, AutoCompleteSelectEvent uiEvent) { // Note we assume that the binding has added an array of string items AutoCompleteItem item = (AutoCompleteItem)uiEvent.Item; string data = ((string)item.Data); if (data == "footerlink" || data==null) { footerButton.OnClick(item); e.PreventDefault(); e.StopImmediatePropagation(); Script.Literal("return false;"); } else { setValue(item, true); Script.Literal("return false;"); } }; options.Open = delegate(jQueryEvent e, jQueryObject o) { if (showFooter && totalRecordsReturned>0) { WidgetObject menu = (WidgetObject)Script.Literal("{0}.autocomplete({1})", inputField, "widget"); XrmLookupEditor.AddFooter(menu, totalRecordsReturned); } }; options.Close = delegate(jQueryEvent e, jQueryObject o) { WidgetObject menu = (WidgetObject)Script.Literal("{0}.autocomplete({1})", inputField, "widget"); jQueryObject footer = menu.Next(); if (footer.Length > 0 || footer.HasClass("sparkle-menu-footer")) { footer.Hide(); } }; // Get the query command Action<string, Action<EntityCollection>> queryCommand = (Action<string, Action<EntityCollection>>)((object)allBindingsAccessor()["queryCommand"]); string nameAttribute = ((string)allBindingsAccessor()["nameAttribute"]); string idAttribute = ((string)allBindingsAccessor()["idAttribute"]); string typeCodeAttribute = ((string)allBindingsAccessor()["typeCodeAttribute"]); string[] columnAttributes = null; // If there multiple names, add them to the columnAttributes string[] columns = nameAttribute.Split(","); if (columns.Length > 1) { columnAttributes = columns; nameAttribute = columnAttributes[0]; } // wire up source to CRM search Action<AutoCompleteRequest, Action<AutoCompleteItem[]>> queryDelegate = delegate(AutoCompleteRequest request, Action<AutoCompleteItem[]> response) { Action<EntityCollection> queryCallBack = delegate(EntityCollection fetchResult) { int recordsFound = fetchResult.Entities.Count; bool noRecordsFound = recordsFound == 0; AutoCompleteItem[] results = new AutoCompleteItem[recordsFound + (footerButton!=null ? 1 : 0) + (noRecordsFound ? 1 : 0)]; for (int i = 0; i < recordsFound; i++) { results[i] = new AutoCompleteItem(); results[i].Label = (string)fetchResult.Entities[i].GetAttributeValue(nameAttribute); results[i].Value = fetchResult.Entities[i].GetAttributeValue(idAttribute); results[i].Data = fetchResult.Entities[i].LogicalName; GetExtraColumns(columnAttributes, fetchResult, results, i); string typeCodeName = fetchResult.Entities[i].LogicalName; // Get the type code from the name to find the icon if (!string.IsNullOrEmpty(typeCodeAttribute)) { typeCodeName = fetchResult.Entities[i].GetAttributeValue(typeCodeAttribute).ToString(); } results[i].Image = MetadataCache.GetSmallIconUrl(typeCodeName); } if (fetchResult.TotalRecordCount > fetchResult.Entities.Count) { totalRecordsReturned = fetchResult.TotalRecordCount; } else { totalRecordsReturned = fetchResult.Entities.Count; } int itemsCount = recordsFound; if (noRecordsFound) { AutoCompleteItem noRecordsItem = new AutoCompleteItem(); noRecordsItem.Label = SparkleResourceStrings.NoRecordsFound; results[itemsCount] = noRecordsItem; itemsCount++; } if (footerButton != null) { // Add the add new AutoCompleteItem addNewLink = new AutoCompleteItem(); addNewLink.Label = footerButton.Label; addNewLink.Image = footerButton.Image; addNewLink.ColumnValues = null; addNewLink.Data = "footerlink"; results[itemsCount] = addNewLink; } response(results); // Disable it now so typing doesn't trigger a search AutoCompleteOptions disableOption = new AutoCompleteOptions(); disableOption.MinLength = 100000; inputField.Plugin<AutoCompleteObject>().AutoComplete(disableOption); }; // Call the function with the correct 'this' context Script.Literal("{0}.call({1}.$parent,{2},{3})",queryCommand, context, request.Term, queryCallBack); }; options.Source = queryDelegate; options.Focus = delegate(jQueryEvent e, AutoCompleteFocusEvent uiEvent) { // Prevent the value being updated in the text box we scroll through the results Script.Literal("return false;"); }; inputField = inputField.Plugin<AutoCompleteObject>().AutoComplete(options); // Set render template ((RenderItemDelegate)Script.Literal("{0}.data('ui-autocomplete')", inputField))._renderItem = delegate(object ul, AutoCompleteItem item) { if (item.Data==null) { return (object)jQuery.Select("<li class='ui-state-disabled'>" + item.Label + "</li>").AppendTo((jQueryObject)ul); } string html = "<a class='sparkle-menu-item'><span class='sparkle-menu-item-img'>"; if (item.Image!=null) { html += @"<img src='" + item.Image + "'/>"; } html += @"</span><span class='sparkle-menu-item-label'>" + item.Label + "</span><br>"; if (item.ColumnValues != null && item.ColumnValues.Length > 0) { foreach (string value in item.ColumnValues) { html += "<span class='sparkle-menu-item-moreinfo'>" + value + "</span>"; } } html += "</a>"; return (object)jQuery.Select("<li>").Append(html).AppendTo((jQueryObject)ul); }; // Add the click binding to show the drop down selectButton.Click(delegate(jQueryEvent e) { AutoCompleteOptions enableOption = new AutoCompleteOptions(); enableOption.MinLength = 0; inputField.Focus(); inputField.Plugin<AutoCompleteObject>().AutoComplete(enableOption); inputField.Plugin<AutoCompleteObject>().AutoComplete(AutoCompleteMethod.Search); }); // handle the field changing inputField.Change(delegate(jQueryEvent e) { string inputValue = inputField.GetValue(); if (inputValue != _value.Name) { // The name is different from the name of the lookup reference // search to see if we can auto resolve it TrySetObservable(valueAccessor, inputField, null,false); AutoCompleteRequest lookup = new AutoCompleteRequest(); lookup.Term = inputValue; Action<AutoCompleteItem[]> lookupResults = delegate(AutoCompleteItem[] results) { int selectableItems =0; // If there is only one, then auto-set if (results != null) { foreach (AutoCompleteItem item in results) { if (isItemSelectable(item)) { selectableItems++; } if (selectableItems > 2) break; } } if (selectableItems == 1) { // There is only a single value so set it now setValue(results[0], false); } else { inputField.Value(String.Empty); } }; queryDelegate(lookup, lookupResults); } }); Action disposeCallBack = delegate() { if ((bool)Script.Literal("$({0}).data('ui-autocomplete')!=undefined", inputField)) { Script.Literal("$({0}).autocomplete(\"destroy\")", inputField); } }; //handle disposal (if KO removes by the template binding) Script.Literal("ko.utils.domNodeDisposal.addDisposeCallback({0}, {1})", element, (object)disposeCallBack); Knockout.BindingHandlers["validationCore"].Init(element, valueAccessor, allBindingsAccessor, null, null); // Bind return to searching inputField.Keydown(delegate(jQueryEvent e) { if (e.Which == 13 && !justSelected) // Return pressed - but we want to do a search not move to the next cell { selectButton.Click(); } else if (e.Which == 13) { return; } switch (e.Which) { case 13: // Return case 38: // Up - don't navigate - but use the dropdown to select search results case 40: // Down - don't navigate - but use the dropdown to select search results e.PreventDefault(); e.StopPropagation(); break; } justSelected = false; }); //Script.Literal("return { controlsDescendantBindings: true };"); }
/// <summary> /// Checks for an existing N:N relationship between two records by executing a fetch against the relationship /// association table. /// </summary> /// <param name="relationship">The Relationship to evaluate.</param> /// <param name="Entity1">EntityReference for the one of the entities to test.</param> /// <param name="Entity2">EntityReference for the second entity to test.</param> /// <returns>Boolean true if Entity1 and Entity2 have an existing relationship.</returns> public static bool DoesNNAssociationExist(Relationship relationship, EntityReference Entity1, EntityReference Entity2) { string fetchXml = "<fetch mapping='logical'>" + " <entity name='" + relationship.SchemaName + "'>" + " <all-attributes />" + " <filter>" + " <condition attribute='" + Entity1.LogicalName + "id' operator='eq' value ='" + Entity1.Id.Value + "' />" + " <condition attribute='" + Entity2.LogicalName + "id' operator='eq' value='" + Entity2.Id.Value + "' />" + " </filter>" + " </entity>" + "</fetch>"; EntityCollection result = OrganizationServiceProxy.RetrieveMultiple(fetchXml); if (result.Entities.Count > 0) { return(true); } return(false); }
public override void LoadValue(Dictionary<string, object> item) { _originalValue = (EntityReference)item[_args.Column.Field]; _value = _originalValue; if (_originalValue!=null) _input.Value(_originalValue.Name); }
/// <summary> /// Assigns an object to be the value for a property on a <c>Entity</c>. /// </summary> /// <param name="reference">The <c>object</c> be assigned as the value</param> /// <param name="entity">The <c>Entity</c> to be assigned to</param> /// <param name="propertyToBeAssignedValue">The name of the property on the <c>Entity</c> to assign the supplied object to</param> /// <remarks>If the <c>object</c> is null, nothing is assigned to the property</remarks> protected static void AssignReferencePropertyValue(EntityReference reference, Entity entity, string propertyToBeAssignedValue) { if (entity == null) { throw new AdapterException(string.Format(CultureInfo.CurrentCulture, Resources.ArgumentNullExceptionMessage), new ArgumentNullException("entity")) { ExceptionId = AdapterException.SystemExceptionGuid }; } // These checks are only for updates if (entity.Contains(CRM2011AdapterUtilities.IsNew) && !(bool)entity[CRM2011AdapterUtilities.IsNew]) { if (entity.Contains(propertyToBeAssignedValue)) { if (reference == null) { // Since the reference entity supplied is null, remove the property from the retrieved entity to avoid a potential update storm entity.Attributes.Remove(propertyToBeAssignedValue); } else if (((EntityReference)entity[propertyToBeAssignedValue]).Id == reference.Id) { // Since this property has the same value we are trying to assign it, remove it to avoid a potential update storm entity.Attributes.Remove(propertyToBeAssignedValue); } else { entity[propertyToBeAssignedValue] = reference; } return; } } // This is a new instance or the existing instance did not contain this property when it was retrieved if (reference != null) { entity[propertyToBeAssignedValue] = reference; } }
private EntityLink AddLinkIfLoaded(EntityNode target, EntityReference source, bool delayAdd) { EntityNode sourceNode = GetEntityFromReference(source); if (sourceNode != null) { // Create Link EntityLink link = AddLink(sourceNode, target, delayAdd); return link; } return null; }
private static void TrySetObservable(Func<object> valueAccessor, jQueryObject inputField, EntityReference value, bool setFocus) { Observable<EntityReference> observable = (Observable<EntityReference>)valueAccessor(); bool isValid = true; observable.SetValue(value); if (((string)Script.Literal("typeof({0}.isValid)", observable)) != "undefined") { isValid = ((IValidatedObservable)observable).IsValid() == true; } if (isValid && setFocus) { // Ensure the field is reinitialised inputField.Blur(); inputField.Focus(); } }
/// <summary> /// Used to actually create instances of the child entities in an inherited class. /// </summary> /// <param name="parentKey">The <c>Key</c> of the parent entity.</param> /// <param name="childEntity">The child entity to be created in the form of a <c>Entity</c>.</param> /// <param name="collectionFieldName">The name of the field in the <c>ObjectProvider</c>'s configuration file that is being mapped currently.</param> protected virtual void CreateUpdateChildInstanceForField(Guid parentKey, Entity childEntity, string collectionFieldName) { if (parentKey == null || childEntity == null) { throw new AdapterException(string.Format(CultureInfo.CurrentCulture, Resources.ArgumentNullExceptionMessage)) { ExceptionId = AdapterException.SystemExceptionGuid }; } if (!childEntity.Contains(childEntity.LogicalName + "id")) { // Set a default value of parnet entity name + id string parentAttribName = this.ProvidedEntityName + "id"; // Select the child entity's type def TypeDefinition childType = this.ObjectDefinition.Types.SingleOrDefault(td => td.Name == childEntity.LogicalName); if (childType != null) { // Query to limit the number of fields on the child type we iterate over when looking for the parent field var childFields = from childField in childType.Children where childField.AdditionalAttributes != null select childField; foreach (FieldDefinition fieldDef in childFields) { XmlAttribute attrib = fieldDef.AdditionalAttributes.FirstOrDefault(at => at.Name == CRM2011AdapterUtilities.IsParentField); if (attrib != null && attrib.Value.ToUpperInvariant() == true.ToString().ToUpperInvariant()) { // Set the parent field's name and break out of the foreach loop parentAttribName = fieldDef.Name; break; } } } childEntity[parentAttribName] = new EntityReference(this.ProvidedEntityName, parentKey); this.CreateNewEntity(childEntity); } else { this.UpdateEntity(childEntity); } }
private static void InitLocalisedContent() { Dictionary<string, string> parameters; string id; string logicalName; int pageSize = 10; string defaultView=null; #if DEBUG id = "C489707F-B5E2-E411-80D5-080027846324"; logicalName = "account"; parameters = new Dictionary<string, string>(); #else parameters = PageEx.GetWebResourceData(); // The allowed lookup types for the connections - e.g. account, contact, opportunity. This must be passed as a data parameter to the webresource 'account=name&contact=fullname&opportunity=name id = ParentPage.Data.Entity.GetId(); logicalName = ParentPage.Data.Entity.GetEntityName(); ParentPage.Data.Entity.AddOnSave(CheckForSaved); #endif EntityReference parent = new EntityReference(new Guid(id), logicalName, null); string entities = "account,contact,opportunity,systemuser"; foreach (string key in parameters.Keys) { switch (key.ToLowerCase()) { case "entities": entities = parameters[key]; break; case "pageSize": pageSize = int.Parse(parameters[key]); break; case "view": defaultView = parameters[key]; break; case "category": category = int.Parse(parameters[key]); break; } } // Get the view QueryParser queryParser = new QueryParser(new string[] {"connection"}); queryParser.GetView("connection", defaultView); queryParser.QueryMetadata(); EntityQuery connectionViews = queryParser.EntityLookup["connection"]; string viewName = connectionViews.Views.Keys[0]; FetchQuerySettings view = connectionViews.Views[viewName]; vm = new ConnectionsViewModel(parent, entities.Split(","), pageSize, view); // Bind Connections grid GridDataViewBinder connectionsGridDataBinder = new GridDataViewBinder(); List<Column> columns = view.Columns; // Role2Id Column - provided it is in the view! foreach (Column col in columns) { switch (col.Field) { case "record2roleid": XrmLookupEditor.BindColumn(col, vm.RoleSearchCommand, "connectionroleid", "name,category", ""); break; case "description": XrmTextEditor.BindColumn(col); break; case "effectivestart": case "effectiveend": XrmDateEditor.BindColumn(col, true); break; } } connectionsGrid = connectionsGridDataBinder.DataBindXrmGrid(vm.Connections, columns, "container", "pager", true, false); connectionsGrid.OnActiveCellChanged.Subscribe(delegate(EventData e, object data) { OnCellChangedEventData eventData = (OnCellChangedEventData)data; vm.SelectedConnection.SetValue((Connection)connectionsGrid.GetDataItem(eventData.Row)); }); connectionsGridDataBinder.BindClickHandler(connectionsGrid); // Let's not use a hover button because it get's in the way of the editable grid! //RowHoverPlugin rowButtons = new RowHoverPlugin("gridButtons"); //connectionsGrid.RegisterPlugin(rowButtons); ViewBase.RegisterViewModel(vm); OverrideMetadata(); jQuery.Window.Resize(OnResize); jQuery.OnDocumentReady(delegate() { OnResize(null); vm.Search(); }); }
/// <summary> /// Gets a new <c>EntityReference</c> object that represents an instance of an entity within the target system. /// </summary> /// <param name="field">The field that is currently being set to a <c>EntityReference</c>.</param> /// <param name="mappedLookupObject">The <c>Dictionary</c> that contains the data for populating the returned <c>EntityReference</c>.</param> /// <returns>A new instance of a <c>EntityReference</c> object initialized with the proper values from the target system or null /// if the dynamics_integrationkey in the supplied <c>Dictionary</c> is null or empty.</returns> protected EntityReference MapEntityReference(FieldDefinition field, Dictionary<string, object> mappedLookupObject) { if (field == null) { throw new AdapterException(string.Format(CultureInfo.CurrentCulture, Resources.ArgumentNullExceptionMessage), new ArgumentNullException("field")) { ExceptionId = AdapterException.SystemExceptionGuid }; } if (mappedLookupObject == null) { throw new AdapterException(string.Format(CultureInfo.CurrentCulture, Resources.ArgumentNullExceptionMessage), new ArgumentNullException("mappedLookupObject")) { ExceptionId = AdapterException.SystemExceptionGuid }; } CRM2011AdapterUtilities.ValidateDictionary(mappedLookupObject); EntityReference reference = this.GetReferenceInstanceType(field); var lookupField = field.AdditionalAttributes.FirstOrDefault(x => x.Name == "LookupField"); var lookupEntity = field.AdditionalAttributes.FirstOrDefault(x => x.Name == "LookupType"); var typeSplit = lookupEntity.Value.Split(','); var fieldSplit = lookupField.Value.Split(','); var typeFieldList = new List<KeyValuePair<string, string>>(); if (typeSplit.Count() > 1 && fieldSplit.Count() > 1) { for (int i = 0; i < typeSplit.Count(); i++) { typeFieldList.Add(new KeyValuePair<string, string>(typeSplit[i], fieldSplit[i])); } lookupEntity.Value = mappedLookupObject["LogicalName"].ToString(); lookupField.Value = typeFieldList.FirstOrDefault(x => x.Key == lookupEntity.Value).Value; } if (lookupField != null && lookupEntity != null) { var entityCollection = this.RetrieveEntityReferenceValue(field, lookupEntity, lookupField, mappedLookupObject); if (entityCollection != null) { if (entityCollection.Entities.Count != 0) { var integrationKeyValue = entityCollection.Entities.First().Id; if (integrationKeyValue != Guid.Empty && integrationKeyValue != null) { return new EntityReference(lookupEntity.Value, integrationKeyValue); } } } } else { CRM2011AdapterUtilities.SetRelationshipValuesFromDictionary(mappedLookupObject, reference); } if (reference.Id == Guid.Empty) { if (field.Name.Contains("pricelevelid")) { reference = new EntityReference("pricelevel", (Guid)this.GetBaseCurrencyPriceLevel()["pricelevelid"]); return reference; } if (field.Name == "transactioncurrencyid") { reference = new EntityReference("transactioncurrency", this.CrmAdapter.BaseCurrencyId); return reference; } return null; } if (reference.Id == Guid.Empty) { return null; } return reference; }
public XrmLookupEditor(EditorArguments args) : base(args) { _args = args; _container = jQuery.FromHtml("<div ><table class='inline-edit-container' cellspacing='0' cellpadding='0'><tr><td><INPUT type=text class='sparkle-input-inline' /></td><td class='lookup-button-td'><input type=button class='sparkle-lookup-button' /></td></tr></table></div>"); _container.AppendTo(_args.Container); jQueryObject inputField = _container.Find(".sparkle-input-inline"); jQueryObject selectButton = _container.Find(".sparkle-lookup-button"); _input = inputField; _input.Focus().Select(); _autoComplete = inputField.Plugin<AutoCompleteObject>(); AutoCompleteOptions options = new AutoCompleteOptions(); options.MinLength = 100000; options.Delay = 0; // TODO- set to something that makes sense bool justSelected = false; options.Select = delegate(jQueryEvent e, AutoCompleteSelectEvent uiEvent) { if (_value == null) _value = new EntityReference(null,null,null); // Note we assume that the binding has added an array of string items AutoCompleteItem item = (AutoCompleteItem)uiEvent.Item; string value = item.Label; _input.Value(value); _value.Id = ((EntityReference)item.Value).Id; _value.Name = ((EntityReference)item.Value).Name; _value.LogicalName = ((EntityReference)item.Value).LogicalName; justSelected = true; Script.Literal("return false;"); }; // options.Focus = delegate(jQueryEvent e, AutoCompleteFocusEvent uiEvent) { // Prevent the value being updated in the text box we scroll through the results Script.Literal("return false;"); }; XrmLookupEditorOptions editorOptions = (XrmLookupEditorOptions)args.Column.Options; // wire up source to CRM search Action<AutoCompleteRequest, Action<AutoCompleteItem[]>> queryDelegate = delegate(AutoCompleteRequest request, Action<AutoCompleteItem[]> response) { // Get the option set values editorOptions.queryCommand(request.Term, delegate(EntityCollection fetchResult) { AutoCompleteItem[] results = new AutoCompleteItem[fetchResult.Entities.Count]; for (int i = 0; i < fetchResult.Entities.Count; i++) { results[i] = new AutoCompleteItem(); results[i].Label = (string)fetchResult.Entities[i].GetAttributeValue(editorOptions.nameAttribute); EntityReference id = new EntityReference(null, null, null); id.Name = results[i].Label; id.LogicalName = fetchResult.Entities[i].LogicalName; id.Id = (Guid)fetchResult.Entities[i].GetAttributeValue(editorOptions.idAttribute); results[i].Value = id; string typeCodeName = fetchResult.Entities[i].LogicalName; // Get the type code from the name to find the icon if (!string.IsNullOrEmpty(editorOptions.typeCodeAttribute)) { typeCodeName = fetchResult.Entities[i].GetAttributeValue(editorOptions.typeCodeAttribute).ToString(); } results[i].Image = MetadataCache.GetSmallIconUrl(typeCodeName); } response(results); // Disable it now so typing doesn't trigger a search AutoCompleteOptions disableOption = new AutoCompleteOptions(); disableOption.MinLength = 100000; _autoComplete.AutoComplete(disableOption); }); }; options.Source = queryDelegate; inputField = _autoComplete.AutoComplete(options); ((RenderItemDelegate)Script.Literal("{0}.data('ui-autocomplete')", inputField))._renderItem = delegate(object ul, AutoCompleteItem item) { return (object)jQuery.Select("<li>").Append( "<a class='sparkle-menu-item'><span class='sparkle-menu-item-img'><img src='" + item.Image + "'/></span><span class='sparkle-menu-item-label'>" + item.Label + "</span></a>").AppendTo((jQueryObject)ul); }; // Add the click binding to show the drop down selectButton.Click(delegate(jQueryEvent e) { AutoCompleteOptions enableOption = new AutoCompleteOptions(); enableOption.MinLength = 0; _autoComplete.AutoComplete(enableOption); _autoComplete.AutoComplete(AutoCompleteMethod.Search, inputField.GetValue()); }); // Bind return to searching _input.Keydown(delegate(jQueryEvent e) { if (e.Which == 13 && !justSelected) // Return pressed - but we want to do a search not move to the next cell { if (inputField.GetValue().Length > 0) selectButton.Click(); else { // Set value to null _value = null; return; } } else if (e.Which == 13) { return; } switch (e.Which) { case 13: // Return case 38: // Up - don't navigate - but use the dropdown to select search results case 40: // Down - don't navigate - but use the dropdown to select search results e.PreventDefault(); e.StopPropagation(); break; } justSelected = false; }); }
public static object DeSerialise(XmlNode node,string overrideType) { // Check if the value is null bool isNil = (XmlHelper.GetAttributeValue(node, "i:nil") == "true"); object value = null; if (!isNil) { string typeName = overrideType; if (typeName==null) typeName = _removeNsPrefix(XmlHelper.GetAttributeValue(node, "i:type")); string stringValue = XmlHelper.GetNodeTextValue(node); switch (typeName) { case AttributeTypes.EntityReference: EntityReference entityReferenceValue = new EntityReference( new Guid(XmlHelper.SelectSingleNodeValue(node, "Id")), XmlHelper.SelectSingleNodeValue(node, "LogicalName"), XmlHelper.SelectSingleNodeValue(node, "Name")); value = entityReferenceValue; break; case AttributeTypes.AliasedValue: value = DeSerialise(XmlHelper.SelectSingleNode(node, "Value"),null); break; case AttributeTypes.Boolean_: value = (stringValue == "true"); break; case AttributeTypes.Decimal_: value = decimal.Parse(stringValue); break; case AttributeTypes.DateTime_: DateTime dateValue = DateTimeEx.Parse(stringValue); // We need it in the CRM Users timezone UserSettings settings = OrganizationServiceProxy.UserSettings; if (settings != null) { // Remove the local date formating so that it is in UTC irrespective of the local timezone dateValue.SetTime(dateValue.GetTime() + (dateValue.GetTimezoneOffset() * 60 * 1000)); DateTime localDateValue = DateTimeEx.UTCToLocalTimeFromSettings(dateValue, settings); value = localDateValue; } else value = dateValue; break; case "guid": value = new Guid(stringValue); break; case AttributeTypes.Int_: value = int.Parse(stringValue); break; case AttributeTypes.OptionSetValue: value = OptionSetValue.Parse(XmlHelper.SelectSingleNodeValue(node, "Value")); break; case AttributeTypes.Money: value = new Money(decimal.Parse(XmlHelper.SelectSingleNodeValue(node, "Value"))); break; default: value = stringValue; break; } } return value; }