How to display dynamic default value in field of Strapi collection page? - node.js

I want to display some read only URL in STRAPI collection page.
let's say I am at
/admin/plugins/content-manager/collectionType/application::my-public-form.my-public-form/1
now I have one field that need to display URL like this
https://myurl/1
is there is any way to get current url i.e. /admin/plugins/content-manager/collectionType/application::my-public-form.my-public-form/1
and in field I display https://myurl/1

This is going to be a lengthy answer, but let me try to simplify as much as possible.
Explanation:
To achieve this you need to simply create a field in the collection type and mark it as non-editable in the admin interface. This will make it a read-only property. Next, we need to override the afterFindOne from the lifecycle hooks of the model so that when it fetches the entry from the db, we can pre-populate the url for that particular entry, so that it's displayed in the read-only field in the UI.
Implementation:
Let's assume we are creating a collection-type called Student, which some basic field like first_name, last_name, dob and student_url. We are going to make the student_url field read-only in the following way:
Create the collection type Student as show in the screenshot.
Visit the newly created collection-type in the content-manager, click on Create new entry button, and then click on Configure view in the right hand panel.
Click on the small pencil icon which is besides the student_url field to open a popup, and then set the Editable property to False and click Finish.
At this point you're almost done, the only thing left to do is set the lifecycle hook to populate the student_url field when it's fetched from the database so that it's displayed correctly in our UI.
Create a lifecycles.js file in your model folder.
// src/api/student/content-types/student/lifecycles.js
module.exports = {
afterFindOne(event) {
const { result } = event;
// You can easily change this line to `/admin/plugins/content-manager/collectionType/application::my-public-form.my-public-form/${result.id}` in your project.
if (result) result.student_url = `https://example.com/${result.id}`;
},
};
And that's it. Now create an entry in the admin UI with the rest of editable fields and see entry being populated automatically with the student_url. Cheers!

Related

Lightswitch Search screen - choosing what you can search by

I have a search screen which shows results from a 'projects' entity. One of the fields is a link to a 'Clients' entity, which has a client name.
I can use the search box above the data to search by project name, date, etc but I cannot search by client name. i guess because it is actually a reference to a seperate entity.
How can i make it so that I can search for projects, using the search box, by client name?
To try to explain clearer here is the database layout.
Project
------
ProjName
ProjType
ProjComment
Client --------------- Client
-----
Name
Address
I can search by the project fields, but not the client name.
Create a custom query for Project entity and add optional parameters for all the Project and Client properties that you wish to search for. Wire up the custom query filter.
For full control do not wire up the custom query filter, instead filter in code behind, the PreProcess event.
if your using the HTML Client it can be done as follows on a browse screen associated with in your case the Project Table. if you look at the left navigation bar, click on edit query and within here, you can see 3 options, Filter, Sort and Parameters.
Filter should say Client.Name based on your table structure, the second should be changed to "contains", the 3rd should be set as parameter and finally the 4th box is where you create the new parameter you are going to use as a search box...
you can rename the Parameter at the bottom and I always find its best when on this, to set it as optional in the bottom right property box. (This means all the data will be displayed rather than nothing until searched)
Now if you were to go back to your main screen page, drag this parameter from the left onto the main screen page and set it as a text box. Using this and pressing enter after you have typed something will display the results that match what you have typed so far.
a little more to the above, if you were to click "Edit PostRender Code" and add the below then after 3 characters are entered, the table list your searching through will be updated automatically after each finger stroke...
$searchBox = $("input", $(element));
setTimeout(function () {
$searchBox.focus();
}, 1);
onInputAsYouType(element, 1, function (text) {
contentItem.screen.[CREATED PARAM NAME] = text; //SearchText here is the data item in the screen designer linked to the query parameter
});
function onInputAsYouType(element, numberOfRequiredChars, done) {
var inputbox = $("input", $(element));
inputbox.on("input", function (e) {
var text = $(this).val();
if (text.length >= numberOfRequiredChars)
done(text);
});
};
};

xpages embedded view or view panel

