Deleting Orchard CMS HtmlWidget in code - orchardcms

I have a HtmlWidget with an IdentityPart with an Id value like "/Identifier=40b3f227-61af-4d8b-95c9-53bd6021a70e".
<HtmlWidget Id="/Identifier=40b3f227-61af-4d8b-95c9-53bd6021a70e" Status="Published">
<IdentityPart Identifier="40b3f227-61af-4d8b-95c9-53bd6021a70e" />
....
What would be the right way to delete a widget like this in code?
I assume we grab the object using the contentmanager somehow and delete or unpublish it. But I am not sure about the exact mechanics of doing that. Would appreciate an example and some guidance on the approach.

Basically you retrieve the item the item using the content manager as you have suggested. For example if you wanted to retrieve the item by its identity:
var item = _contentManager.Query<IdentityPart, IdentityPartRecord>()
.Where(c => c.Identifier == "40b3f227-61af-4d8b-95c9-53bd6021a70e")
.Slice(0, 1).FirstOrDefault();
Then you pass the retrieved content item back to the content manager to remove or unpublish:
if (item != null)
{
//delete the item - remains in the db but is no longer a draft or published
_contentManager.Remove(item.ContentItem);
//or unpublish
_contentManager.Unpublish(item.ContentItem);
}

Related

How to access document attachments from hierarchical transformation

My site has this structure:
Products
category 1
item 1
item 1 attachments
category 2
item 2
item 2 attachments
I have successfully written a hierarchical transformation that shows the data on the page at the top level. I cannot for the life of me figure out how to access the attachments for each document though.
Anyone have any idea?
If you are talking about Group attachments (this is when you have a field in your page type using the Attachments data type) then in order to access the attachments inside your transformation you need to write either a custom macro (when using Text/XML transformation) or custom transformation method. Both can be done very easily. The code itself that gets you the attachments can be like this:
public ObjectQuery<AttachmentInfo> GetAttachmentsFromField(string className, int documentID, string attachmentColumnName)
{
// get class info
var classInfo = new FormInfo(DataClassInfoProvider.GetDataClassInfo(className).ClassFormDefinition);
if (classInfo != null)
{
// get attachment field definition
var attachmentsField = classInfo.GetFormField(attachmentColumnName);
if (attachmentsField != null)
{
// get attachments strored in the field by GUID
var attachments = AttachmentInfoProvider.GetAttachments()
.WhereEquals("3CCC6E6C-56F3-42EB-8385-979973D99C55", attachmentsField.Guid)
.And()
.WhereEquals("AttachmentDocumentID", documentID);
return attachments;
}
}
return null;
}
With this it is very important to take into account that this code introduces several other SQL queries against database and therefore it should be optimized by using caching appropriately.
I suppose you mean unsorted attachments you add in Properties -> Attachments section. In this case yuo can register following control in your transformation:
<%# Register Src="~/CMSInlineControls/DocumentAttachments.ascx" TagName="DocumentAttachments" TagPrefix="cms" %>
And use it like this:
<cms:DocumentAttachments ID="ucDocAttachments" runat="server" TransformationName="cms.root.attachment" Path='<%# Eval("NodeAliasPath") %>' />
I wrote a pretty detailed blog post on this a while back. It describes very similar attributes to Enn's answer but gives great detail on why you do specific things.

Write the plugin when Selecting the lookup flied and according to filed selection Show/Hide Address filed in form.....?

