Xpages ACL validation from the XSP document level - xpages

Is it possible to validate the Xpage's ACL depending on the Source document's field value.
We need to make the Authors & Readers ability at XPage level (as per requirement I am not supposed to use the ROLES, since, it is dependent on each individual Authors which is stored in backend document FIELD).
Kindly suggest the approach, as I am not even looking HideWhen for the Buttons(edit,save etc)
Example code in the ACLEntry[0] in Xpage:
if getComponent("inputText1").getValue() == sessionScope.user {
session.getEffectiveUserName();
} else {
return false;
}
Thanks.

I do not quite understand your code on that property...
To query the readers/authors level at XPage level I suggest to use the database.queryAccess method (http://www-10.lotus.com/ldd/ddwiki.nsf/dx/NotesDatabase_sample_JavaScript_code_for_XPages?opendocument&comments#queryAccess)
You try to compare the username only. This may fail if your access level is computed by a membership in a group where your username is not relevant.
XPages' ACL depends on the database ACL, so you have to setup the levels there - the XPages' ACL is in addition to the "real" ACL as far as I experienced.
I also experienced that readers fields affect the ability to use an XPage to open a document by default.
I hope my answer is not too confusing ;-)

I think the question is valid (to my current knowledge):
If I want to design a workflow application but the current approver should not edit the full document I want to give him only access to parts (ie. a comment field and the approval button).
The question above relateds somehow to access controlled sections in old LN development. I so far also didn't find a good solution

What you describe is a very common workflow scenario. There are several ways how you can implement that efficiently. Here is what I would do:
Have one (or more) custom controls that render the "payload" (the fields the requester fills in)
assemble them into one bigger control that is used to render the form
compute the mode to read/edit depending on who is opening the form and the mode (new, pending approval, approved, rejected etc.)
Optional: when submitted remove submitter from the author field
Have one "Approval Control" that show only when the current user is the (current) approver and status is "pending approval" That control has fields that are NOT bound to the document, but a scope variable
The approval button triggers SSJS that takes the scope variable values and updates the document (and triggers notifications, access change etc)
The approval component can be used for any approval form. You then can contemplate not to give the approver write access since you could handle that in code.

Related

Filtered and Categorized view on Lotus XPages within Notes client

Hoping someone can point me in the correct direction for an XPages application we are writing inside the Domino Client (Notes?) viewer.
I have a view of documents which is being returned, this view has categories on it, and shows fine as this in an XPage, we now apply a filter to the view to limit it to specific owners of the documents, but as soon as we apply the filter, the categories disappear, which means we are left with a long list of documewnts, but unsorted - is there any way to display a filtered view in a categorized manner, on an XPage.
Moving further down my list, I also need to be able to select these documents (and one or many owners) to send to an Lotus Agent which will then create a JSON document to be sent to our friends at DocuSign requesting signatures from the selected owners on the selected documents. I'm not sure what an Agent is yet, but that is the goal ...
Caveat: I'm not a Domino developer, so excuse me if some of the terminology is incorrect.
Categorised views are a very "Notes" construct. When you filter a view, it will only show documents, but not categories. While they are practical in the back, they are cumbersome in the UI.
There are a few design considerations how to tame them in a webUI. However if your users love them, you might consider to flatten them out and recreate the categories in the UI (client side) only.
The actual better way for your use case: add another view that is firstly categorised by the owner and secondly by your category. Use the category filter of the view control to limit the documents to that author. This should do the trick. Eventually use one of the controls from the extension library.
For the agent: don't bother, that's "old Notes speak". An agent would be a piece of code (LotusScript or Java, but since you do web interaction: Java) that gets triggered by an event: manual, on schedule, on document create/update (with some delay).
Since you are in an XPage, you have easier options at your disposal: create a Bean that has the JSON format you need, add a method that takes a Notes document as parameter to populate it, something like public void populate(final Document doc) {...} and use e.g. the GSON library to simply marshall them to JSON (or a collection of them). The GSON library probably is on a current Domino, I put it there as part of VoP 1.0.
Then use a managed bean to talk to Dokusign. When traveling down the managed bean road is is much easier to test than trying to mess with agents.
Hope that helps and ask more questions! (Check the Learning XPages Cheatsheet too)

MVC 5 Save Drafts While Ignoring Missing Required Fields