I know it is a very simple question , but I'm trying to see the difference between a view panel ( that I drag from the Container Controls ) and an embedded view.
How can I add an embedded view on my xpages?
Or the 2 items are one and the same.
The reason why I'm asking this question: I have a view panel on my xpage ( I thought it is like an embedded view in clasic lotus notes programming ) where I have listing some docs. The first column is categorized based on the UNID document.
I noticed if I compose again another document, this view contains all the previous docs., and all the UNID categorized. The view panel isn't empty.
In lotus notes programming:
If I have a main form and a computed text field with #Text(#DocumentUniqueId) and some button for composing another form ( of course, when clicking the button I saved the main form to obtain the UNID ), and this form has the same text field name as the previous - I'm passing the UNID to this second form. If the main form contains an embedded view listing all documents saved from the second form I will use the first column categorized and hidden with the name of the field from the second form ( which will contain the UNID ). If I save and close the 1st main, and then I'll compose another main form, the embedded view is not listing the previous documents already saved.
Well, this view is already created.
I did drag and drop this view in myxpage. I have a button inside myxpage that shows a dialog. Here a datasource is declared, the dialog containing some fields. In the main xpage ( where is defined another datasource ) there is a computed field which takes the UNID of the document. Before I click the dialog I save the first datasource, to pass the value UNID to other field inside the dialog.
I save the datasource from the dialog & close the dialog, and then the view panel ( which is the view from the lotus notes classic presented above ) lists the doc. If I close the main xpage ( save it if is a new one ) and then open another main document, the view isn't empty, it contains the previous document lists. ( I tried also to hide it, if the xspDoc is new. But when I try adding other docs. from the dialog, the view panel lists also the previous documents from the previous doc., even if the UNIDs are distinct )
Thanks in advance.
To explain this best, it's good to consider what a view and an embedded view in Notes Client is. A view determines the look and feel, like a View Panel and by default will show all documents found by the selection criteria. So in this case the documents available correspond to a dominoView datasource bound to the underlying view with no additional criteria defined.
An embedded view still uses the view to determine the look and feel, but will not display the first column (that's effectively a property of the embedded view "control" in Notes Client). In the View Panel you choose which columns display, so you would need to code that yourself on the View Panel, where you choose which columns to display. The embedded view also has a property to define the single category. But the View Panel and other repeating containers (like Data Table and repeat control) don't restrict the data available, that's done by the datasource - a dominoView or e.g. a ViewEntryCollection for anything other than the View Panel. So in that you set the filter.
However, a new document does not have a UNID, so it cannot restrict what is displayed. Instead, I think a good approach is to set the visibility so the View Panel is only displayed if it's not a new document. You can use loaded, if you fully reload the page after save, or else rendered.
First off, this is not a stupid question.
I am assuming you are using a self implemented parent response system and have a view sorted by the parent UNID. Under the data source of the view panel, find the the "filter by category name" option. there compute the UNID value, or category value you are searching for.
Steps:
insure that the background view is categorized (ascending order is best to insure that this works, though I doubt it is needed)
drag (my favourite is the dynamicViewPanel) a view control onto the xpage.
Under Properties/Data there is a place to calculate the value of the category to show. If you want an exact match, check the exact match check box.
If you mistype the category value or the value is not there, then no documents will be shown.
if you put in an empty value all documents are shown (at least in the tests that I can remember)
if documents are returned, the categorized column is automatically hidden.
EDIT
If you are reading the value from a field, you can use the code:
xspDoc.getItemValueString("fld");
If you are searching based on the UNID, again, hide the viewPanel if the document is new. If the value is not yet set, also hide the panel.
If you have two custom controls, even if a custom control is embedded in the second, you cannot easily have one custom control access the values of the datasource in another. I am sure there are ways to trick this into working, but in this case, use a viewScope variable to access the values and possibly an onLoad, onChange or onSave event to update the viewScope variable. Make sure to verify that the result is not null or empty by either printing it out to the server log or another field.
Final Edit after question edit/expansion
These are the steps that I would take to do what you described.
You have your parent document XPage. Insert all fields for this Xpage.
Drag a dynamicViewPanel onto the XPage. If parentDoc is New, then hide.(this could be a custom control in theory, but if you are having trouble, try it without for the sake of trouble shooting.
Set dynamicViewPanel datasource to ignoreReqeustParams.
Calculate the datasource and setting the "Filter by category name" filter. When computing this, for the sake of ease and troubleshooting, print this value out to the server, or other logging mechanism. You can delete it later.
Verify that the correct UNID/Value is being inserted into the document you create in the dialog.
If you are using a scoped variable to hold the filter value, be sure you are using viewScope and not appliationScope or sessionScope.
if you are using a custom control and standard parameters (not scopedVars), verify that the compositeData variable is being updated with a log or server print.
Consider setting Dialog Properties/AllProperties/basics/refreshOnShow to true
Play with the partial refresh option for the dialogOpen action, test a full vs partial refresh.
Remember to set the ignoreRequestParams for the document you are creating in the dialog to true
Consider making the new document data source created in the Dialog to request scope.
And of course consider and test all datasources being defined on the XPage on not some here, some there.
Verify that you are taking the value of the UNID from the main document and not the new dialog document by mistake!
Those are all of the tips I can think of right now, pretty much in the order I'd try them in. If that does not help, then I suspect there is a piece of this puzzle that you are not including in the question. Remember, try to keep things as simple as you can. You can over think things, make things harder than they need be.

Opening different xpages forms from a view panel

I have an Xpages application that pulls data from another .nsf file. I have a view panel linked to a view in that db. The view has documents with several different forms in it. I want to be able to open each document in it's own form(xpage).
How do I write a computed At Runtime, open selected document using: statement that will select the correct Xpage to present the document.
If you use the Data View component instead of a View Panel, you can compute the pageName attribute, referencing the var attribute to return a different value for each row based on the document that row represents. The flexibility of the Data View component also makes it easier to make your app look more like a modern web application and less like an Excel spreadsheet. As an additional bonus, the mobile theme invokes a renderer that makes each Data View instance look like a native mobile list, so using Data Views instead of View Panels simplifies mobile development.
You have 2 options:
use "use xpage associated with form" and edit the form's property
use a SSJS formula to compute the Form. You provide a variable name in the view control var to access a view row as XSPViewEntry. If the Form is in a view column even one you don't display you use .getColumnValue otherwise getDocument.getItemValueString
Does that work for you?
Maybe this mothed can help you: Unable to get document page name for
Hope this helps
Mark
I had a similar problem today. I use only one form but 3 different xpages for associated with this form. I have 3 different document types in the view. I used rowData the get the type of the document.
try{
var v=rowData.getColumnValue("form");
if(v.indexOf("x")> -1){var page ="x.xsp"}
else if(v.indexOf("y") > -1){var page = "y.xsp"}
else{var page = "z.xsp"}
}catch(e){
var page = "x.xsp"
}
So to your view you can create a column with the value of the form and you can use it.
I have used the extension library Dynamic View control which has an event you can code to get a handle to the NotesViewEntry which was selected. See the demo database page Domino_DynamicView.xsp and the Custom Event Handler tab for an example.
Note, in 8.5.3 (I have not upgraded yet) if you add or edit the eventHandler for onColumnClick it will be added to the XPages source as an xe:eventHandler. It needs to be an xp:eventHandler to work. The way to do it is to copy the code in the source from the exiting event and delete it. Recreate the event and update the code. Then go back into the source and change the tags within the eventHandler to xp:.

Inline Editing of View data used in a repeat

I have a repeat control using a view as the datasource with a custom control within the repeat. The custom control is made up of a panel with two tables. One table has computed fields with an Edit button and the other has editable fields with a Save and Cancel button. The Edit and Cancel buttons work as needed, but the Save button gives a NotesDocument.save() is null error. I have already narrowed the issue down to the error occurring on the edoc.save() line by commenting out all prior lines. I even tried to do an edoc.lock(), but got the same error.
var edoc:NotesDocument = database.getDocumentByUNID(viewScope.get('docid'));
edoc.replaceItemValue('Ext_1',viewScope.get('ext_1'));
edoc.replaceItemValue('DID',viewScope.get('did'));
edoc.replaceItemValue('Mobile',viewScope.get('mobile'));
try {
edoc.save();
} catch(e) {
print(e.toString());
}
The storage of a DocID in the viewScope and a repeat control doesn't seem right. You want to add a custom property to your custom control called DocID and then instead of
database.getDocumentByUNID(viewScope.get("docid"));
You do:
database.getDocumentByUNID(compositeData.DocID);
This was you can be sure that you get the document that was in that view for that row.
What you also might consider, instead of all the manual steps (the ones you commented out) have a panel with a DocumentDataSource and then simply bind your input fields to that one. Handover of id via custom property and "IgnoreRequestParameter = true
Then you simply do a rowDoc.save() (presuming you named the datasource rowDoc) and you don't need to recycle anything. Let us know how it goes.

Person & Group custom field type sharepoint

I have created a custom field type as it is there in sharepoint OOTB, the difference is only that the end user does not need to check the name i.e I have replaced it with DropDownList. The dropdownlist suggest the no. of users available in the web site for that I have created a FieldClass which inherits from SPFieldUser and a FieldControlClass which inherits from UserField. It is working fine in all conditions i.e when I create a List or Document Libarary it shows me the DropDownList
with respective users after saying OK it creates an item for me. I have overriden a Value property in FieldControlClass as follows,
public override object Value
{
get
{
SPUserCollection userscollection = rootWeb.SiteUsers;
//ddlInfoBox is a DropDownList to which I have Binded the collection of users in the form of string
SPUser user = userscollection.Web.EnsureUser(this.ddlInfoBox.SelectedValue);
SPFieldUserValue userval = new SPFieldUserValue(user.ParentWeb, user.ID, user.LoginName);
return userval;
}
set
{
SPFieldUserValue userval = (SPFieldUserValue) this.ItemFieldValue;
this.ddlInfoBox.SelectedValue = userval.Lookupvalue; //Here look up value is nothing but a Login name e.g In-Wai-Svr2\tjagtap
}
}
Due to above property the Custom Field's Value for this current ListItem will be stored as SPFieldUserValue e.g 27#;In-Wai-Svr2\tjagtap.
The main problem is here, when this particular ListItem is shown in the list page views e.g on AllItems.aspx or the custom view pages associated with it, it shows the
number as 27 as a FieldValue insted of HyperLink with text as "In-Wai-Svr2\tjagtap" and PostBackURL as "/_layouts/userdisp.aspx?ID=27".
When I edit this Item it makes the respective value selected in the dropdownlist, also while viewing this item i.e on DispForm.aspx it also shows the hyperlink. I have
acheived it by writting a custom logic in createchildcontrol() method i.e by using ControlMode if it is New or Edit then fill the dropdown list, if it is Display then get the ItemFieldValue Type Cast it into SPFieldUserValue and get corresponding lookupid and value for making the URL and showing Text of the HyperLink.
I have spent a lot of time on searching and bringing the HyperLink as the user name with navigation insted of UserID (27) as a string on the list view pages e.g AllItem.aspx but to no avail, then after a lot of research I found that there might be a way of achieving such kind of functionality by using field type definition xml file where there is a provision to define a DisplayPatteren as you wish by specifying the html code. But here is a problem How can I get the UserID (27) with respective UserName e.g In-Wai-Svr2\tjagtap inorder to make an anchor tag like In-Wai-Svr2\tjagtap which will solve my problem. I have hard coded this anchor tag within the Default case statement of a switch under DisplayPatteren but it shows me the field value on AllItems.aspx as
In-Wai-Svr2\tjagtap27 i.e the value defined in xml file is concatenating with the string value (27).
Please help me to resolve the above mentioned 2 issue. I am really in need of solving this problem ASAP.
Thanks & Regards,
Tejas Jagtap
Have u tried to override the GetFieldValueAsHtml() method in the the custom field class or maybe the RenderFieldForDisplay() method in the custom field control class.
Can you use the DisplayPattern CAML from the User field type?

Resources