Add a new SPView to an SPList - sharepoint-2010

I would need to create views and add them to lists programmatically. In the SPList method there is a Views Property of type SPViewCollection. This has an add method. But this method does not accept a full XML schema. It is divided into a number of paramaters (where you set the query, joins etc). I would need a method where I can just pass the full XML. I was thinking of first creating a 'Dummy' view using this Add method and then reading the View back, and finally using the SetViewXml. But it is a bit of dirty approach - perhaps there is something better and simpler that I am missing. Thanks!

Try this. I don't believe you need XML. You should only need to add the columns using a string collection.
using (SPWeb web = properties.Feature.Parent as SPWeb)
{
System.Diagnostics.Debug.WriteLine("Creating the list");
//web.AllowUnsafeUpdates = true; //use this in an application page no need in a dll
web.Lists.Add("Customers", "Store informations about my Company Customers", SPListTemplateType.GenericList);
web.Update();
System.Diagnostics.Debug.WriteLine("Creating the Fields");
SPList myNewList = web.Lists["Customers"];
myNewList.Fields.Add("First Name", SPFieldType.Text, false);
myNewList.Fields.Add("Last Name", SPFieldType.Text, false);
myNewList.Fields.Add("Adress", SPFieldType.Text, false);
myNewList.Fields.Add("City", SPFieldType.Text, false);
myNewList.Fields.Add("Latest Purchase Date", SPFieldType.DateTime, false);
myNewList.Fields.Add("Sales Comments", SPFieldType.Note, false);
myNewList.Update();
System.Diagnostics.Debug.WriteLine("Creating the view");
System.Collections.Specialized.StringCollection strColl = new System.Collections.Specialized.StringCollection();
strColl.Add("Title");
strColl.Add("First Name");
strColl.Add("Last Name");
strColl.Add("Adress");
strColl.Add("City");
strColl.Add("Latest Purchase Date");
strColl.Add("Sales Comments");
myNewList.Views.Add("Summary", strColl, #"", 100, true, true, Microsoft.SharePoint.SPViewCollection.SPViewType.Html, false);
myNewList.Update();
}

Related

Remove "MIME type" column from Filent Content List

I am Using a Script Adapter by passing payload to get contend for a Content List from "Search with values" event
When Contend get loaded to content list , i have a custom view to preview them. But if i clicked on MIME type column , It opens a separate view with the mapped viewer
So I need to remove this column or make it un-clickable
1) I am passing search values to content list's "Search with values" event , from where can i handle Content List's contend loading ,any Dojo Event i can use ?
2) With Script Adapter can i do this without going for a "response filter"
Edit :
As Nicely explained by "Ivo Jonker" (in his answer - "or try to specifically locate the widgets on your page" and with his example code)
responsed = page.ContentList8.ecmContentList.getResultSet();
var cols = responsed.structure.cells[0];
for (i=cols.length-1; i>0; i--){
var col = cols[i];
if (col.field=="mimeTypeIcon")
cols.splice(i,1);
}
page.ContentList78.ecmContentList.setResultSet(responsed);
I simply remove this row. Thanks Again and lovely blog , hope you keep posting more great articles.
The values passed through the Search With Values event will eventually be handled by the icm.pgwidget.contentlist.dijit.DocumentSearchHandler
that in turn creates a SearchTemplate to execute the search (ecm.model.SearchTemplate.prototype.search). One option would be to aspect/before/around the DocumentSearchHandler#query to manipulat the searchresults and by that way to remove the column.
The wiring however does not provide any handles to achieve this for a specific query-resultset combination leaving you to either fix this on a global scale (icm.pgwidget.contentlist.dijit.DocumentSearchHandler.prototype#query), or try to specifically locate the widgets on your page.
Personally, taking into account #2, i'd go for the responsefilter-option if you feel the global solution wouldn't be a problem, or alternatively i'd personally prefer to create a simple ICM widget that instantiates/implements a "plain" ecm.widget.listView.ContentList and exposes a wire to set the ecm.model.Resultset.
You'd then be able to create your own Searchquery in a scriptadapter, remove the column, and pass the resultset.
The script adapter could be something like:
var scriptadapter=this;
var queryParams={};
queryParams.query = "SELECT * FROM Document where id in /*your list*/";
queryParams.retrieveAllVersions = false;
queryParams.retrieveLatestVersion = true;
queryParams.repository = ecm.model.desktop.repositories[0];
queryParams.resultsDisplay = {
"sortBy": "{NAME}",
"sortAsc": true,
"columns": ["{NAME}"],
"honorNameProperty": true};
var searchQuery = new ecm.model.SearchQuery(queryParams);
searchQuery.search(function(response/*ecm.model.Resultset*/){
//remove the mimeTypeIcon
var cols = response.structure.cells[0];
for (i=cols.length-1; i>0; i--){
var col = cols[i];
if (col.field=="mimeTypeIcon")
cols.splice(i,1);
}
//emit the resultset to your new contentlist, be sure to block the regular synchrounous output of the scriptadapter
scriptadapter.onPublishEvent("icm.SendEventPayload",response);
//The contentlist wire would simply do contentlist.setResultSet(response);
});

Is it possible to dynamic set menu items in a wxMenu?

Hi: I have in a wxFrame a menubar with this wxMenus: File|Edit|Personal. During the frame creation the wxMenu Personal has two wxMenuItems (Information and Need Help), which tells the user that must fill the form and help abou how to fill it. After the user fills the form with personal information, the menu is populated with new items: send, clear, check and remove, deleting/removing the previous ones... At this point I manage to trap the event, like this:
Bind (wxEVT_MENU_OPEN, &MyFrame::processMenuPersonal, this);
// the method
void MyFrame::processMenuPersonal (wxMenuEvent& event) {
wxMenu *menu = event.GetMenu ();
wxMenuItem *item = menu->FindItem (IDM_PERSONAL_EMPTY);
if (item) {
// here I want to dynamic add items and remove the current ones
}
}
Any ideas about how to do this?
Yes. Just append as submenu and treat it like any conditional statement. Here is a sample
void MyFrame::processMenuPersonal (wxMenuEvent& event) {
wxMenu *menu = event.GetMenu ();
wxMenu *item = menu->GetMenu(YOUR_MENU_INDEX);
menu->AppendSubMenu(item, wxT("User Items"));
if (YouConditionHere) {
item->Append(wxID_ANY, "Item 1")
item->Append(wxID_ANY, "Item 2")
item->Append(wxID_ANY, "Item 3")
}
}
Note that Items 1,2,3 are the information you want to append after processing your data (in your case deleting old entries)

Using Rich Text Editor in Orchard CMS Custom Module

I am creating a custom module in Orchard CMS 1.7.1
So far all is going well (ish)
One of my properties is a string (called InfoBubbleHtml).
I would like to utilise the rich text edit for this input on my modules create/edit form.
Is there a helper already in place that would render my property as a rich text area rather than just a textarea or input field?
If not, what would i need to do to be able to have this property render the rich text editor?
Thanks in advance.
Update
As an update/addition to this question... Any HTML that I enter into my current text area is being ignored; guessing to do with request validation. how is this disabled for my controller so i can allow html in the admin?
Update 2
Ok, so i have figured out how to add this to my view by using:
#Display.Body_Editor(Text:Model.InfoBubbleHtml,EditorFlavor:"html")
Any idea how to set the ID of the editor?
#Display.Body_Editor(Text:Model.InfoBubbleHtml,EditorFlavor:"html") is rendering a shape named Body.Editor.cshtml.
This file lives in : Orchard.Web\Core\Common\Views\Body.Editor.cshtml
And it's content is
#using Orchard.Utility.Extensions;
#{
string editorFlavor = Model.EditorFlavor;
}
#Html.TextArea("Text", (string)Model.Text, 25, 80, new { #class = editorFlavor.HtmlClassify() })
So using this Shape you cannot set Id, Model is the anon that you send on the Display (Text and EditorFlavor).
Shapes.cs on Orchard.Core/Common is hooking an alternate using the EditoFlavor string.
public void Discover(ShapeTableBuilder builder) {
builder.Describe("Body_Editor")
.OnDisplaying(displaying => {
string flavor = displaying.Shape.EditorFlavor;
displaying.ShapeMetadata.Alternates.Add("Body_Editor__" + flavor);
});
}
So the final file that is rendered : TinyMVC\Views\Body-Html.Editor.cshtml
using Orchard.Environment.Descriptor.Models
#{
var shellDescriptor = WorkContext.Resolve<ShellDescriptor>();
}
<script type="text/javascript">
var mediaPickerEnabled = #(shellDescriptor.Features.Any(x => x.Name == "Orchard.MediaPicker") ? "true" : "false");
var mediaLibraryEnabled = #(shellDescriptor.Features.Any(x => x.Name == "Orchard.MediaLibrary") ? "true" : "false");
</script>
#{
Script.Require("OrchardTinyMce");
Script.Require("jQueryColorBox");
Style.Require("jQueryColorBox");
}
#Html.TextArea("Text", (string)Model.Text, 25, 80,
new Dictionary<string,object> {
{"class", "html tinymce"},
{"data-mediapicker-uploadpath",Model.AddMediaPath},
{"data-mediapicker-title",T("Insert/Update Media")},
{"style", "width:100%"}
})
You need to add this to the template and include another parameter in the TextArea Dictionary parameter named : {"id", "THE ID YOU LIKE"}.
Take a look at the docs about Shapes if you want to learn more Docs
You can patch the TinyMVC\Views\Body-Html.Editor.cshtml file to enable it to use custom Name/ID for the text area. The modification is quite simple - replace
#Html.TextArea("Text", (string)Model.Text, 25, 80,
with
#Html.TextArea((string)Model.PropertyName ?? "Text", (string)Model.Text, 25, 80,
Now you can use additional parameter PropertyName in your call:
#Display.Body_Editor(PropertyName:"InfoBubbleHtml", Text:Model.InfoBubbleHtml, EditorFlavor:"html")
The downside is that you are patching a foreign code and have to reapply this patch every time this file in TinyMVC module is updated.

