5

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?

  • Are you using OOB newform.aspx to create new item? – Asad Refai Aug 12 '15 at 13:34
  • I created a webpart page. Edited that page from designer 2013 and insterted new form. I have hidden toolbar for that list in webpart. – Danilo Aug 12 '15 at 13:40
5

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

3

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.

  • 2
    If I understood you correctly, you want me to check everytime someone creates item and than to disable them from entering more items? that is impossible because there will be a 1000 entries/users daily. – Danilo Aug 12 '15 at 13:43
  • 3
    sorry, but your requirement IS to check everytime, when someone wants to create an item. If you think this is impossible, you won´t reach your requirement – Leopold Lerch Aug 12 '15 at 13:49
  • 1
    I think event receiver would be best bet for this requirement – Amit Kotha Aug 12 '15 at 13:53
  • 1
    SharePoint consultants who say .... is the only way always make me laugh – Danny '365CSI' Engelman Sep 12 '15 at 10:28
  • 1
    @DaniloKorac, what an event receiver will do is intercept each new item as it is being added. At that time, you can check (through server-side code) the user who is trying to add a new item, and you can check the list to see if they have already added one today. If they have, you can prevent the new item from being saved to the list. There is no manual intervention required. While this is probably the most direct way of meeting the requirement, from a certain perspective it may not be the best solution, because the users will never be told that there is a limit or why their item was not... – Dylan Cristy Sep 12 '15 at 22:28
1

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();
        });
    });


}); 
  • good idea. will try it. i will write it tomorrow if I managed to do it. thanks a lot for suggestion. – Danilo Aug 12 '15 at 14:01
  • @DaniloKorac I have used this approach on my SharePoint 2013 on premise environment. And it runs successfully on production environment. Event receivers some times cause problems as they are not in your control. But JSOM is totally in your hand. – Asad Refai Aug 12 '15 at 14:01
  • You can replace all these lines of code with just 2 lines if you let SharePoint do the Created By=[Me] and Created=[Today] – Danny '365CSI' Engelman Sep 12 '15 at 10:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.