Get SPSetMultiSelectSizes and CascadeDropdowns to play together nicely...

Jun 17, 2010 at 8:24 PM
Edited Jun 17, 2010 at 8:26 PM

I'm a JQuery novice, so appoligies if these are obvious questions....

I am trying to speed up my pages, having got the basics of these wonderful calls working :-)

1. Can I wrap the SPServices calls in an 'If Exists' type construct? (I have a number of content types using the same newForm.aspx at the moment, not all have the Multiselect box)

2. Can I only run the resize after the cascade has happened?

3. Is there any way NOT to load the Multiselect box with all 2000 items before doing the cascade call that hides it ...  :-0

Many thanks, Ruth

code so far:

<script type="text/javascript">
$(document).ready(function() {
     $().SPServices.SPCascadeDropdowns({
   relationshipList: "{D5776331-01FB-4659-972F-7E9084340461}",
   relationshipListParentColumn: "Department_x002e_",
   relationshipListChildColumn: "Title",
   parentColumn: "Department.",
   childColumn: "Role(s) to Add",
   promptText: "Choose {0}...",
   debug: true ,
   completefunc: resizeAdd
  });
  $().SPServices.SPCascadeDropdowns({
   relationshipList: "{D5776331-01FB-4659-972F-7E9084340461}",
   relationshipListParentColumn: "Department_x002e_",
   relationshipListChildColumn: "Title",
   parentColumn: "Department.",
   childColumn: "Role(s) to Remove",
   promptText: "Choose {0}...",
   debug: true ,
   completefunc: resizeRemove
  });
 
 });
function resizeRemove() {
$().SPServices.SPSetMultiSelectSizes({
         multiSelectColumn: "Role(s) to Remove",
         maxWidth: 500
       });
}
function resizeAdd() {
$().SPServices.SPSetMultiSelectSizes({
         multiSelectColumn: "Role(s) to Add",
         maxWidth: 500
       });
}
</script>

Coordinator
Jun 20, 2010 at 8:58 PM

Ruth:

Sorry for the delayed reply.

1) If you call SPCascadeDropdowns and the column doesn't exist on the page, you'll get an error.  Probably the best thing to do is to check to see if the column exists on the page before calling it, as you are suggestion.  You can do this in a number of ways, but perhaps the simplest is to just see if the DisplayName of the column exists in a table cell with the ms-formlabel CSS style applied to it. This will indicate that the column is being displayed. Ideally you'd check for the dropdown control itself.

2) You should call SPSetMultiSelectSizes *before* calling SPCascadeDropdowns, as I just added in a note to the docs. (See the note for particulars.)

3) No, there is no way not to have all of the values loaded. That work is done server-side, and SPServices works on client-side after the page is rendered.  If you want to change what happens server-side, you'll need to write some .NET code.  (If you're using SPServices, that's probably something you're trying not to do.)

M.

Jul 7, 2010 at 8:29 PM

Thanks for your response sympmarc

I have had a chance to revisit my code again tonight, and tried various load time benchmarks.  (see end)
(my underlying problem = there are stupid numbers of rows to display in the multiselect box I have)

Conclusions: (timings taken after after refreshes to get over the '1st time slow' thing)

  • Original code in above post = 15s
  • Running 2x SPSetMultiSelectSizes followed by 2x SPCascadeDropdowns from the document ready function seems to take the longest to load = 38s
  • Getting rid of the resize call completely, just running the 2x SPCascadeDropdowns = 16s
  • Running only 1x SPCascadeDropdown call = 15s
  • No code at all in the document ready codeblock = 10s