JSFL: selecting items returned by fl.findObjectInDocByType()

I can't seem to use the info returned by fl.findObjectInDocByType() with fl.getDocumentDOM().selection.
I want to use document.setTextRectangle to re-size some text fields from an array generated using fl.findObjectInDocByType().
I can easily access all the textObject properties but since document.setTextRectangle requires a current selection, I am at a loss.
The example in the documentaion for setting selection is:
fl.getDocumentDOM().selection = fl.getDocumentDOM().getTimeline().layers[0].frames[0].elements[0];
fl.findObjectInDocByType() returns an array of objects with the attributes: (object.timeline, object.layer, object.frame, object.parent)
But these are objects, and don't have a property for array index numbers required by fl.getDocumentDOM().selection=...
var doc = fl.getDocumentDOM();
var textFieldArray = fl.findObjectInDocByType("text", doc);
for (var i=0; i < textFieldArray.length; i ++){
fnResizeTheTextField(textFieldArray[i]);
}
function fnResizeTheTextField(theTextField){
//force current selection to be theTextField
//doc.selection MUST be an array, so assign theTextField to an array...
var selectArray = new Array();
selectArray[0] = theTextField.obj;
var theTimeline =theTextField.timeline;
var theLayer =theTextField.layer;
var theFrame =theTextField.frame;
doc.currentTimeline =theTextField.timeline;
doc.selection = doc.getTimeline().theLayer.theFrame.selectArray;//error
//resize the text rectangle
doc.setTextRectangle({left:0, top:0, right:1000, bottom:1000});
}
}
Result: Error:doc.getTimeline().theLayer has no properties
It turns out, the ObjectFindAndSelect.jsfl script already contains a function specifically for this: fl.selectElement(). Much more elegant:
var doc = fl.getDocumentDOM();
// generate an array of elements of type "text"
var textFieldArray = fl.findObjectInDocByType("text", doc);
for (var i=0; i < textFieldArray.length; i ++){
fnResizeTheTextField(textFieldArray[i]);
}
function fnResizeTheTextField(theTextField){
//force current selection to be theTextField
fl.selectElement(theTextField,false);//enter 'edit mode' =false...
//resize the text rectangle
doc.setTextRectangle({left:0, top:0, right:1000, bottom:1000});
}
}
I found the answer. In order to select anything for a document level operation, you have to also make flash focus on the keyframe of that object.
so, if I loop through an array of objects created by fl.findObjectInDocByType(), I use this code to make flash focus on the object correctly:
function fnMakeFlashLookAt(theObject){
doc.currentTimeline =theObject.timeline;
doc.getTimeline().currentLayer =theObject.layer;
doc.getTimeline().currentFrame =theObject.frame;
}
this may not work on objects nested inside a symbol however.
I had a similar issue recently, and apparently all google results about setTextRectangle() direct us here. It's unbelievable how poorly documented jsfl is :)
If you need to use setTextRectangle() inside an library item that is not on stage, you need to open for edit the item first.
Here's the code that solved my problem:
library.selectItem(libraryItemName);
doc.selection = [tf];//where tf is the reference to textfield we need to edit
doc.library.editItem(libraryItemName);
doc.setTextRectangle({left:l, top:t, right:r, bottom:b});
doc.selectNone();
If you have a better working solution, please post. I hope it saves somebody's time. Good luck!

