Select the search type
  • Site
  • Web
Search
You are here:  Support/Forums
Support

Bring2mind Forums

Add Custom Attribute with custom control?
Last Post 04/01/2010 5:30 PM by Bruce M. 14 Replies.
Sort:
PrevPrev NextNext
You are not authorized to post a reply.
Author Messages
Gaurav Kumar
New Member
New Member
Posts:39


--
05/13/2008 2:01 PM

Hi All, I have added a custom attribute called "Client" and it works fine if I use default settings. I want to use Drop Down Control(Combo Box) instead of default TextBox Control. I have added coustom ascx control "ClientList.ascx" in controls folder and added the reference of control file in the "Control To Load" field and after adding attributes on ascx file when I save attributes, it successfully saved. After saving attributes I go on document Folder, Right Click on document folder and select Edit attributes then it gives "NullReferenceException" error in first line on EditEntry.ascx.vb  page in Private Sub Page_PreRender()  Procedure.

Peter Donker
Veteran Member
Veteran Member
Posts:4536


--
05/14/2008 12:39 PM
Hi Gaurav,
You're on the right track. The ControlToLoad value is a path to the control starting at DesktopModules. E.g. 'Bring2mind/DMX/addons/AutoDocProcess/SetProcesses.ascx'. Then this control should inherit from DMX.Framework.EntrySettingsBase. This exposes the following:

Public MustOverride Sub LoadSettings()
Public MustOverride Sub WriteToCurrentEntry(ByRef EntryToUpdate As EntryInfo)

and lately as well:

Public Overridable Sub BeforeSubmit(ByRef EntryBeingUpdated As EntryInfo)
Public Overridable Sub AfterSubmit(ByRef EntryBeingUpdated As EntryInfo)

This gives you ample intervention points in the editing process. The update (WriteToCurrentEntry) logic for your control will probably include something like this:

Dim att As AttributeInfo = AttributesController.FindAttributeByName("MyVar", PortalId)
For Each eatt As EntryAttributeInfo In EntryToUpdate.CustomAttributes
If eatt.AttributeId = att.AttributeId Then
eatt.Value = procs.ToString
bExists = True
End If
Next
If Not bExists Then
Dim eatt As New EntryAttributeInfo
With eatt
.AttributeId = att.AttributeId
.EntryId = Me.EntryId
.Value = procs.ToString
End With
EntryToUpdate.CustomAttributes.Add(eatt)
End If

Let me know how it goes.

Peter

PS I'll move this thread to the API forum.
Gaurav Kumar
New Member
New Member
Posts:39


--
05/14/2008 3:25 PM
thanks. I'll try it out and would let you know.
Paul Deschenes
New Member
New Member
Posts:33


--
05/14/2008 9:29 PM
Hi Peter, in a broader sense, is there any recommended documentation, recommended practices, forum posts or anything that you have which would get us down the right path to learning the customization of DMX partial source version efficiently?
Peter Donker
Veteran Member
Veteran Member
Posts:4536


--
05/15/2008 12:03 AM
Paul,

This forum is meant to build this. Currently the API is still very much being refined by various custom projects going on. Fire your questions here and I'll answer. It is also hard to imagine in how many different ways people want to adjust this.

Peter
Gaurav Kumar
New Member
New Member
Posts:39


--
05/15/2008 2:46 PM
Thanks, that worked. Thanks a lot.
Bruce M
New Member
New Member
Posts:22


--
03/02/2010 3:21 PM

I am resurrecting this older thread because it appears Peter's code doesn't work in 5.2.2.  There does not appear to be a "findattributebyname" method anywhere in the DMX classes.

 

If anyone has custom controls working with custom attributes in 5.2 I would really appreciate an example.

Thanks.

Peter Donker
Veteran Member
Veteran Member
Posts:4536


--
03/15/2010 10:09 AM
Hi Bruce,

Use FindAttributeByKey. The names have been localized and the only accurate thing you can look for is in the Key column.

Peter
Bruce M
New Member
New Member
Posts:22


--
03/27/2010 1:49 AM

Thanks, Peter.  I've gotten further but I am puzzled by a problem I am having (version is 5.2.2). 

I've modeled my code after your example above.  So, I look up the attribute by key, and it finds it correctly (the problem happens to be with key number 9).  I have 6 of my own attributes altogether, they are keyed 3,4,7,8,9 and 10. 

When I iterate with

For

Each eatt As Bring2mind.DNN.Modules.DMX.Business.EntryAttributeInfo In EntryToUpdate.CustomAttributes

debugging shows that the for loop finds 3,4,7,8 and 10, but not 9 so it never gets a "found" condition on it and thus never updates.  The initial add of all the attributes, including #9, works fine, and updates of any attribute but #9 works, but the update never finds its match for #9 in the CustomAttributes.  It thus falls into the add processing, and I assume an add on existing data effectively does nothing.

It seems like I must be missing something pretty obvious.  I can see the attribute in the DMX_EntryAttributes table after it gets initially added.  The other attributes are of type String and Date.  #9 is of type Custom.  #9 uses a control that has four fields defined.  Those 4 fields are all concatenated together into the .Value property of the WriteToCurrentEntry method.  That concatenation works fine when the Add happens and I can display them in the control just fine.

Any clues would be most appreciated.  Thanks.

Bruce

Peter Donker
Veteran Member
Veteran Member
Posts:4536


--
03/29/2010 3:18 PM
Hi Bruce,

At what point are you iterating? Set a breakpoint in your custom attribute control where it adds to the collection of attributes and set a breakpoint at the start of the loop above. Which one is hit first? The custom types are handled just after the core attribute types.