I have searched for current solutions, but can't find a set of guidelines or examples as to how to achieve the following:
The original requirements involved models with required fields, so we included annotations to those fields. As usual, there is a last-minute change and we are being asked to allow the users to save drafts. These drafts must allow the user to save the forms without any of the required fields.
I would like to know what the best practices for this problem are.
Solutions I am considering, but I accept they might be a hack (and that's why I am asking the experts)
If the user clicks "Save as Draft" I can capture the fields that have information in another ActionResult and run basic validation on those fields. Since there is a chance that required fields are missing, I am thinking in storing the captured info in a temporal model (without any required annotations). If the user decides to edit such form, I can populate fields in the view with the temp. model until the user clicks on "Submit"
Another option is to remove all required annotations and run client-side validations... but am wondering on the amount of work required to do so.
Any thoughts are very much appreciated.
Just have 2 save methods. 1 which is called from the autosave and 1 that is used to submit the process. In the autosave method do not check if(ModelState.IsValid).
Whether you choose to save the incomplete objects to the same table or a different table is your choice. In a relational world I would likely use a separate table, in a non-relational world I would use a singular object collection.
This will allow you to keep the same set of original models. There is a very high cost to duplicating your models, there are certainly times that warrants pass by value/copy but make sure the cost of mapping is there. In this situtation I do not believe there is value in mapping, except perhaps at the persistence level if you need to map to a different object because of an ORM's constraints.
There is deep value in these partial forms. Recording this on the server will allow you to apply analytics to learn why your users abandon your processes. It also gives you the ability to follow up on users who leave incomplete forms such as sending a reminder (nag) email.
You don't want to save anything to your database until it is complete. Having a duplicate table where everything is nullable is cludgy as hell. Before HTML5, the typical path was to save the information to the session, which you could then pull from to refill the fields, but that's requires having a session with a relatively high expiry to be useful.
Thankfully, HTML5 has local storage, which is really the best way to handle this now. You just watch for onchange events on your fields and then insert that value into local storage. If the user submits the form successfully, you destroy the local storage values. Otherwise, you attempt to read those values from local storage when the page loads and refill the fields.
See: http://diveintohtml5.info/storage.html
There's pretty broad support, so unless you need to worry about IE6 or IE7, you won't have any issues.
Another option (depending on your data obviously) would be to comply with the database but not the model. By this I mean ignore Model.isValid and disable Javascript validation on the front end but then satisfy the database table. In a form, you mostly have:
textboxes - default to "" or " "
checkboxes - easy true/false default
radio buttons - one is probably already selected
dates - default to DateTime.MinValue (or DateTimeUTC)
enums - default to 0 (usually for 'unspecified')
Hopefully you are also saving a flag designating that it is in Draft state so that you know you need to interpret the 'null codes' you have set when it comes to displaying the semi-populated form again.

How should I implement `OnLoad` event handler when creating an activity using a contact?

I've created my own solution with a custom entity of type activity. I'd like to show a message whenever a new instance of it is created using an existing contact but not allow the user to create one, if only attempting to do that without going via contact.
Basically, my aim is that it won't be impossible to just create that activity (the form will be hidden directly at any attempt except for one way only). The user will have to go to contacts (or leads etc.) and in there add and create an instance of the custom activity entity. That way, I can assure that the field "regarding" will be filled out already.
I'm guessing that I need to detect somehow that the opening of the form is a creation attempt. How can I do that?
Also, as it is now, the user can't create a contact-less activity of the custom type because it doesn't appear on the menu with other activities. I must have disabled it somehow but I have no idea how. Anybody who has one?
You could do this a bunch of ways but the easiest would probably be to:
Make the regarding field read only.
Make the regarding field mandatory.
That way if a user opens a create new form they wont be able to set the regarding and because its mandatory they wont be able to save the record. When they open via an existing contact the regarding field will be mapped automatically. That said in this case just making it mandatory my be enough.
(As a side JavaScript can be used to identify the current form state, but I'm not sure how useful that is here).
In terms of where custom activities appear, by default mine show in a number of locations, for example:
CRM > Workplace > Activities > Ribbon > Other Activities > XXX.
CRM > Workplace > Activities > View Selector > XXX.
They don't show under the left hand navigation of the workplace because they are grouped under 'Activities'. I'm pretty sure these are all the default settings.
You can exercise greater control by editing the sitemap, where you can put pretty much anything, anywhere.
In addition to Mr Wood, I'd like to show you some code. It works as supposed to but I'm not sure if it's optimal.
var foo = function () {
var whatIsGoingOn = Xrm.Page.ui.getFormType();
if (whatIsGoingOn === 1)
alert("Let there be an entity!");
else
alert("Not a creation...");
}
The other states' (deletion, update etc.) numeric values are listed here.
Answering the second part of your question:
When you create a custom activity you can choose whether to have it appear in 'normal' Activity menus or not by checking the box at the top right of the entity form. This is a once-only choice as far as I know and can't be changed later.
For your setup, I would suggest NOT checking this box, so it does not appear in the activity menus to avoid users even being tempted to do it that way.
Instead, add an explicit relationship to the activity N:1 to Contact, and another N:1 to Lead. Use this relationship to add your activity to the left navigation of Contact and Lead forms, or add a grid for them (depends on how you want to use this and if you need to filter the view to something other than the default "Associated View").
When a user navigates to this section they will see if any previous activities of this type exist, and be able to add a new one. BUT this means that the child record is a child via this relationship, not using "regarding", so use a script on the form for the activity so that if Contact is filled in, it is copied to Regarding, and if Lead is filled in then that is copied. If neither, then use an alert or other means to warn the use that something is wrong (see comment earlier). If you want Regarding to be read-only but filled in by script, you will need to make sure to use the force the value to be saved:
Xrm.Page.getAttribute("regardingobjectid").setSubmitMode("always");
You must have the lookups for Contact and Lead on the form to be able to use them in your scripts, but you can make them not "visible by default" so they are there but not seen by the user (and taking up no space).

How to Enabled a single field for update for a particular role in CRM 2011

What I need
I have a custom Entity with that with multiple fields. Admin Role has "god" access. All other roles except for one have read only. The one non admin role with update access, should only be able to update a single field.
What I believe to be true
I believe I have three main options to implement this requirement:
Enable Update Access to the role for that entity then write Javascript to disable all fields on the form for that role, except for the one that I want that role to be able to edit
Enable Update Access to the role for that entity then create a new form that disables all fields on the form for that role, except for the one that I want that role to be able to edit.
Enable Update Access to the role for that entity then turn on field security for each field, disabling access using the field security, for each field except for the one I want them to edit.
What's the Best Practice?
What options should I choose?
If I go with options 1 or 2, will the user be able to edit the field on the bulk edit form?
From a user perspective, I think it's confusing when a form opens up with things enabled, then they get locked down. Plus someone could possibly get data in there before the fields get locked. I'd say you'd have to combine this with a plugin to prevent changing fields you don't want changed.
I like this option better, although again, the field can be unlocked if someone knows what they're doing, so a plugin to double check would be nice.
This would avoid having to double check in a plugin, but you also have to rely on the admin correctly setting up security for new fields going forward. If that's not a concern, this might be best.
Bulk edit is a global privilege, so they'd have bulk edit for all entities. Also, the bulk edit form does not load scripts, so that knocks out option 1. I'd say if it's just this one field, I might leave the privilege locked down and provide my own Bulk edit button on the grid that would show a custom page that just has that one field on it, then handle the updates though script.
2 is most likely best, or as an alternative put the fields in the header or footer rather than as read-only fields on the form.
This also means the fields won't be available to bulk edit, but other methods such as data import or workflows would let users get round this if they know how and have rights to do such things.
3 Field Security is the most robust and works for all scenarios
Possible option 4: create another entity to contain those fields and apply different security to that entity. If created as a child, show the record in a grid on the form with the values included in the view. If it is a parent then you could use methods such as showing the values via an HTML webresource page included on the form.

SharePoint 2010 - Customizing the rendering and behavior of a List field

In my SharePoint List, I have an "Employee" column that is a User type field. I would like to add some custom Business Logic to the processing of this field.
Currently, when the user adds a row, I check to see if the user is an Employee or a Manager and then change the behavior on this column accordingly. I do this by statically rendering the field in my custom "ListForm Rendering Template", just before my custom ListFieldIterator. I simply use a standard SharePoint FormField (and FormLabel) control. In the markup of the FormField control, I specify the FieldName (Employee) and an event handler for the Load event. In this Load event, I will check to see if the current user is an Employee or Manager (using two different SharePoint groups). If the user is an Employee I set the value of the field to the current user (this part works perfectly). I also want to change the field so it can't be modified. I thought I might be able to just change the ControlMode on the field (in the code of the OnLoad Event Handler) to Display, but for some reason this has no effect. The field still renders with the full, people picker editor. Am I not changing the fields control mode soon enough? Or is this simply not the correct approach? The other logic I want to put in is if the user is a Manager, I would like to allow that user to select the person from a list (SharePoint group) of Employees. It may be easier to just use the people picker and limit the selectable users to that group. (I think I can do this with the SelectionGroup property.) Although, it would be better if I could just provide a dropdownlist of users, which I could possibly do with a hidden dropdownlist that I would show and event handlers that I could use (handle event selectedindexchanged) to pull the value selected and populate the (now hidden) Employee (user) field. Does this approach make sense? Assuming all that will work, the real difficulty I am having is with changing the ControlMode (rendering) on the field (when the user is an employee) to a label or some kind of read only control, which is how that field renders when viewing the row, which is why I think if I can just trick the control into thinking it is in Display mode then it should work perfectly!
I am still learning SharePoint, but I am very proficient in ASP .Net. This is why I would like to keep my customizations in this Custom Rendering Template, using code behind and leverage my existing skill set as much as properly.
Any thoughts, opinions or advice? Does anyone know why I can't get the column to switch the "Control Mode"?
I do not think that I fully understand your scenario. Some code samples could help.
But anyway it sounds like you want some heavy customizations of the user field. In that case you might want to have a look at creating a custom field with all its advantages and disadvantages. Have a look at MSDN: http://msdn.microsoft.com/en-us/library/gg132914.aspx
Another option might be - in case you do not want to re-use this column in many list definitions - that you can get away with your custom rendering template and create a custom create/edit form where you implement the specific edit behaviour for the field (plain ASP.NET with some SharePoint controls). Here is a nice walk-through on how to grab a custom edit form from SharePoint designer: http://community.bamboosolutions.com/blogs/sharepoint-2010/archive/2011/05/12/sharepoint-2010-cookbook-how-to-create-a-customized-list-edit-form-for-development-in-visual-studio-2010.aspx
I hope this helps. Kr., Bernd.

Resources