0

I am using Dialog popup to create a new list item which uses a people picker to automatically fill in the user field. The way this form works is it gets updated on a day-by-day basis. With the New form button, obviously when you want to update the previous item, it will not do that, it will just open up a new form. With the edit form, I need to add the people picker script, but it still doesn't do what I want it to. Is there a way I can create a conditional script or something that when the user clicks on the update form button, their specific list item for the week will pop up by searching for their name?

Right now, both of these open up a blank form on click:

<a href="#" class="button" onclick="openDialog('/Lists/MorningReport/NewForm.aspx');">Create New Week Report</a>
<a href="#" class="button" onclick="openDialog('/Lists/MorningReport/EditForm.aspx');">Update Current Week Report</a>

UPDATE:

Dylan, I have done some research in regards to your answer/comments.

Here is what I have so far and I seem to be at a point where I know longer know what to do:

<script type="text/javascript">

var currUserId = _spPageContextInfo.userId

console.log(currUserId)

var curr = moment(); //get the current day
var currMonday = moment(curr.clone().weekday(1)).format("MM/DD/YYYY");

function getUserData(currUserId) {
$.ajax({ 
                url: _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/GetByTitle('MorningReport')/items",
                method: "GET", 
                headers: {
                    "Accept": "application/json; odata=verbose"
                },
                success: function(data) {
                    //console.log(data);
                }
            });
    if(currUserId === data.d.user.Id){
        
    }
}

openDialog('/Lists/MorningReport/EditForm.aspx?ID=' + idOfItemRetrieved);

</script>

1 Answer 1

1

In order for the Edit form to open with the data from a specific list item, you need to pass the item's ID as a query parameter in the URL, so something like

/Lists/MorningReport/EditForm.aspx?ID=27

So instead of having the button you have to open the Edit form call openDialog directly on click, have the onclick call another function that:

  • determines the current user ID

  • makes a REST call to the list that retrieves the item you want to open in the Edit form based on the conditions you are using to figure out which item is "their specific list item for the week":

  • is "their item" determined by them being the creator/author? or are you checking to see if they are the user in this particular field where you have auto-populated the value?

  • is "this week" determined by a value in a specific field? or is it determined by the created date being between, say, last sunday and next saturday?

  • after you make the REST request and have retrieved the item, you will now have its ID, so at the end of that function you can call

    openDialog('/Lists/MorningReport/EditForm.aspx?ID=' + idOfItemRetrieved);

and that will open the Edit form for the item you want.


Ok, I see by what you put in your edit you aren't exactly understanding what I'm getting at. If you do a simple

GET _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/GetByTitle('MorningReport')/items"

you will end up with all of the list items in the list. Then you are going to have to loop through them all in your own code to find the one you want. That's a lot of work.

I don't know about you, but personally, I'm lazy. I don't want to have to do all that work. I'd much rather if SharePoint would do all that work for me. Luckily, there is a way to tell SharePoint to do all the work of finding the specific item (or items) you are looking for.

I guess it's not super well documented in the Microsoft documentation about the SharePoint REST API, but here it says

Use the $filter query option to select which items to return. OData query operators supported in the SharePoint REST service lists the filter query comparison options and functions you can use with the SharePoint REST service.

The basic point is, you can use the $filter query parameter to make SharePoint do all the work of finding the specific item you are looking for based on the conditions you tell it to look for.

Now, you've said that one of the conditions you are looking for is that the item you want to find is for the current user ("their item"), and that the "Created By" field would work to identify "their item".

