Problem with SPCascadeDropdowns and simpleChild=TRUE and promptText param

Jan 5, 2012 at 10:31 PM

Mark,

SPService v0.7.0

jQuery: v1.6.4

I'm encountering 2 problems in IE and SPCascadeDropdowns when used on a field that is complex...

Problem 1

Upon submitting the form (new item), SP returns an error under the column that was made "simple" indicating:

Error: Value is not among the set of valid lookup values.

The field is optional and thus I am not making a selection (I want it to be blank). I recreated this issue on a blank site, just so that I take out all of my other customization and was able to recreate it... The test set up is as follows:

  • 3 lists:
    • spservicetest
      Has 3 columns; Title, Product and Customer.
      Product is a Lookup field to the product List. Customer is a lookup field to the Customer field.
      The only Required column is Title.
    • product
      Has only 2 rows in the list.
    • customer
      Has 2 columns: Title and Product.
      Product is a lookup field to the Products list.
      List has over 20 items in the list; all have a product populated in the product column

 

My code on the NewItem.aspx page for the spservicetest list is as follows:

       $().SPServices.SPCascadeDropdowns({
            relationshipList: "Customer",
            relationshipListParentColumn: "Product",
            relationshipListChildColumn: "Title",
            parentColumn: "Product",
            childColumn: "Customer",
            simpleChild: true,
            debug:      true,
            promptText: "Select {0}...",
            completefunc:   function(){
            
            }
       })

 

Using fiddler, I was able to capture the network traffic for the update, and noticed the following on the complect fields:

SPCustomer_Hiddenctl00%24PlaceHolderMain%24g_3eff746a_8b11_4fba_90ea_6c57eb054da7%24ff11_1%24ctl00=0

ctl00%24PlaceHolderMain%24g_3eff746a_8b11_4fba_90ea_6c57eb054da7%24ff11_1%24ctl00%24ctl01=Select+Customer...

The first one looks correct... the second does not.. it probably needs to be the Title of the Customer that was selected.

 

Problem 2

Taking the example above, where the Customer field is optional in the spservicetest List, if SPCascadeDropdowns is used with promptText="" (same code as above, but remove "Select {0}..."), then there is no way for that field to be left blank... The drop-down does not include a "blank" option..

 

Appreciate your help when you get a chance.

Paul

 

 

 

 

 

 

 

 

 

 

 

Coordinator
Jan 9, 2012 at 2:28 PM

Paul:

I think that #1 is the same as this issue: http://spservices.codeplex.com/workitem/9789 Agree?

On #2, if you don't use simpleChild, do you see a "(None)" value for the Customer column? I'm only taking the values that SharePoint puts into the page.

BTW, as I note in the docs, I highly discourage using the promptText option. It was a bad idea to build it in, but I've left it in in case people really need it for backward capability.

M.

Jan 9, 2012 at 4:27 PM

Mark,

Thanks for the reply..

On Issue #1, yes, I agree that it looks like the same issue... I will download 0.7.1 and test with it later today...

 

On Issue #2:

Yes, the value of "(Note)" is present on the complex field drop-down... Here is what the field looks like in IE:

<input 
name="ctl00$m$g_bea9ce01_7769_45c6_83ef_e137d6ea68d5$ctl00$ctl04$ctl02$ctl00$ctl00$ctl04$ctl00$ctl01" title="Customer" 
class="ms-lookuptypeintextbox" 
id="ctl00_m_g_bea9ce01_7769_45c6_83ef_e137d6ea68d5_ctl00_ctl04_ctl02_ctl00_ctl00_ctl04_ctl00_ctl01" 
onkeydown="HandleKey()" 
onkeypress="HandleChar()" 
onchange="HandleChange()" 
onfocusout="HandleLoseFocus()" 
type="text" 
choices="(None)|0|AT&T|1|BellSouth|11|CBT|10|Customer 1|12|customer 10|21|customer 11|22|Customer 12|23|Customer 12|24|customer 13|27|customer 15|28|customer 16|29|customer 17|30|customer 18|31|customer 19|32|customer 2|13|customer 20|33|customer 21|34|Customer 21|35|customer 3|15|customer 4|14|customer 5|16|customer 6|17|customer 7|18|customer 8|19|customer 9|20|ny bell|8|pac bell|7|qwest|6|TI|9|Verizon - north|2|verizon - south|3|verizon - west|4|verizon south east|5" 
match=""
optHid="SPCustomer_Hiddenctl00$m$g_bea9ce01_7769_45c6_83ef_e137d6ea68d5$ctl00$ctl04$ctl02$ctl00$ctl00$ctl04$ctl00"

