Regex Validation for TreelistEx is not working - regex

In Sitecore Content editor/Page editor, when I add items to TreelistEx I would like the TreelistEx to allow only 12 items. To achieve this solution, I have added a Regex ^.{0,467}$ in the validation field inside the template section in which I want to limit the items.
I have referred this article
This Regex works properly in Content editor. But for the page editor whenever I add an items in treelistEx it works fine for the first time but again if I add/remove items it gives me validation message for both greater and less number of items just after on click of "Ok"and items are also not saved.
Ideally it should give validation message if number of items are greater than 12 and only on Click of "save" button same as it is working in Content editor. How can I solve this Regex validation problem in Page editor? I am using Sitecore 8.1

I also had the same issue a while ago and because of the limited time i had i implemented a not so ideal way but you can implement it if you want.
Let the user add the items and then just grab the first 12 in your code. It will be something like this:
Create a method to get the multicast item (For flexibility).
public static MultilistField GetMultilistField(Item item, string fieldName)
{
if (item != null && !string.IsNullOrWhiteSpace(fieldName))
{
MultilistField field = item.Fields[fieldName];
if (field != null)
{
return field;
}
}
return null;
}
Get the items within the Miltilist field.
MultilistField field = GetMultilistField[DatasourceItem, "fieldName"];
var returnList = field.GetItems().Where(c => c.TemplateName.Equals("someValidationIfYouWant")).ToList().Take(12);

Related

Acumatica-LotSerialNbrAttribute screen on mobile app

I'm using Acumatica customization Acumatica-LotSerialNbrAttribute
This customization adds a new screen for look for InventoryID and LotSerialNbr and visualize its attributes.
I'm trying to add this window to the acumatica mobile app.
Here my code:
add screen IN202501 {
add container "InventoryLotSerialContainers" {
add field "InventoryID"
add field "LotSerialNbr"
add group "Attributes" {
displayName = "Attributes"
collapsable = True
add attributes "AttributesAttributes"
}
add recordAction "Save" {
behavior = Save
}
add recordAction "Cancel" {
behavior = Cancel
}
attachments {
}
}
}
And the screen is visible on the mobile app with the 2 selectors
Then I select Inventory and when I select Lot Serial Nbr, the first selector is in blank, causing that I can't review the attributtes neither save the information.
Here the InventoryID selector in blank.
Hope you can help me to successfully publish this screen on acumatica mobile app.
Thanks.
Attributes are a grid style representation in Acumatica. That means you need a container that will show multiple records. I'm getting rusty on mobile pretty quickly, but I believe your definition is set to display a single value value only.
Try adding a separate container for attributes:
add container "AttributesAttributes" {
add field "Attribute"
add field "Value"
}
This should open into a view of multiple records, showing all of your attributes. By specifying the Attribute and Value fields, you should see both data elements in the container.

Sitecore get all parent (ancestor) with little processing (performance)

I'm trying to come up with solution on getting all the ancestors for the context item. One option is to store _path in index and other option is to do similar to one below:
http://www.glass.lu/Blog/GettingAncestors
I'm having no luck with getting the solution work for above (glass mapper) solution.
I got the index solution working but would like to avoid using index just to get the _path (collection of ancestors) as we don't have any other requirements to use index e.g. search etc.
Appreciate if someone could share the snippet for working solution or even better if Glassmapper has already included the above blog solution.
The most efficient way to check if one item is a descendant of another is to simply check that the current item property Paths.LongID starts with the LongID of the parent item:
Item currentItem = Sitecore.Context.Item;
IList<Item> menuItems = GetMenuItems();
foreach (var menuItem in menuItems)
{
bool isActive = currentItem.Paths.LongID.StartsWith(menuItem.Paths.LongID);
// do code
}
This will work since the path GUIDs are unique for each item.
Alternatively, if you want to use Glass models only then you can use the SitecoreInfoType.FullPath attribute:
[SitecoreInfo(SitecoreInfoType.FullPath)]
public virtual string FullPath { get; private set; }
And then from your code you can simply check:
Item currentItem = Sitecore.Context.Item; //or use SitecoreContext() to get a strongly types model
IEnumerable<MenuItem> menuItems = GetMenuItems();
foreach (var menuItem in menuItems)
{
bool isActive = currentItem.Paths.FullPath.StartsWith(menuItem.FullPath);
// do code
}
Just a word of warning, since each menu item now need code to run in order to determine state, this will make your menu component difficult to cache, resulting caching too many variations or caching per page. You would be better to move this logic into Javascript to set the menu state using the current page URL, this will allow your component to be cached once for all pages.