We Have Contact Entities in contact Entitie one lookup filed company Name in that lookup having two values 1.Account and 2.Contact . When we are selecting contact show the address filed when we select account hide the address filed we needs to write the plugin to Execute that works. Kindly any one help me on the same.
Thanks!!
Rajesh Singh
First, if you need to make change on a form, you can't use plug-ins. Plug-ins are made for bussinees logics, like Update another record when the first one is created, make complex logic, etc...
What you need it is a javascript that executes on the OnLoad of the form and OnChange event in that OptionSet.
The lines you are looking for are:
function ShowField()
{
// The field is present on the form so we can access to its methods
var optionSet = Xrm.Page.getAttribute("custom_attribute");
if (optionSet == undefined)
{
return;
}
// The control is present on the form so we can access to its methods
var controlAddress = Xrm.Page.getControl("custom_address");
if (controlAddress == undefined)
{
return;
}
var valueOptionSet = optionSet.getValue(); // This is the value you set creating the OptionSet
switch (valueOptionSet)
{
case 0: // Your account value, show
controlAddress.setVisible(true);
case 1: // Your contact value, hide
controlAddress.setVisible(false);
default:
return;
}
}
You need to register a web resource and register the event, if you need more information about the code or why this stuff is here and why this not just tell me.

On Orchard CMS, how can I display a message when the query returns no records for a projection

Using the admin panel on Orchard CMS I've created the following:
A content type called CalendarEvent, it contains several fields including the EventDate;
A query that has 2 filters, one by the content type (= CalendarEvent) and another one based on the date of the event. The Display Mode on the Layout is set to Properties;
A projection to display the query when a menu item is clicked.
The problem is that based on the EventDate we only display upcoming events, not the ones in the past. If for some reason there are no events to be displayed, all the user gets is an empty page with no information whatsoever.
My question is, how can I modify my query or projection in order to display something like: "There are no current events scheduled"?
I know the Properties on the Query's Layout allow me to specify a "No Result", but this implies that a record is present and that the actual property is empty. However, in my example, no record is present.
Thank you all in advance.
Rafael
By the way, I am using the latest Orchard version 1.6.
What I have done is to create a shape and use it as a view in my query. The shape will then have an if statement to check if the query return gives any results.
Example:
#using Orchard.ContentManagement
#using Orchard.Utility.Extensions
#{
var dealsTerms = ((IEnumerable<ContentItem>)Model.ContentItems).ToList();
}
#if (dealsTerms.Any() )
{
<div>
#foreach (var dealTerm in dealsTerms)
{
var contentManager = dealTerm.ContentManager;
<div>
#Display(contentManager.BuildDisplay(dealTerm, "Summary"))
</div>
}
</div>
}
else
{
<p>No deals found</p>
}
I used this article as reference:
http://www.ideliverable.com/blog/ways-to-render-lists-of-things
Good luck
If your projections are Layouts elements, you can create a Projection.cshtml file in your theme's Views/Elements folder with the following:
#{
var list = Model.List;
var pager = Model.Pager;
if (list != null)
{
#Display(list)
if (list.Items.Count == 0)
{
<div>There are currently no items.</div>
}
}
if (pager != null)
{
#Display(pager)
}
}
This is a copy of the default template with the if (list.Items.Count == 0) section added. Edit as needed.

SharePoint: How do I create a new list from a list template?