opt="_Select"/> Paul.

 

Jan 9, 2012 at 5:56 PM

Mark,

I have validated that v0.7.1 fixes Issue 1 I reported here (bug item 9789).

 

Something I noticed on Issue 2....

In my case, the "product" field (the one that drive the child column) is optional, thus its initial value is "(None)"). on initial page load, the Custom field is blank, which I think is suppose to also be "(None)".

 

Paul.

Coordinator
Jan 9, 2012 at 7:41 PM
Edited Jan 9, 2012 at 8:07 PM

Hmm. I haven't fixed 9789 yet (working on it now). Working on it leads me to...

On Issue 2, it's a little tricky, I think. Because Customer is the child, there are not yet any acceptable values when you open the NewForm (Product is blank, so Customer is blank). That's why you aren't seeing (None).

So I think I may need to make a change to SPCascadeDropdowns, leaving simpleChild out of it. If the childColumn is not required, then it should always have a (None) value available for Simple and Complex dropdowns regardless what the parentColumn selection is. Do you think that sounds right?

M.

Coordinator
Jan 9, 2012 at 8:39 PM

Actually, now that I'm looking into it some more, I should already have Issue 2 covered. I already show the (None) option if the column isn't required unless you've provided your own promptText.

M.

Jan 10, 2012 at 1:05 AM

Mark,

I tried a few more tests just now... Here are my results with v0.7.1 ALPHA7:

With no customization:

  • The Product field is a displayed by SP as a <select> field (list has <20 items). the preselected item on the list is "(None)"
  • The Customers field is displays by SP as a "complex" field with nothing visible on the (type ahead) input field. If I click the down arrow and the field's values are presented, the first value I see is "(None)"

 

1. With customization - No use of simpleChild or promptText

$().SPServices.SPCascadeDropdowns({
    relationshipList: "Customer",
    relationshipListParentColumn: "Product",
    relationshipListChildColumn: "Title",
    parentColumn:   "Product",
    childColumn:    "Customer",
    debug:          true,
    completefunc:   function(){
    
    }
});

Observation:

The New form displays the Customer field as a SP complex field, with the (type ahead) input field blank (no text). Clicking the down array presents a list of selection items containing only the "(None)" item as a choice.

I was able to successfully create a new item in the list.

 

2. With Customization - No use of promptText

$().SPServices.SPCascadeDropdowns({
    relationshipList: "Customer",
    relationshipListParentColumn: "Product",
    relationshipListChildColumn: "Title",
    parentColumn:   "Product",
    childColumn:    "Customer",
    simpleChild:    true,
    debug:          true,
    completefunc:   function(){
    
    }
});

Observation:

The New Form displays the Customer field as a <select> element.  However, the Select field has 1 item selected with a visual title of "Choose Customer".  Note that I did not use the promptText options in the call above, which I think contradicts what you stated in your last post.

