Question

sharepoint 2013

I have a list where users should be able to create only one item per day (every user can create only one item per day).

Any help or suggestion how to manage this?

Était-ce utile?

La solution

Note:

Since june 2017 this answer no longer applies for SharePoint versions;
Microsoft disabled the use of JavaScript in a Calculated Columns

For long explanation and work arounds see:
June 13th 2017 Microsoft blocked handling HTML markup in SharePoint calculated fields - how to get the same functionality back


Original answer:


Disclaimer:

The best failsave solution is indeed Server-Side Code that never displays an EntryForm.

But hiding the new form is a much easier solution and can be done out of the box (But you have to think out of that box)

You need:

  • A WebPart on the NewForm
  • displaying a View
  • with one Calculated Column
  • executing 2 lines of JavaScript

Step 1 - Tell SharePoint what you want

  • Open your List/Library
  • Add a Calculated Column "EntryLimit"
  • Set the Formula to:

    ="<b style=color:red>Please SharePoint, I need a one item per day limit</b>"
    

    (The Please SharePoint part is not required.. but does help)

  • Set the datatype to: Number
    (this will make it all work, explanation at: http://www.viewmaster365.com/#/How)

  • Do not add this column to the default View or ContentTypes !!!
  • Save the Column
  • (optional) Open the Column again, and make a Browser Favorite of this EditColumn page
    (this will make later editting a whole lot easier)

Step 2 - Create a View

  • Create a new View "EntryLimit" in you List/Library
  • Include the EntryLimit Column you just created
  • Include (but not required) the Fields: Created, Created By, Modified , Modified By

Now let SharePoint do what you need

  • Set the Filter to: Created By=[Me] and Created=[Today]

  • Save the View
  • If the View is empty, create a new Item

Step 3 - Add the View to NewForm

  • Open the NewForm (edit Page, no need for SharePoint Designer)
  • Add the "EntryLimit" View from your List/Library to the page
  • Move the WebPart to the bottom (WebPart->Layout->Zone Index:99)
  • Save the page
  • Open the page to Create a New Item

Your New Form should now look like:

Tip!! You can use Audience Targetting on this WebPart to only apply the OneEntry restriction to certain users/groups.

Step 4 - Hide the New Form with the List Item as the trigger

You now have 2 options:

On SP2013 you can use CSR - Client Side Rendering:

  • Create a Javascript file with some 20 lines of code to change the NewForm
  • Make a JSlink to execute that code (only) when the EntryLimit Column is displayed

But I am lazy and that is way to much work for me

  • Go back to the List Settings and edit the Calculated Column "EntryLimit"
    I told you to create a direct link with a Browser Favourite
  • Change the Formula to:

    ="<img src=/_layouts/images/blank.gif onload=""{"
      &"var msg='<h1 style=color:red>This List has a one item per day limit</h1>';"
      &"document.getElementById('DeltaPlaceHolderMain').innerHTML=msg;"
    &"}"">"
    

Explanation on How this works at: http://www.viewmaster365.com/#/How

Step 5 - That is it

If a user has Created a List Item Today, that Item will be displayed on the New Form, the JavaScript code from the EntryLimit Column will be executed, it will replace the whole Form with a text.

Yes, the whole page is displayed and then replaced. If you don't want that you need to use/add the other coding solutions.

Step 6 - Clean up

  • On the NewForm page set the OneEntry WebPart Layout->Fixed height to 0 to hide it
  • Remove the View created in Step 2 so users can never select it, it won't display properly, because it triggers the same JavaScript code
  • If you want to change the Filter you have to edit the WebPart in the NewForm page

ICC top20 iJS iForm

Autres conseils

You can use Event Receiver for this feature.

So in item adding event you have to check whether the user who is adding item has already added any item for today.If yes then stop him for adding more item.

I think of one approach which is to create a custom form not through SPD (Can be inside custom webpart), and using JavaScript Object Model you create a new item in a list. Where you can place your custom validation function which is called before creating new item.

Validation Function: Query your list with Created By equal to current logged in user for Today's Date, If you get an item in return, then this means user has already entered one item and now function should return without creating an item and providing Error Message to a user.

This could be your complete JavaScript.

First get current user -> then validate -> if no record then create an item else give message to user.

var NameSpace = window.NameSpace || {};
var ItemCreation = NameSpace.ItemCreation || {};
ItemCreation.UserName = '';
ItemCreation.ListName = 'YourListName';
var newListItem = '';


ItemCreation.CreatingItem = (function () {

    CreateItem = function() {

        var clientContext = new SP.ClientContext.get_current();
        /* Get current web */
        var oWeb = clientContext.get_web();

        /* Get list by title */
        var oList = oWeb.get_lists().getByTitle(ItemCreation.ListName);

        /* Create new object for list item creation */
        //
        var oListItemCreationInfo = new SP.ListItemCreationInformation();
        newListItem = oList.addItem(oListItemCreationInfo);

        newListItem.set_item('Title', document.getElementById("txtTitle").value.trim());
        newListItem.set_item('Column1', document.getElementById("txtColumn1").value.trim());
        newListItem.set_item('Column2', document.getElementById("txtColumn2").value.trim());
        newListItem.update();
        clientContext.load(newListItem); 
        clientContext.executeQueryAsync(onSuccess, onFailure);

    },

    Validate = function() {

        var clientContext = new SP.ClientContext.get_current(),
            web = clientContext.get_web(),
            list = web.get_lists().getByTitle(ItemCreation.ListName),
            camlQuery = new SP.CamlQuery();
            camlQuery.set_viewXml('<View><Query><Where><And><Eq><FieldRef Name="Author" /><Value Type="User">"+ ItemCreation.currentUser +"</Value></Eq><Eq><FieldRef Name="Created" /><Value IncludeTimeValue="TRUE" Type="DateTime"><Today /></Value></Eq></And></Where></Query></View>');

        ItemCreation.Item = list.getItems(camlQuery);
        clientContext.load(ItemCreation.Item); 
        clientContext.executeQueryAsync(onValidateSuccess, onFailure);
    },

    onValidateSuccess = function() {
        if (ItemCreation.Item.get_count() > 0) {
            alert("You can not create more than one item in a day");
        }
        else {
            CreateItem();
        }
    },

    getCurrentUser = function () {
        try {
            var clientContext = new SP.ClientContext.get_current();
            var tempcurrentUser = clientContext.get_web().get_currentUser();
            clientContext.load(tempcurrentUser); 
            clientContext.executeQueryAsync(function () {
                var index = tempcurrentUser.get_loginName().indexOf('|') + 1;
                ItemCreation.currentUser = tempcurrentUser.get_loginName().substring(index);

                Validate();
            }, onFailure);
        }
        catch (err) {
            onFailure();
        }
    },


    onSuccess = function() {
        alert("Success");
    },

    onFailure = function() {
        alert("Error");
    }



    return {
        getCurrentUser: getCurrentUser
    };

}());


$(document).ready(function () {

    SP.SOD.executeFunc('SP.js', 'SP.ClientContext', function () {
        SP.SOD.executeFunc('user', 'SP.UserProfiles', function () {
            ItemCreation.CreatingItem.getCurrentUser();
        });
    });


}); 
Licencié sous: CC-BY-SA avec attribution
Non affilié à sharepoint.stackexchange
scroll top