How can I create a function that copies some item from one Sharepoint discussion board to another? Everything is quite simple except field name Posted By, MyEditor, and Editor.
If this is a one-time thing, you might look at using the Content Deployment API (there's a Content Deployment Wizard app that provides a UI for it).
Otherwise, you should be able to set the "posted by" by using something like this (assuming web is an open SPWeb and newItem is a discussion item):
SPUser user = web.Users["DOMAIN\\username"];
newItem[SPBuiltInFieldId.Author] = user.ID;
newItem[SPBuiltInFieldId.Editor] = user.ID;
newItem.SystemUpdate();
Related
I'm just starting to use sharepoint designer and realised there's a lot that can be done to extend the basic features in sharepoint. We have an email alert sent out when a new task is created (by the user) and I want to customise the email so that it also includes a link called 'Assign'. When clicked, I want this link to automatically update the task with the assigned to field for the person that clicked it.
So I think the way to do this would be to hard-code the assign to value in the url behind this link, but I have no idea if this is possible or if there is an easier/better way to do this.
Any advice would be appreciated as I'm a complete beginner.
thanks.
I will not cover "How to modify the contents of an eamil alert" here as that is a seperate question and there are a lot of articles that cover that already.
For the Assigned link :-
You would need to create a custom page (or web part on an existing page) as the destination of your Assign link - this would take the Task ID as a query string param and then update the assigned to with the current user.
You could make this flexible by also taking the ListID but you may want to think about how this could be abused and put appropriate measures in place.
EDIT - in response to comment.
This is top of my head, not checked in compiler. This would have to sit on the same server as SharePoint to work as its using the OM - if you want to use a different server (why would you though) then look in the web services.
private void updateAssignedTo(Guid listId, int itemID)
{
SPWeb web = SPContent.Current.Web();
SPList list = web.Lists[listId];
SPListItem item = list.GetItemById(itemID);
item["Assigned To"] = web.CurrentUser;
item.Update();
}
You're going to have to work out how to get this code into to page or web part (SharePoint Designer is not going to cut it I think, you need Visual Studio) but its a starting point.
We use Sharepoint Services 3.0 as a project tracking tool. We have a list set up that contains your basic information (description, etc.) plus we have a "assigned person" column that is of type Person or Group that we use to associate list items with individuals. This column supports multiple selections.
We would like to set up alerts such that each person gets an alert email only if they are assigned to a list item. The approach we have taken is to set up a view on this list that is filtered to show list items where the assigned person equals [Me], and then to create an alert on this list that is set to send an email when someone changes an items that appears in the view.
This works well when there is only one person in the assigned person column. It does not work when there is more than one person in the assigned person column.
Does anybody know why this wouldn't work, or what I can do to troubleshoot? Is there a better way to achieve the end result? We could make several "assigned person" columns and not allow multiple selections, but that seems kind of kludgy.
Try this info site,
http://www.sharepointalert.info
it has a good alert trouble shooting guide.
The reason it works for one person but not multiple people is because the check is specifically against an individual. The comparison your view does is whether Assigned is equal to [Me], not if Assigned has [Me] as one of its entities.
Instead of using a list filter of is equal to, use the list filter contains. That should do the trick.
EDIT IN RESPONSE TO COMMENTS
To access the object model, you'll need to use Visual Studio. I'm unaware of a method to accomplish this kind of thing using SharePoint Designer, but maybe there's some sort of crazy Datasheet View thing you can do. Anyway... onto your actual needs...
The following code sample illustrates a very basic method for achieving your goal.
using (SPSite site = new SPSite("yourwebsiteurlhere"))
{
using (SPWeb web = site.OpenWeb())
{
SPList list = web.Lists["titleoflist"];
SPView view = list.Views["filteredviewname"];
view.Query = "<Where><Contains><FieldRef Name=\"assignfield\"/><Value Type=\"Integer\"><UserID Type=\"Integer\" /></Value></Contains></Where>";
view.Update();
}
}
Replace "yourwebsiteurlhere" with the website url, "titleoflist" with the title of your list in question, "filteredviewname" with the name of the view, and "assignfield" with the internal name that you used for your assignment field. If you created it through the standard SharePoint UI, this should be the name of the field without any spaces.
As far as where to run the code, you could put this kind of thing in a one-time workflow. I sometimes do that just to make sure I have necessary privileges. Hope this helps!
If you're not able to/allowed to use Visual Studio, then your solution will probably have to be to look into a 3rd party solution.
I'm working on a SharePoint publishing site and I want to "log" all the changes made by users in a SharePoint list.
Some searches on the web guided me to the EventReceiver.
But my EventReceiver must be generic and attached to all lists in the site collection. The "log list" has several columns like the name of the list in which the event occurred, the name of the modified item, its old value and its new value.
Can someone guides me on how to achieve this?
There's already a provided answer for you on StackOverflow, hurrayy!!
It sounds possible. Create a class that inherits from SPItemEventReceiver and override ItemUpdating. You can use the following code to get the list:
using (SPWeb web = properties.OpenWeb())
{
SPList list = web.Lists[properties.ListId];
}
You can then use list to grab the list's title and URL. Next, compare each DictionaryEntry entry in properties.AfterProperties to the corresponding value in properties.ListItem to get your differences. Then save it to your log list. The trick would be automatically attaching your Event Receiver to each newly created list. Perhaps a timer job would work.
That said...
Before trying any of that, go to your site collection's Site Settings. Under Site Collection Administration, click Site collection audit settings. Under Specify the Document and Item events to audit, check Editing items. Only go with a custom solution if that does not give you what you need.
Would Version history not achieve the same functionality?
You can see what fields were changed by who and when. Though you would have to look at a list by list basis.
You can also access the version history information via the object model if you want to generate reports web part.
Otherwise using Janis Veinbergs link on how to attach a event handler to all lists and Rich Bennema method of getting the values from the updated item in a generic way, though I would use ItemUpdated as you don’t want to change the data that was updated only copy it to another location so there is no need to catch the data before it is submitted to the SharePoint database
I'm looking to add a new field onto my NewForm.aspx, EditForm.aspx and DispForm.aspx pages in Sharepoint Designer 2007. I've managed to add a new textbox webpart and have edited the Common Textbox Tasks to make the Data Field my new field (Contacts..)
But how do I edit Edit.aspx and DispForm.aspx to display this new field?
I've looked around already answered questions on the site but I haven't run across what I'm really looking for -- sorry if I missed it!
Thanks!
Shannon
It doesn't count as "development", but wouldn't creating a new List column, Site Column or Content Type add this additional field to all your list forms just fine? How does this not work in your particular case?
You have to use SharePoint Designer to access the site and edit those aspx (in the 'Forms' subfolder of the folder named after the list)
You are probably going about this the wrong way. You should not need to change the edit and new forms for a list just because you want a new field. You do need to add the field to the underlying list and rely on the code in the forms to display the field correctly.
IN SPD choose the Table tab on the far right, then Select a row, then you can Insert Above or Insert Below, then you can add your new field.
New item, edit, and display forms aren't attached to lists so much as they attached to content types. If you can't use InfoPath or Designer to set these up, what you do is the following:
Create the form in question as an application page. For whatever reason, SharePoint application pages won't render on-screen, so to get an idea of what I'm looking at I generally make them in a visual web part or separate ASP application first, then copy and paste the ASP/HTML over, then delete the original.
In the case of edit and display forms, SP will pass you a query string with the ID in it. I capture the item in question thusly:
NameValueCollection nvQueryString = Page.Request.QueryString;
taskID = Convert.ToInt32(nvQueryString["ID"]);
ViewState["TaskID"] = taskID;
SPWeb thisWeb = SPContext.Current.Web;
SPList taskList = thisWeb.Lists["Job Request approval tasks"];
SPListItem taskItem = taskList.GetItemById(taskID);
After adding on whatever it is you need to add on, you do need to add logic to the .cs page or a separate class that actually edits/adds the item in question. Probably pretty obvious...
From here you have three options: either create an event receiver that points the editformURL/displayformURL/newformURL of the content type in question to your application page, create a brand new content type and add the URL for your application page in its XML definition, or add it manually via Powershell.
I have a customer request to create a number of announcements based on some data from another database. Most of it seems easy enough but the new elements should be created by the user (login) specified in the input data.
I was planning to add the announcements using the list web services but I sure would like to avoid using impersonation in order to get the create user right. Is there a way to assign the correct user as the creator without using impersonation?
This may not be the answer you are looking for, but impersonation is pretty easy if you have code running in the GAC on a SharePoint server. You don't need to know any password which many do not realize, so I'll continue assuming that this was the reason you did not want to do impersonation. Here's how to do it.
You can connect to SharePoint using the typical constructor you use for SPSite and find the appropriate SPUser object. Once you do that, you can get the UserToken property for that SPUser. Then you'll need to use the SPSite constructor again, but use the overload that provides the SPUserToken. Then anything you do in SharePoint will be done via impersonation. No need to run with elevated privileges.
OK, now that I've said it in words, I'll try to guess at the code. It should be something like:
// Just determine the user token for a particular user
SPUserToken userToken = null;
using (SPSite tempSite = new SPSite("http://sharepointurl"))
{
using (SPWeb tempWeb = tempSite.OpenWeb())
{
// I think this next line works, but I'm going from memory
// I believe the user needs to have already logged into the site at least once
SPUser user = tempWeb.AllUsers["username"];
userToken = user.UserToken;
}
}
// Now do whatever we want impersonating that user
using (SPSite site = new SPSite("http://sharepointurl", userToken))
{
using (SPWeb web = site.OpenWeb())
{
// Do whatever you want here
}
}
I don't think that there is a method to archive this.
But perhaps this workaround might help. I have to admit I never tested this, it's only an idea how you might solve your problem.
You could try this. Create the new announcement with an admin user or with RunWithElevatedPrivileges(). After that use the RunWithElevatedPrivileges() method again and set the "created by" field to the user who should be the actual creator of the announcement. By this way only the "edited by" field should show the "wrong" user.
I know this is not a very elegant solution but it might work. ;)
I just realized that that my requirement was actually to circumvent the audit trail in SharePoint so I sure hope that it can't be done :-)
I came up with another solution: I added a new user or group field to the announcement list, and copy the AD-user logon into this field. Any report or view that previously used the "created by" field should now use the new field.
How about the situation where a real user enters a new element in the announcement list then? That will not update the new field with the logged in user!
Well, the only solution I could come up with is to add a ListItem Add trigger on the list. When a new element is added I check whether the new field contains a value, is not then I update the new field with the ID of the logged in user. That way the new field should always contain a valid userID.
I know this is not an elegant solution, but for the time being it is the best I can think of.
As alluded to in the answer's code comments, if the user has not visited the site at least one time, then there is no user metadata available from which to derive a proper usertoken.
With SharePoint 2010, you can simulate a user visit, with the EnsureUser method available from the SPWeb class (this snippet creates the user and also tweaks their profile a bit):
SPUser alice = web.EnsureUser(#"MYDOMAIN\alice");
SPList userInfo = web.SiteUserInfoList; //metadata storage of user info
SPListItem item = userInfo.GetItemById(alice.ID);
item["About Me"] = "I am Alice from Mel's Diner";
item.Update();