Using a bucket as a datasource for a droplink/tree field - sitecore

I'm trying to enable content editors to select an item that resides in a bucket in a droplink field but I'm unable to find a field type/datasource that enables this.
I need to allow the user to select a single item (so not a multilist), the items are in a bucket as the number of items may be huge and the search api would be most helpful to the editors.
Is there a field or datasource query that will enable a lookup field to select a single bucketed item?

The simplest solution is to use a Sitecore multilist with search field.
First you need to set the source of your field to display items within your bucket of a specific template(s).
Example: StartSearchLocation={11111111-1111-1111-1111-111111111111}&Filter=+_templatename:sample item
Here is an article describing how to set the source of your field: Sitecore 7 field types
If you need to limit the selection to one item then you need to also apply some regex. To achieve this you need to enable standards values in the view tab so you can alter the data section.
In the data section add the following regex: ^({[^}]+}\|?){0,1}$ and add some validation text.
Example:
This article provides additional infromation:Limit selected items on Sitecore multilist field

Just in case anyone else comes across this as I did, you can also use a query in the source field to filter the items in a droplink.
query:/sitecore/content/Home/YourBucket//*[##templateid='{your-template-guid}']
You can also use ##templatename='Your Template Name'
Keep in mind that unless your bucketed items aren't numerous (for some reason), the suggested answer is probably better since it provides search, and will not create a massive dropdown list of items.

I made some custom fields for this very purpose: https://github.com/Barsonax/SitecoreSearchFields
It gives you the same rich search interface you normally get when searching in buckets.

Related

How to create multiple numbers of fields based on the value in one number field in Oracle Apex form?

I am working on a form in which I need to take numeric value from one field and based on that number(n) I need to create n fields for another column. How can I do so?
Probably you can use APEX_ITEM API if I understand your task right:
https://docs.oracle.com/en/database/oracle/application-express/19.2/aeapi/APEX_ITEM.html
Something like this:
SELECT APEX_ITEM.TEXT(rownum)
FROM DUAL
CONNECT BY rownum < :YOUR_ITEM;
You will not be able to create n page items in a declarative way. APEX simply wasn't made for this.
I can think of two workarounds:
Use a plsql dynamic content region to generate html with the apex_item package just like Ivan Dubashinskii suggested. You will need to submit the page in order to have the region re-generate your page items when the amount n is changed. There are some downsides to this approach, as for example it won't be that simple to use your page items in a page process.
Just limit your page items to some number, like 10. Then, create 10 page items in a declarative way and use dynamic actions to show/hide them when n changes. This way, it will also be much easier to use your items in a page procress.

Mapping user spreadsheet columns to database fields