In order to use the $filter query parameter, you are going to have to refer to fields by their internal name. The internal name of "Created By" is actually Author. Now, before we go and start using Author, there is something you need to know about how the SharePoint REST API treats User fields. User fields are actually Lookup fields, which means what they store on the actual item is just an ID of an item in another list in which there is much more data. In the case of User fields, this other data includes things like the Display Name, the Login Name, the Email Address, etc. But - SharePoint provides a "shorthand" version of User fields where it appends the suffix "Id" to the internal name of the field, and that has the ID of the item in the lookup list. So for "Created By", even though the true internal name of "Created By" is just Author, unless you do some other special REST operations (which we're not going to get into here), the Author field is actually surfaced as AuthorId. Here's what I'm talking about:

screenshot of JSON data

As you've already demonstrated, you know you can get the current user's ID through

_spPageContextInfo.userId

So we don't need to get any deeper into how to query the Author field at this time, we simply want to match where the shorthand AuthorId is equal to _spPageContextInfo.userId.

Now, the other criteria you said you were looking for in order to identify the correct item is "for this week". Based on what you said in the comments:

This week is determined by certain fields. There is a Monday-Friday Field, which are all calculated (i.e Monday is =(2-WEEKDAY(Today)+(Today)) and all other days are Monday + x.

What I am getting from that (and if my understanding is wrong, then the rest of what I am about to say will be wrong), is that you have five fields, all named after the days of the work week, set to the dates of those days for that particular week. Part of my assumption here is that all of these calculated columns are actually returning "Date and Time" type data.

Given that, the easiest way I would think to determine if something is "this week" would be if: "today is between Monday and Friday (inclusive)."

To use date/time information in a $filter query, you need to pass it as an ISO formatted string (if you don't know what that is, Google it), and you need to use the syntax

$filter=MyDateField eq datetime'2021-08-17T02:54:40.796Z'

Given the fact that SharePoint stores Date/Time information in UTC (if you don't know what that is, Google it), and any dates you generate in Javascript are going to be local, and there are almost certainly going to be discrepancies based on time zone offset, I usually take the approach of expanding the date range I'm querying for by enough to absorb any time zone offset issues.

What that means for your particular case is that to find something where "today is between Monday and Friday (inclusive)", what I'm really going to check for is "if today is greater than or equal to Monday midnight (incudes all of Monday), and less than or equal to Saturday midnight (includes all of Friday)". (And if that doesn't work, you might have to expand the first part to be Sunday instead of Monday.)

So, if my assumption about your five date fields is correct, let's assume that their internal name happens to be exactly the name of the day of the week, i.e. Monday, Tuesday, Wednesday, Thursday, Friday.

OH! Before we actually get into some code, let me just say one other thing about using the $filter query parameter with the SharePoint REST API: if you use $filter, even if you are expecting only a single result, SharePoint will always give you an array of results.

If

/mysite/_api/web/lists/getbytitle('MyList')/items(27)

gives you

returnData.d   // and there's the single item right there

then

/mysite/_api/web/lists/getbytitle('MyList')/items?$filter=SomeField eq 'Some Value'

will give you

returnData.d.results[]  // an array, which could be empty, or have a single item, or have multiple items, depending on what actually matches the filter

So, given the assumptions I've made, here's how I would do what you are trying to do.

<a href="#" class="button" onclick="openDialog('/Lists/MorningReport/NewForm.aspx');">Create New Week Report</a>
<a href="#" class="button" onclick="openEditForThisUserThisWeek();">Update Current Week Report</a>

<script type="text/javascript">
    function openEditForThisUserThisWeek() {

        // we already know we can get the current user ID
        var userId = _spPageContextInfo.userId;

        // forget about moment, you can do whatever you need to do
        // with native javascript Date objects

        var today = new Date();

        // setting hours, minutes, seconds and milliseconds
        // to zero essentially sets it to "midnight"
        today.setHours(0,0,0,0);

        // get monday of this week (at midnight)
        // NOTE - as mentioned, if this does not accurately
        // account for time zone offset, you might need to 
        // change this to sunday by changing the "1" to "0"
        var monday = new Date(today);
        monday.setDate(today.getDate() + (1 - today.getDay()));

        // get saturday of this week (at midnight - accounts for all of friday)
        var saturday = new Date(today);
        saturday.setDate(today.getDate() + (6 - today.getDay()));

        // in order to make the REST query, we need ISO strings
        var mondayISO = monday.toISOString();
        var saturdayISO = saturday.toISOString();

        // when building the filter, for comparison operators,
        // "eq" means "equals", "ge" means "greater than or equal to",
        // and "le" means "less than or equal to"
        var filter = "$filter=AuthorId eq '" + userId + "' and Monday ge datetime'" + mondayISO + "' and Friday le datetime'" + saturdayISO + "'";

        // use the filter as part of the overall query URL
        var queryUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/GetByTitle('MorningReport')/items?" + filter;

        // don't bother with the "success" parameter, just chain it
        $.ajax({
            url: queryUrl,
            method: 'GET',
            headers: {
                accept: 'application/json;odata=verbose'
            }
        }).done(function(response) {
            if (response.d.results.length > 0) {
                // keep in mind that i am only checking that the
                // filter found more than zero results - more than zero
                // could be _one_, which is what we are expecting, OR
                // it could be MORE THAN ONE, which is _not_ what we are
                // expecting, but i'm not caring about that here.  if you care
                // that there is more than one item for the current user for this
                // week, then you will need to add additional code here to deal with
                // that eventuality. but here i am just going to take
                // the first result and run with it.
                var reportEntry = response.d.results[0];
                openDialog('/Lists/MorningReport/EditForm.aspx?ID=' + reportEntry.ID);

            } else {
                // the length of the response array
                // must have been zero, which means nothing
                // matched the filter parameters, which in turn
                // means nothing was found for the current
                // user for this week
                alert('No Morning Report item found for the current user for this week.');
            }
        }).fail(function (jqXhr, code, err) {
            // something went wrong with the GET request
            console.log(err);
            console.log(code);
            console.log(jqXhr);
        });
    }
</script>
13
  • So I have the function to get the current user ID. for the REST call I would call a GET correct? Their item is created by them being the author. But their is also a User/Employee field where I use the people picker that populates the field automatically for them. But the CreatedBy field would work as well. This week is determined by certain fields. There is a Monday-Friday Field, which are all calculated (i.e Monday is =(2-WEEKDAY(Today)+(Today)) and all other days are Monday + x. I understand the overview of your answer, but am still a little confused
    – BeerusDev
    Commented Aug 16, 2021 at 15:12
  • Yes, a simple GET to get the item will be fine. You said you wanted to get "their item for this week". You need to answer two questions: 1) How do I determine it is "their item"? You said CreatedBy OR your User/Employee field could work. Fine, use whichever you prefer. 2) How do I determine it is the item "for this week"? You say "this week is determined by certain fields." That's fine also. If you need to create a query that is checking values for more than one date field, figure out that query. Commented Aug 16, 2021 at 16:09
  • Please see my most recent edit
    – BeerusDev
    Commented Aug 16, 2021 at 19:19
  • @BeerusDev updated my answer Commented Aug 17, 2021 at 4:14
  • 1
    Thanks for catching that bug, I will correct it in my answer. Not sure what that other error is about. Commented Aug 17, 2021 at 14:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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