How do I show the correct Taxonomy control in a SharePoint 2010 EditModePanel?

We have a custom content type in our SharePoint 2010 build which includes a Managed Metadata field for keywords.
The field seems to have deployed OK because if I edit an item in the list in which it resides I get the correct Taxonomy picker control and my terms are retrieved from the term store.
However; we are using an EditModePanel on the PageLayout for the item to allow in-site editing of the items and I can't get the correct Taxonomy picker control to appear.
If I add a TaxonomyWebTaggingControl to the page layout and hardcode the SSPId etc then it works;
<TaxonomyControls:TaxonomyWebTaggingControl runat="server" SSPId="234234-234234-34341-343" TermSetId="234234-23342-34234-234-234"/>
However we can't hardcode the values as the term store will be created when the client deploys the site.
When we create the Content type we have an Event Receiver which binds the field to the correct Term Store/Set using their names but I don't understand how to get a field in the EditModePanel to get/set these.
What I really want is something like:
<TaxonomyControls:TaxonomyWebTaggingControl runat="server" TermStore="My term store name" TermSet="Keywords"/>
Am I missing something?
My event receiver looks like this:
try
{
SPSite site = ((SPWeb)properties.Feature.Parent).Site as SPSite;
Guid fieldId = new Guid("3211B052-5332-424C-A066-BBE21AEAB878");
if (site.RootWeb.Fields.Contains(fieldId))
{
TaxonomySession session = new TaxonomySession(site);
if (session.TermStores.Count != 0)
{
var termStore = session.TermStores["Managed Metadata Service"];
var group = termStore.Groups.GetByName("My Client");
var termSet = group.TermSets["Keywords"];
TaxonomyField field = site.RootWeb.Fields[fieldId] as TaxonomyField;
field.SspId = termSet.TermStore.Id;
field.TermSetId = termSet.Id;
field.AnchorId = Guid.Empty;
field.AllowMultipleValues = true;
field.TextField = fieldId;
field.TextField = new Guid("{574C5BCE-74E8-40C8-BE90-C9338135D491}");
field.Update();
Log.Logger.LogEvent("ContentType Activation", "Updated keywords field with MMS details");
}
}
}
catch (Exception ex)
{
Log.Logger.LogException(ex, "Content Type Activation", ex.Message);
}
You should use the TaxonomyFieldControl for this:
<%# Register Tagprefix="Taxonomy" Namespace="Microsoft.SharePoint.Taxonomy" Assembly="Microsoft.SharePoint.Taxonomy, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<Taxonomy:TaxonomyFieldControl FieldName="My Field Name" runat="server" id="myField"/>