I’m not sure where to start on this project. I know how to read the contents of the excel spreadsheet, I know how to identify the header row, I know how to loop over the contents. I believe I have the UX portion worked out but I am not sure how to process the data.
I’ve googled and only found .Net solutions but I’m looking for a ColdFusion/Lucee solution.
I have a working form allowing me to map a user's spreasheet column to my database values (this is being kept simple for this post; user does not have direct access to the database).
Now that I have my data, I'm not sure how to loop over the data results. I believe there will be several loops (an outer and an inner). Then of course I also need to loop over the file contents but I think if I can get the headings mapped out,I can figure out the remaining.
Any good links, tutorials, or guides would be greatly appreciated.
Some pseudo code might be enough to get me started.
User uploads form
System reads headers and content.
User is presented form with a list of columns from their uploaded spreadsheet to match with available database fields (eg “column1” matches “customer name”.
User submits form.
Now what?
UPDATED
Here is what the data looks like AFTER the mapping has been done in my form. The column deliiter is the ::: and within the column the ||| indicates the ID associated with the selected column value. I've included the id and the column value since I plan on displaying the mapping again as a confirmation. Having the ID saves a trip to the database.
If I understand correctly, your question is: how do you provide the user a form allowing them to map their spreadsheet columns to that of the database
Since you have their spreadsheet column names, and you have the database column names, then this problem is essentially a UI/UX problem. You need to show both lists, and allow the user to map them. I can imagine several approaches to this. My first thought would be some sort of drag/drop operation, as follows:
Create a list of boxes, one for each field in your database table, and include the field name in (or above) the box. I'll call this the db field list. Then, create another list for each column from the spreadsheet, which I'll call the spreadsheet column list. The user would drag/drop items from the spreadsheet column list to the db field list.
When a mapping has been completed by the user, you would store the column/field names in as data for the DOM element of the db field list box. Then upon submission, you would acquire the mapping data by visiting each box and adding it to an array. Then you would serialize that array into JSON and send that to your form submission handler.
This could be difficult or easy, depending on your knowledge of UI implementations using JavaScript. jQuery makes this easy (if you know jQuery). There's even a jquery UI plugin that does this: https://jqueryui.com/droppable/.
A quick search for javascript drag drop would help, and here's a few articles I found:
https://www.w3schools.com/html/html5_draganddrop.asp
https://medium.com/quick-code/simple-javascript-drag-drop-d044d8c5bed5
You would also need to submit the array of mappings using javascript. You could search for that as well, and here's an article I found:
https://codereview.stackexchange.com/questions/94493/submit-an-array-as-an-html-form-value-using-javascript

Basic List on Entity Form

In Dynamics CRM online, I can add a list of entities to another entity, for example a list of products to an opportunity.
Is there any way I can have a list that is not picked from pre-populated items, e.g. just a simple list of {number, date, text} that you type in each time you want to add to the list, not picking items from a pre-defined list.
I am just using the web interface to customise at the moment, but I am open to any suggestions.
EDIT:
So far i have;
Created two entities, proposal and proposal version
Added a 1:N relationship between proposal and proposal version
Added a sub-grid to the proposal form, tried to make it editable but it refuses to work
This lets me add new rows by opening up the proposal version form and adding a new one or picking from already created ones for other proposals but that is rather clunky for a simple list.
I don't want it to offer to search for previous entries, just let me add to the list by typing stuff in, surely this should be fairly simple?
If you want a pre-defined list of items that are simple (number, date, text..) then you can create an option set field in CRM. These lists are fixed and can only be extended by customising the system. An example option set field might be Organisation Type:
Prospect
Site
Head Office
...
If you want a pre-defined list that can be extended, you need to create a new entity. Following from the previous example, you would create a custom entity called Organisation Type and then create a record for each type you wanted, populating only the name field with the type: Prospect, Site etc.
Then you would add a lookup field pointing to the Organisation Type entity on any other entity that used the field, such as Organisation (Account).
You see how the custom entity still appears as simple data because you're only populating the name field, which can be text, a number etc. You can also apply security roles to this entity, limiting which users can create and delete options from your list.
Edit: to only allow the creation of new records in a subgrid, make sure the lookup attribute to the parent entity on the child entity is business required.

How to use Droplist types in Sitecore template fields

Is there anyone who knows how to use "Droplist" type in template fields?
I guess "Droplist" is the same as <select><option></option></select> type.
I'd like to specify select list types with static values so that Sitecore editors can select only one of many available lists when they create a page.
My plan is to add CSS class names (<option>) in the list (<select>) and editors will use one of styles by selecting one of them.
How to add the values in select list? Do I have to write code?
The Droplist is similar to the Droplink field type in that they are both dropdowns. The Droplist will only store the name of the item (so it will not have a link to that item), while the Droplink stores the ID of the item. That means if you rename an option, or move it elsewhere in your Content Tree, the Droplist will not update (resulting in possible broken links), the Droplink will update.
You can add values to the Droplist by setting the Datasource field in the templates to something (for instance /sitecore/content/Home/CSS/ if that's where you would like to store your CSS class names).
You can access the Droplist in code like so:
Item item = Sitecore.Context.Item;
string css = item["FieldName"]; // Also possible is item.Fields["Fieldname"].Value;
A Droplink could be accessed like this:
string dropDownItemId = item["Fieldname"]; // Or, again, item.Fields["Fieldname"].Value; if you prefer
var cssItem = Sitecore.Context.Database.GetItem(dropDownItemId); // And now you can
// access any fields in this item.
Edit
A good article going into some more detail in the differences between Droplink and Droplist
I would proceed exactly as #Trayek suggested in his solution. To expand on that, this should be your implementation:
You create your own template, maybe called CSS Class, and you will add a Single-Line Text field to it, maybe called Value. You will put the actual CSS classes in that field when you create the items.
Next, you will add a folder item somewhere in the Content tree, and you will add your CSS Class items to that folder. That folder will also be the datasource of your droplist/droplink.
To set your datasource, this blog post should be of help. You will be looking to use number 1 under For Fields without Search (screenshot included, below). I wrote the article a while back, so if you need any additional help just let me know.

How to filter items that display in a Sitecore Treelist?

I have the following content structure in Sitecore:
Home
Products
A-E
A Sample Product A
B Sample Product B
F-J
K-O
L Sample Product L
P-T
U-Z
In addition each Product has a checkbox field called "Active". I would like to have a Treelist that lets the user select one or more products - but they should only be allowed to select Products where the Active checkbox is checked. Is this possible?
It sounds like you can achieve what you need using Sitecore query. Check out the documentation for exact syntax rules.
Not all field types support Sitecore query though, so you will need to use a field type that does (Multilist). Or you could implement a custom TreeList field type that works with query.
You can also use the properties IncludeTemplatesForDisplay or IncludeTemplatesForSelection to keep your TreeList fields clean.
IncludeTemplatesForDisplay makes certain only those templates will show up in the TreeList.
IncludeTemplatesForSelection allows you to define which templates you can actually select in the TreeList field.
In your case, you could set IncludeTemplatesForDisplay the template of your Products item, then the A-E etc. items, and also the actual Products template. If you then select IncludeTemplatesForSelection you can make sure the content editors can still only select the actual product item.
Other parameters are ExcludeTemplatesForSelection, DatabaseName, ExcludeTemplatesForDisplay, IncludeItemsForDisplay, ExcludeItemsForDisplay and AllowMultipleSelection.
Do keep in mind that won't allow selections where a checkbox is ticked, but you could consider creating a custom field based on a TreeList field, which has the additional property which checks whether the Active field is set.
I'm not sure that there is a way out of the box to set the datasource of a treelist (or any list based field, for that matter) to a set of Items and filter by the value of their fields.
How about thinking about it differently.
What if you had a mirror of the products section of the tree somewhere else in your tree but, instead of having all products in this mirrored section, you'd have only the products that are active. The items in this mirrored section would have a drop-link field that maps to the original product in the original section of the tree. To keep this list up-to-date, you could use a custom action when the original product is saved. When a product is saved, if the Active checkbox is checked, create an item of type Mirrored Product (for example) in the Mirrored Products section of the tree and set the drop-link to the original product. When a product is saved, if the Active checkbox is not checked, find the Mirrored Product that maps to this product being saved and delete it.
Finally, the datasource for your treelist would be the root of these Mirror Products section of the tree, not the original products themselves. This way, the options for your treelist would always only ever items that map to products whose Active checkbox was checked.
One thing to keep in mind: when you delete a Mirrored Product, if it's referenced by a treelist, that reference will remain; you'll need to have your code check for null before trying to use a treelist item.