1

Has anyone ever successfully added a new item to a list which is used as the source for a lookup column while using an EditForm (or NewForm, same mechanism) and been able to save the form successfully with the new value?

Here’s what I mean:

  • I have a list called Regions with a lookup column called Country
  • Country is a lookup into Countries.Title
  • In my Regions EditForm, I’ve got a call to UpdateListItems using SPServices which adds a new value to Countries
  • I add the new option to the Country dropdown (select) using the new ID and innerHTML and set it as “selected”
  • When I save the Regions EditForm with the new value selected I get the dread “An unexpected error has occurred.”

I've checked with Firebug and the correct ID for the newly created lookup value is what is sent with the POST, so I believe that my script is doing what it should.

I can still save the form with no problem if I select any of the previously existing lookup values. Only the new value throws the error.

I’ve fiddled with this too much. I’m wondering if SharePoint’s trying to be “smart” here by only allowing values which existed when the form was originally loaded.

Any ideas?

18
  • Just a thought: Have you tried ajax'ing the ddl into the page after your new item has been created? You may run into an issue there if the ddl has 19 items and then has 20. As you know, there's javascript bound to that control and ajax doesn't play well in certain scenarios, such as this one.
    – iOnline247
    Aug 16, 2011 at 15:59
  • I was thinking the exact same thing! Aug 16, 2011 at 16:03
  • There's no JavaScript I'm aware of if there are fewer than 20 items. That's where I've been doing my testing, figuring that I'd get to the 20+ mess once I have it working. Aug 16, 2011 at 16:18
  • I am wondering if this is a viewstate issue. Maybe it is passing in the valid values in the viewstate. Hence when saving it, the value is not valid. Just a thought. Aug 16, 2011 at 16:43
  • 1
    Now that you've caused me to "think different", it occurs to me that there are a lot of cool widgets I can use with a Single line of text and still keep things straight. Stay tuned... Aug 17, 2011 at 12:19

4 Answers 4

1

After considerable work on this, testing over and over, and having a really interesting discussion (see the comments above), I am thoroughly convinced that this is not possible.

My current belief (I'd love it if someone could confirm or deny) is that something in the viewstate "tells" SharePoint something about the state things were in when the form loaded which prevents the new value from being acceptable.

I've moved on to other approaches to solve the particular client requirement which triggered this question, but if you have other ideas, please add them!

3
  • Marc, I am trying to test something, but my environment is not cooperating at this time. My thought was that maybe it might not be the view state so much as persisting the values of the select control on the postback. What I wanted to try was to add a querystring value on the commit of the save button that adds the value that was put in the select with the SPServices code. One postback, it is redrawing the control which is now missing that piece of data so if I add it back in on page load, it might work. Does that make sense or sound wrong? Aug 29, 2011 at 21:24
  • I'm not sure I quite get it, but it sounds a little convoluted. Where would you process the Query String value? If it was in the same page, then I doubt that you'd beat the issue. Essentially, you'd be adding the new value back to the select on a validation error, right? Aug 30, 2011 at 2:46
  • Something I did try today that seemed to work for me in a "slightly" different approach was to use a SharePoint DVDropDown and set its viewstate to false. I was able to change the list it was pulling data from and update an item from the newform. I am wodering if just disabling viewstate will allow what you want to work. I "dislike" viewstate! Oct 13, 2011 at 18:43
1

I have been successful doing this for most forms with the following code. This code is after you have done the mods to the lookup list and you are ready to save the form.


function PreSaveAction() {
    var qv = $().SPServices.SPGetQueryString();
    if (qv["PreSave"] == "skip") {
        return true;
    }
    else {
        var loc = new String(window.location);
        loc = loc.split("?");
        var formpage = loc[0];
        formpage += "?PreSave=skip";
        $("#aspnetForm").append("");
        $("#iframea").attr("src", formpage);
        setTimeout("copyfields()", 4000);
    }
}

function copyfields() {
    try
    {
        var i = 1;
        $("td.ms-formbody").each(function() {
            $(this).attr("id", "tdelement_" + i);
            i += 1;
        }); 
        i = 1;
        $("#iframea").contents().find("td.ms-formbody").each(function() {
            $(this).attr("id", "tdelement_" + i);
            i += 1;
        });
        for (var z = 1; z < i; z++) {
            var tid = "tdelement_" + z;
            $("#iframea").contents().find("td[id='" + tid + "']").html($("td[id='" + tid + "']").html());
        } 
    }
    catch(e) {alert("Error " + e);}
    // Once copied submit the form and then redirect to the original source page.
    $("#iframea").contents().find("input[name*='SaveItem']").trigger('click');
    setTimeout("refreshpage()", 3000);
}

function refreshpage() {
    var qv = $().SPServices.SPGetQueryString();
    var source = new String(qv["Source"]);  
    window.location = source;
}

This uses the presave action to create a hidden iframe. A new copy of the form is added to the frame and your selections are then copied to this hidden form. The code will then submit this form and reloads the page after a few seconds. I have tested this several times and it has worked each time. It is not perfect and I would like to find a way to make it cleaner, but it does work.

1
  • This is really cool and I'm definitely going to try it. Thanks, Dan! Oct 22, 2011 at 11:44
0

I believe that an out of box list form will have the issues described and it will not work because viewstate is enabled. Viewstate does store the valid values of a select and when you post back it will not accept an updated item. However, you can do this using SPDesigner and a custom form for the list. I created a list of categories and a list that used the categories list for a lookup fittingly called category. The list was called DataSourceTest and is just a custom list. In Designer I copied the NewForm.aspx page into a new file called NewFormTest.aspx and then removed the default listform. I added a SharePoint:SPDataSource element and an SharePoint:DVDropDownList to the form. The DataSource was set to the categories list and the DVDropDownList was bound to the category field and its EnableViewState property was set to FALSE (This is important!). I added a dummy dropdown that had some data that using SPServices would update the category list with a new category and return the new ID back to the form and then add this new item to the DVDropDownList. I could then save the form and it would post the changes including the updated value back to the list with no errors. This is not the most ideal solution I know, but it does work!

2
  • Dan: This is a useful approach, and I'll keep it in mind for another time. When I asked the question, I was trying to figure out how to include this capability in SPServices. While your approach works, it's not appropriate for SPservices, unfortunately. Oct 14, 2011 at 20:14
  • I know it is not ideal for SPServices. I really wish that SharePoint did not use ViewState for this very reason! I have only given up 98% though. 2% still wants to find a way! Oct 15, 2011 at 12:45
0

I solved this by adding a hidden ASP button on the form. I set UseSubmitBehavior="False" for that button but it still causes postback which in turn reloads the lookup list (which is what we want) while retaining form data. I invoke that button's click event with javascript after successfully adding a record to target lookup list with ajax. It causes validation as well so I set all fields to optional and made sure to validate their values using javascript in PreSaveAction() function. Quick and easy.

Your Answer

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

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