Peter
Bruce M
New Member
New Member
Posts:22


--
03/29/2010 4:28 PM

Hi Peter,

6 rows exist in DMX_EntryAttributes for this document entryID.  Their attributeIDs are 3,4,7,8,9,10

Here's my WriteToCurrentEntry code in my user control codebehind:

Public Overrides Sub WriteToCurrentEntry(ByRef EntryToUpdate As Bring2mind.DNN.Modules.DMX.Business.EntryInfo)
    Dim bExists As Boolean = False
    Dim att As Bring2mind.DNN.Modules.DMX.Business.AttributeInfo = Bring2mind.DNN.Modules.DMX.Business.AttributesController.FindAttributeByKey("att9", PortalController.GetCurrentPortalSettings().PortalId, Locale)
    For Each eatt As Bring2mind.DNN.Modules.DMX.Business.EntryAttributeInfo In EntryToUpdate.CustomAttributes
        ' breakpoint here shows that att.AttributeID is 9 and eatt.AttributeIDs are 3-7-4-8-10 in that order
        If eatt.AttributeId = att.AttributeId Then
            eatt.Value = "whatever"
            eatt.Value = eatt.Value & " some more whatever"
            bExists = True
        End If
    Next
    If Not bExists Then
        ' breakpoint here is reached for attribute ID 9, and occurs after we have hit the breakpoint shown above for attributeID of 3-7-4-8-10
        Dim eatt As New Bring2mind.DNN.Modules.DMX.Business.EntryAttributeInfo
        With eatt
            .AttributeId = att.AttributeId
            .EntryId = Me.EntryId
            .Value = "whatever"
            .Value = .Value & " some more whatever"
        End With
        EntryToUpdate.CustomAttributes.Add(eatt)
    End If
End Sub

Peter Donker
Veteran Member
Veteran Member
Posts:4536


--
03/31/2010 4:39 PM
OK, but at this point you're in your control and you know the value that you are going to give it, no? If I'm correct the first loop makes sure there is no duplicate by accident. It is normal to not have the attribute set yet as this is the method where it is added. After this code DMX should set all the attributes in the DB. Or are you saying that after you add your "eatt" it doesn't seem to get to the DB?

Peter
Bruce M
New Member
New Member
Posts:22


--
03/31/2010 9:33 PM

Maybe I am misunderstanding the purpose of WriteToCurrentEntry. 

When the attribute does not already exist, my code does, in fact, add the attribute to the database quite nicely.  I want to be able to update the attribute after it already exists.  Should WriteToCurrentEntry be used for this purpose? 

The loop where I am checking existing attributes for this entry does not find the #9 attribute when it does already exist. It looks to me like it ought to find it, as the code executed when an attribute match is found loads the values from the control into the eatt.value.  I observe that it does not call a method to do an "update" (should it? The sample code early in this thread that I based mine upon does not).  When not found (and yet the #9 attribute exists in the DB for the entry) it calls the "add" method.

As far as I can't tell, then, my existing attribute is not found by the loop and the "add" code branch executes but does not change the attribute value in the DB.

Why would my #9 attribute not be in the EntryToUpdate.CustomAttributes set?  I can successfully update all my custom attributes that don't use custom controls, so it's an issue only with custom controls.  Might it be that EntryToUpdate.CustomAttributes excludes those attributes with custom controls intentionally?  If so, then there would need to be some other means of updating existing attributes that employ custom controls.

I hope this clarifies the issue.  When I get a chance I will add another attribute with a custom control and see if the same issue occurs.

Peter Donker
Veteran Member
Veteran Member
Posts:4536


--
04/01/2010 4:34 PM
Hi Bruce,

No, it's not passed in. The logic may seem twisted but this is what happens:

1. The main CustomAttributes control is called and asked to update all attributes
2. The entry to be updated starts with an empty list of attributes
3. It fetches a list of existing attributes and then looks through the table on the page to see what attributes were "core handled" attributes. It adds those to the entry being updated.
4. Subcontrols are called. This is where it comes into your WriteToCurrentEntry
5. Now you can just add an ent att yourself. If you need to know a previous value, you can retrieve the ent att from the db at this point as well. The logic is the same for a new or existing entry.

Looking back at the code above you could have skipped the check for if it was there. It was a safeguard and you could do it if you have multiple controls that interact and need info from each other. But frankly that is a rare scenario.

I hope this clarifies it a bit.

Peter
Bruce M
New Member
New Member
Posts:22


--
04/01/2010 5:30 PM
Peter,

Yes, thanks, much clearer now. The loop through existing attributes had sent me thinking in a wrong direction. I can see that it could be eliminated from my code. I had that just about figured out when your message arrived. The other thing I just realized is that the PageLoad is firing when we first click on "Edit Attributes" and when we actually click on the Custom tab we are getting a second page load, this second one is as a Postback. My data loading into the control was not taking that into account. Unfortunately, the way these two page loads is timed is giving me fits as I try to set the selected value of an asp:dropdown in my custom control.

But that's for me to solve, probably with some event or other. I would like to point out to others who might try something like I am doing (dropdown as custom control) that the two page load events are likely to complicate setting the selectedvalue from the custom attrbute data value. In plain old asp.net, binding to a datasource and getting the selectedvalue from it works nicely. I wanted to avoid doing a data object for the custom attribute data, but perhaps that's the only way.

Thanks again, Peter, for your input on this. Being able to have custom controls is a very nice feature of DMX, despite my struggles.

Bruce
You are not authorized to post a reply.