How to determine in sitecore whether given item is start item?

In config file we set start item for each website in element (e.g. startItem="/Home"). And we also can select start item in code. But what I am asking about is how to determine for any selected item whether it is start item or not?
At least we can select start item and compare with given item, but it is not elegant code I think
We typically have an extension method on the SiteContext class to get the Home Item:
public static class SiteExtensions
{
public static Item GetHomeItem(this SiteContext site)
{
return Sitecore.Context.Database.GetItem(site.StartPath);
}
}
With this you can test any item (not just the Context item) to see if it's the home item.
Item home = Sitecore.Context.Site.GetHomeItem();
if (Sitecore.Context.Item.ID == home.ID)
{
// Context item is the home item
}
Just from the top of my head:
bool isStartItem = item.Paths.FullPath.Equals(
Sitecore.Context.Site.StartPath, StringComparison.OrdinalIgnoreCase)
I support there may be cleaner solution but this one works and is fast.
Remember that in multisite solutions for one site your item can be a start item while for another site sane item doesn't have to be a start item.

Sitecore: multilist during deployment

How to enable the multilist to be control in content editor?
for example I have a list of item, item1 to item10. In the standard template value, I defined item1,2,3. After I have deploy the solution, how am I going to enable users in content editor mode or page editor mode to select item7,8,9 and 10?
And also, after I tested/rendered the multilist, only RAW VALUES are being rendered, is there any possible to render the item name such as item1? Do I need to customize the multilist?
The multilist control should be directly visible to the user in the Content Editor, you do not need to do anything else. Since you defined some items in standard values then those will be "pre-selected" when that item is first created. The user can then add the additional items as required.
To allow users to select values from the Page Editor you can Use Sitecore EditFrame in PageEdit
The reason the item is being rendered as the raw value is because you need to get the item and then iterate over the target id's. There is an example of this here here
//Get a multilist field from the current item
Sitecore.Data.Fields.MultilistField multilistField = Sitecore.Context.Item.Fields["myMultilistField"];
if (multilistField != null)
{
//Iterate over all the selected items by using the property TargetIDs
foreach (ID id in multilistField.TargetIDs)
{
Item targetItem = Sitecore.Context.Database.Items[id];
litItemTitle = targetItem.DisplayName;
// Do something with the target items
// ...
}
}
You can use the following instead for the datasource of a repeater
Sitecore.Data.Fields.MultilistField multilistField = Sitecore.Context.Item.Fields["myMultilistField"];
Sitecore.Data.Items.Item[] items = multilistField.GetItems();

How do I utilize the save event in a Sitecore custom Item Editor?

I am creating a custom item editor, and am using the following blog post as a reference for responding to the "save" event in the Content Editor, so that I do not need to create a second, confusing Save button for my users.
http://www.markvanaalst.com/sitecore/creating-a-item-editor/
I am able to save my values to the item, but the values in the normal Content tab are also being saved, overriding my values. I have confirmed this via Firebug. Is there a way to prevent this, or to ensure my save is always after the default save?
I have this in as a support ticket and on SDN as well, but wondering what the SO community can come up with.
Thanks!
Took a shot at an iframe-based solution, which uses an IFrame field to read and save the values being entered in my item editor. It needs to be cleaned up a bit, and feels like an interface hack, but it seems to be working at the moment.
In my item editor:
jQuery(function () {
var parentScForm = window.parent.scForm;
parentScForm.myItemEditor = window;
});
function myGetValue(field) {
var values = [];
jQuery('#myForm input[#name="' + field + '"]:checked').each(function () {
values.push(jQuery(this).val());
});
var value = values.join('|');
return value;
}
In my Iframe field:
function scGetFrameValue() {
var parentScForm = window.parent.scForm;
if (typeof (parentScForm.myItemEditor) != "undefined") {
if (typeof (parentScForm.myItemEditor.myGetValue) != "undefined") {
return parentScForm.myItemEditor.myGetValue("myLists");
}
}
return null;
}
In theory, I could have multiple fields on the item which are "delegated" to the item editor in this way -- working with the content editor save rather than trying to fight against it. I'm a little uneasy about "hitchhiking" onto the scForm to communicate between my pages -- might consult with our resident Javascript hacker on a better method.
Any comments on the solution?
EDIT: Blogged more about this solution