When I select a Product, *but no customer*, the Customer field continues to display the words "Choose Customer". I have validated that the <option> value for "Choose Customer" is in fact 0 (which is normally associated with "(None)". If I click OK, SP returns an error under the customer field indicating "Value is not among the set of valid lookup values."

 

3. With Customization - Use of promptText with blank value

$().SPServices.SPCascadeDropdowns({
    relationshipList: "Customer",
    relationshipListParentColumn: "Product",
    relationshipListChildColumn: "Title",
    parentColumn:   "Product",
    childColumn:    "Customer",
    simpleChild:    true,
    promptText:     "",
    debug:          true,
    completefunc:   function(){
    
    }
});

Observation:

The New Form displays the Customer field as a <select> element.  However, the Select field is blank, with no items in the dropdown.   When I select a product from the Product field, the Customer field is populated with the valid Customers for that product, however, the first value in the list is pre-selected. The Customer dropdown has no "(None)" value among its possible choices.

I'm able to successfully create the item (because I'm unable to set Customer to blank (or "(None)" with a value of 0).

4. With Customization - Use of promptText with a value of "(None)"

$().SPServices.SPCascadeDropdowns({
    relationshipList: "Customer",
    relationshipListParentColumn: "Product",
    relationshipListChildColumn: "Title",
    parentColumn:   "Product",
    childColumn:    "Customer",
    simpleChild:    true,
    promptText:     "(None)",
    debug:          true,
    completefunc:   function(){
    
    }
});

 

Observation:

The results were the same as test #2, with the exception that "(None)" is seen in the Customer field instead of "Choose Customer".

 

Although my prior post indicated that 0.7.1 ALPHA7 might have fixed my issue 1, I realized now that it did not (and for obvious reasons: you have not yet fixed bug # 9789 ).

Possibly the problem:

I also took a look at your code and focused on the .change() event you bind to the <select> element that you insert in the page.  I think the intent you have with this utility is to allow SP client side js to still execute and do its thing, thus why you hide original element and set its values... I placed a breakpoint on SP's core.js HandleChange(), HandleKey() and HandleChar(), to see if they got triggered when you set the values trough js and they did not... I tried to force it, using jQuery (added a $(columnSelect.Obj).change(); to your code after setting the value), but that got me an error in core.js's HandleChange() indicating that event.srcElement is not an object.  Perhaps if done via DOM directly it may be ok... this is where I stopped. :)

I don't know if I am on to something here, but once I got looking at this, I could not stop... hopefully you will find some usefulness to all this...

Paul

 

Coordinator
Jan 11, 2012 at 4:10 PM

Paul:

Thanks for doing the research.

#1 sounds right to me. You should see all the available values for Product and only (None) for Customer.

#2 doesn't make sense to me, though. The "Choose Customer" prompt would have to come from somewhere, and I'm not doing it in SPServices UNLESS the dropdown is "simple" AND you provide a value for promptText AND the column (in this case, Customer) is not required.

Here's the relevant code in SPCascadeDropdowns:

    // Add an explanatory prompt
    switch(childSelect.Type) {
     case "S":
      // Remove all of the existing options
      $(childSelect.Obj).find("option").remove();
      // If the column is required or the promptText option is empty, don't add the prompt text
      if(!childColumnRequired && (opt.promptText.length > 0)) {
       childSelect.Obj.append("<option value='0'>" + opt.promptText.replace(/\{0\}/g, opt.childColumn) + "</option>");
      }
      break;
     case "C":
      // If the column is required, don't add the "(None)" option
      choices = childColumnRequired ? "" : opt.noneText + "|0";
      childSelect.Obj.attr("value", "");
      break;
     case "M":
      // Remove all of the existing options
      $(childSelect.Obj).find("option").remove();
      newMultiLookupPickerdata = "";
      break;
     default:
      break;
    }

M.

Coordinator
Jan 11, 2012 at 4:30 PM

Hold on that. I just was doing something else in Firefox and noticed the promptText showing up on a "complex" column. That is, it's a complex column in IE. SharePoint only renders the complex structure IF it's IE. (Nice consistency, eh?) Might that be where you were seeing it?

M.

Jan 11, 2012 at 5:41 PM

Hi Mark... Thanks for the reply...

I'm seeing some very unusual behavior and am now thinking that I may not want ot bother you with this until I understand what is going on in my environment.

So I just brought up the test site in IE (launched IE firs time) and the first time I tried it I go the expected "(none)" in the customer field... however, the customer field has all of the values available, even with no Product selected... it is as if the Cascading was not applied.

I refresh the page (in IE) and, Yes, the Customer field comes back with "Choose Customer"... Weird...  Specially since you indicated you don't insert that piece of information... In FF, I checked the HTML that came back from SP and cant find "Choose Customer"... I'm assuming it is one of the SP js files that inserts it?

Like I said... I have a feeling this may be an issue with my environment.... I have to look at it a little closer, so don't get tied up with this one... I'll post back whatever I find.

 

Paul

Coordinator
Jan 11, 2012 at 9:00 PM

The "Choose Customer..." text would come from SPServices, but you shouldn't see it in IE with a complex dropdown. That's what I thought you were saying that you saw.

I should really remove the promptText option; it's more trouble than it is useful.

M.

Jan 11, 2012 at 11:06 PM
Edited Jan 11, 2012 at 11:22 PM

Marc,

Does your code have a bug above in the case of a simple drop-down for optional fields?

In firefox, where these drop-downs are always "simple", how does the "(None)" ever get into the <option>'s?  I see it above for fields that are Complex, but not for Simple.  I have been searching the code and I cant seem to determine it. But when I make the following change, it work in FF (the "(None)") is one of the selection options):

([pt, update 1] Corrected my fix in sample below)

// Add an explanatory prompt
switch(childSelect.Type) {
    case "S":
        // Remove all of the existing options
        $(childSelect.Obj).find("option").remove();
        // If the column is required or the promptText option is empty, don't add the prompt text
        if(!childColumnRequired && (opt.promptText.length > 0)) {
            childSelect.Obj.append("<option value='0'>" + opt.promptText.replace(/\{0\}/g, opt.childColumn) + "</option>");
        
        // PT: Add the "(None)|0" option if field is optional
        } else if(!childColumnRequired){
            childSelect.Obj.append("<option value='0'>" + (opt.noneText || "(None)") + "</option>");
        }
        break;
    case "C":
        // If the column is required, don't add the "(None)" option
        choices = childColumnRequired ? "" : opt.noneText + "|0";
        childSelect.Obj.attr("value", "");
        break;
    case "M":
        // Remove all of the existing options
        $(childSelect.Obj).find("option").remove();
        newMultiLookupPickerdata = "";
        break;
    default:
        break;
}

Also,

In reviewing your function I now see how the promptText is being set... you have the option's default value set at "Choose {0}..." when you mentioned it earlier that you discouraged its use, I assumed the default was already blank ("").

(FYI... I'm still having problems with IE, even with the two changes above... My work-around has been to now convert them to simple child's... If I get some more time, I will continue to investigate that one)

 

Paul

Coordinator
Jan 13, 2012 at 3:30 PM

Paul:

Partly because of this thread, I've done some significant rewrites in SPCascadeDropdowns. They are in v0.7.1ALPHA9, which I've just posted. I'm considering setting promptText to "", as you had assumed I already had as well, but I haven't in this alpha.

Let me know if you still see odd behaviors and we'll get 'em sorted out.

M.

Jan 13, 2012 at 8:28 PM

Thanks Marc... I'll download it and try it out in the test env. I created for this issue. I'll post back to see if I still see anything that feels unusual.

I will also consider moving this version (when it is released) into my other application cycles...

Paul.

Jan 16, 2012 at 8:06 PM

Marc,

Re-Ran the test cases above (post on Jan 9 at 8:05 PM) on my test site with v0.7.1 ALPHA10, and here is what I got (using IE):

  • Use Case 1: Ok
  • Use Case 2: OK. No longer get the error from SP.
  • Use Case 3: NOT OK.
    When the promptText is blank (""), it makes the Customer field "required"... there is no "blank" option for the user to select... The problem is still in the same location I highlighted above (post on 11th at 6:06 PM). Under your current implementation, if we use promptText:"" and the field is *NOT* required, you are essentially making it required.  In additional the fix I suggested above, you could also use the following instead of checking the length of the string: opt.promptText !== undefined
  • Use Case 4: OK

I would recommend that you remove support for the promptText altogether... or change the code to allow the use of any of value set by the user (blank included). 

Personally, I'm going to take your advise, and am going to search my source files and remove the option all together.

 

Paul

Coordinator
Jan 17, 2012 at 2:41 PM
Edited Jan 17, 2012 at 2:45 PM

Paul:

I've added something similar your fix to the next alpha (11) in SPCascadeDropdowns and SPFilterDropdown. Since I've got a, option for noneText, I can simply set the value it it all the time.

} else if(!childColumnRequired){
  childSelect.Obj.append("<option value='0'>" + opt.noneText + "</option>");
}

I think what I'll do is set the promptText to "" by default and deprecate it in the documentation. Everything should then continue to work as it alqways has for those using it and hopefully no one will use it going forward.

M.


Jan 17, 2012 at 4:57 PM

Marc:

Sounds good... Thanks.

Paul.

Feb 27, 2012 at 8:00 PM
Edited Feb 27, 2012 at 8:22 PM

I'm about to change our field to "not required" in order to get the promptText to show. I want the promptText, so I can test for it at submission time -- this is as a solution (workaround) for the fact that SharePoint does not correctly enforce required simple lookups (what it does is defaults the choice to the first on the list, so the user gets that, rather than being forced to choose a value). We hook the submit and check for value of 0, which is from the promptText, and tells us that the user did not fill out the field.

I am wondering

  1. why promptText isn't shown for required fields
  2. if you might suggest a better workaround to enforce required simple lookup fields -- actually, it now occurs to me that I could probably check for -1 instead, in the simple lookup case if I have no promptText -- but we prefer to have the promptTex.

(NB: I edited this post several times, as I realized a couple things post facto.)