cancel
Showing results for 
Search instead for 
Did you mean: 

Mandatory Properties Prevent Type Change

ipirat
Champ in-the-making
Champ in-the-making
I have defined a content-subtype, which has a mandatory property (but no default value).
Now I cant change a document to that type, as it complains about the mandatory property being unset.

Is there any way to avoid this (either by automatically present the property edit dialog, or by forcing the type change)
10 REPLIES 10

kaynezhang
World-Class Innovator
World-Class Innovator
First a quest.why don'd you specify a default value in your model definition?

There are several options that you can use to satisfy or skip integrity check.
1.On model definition level
   specify a default value for your property
   add
<mandatory enforced="false">true</mandatory>
element to your property definition
2.On repository level
   You can  diable nable system model integrity checking by setting 
  system.integrity.enabled=false
in your alfresco-global.properties
   Add custom behaviour and set the property to a default value
3. On UI levl
     customize ui ,ask user to provide a value for this property.

ipirat
Champ in-the-making
Champ in-the-making
I dont specify a default where it is not appropriate to end up with a "bad" default => i could have skept the "mandatory" in the first place.

1. nice. will try.
2. this is not an option, as it will disable all integrity checks (including the ones in edit forms)
3. that would be the perfect solution. is there a flag for that?



kaynezhang
World-Class Innovator
World-Class Innovator

I'am sorry it is not possible to do it by customizing .Becuase the node service mthod that change a node'type dosen't allow us to update properties.
you can implement custom behaviors for your type .

ipirat
Champ in-the-making
Champ in-the-making
Thanks for the point to the behaviours. I guess I could set some more dynamic/more elaborate defaults than would be possible with the content model XML.

But as far as I understand the behaviours (didnt implement any on my own yet, though), they are fully server-side, so I cant communicate with the UI there…

Is there any way (configuration, customizing, extension) I can tell the UI "hey, the new type requires some additional properties, please open the edit properties dialog before you let the user save the new type"



kaynezhang
World-Class Innovator
World-Class Innovator
setType()/specializeType() method of node service dose not accept any additional properties parameters.
So if you want the setting type operation to execute successfully without breaking integrity check,you should first perform an update operation and provide all mandatory property values .


So you can customize Type Specializing UI ,in the destionation type selection page ,list all manditory properties that need to be filled by user.
When user submit the form:
first update all mandatory properties ,
and after that you can execute the specialize Type method.

ipirat
Champ in-the-making
Champ in-the-making
this sounds very promising. can you point me in the right direction, where I can "hook in" for the Type Specializing UI customization/extension?

kaynezhang
World-Class Innovator
World-Class Innovator
I have just scanned that part of code ,it is a little complicated to implement your requirment .

1.When we click on "change type" button on document detail page,by default it will trigger "onActionChangeType" javascript method in
/share/components/documentlibrary/actions-min.js.
   javascript code in actions-min.js is compressed and diffcult to read,you can enable client script debug in share-config.xml by setting client-debug to true,or          you can just copy content in  actions.js into actions-min.js.
2.Following code is onActionChangeType method.you'll see it first popup url /share/service/modules/documentLibrary/change-type ,and submit to /share/proxy/slingshot/doclib/type/node.

      onActionChangeType: function dlA_onActionChangeType(record)
      {
         var jsNode = record.jsNode,
            currentType = jsNode.type,
            displayName = record.displayName,
            actionUrl = Alfresco.constants.PROXY_URI + $combine("slingshot/doclib/type/node", jsNode.nodeRef.uri);

         var doSetupFormsValidation = function dlA_oACT_doSetupFormsValidation(p_form)
         {
            // Validation
            p_form.addValidation(this.id + "-changeType-type", function fnValidateType(field, args, event, form, silent, message)
            {
               return field.options[field.selectedIndex].value !== "-";
            }, null, "change", null, { validationType: "mandatory" });
         };

         // Always create a new instance
         this.modules.changeType = new Alfresco.module.SimpleDialog(this.id + "-changeType").setOptions(
         {
            width: "30em",
            templateUrl: Alfresco.constants.URL_SERVICECONTEXT + "modules/documentlibrary/change-type?currentType=" + encodeURIComponent(currentType),
            actionUrl: actionUrl,
            doSetupFormsValidation:
            {
               fn: doSetupFormsValidation,
               scope: this
            },
            firstFocus: this.id + "-changeType-type",
            onSuccess:
            {
               fn: function dlA_onActionChangeType_success(response)
               {
                  YAHOO.Bubbling.fire("metadataRefresh",
                  {
                     highlightFile: displayName
                  });
                  Alfresco.util.PopupManager.displayMessage(
                  {
                     text: this.msg("message.change-type.success", displayName)
                  });
               },
               scope: this
            },
            onFailure:
            {
               fn: function dlA_onActionChangeType_failure(response)
               {
                  Alfresco.util.PopupManager.displayMessage(
                  {
                     text: this.msg("message.change-type.failure", displayName)
                  });
               },
               scope: this
            }
         });
         this.modules.changeType.show();
      },

3.So if you want to add property field to the popup window,
   1.you should edit webscript "/modules/documentlibrary/change-type" which is defined in
share/WEB-INF/classes/alfresco/site-webscripts/org/alfresco/modules/documentlibrary/change-type.get.desc.xml

   2 edit sumbit logic in onActionChangeType to save properties value into  repository,that is rewritting onSuccess call back fucntion first call Update Object (updateProperties) data webscript api and then call change type data webscript api.


you have 2 options
Option 1: Directly edit
 /share/components/documentlibraryactions.js(actions-min.js) and alfresco/site-webscripts/org/alfresco/modules/documentlibrary/change-type.get.js  and alfresco/site-webscripts/org/alfresco/modules/documentlibrary/change-type.get.html.ftl

Option 2: use share extension module to extend share,it need more work but is recommended.

ipirat
Champ in-the-making
Champ in-the-making
Thanks for the very deep explanation. This gives me a few entry points into the whole process.
But it will take some time, to "go and play" with all that.


without having looked into the actual implementations:
<blockquote>
onSuccess call back fucntion first call Update Object (updateProperties) data webscript api and then call change type data webscript api.
</blockquote>
I'd rather have a custom webscript, which does both (not very familiar with the aPI, but doing both in one Server Call offers at least the theoretical possibility to put both in one transaction)

kaynezhang
World-Class Innovator
World-Class Innovator
Yes ,I also thingk it is a good idea to customize a data webscript that does both.It has serveral benifits:
1.You have a reusable data webscript .
2.You can do update properties and change type in one transaction.
3.You don't need to make big change to
onActionChangeType: function dlA_onActionChangeType(record)
method ,maybe just need to set actionUrl to your custom webscript url.