So, I might try a static resize call instead of your lovely dynamic one, but otherwise I seem to have failed on my tune-up mission tonight :-(

Ho hum.

PS. Below is what I thought you meant by running the resize code first - did I get it wrong?

---------------------

$(document).ready(function() {
     $().SPServices.SPSetMultiSelectSizes({
         multiSelectColumn: "Role(s) to Remove",
         maxWidth: 500,
         minWidth: 250
       });
$().SPServices.SPSetMultiSelectSizes({
         multiSelectColumn: "Role(s) to Add",
         maxWidth: 500,
         minWidth: 250
$().SPServices.SPCascadeDropdowns({
   relationshipList: "{D5776331-01FB-4659-972F-7E9084340461}",
   relationshipListParentColumn: "Department_x002e_",
   relationshipListChildColumn: "Title",
   parentColumn: "Department.",
   childColumn: "Role(s) to Add",
   promptText: "Choose {0}...",
   debug: false
  });
  $().SPServices.SPCascadeDropdowns({
   relationshipList: "{D5776331-01FB-4659-972F-7E9084340461}",
   relationshipListParentColumn: "Department_x002e_",
   relationshipListChildColumn: "Title",
   parentColumn: "Department.",
   childColumn: "Role(s) to Remove",
   promptText: "Choose {0}...",
   debug: false
  });

Coordinator
Jul 8, 2010 at 5:00 AM
Edited Jul 8, 2010 at 5:01 AM

Ruth:

Those timings certainly stink.  How many items are in your lists? Can you add a CAMLQuery option to filter things down at all?

And, yes, the code tyou show above is what I meant. By running SPSetMultiSelectSizes first, it can look at all of the possible values and set the widths before anything is filtered.

M.

Jul 8, 2010 at 5:53 PM

Hi again,

The list of Roles/systems is currently 3668 items and is growing as these forms are rolled out to new business areas.

It does seem to be the initial page load that is causing the largest chunk of pain.

How do you mean using a CAML query - as part of the Cascade? of it it a different call?

I am begining to wonder if I might have to use a pop-up or show-extra-info call to grab the Systems/Roles list at a later point.

I tried swapping the code into a CEWP last night too in case the Customised form was taking longer to load than a ghosted one, but it did not seems to make any difference to the speed (after caching had happened)

Can you explain what you meant by the CAML query option?

Thanks
R

Coordinator
Jul 8, 2010 at 6:08 PM
Edited Jul 8, 2010 at 7:07 PM

Yikes. That's a lot of data.  It's going to be slow. Period.

What I meant by the CAMLQuery option is the option which is available in SPCascadeDropdowns (and several of the other functions) to put a filter in place for the items in the list. For instance, if only 2000 of the 3668 items are active, you could add a CAMLQuery option to filter the inactive ones out.  The less data you're returning, the faster it will be.
http://spservices.codeplex.com/wikipage?title=%24%28%29.SPServices.SPCascadeDropdowns

M.

Sep 22, 2010 at 3:33 PM

Thanks sympmarc for all your help above - I am adding my final code here in case it comes in useful for others.

There was too much data in the end, so I used some Javascript and Jquery to avoid the built in multi-select boxes and

  1. Used a Roles Textbox in the form Content type to store the data
  2. Dynamically generated the HTML for a list of roles tickboxes from the SPServices GetListItems which I could pass a CAML filter to.
  3. Added a Save button to copy these into the Roles Textbox.

So, Cascade drop-down in place for the smaller lists of data.

SPServices.SPDisplayRelatedInfo to get a Div that I could write into in the original SharePoint rendered form (I didn't want to Insert a Custom form and lose the ability to add fields later).

And the following:

$().SPServices({
    operation: "GetListItems",
    async: false,
    webURL: "http://moss.web.net/SITES/x",
    listName: "x_Roles",
    CAMLViewFields: "<ViewFields><FieldRef Name='Title' /></ViewFields>",
    CAMLQuery: "<Query><Where><Eq><FieldRef Name='Department_x002e_'/><Value Type='Text'>" + dept + "</Value></Eq></Where></Query>",
    completefunc: function (xData, Status) {
        var preListHtml = "<div id='preRolesMsg'>Select your Department to see available roles, then tick one or more Roles and click the Save Roles button.</div><span onclick='showHideRolesDiv()'><img alt='hideshow' src='_layouts/images/tvplus.gif'>Add Roles: (click to expand) </span> <div id='deptRoles'></div>";		
        var saveButtonHtml = "<TABLE cellpadding=0 cellspacing=0 width=100%><TR><TD align='right' width=100% nowrap><input type='button' value='Save Roles To Add' onclick='copyRolesToTextfield(1)' /></TD></TR></TABLE> ";
		$("#SPDisplayRelatedInfo_DumRoles").append(preListHtml);
		$("#deptRoles").append(saveButtonHtml);
		var inum = 1
		$(xData.responseXML).find("[nodeName=z:row]").each(function() {
        	var chkid = "ctl" + inum
        	var liHtml = "<input id='" + chkid + "' type='checkbox' name='" + chkid + "' /><label for='" + chkid + "'>" + $(this).attr("ows_Title") + "</label><br>";
        	$("#deptRoles").append(liHtml);
        	inum++;
      		});
      	$("#deptRoles").append(saveButtonHtml);
      	hideRolesDiv();

I'm sure I could make my code neater, but the users found the checkboxes easy to use, so job done.

Ruth Jennaway

Coordinator
Sep 23, 2010 at 3:34 AM

Thanks, Ruth!

M.