I've created a list template based on an Issue list and it is saved in the List Template Gallery. Now how do I create a new list based on this template?
string internalName = "MyListTemplateName";
SPListTemplate t = null;
foreach (SPListTemplate template in web.ListTemplates)
{
if (template.InternalName.Equals(internalName)
{
t = template;
break;
}
}
web.Lists.Add("nameoflist", "description", t);
I just encountered the same situation today.
I saved a list as a template and i wanted to use that template in a new list.
On Sharepoint 2013, go to Site Contents > Add an App >
Scroll down and you will see a page numbering saying that you are on page 1
Click on the second page and all your saved templates will be there
It probably just took a while for the timer job to fire.
The template eventually showed up as an option under Lists > Create > Tracking section after a few minutes.
I'm surprised that Johan Leino's answer is marked as useful multiple times as it doesn't work in this particular case. If you create a template yourself, web.ListTemplates does not store it and you won't be able to create the list. It's only working for out-of-the-box templates.If you want to create a list based on your custom template you need to do it this way:
SPListTemplateCollection listTemplates = web.Site.GetCustomListTemplates(web);
SPListTemplate listTemplate = listTemplates["MyCustomTemplate"];
Guid listId = web.Lists.Add("My New List Name", "My Description", listTemplate);
if (listId != null) { //all good }

Sharepoint List redirect with new id

I have a list within Sharepoint, using a custom new form I have added a custom list form control ("New item form" for the list) and changed the SaveButton to a standard input HTML button, and added an 'onclick' event that is as follows:
onclick="javascript: {ddwrt:GenFireServerEvent('__commit;__redirect={NewFormWizard2.aspx?id=}')}"
This works as in saves the data and redirects to the NewFormWizard2.aspx?id= page.
How do I get the ID of the created item to be passed to the redirected page?
Thus once the form is completed it would redirect to NewFormWizard2.aspx?id=23
jtherkel was close, but was missing a '}' on the end of the redirect url. I used an extra concat below
<input type="button" value="Submit" name="btnSave" onclick="javascript: {ddwrt:GenFireServerEvent(concat('__commit;__redirect={lists/MyListName/DispForm.aspx?ID=',/dsQueryResponse/Rows/Row/#ID,'}'))}" />
I am not sure where the ID will exist on the page you host the Javascript from. Does it appear in the querystring or on a field on the page?
There is nothing in the request or response that will identify the item. I have had this issue when doing some web loadtesting.
I can only suggest that your create the item using the webservices as that at gives you some return xml.
This answer does not solve the "new form" issue, but it might help others with the syntax for screens that contain existing list items.
I tested this quickly in my SharePoint (MOSS 2007) environment.
onclick="javascript: {ddwrt:GenFireServerEvent(concat('__commit;__redirect={NewFormWizard2.aspx?id=',/dsQueryResponse/Rows/Row/#ID))}"
The concat syntax is an XSLT instruction that tells the processor to combine the values enclosed in single quotes. I adapted this answer from info I found here.
Loading Values in a Custom List Form
http://wssdevelopment.blogspot.com/2007_04_01_archive.html
I hope this would be helpfull:
1- In SharePoint Designer create new page, call it for example "LastItem.aspx" and place a dataview on it with a single form view for the destination list item.
2-Limit paging to just one record, set the sorting by ID and descending and filter the list to just show item which is created by [current user].
3-Now you do not need to pass any query string to this page. just replace the default "OK" button in NewForm.aspx of the list with a standard HTML input button and add this to its definition "onclick="javascript: {ddwrt:GenFireServerEvent(concat('__commit;__redirect={LastItem.aspx}". After submitting a new item to list you will be redirected to an edit view of the created item.
You can do the same for save button in LastItem.aspx to redirect to some other page after clicking on save button.
found an approach using pure javascript (JQuery) and the SPAPI code from http://darrenjohnstone.net/.
The list contains two fields, title and BodyCopy
I've thewn created a form that asks for a title and a question, both text fields, then the submit button calls the following function: (note that ServerAddress and LIST_question need to be updated to your own details).
The function then uploads the details using the SOAP service within LISTS.ASMX and using the response gets the ID of the new item and redirects the page.
var LIST_question = '{xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}';
var ServerAddress = 'http://xxx/';
function submitQuestion()
{
var title = new String($("#title").val());
var t = new String($("#question").val());
t=t.trim();
if(t=="")
return;
title=title.trim();
if(title=="")
return;
var lists = new SPAPI_Lists(ServerAddress) ;
//
var newItem = { Title : title, BodyCopy : t};
var items = lists.quickAddListItem(LIST_question, newItem);
var id=-1;
if (items.status == 200)
{
var rows = items.responseXML.getElementsByTagName('z:row');
if(rows.length ==1)
{
var r = rows[0];
var id = r.getAttribute('ows_ID');
window.location.href='DispForm.aspx?ID='+id;
}
else
{
alert("Error: No row added");
}
}
else
{
alert('There was an error: ' + items.statusText);
return;
}
}
You can achieve this using JavaScript http://www.sharepointdrive.com/blog/Lists/Posts/Post.aspx?ID=9

Resources