6

I have a specific case where I want to hook up on the NewForm.aspx, hide a MultipleLookupField and set the value by myself.

I'm opening the NewForm.aspx with Javascript and using some query strings and I'm adding a custom class using AdditionalPageHead from an Elements.xml file:

<Control
Id="AdditionalPageHead"
ControlAssembly="$SharePoint.Project.AssemblyFullName$" ControlClass="MyNamespace.AdditionalPageHeadInjection"/>

Then I was able to set the value through code, but with the control visible. So the user still be able to change the value. If I try to hide the control, the value won't be set (null value) when saving.

I DO NOT want to override the NewForm.aspx, just be able to modify some NewForm.aspx controls behavior and visibility.

1

4 Answers 4

5

Assuming you're already have field control object (probably from SPContext.Current.FormContext?), you should use CssClass property to hide the control, rather than Visible property - because Visible property affects control server-side, so it will not be rendered at all.

Sample code:

(control as BaseFieldControl).CssClass = "s4-die";

s4-die class is from COREV4.CSS file, so it will be avaliable by default on all pages in SharePoint 2010. It is defined as follows:

.s4-die{
    display:none;
}

Update: Here is the screenshot which proves that FieldControlCollection items have CssClass property:

enter image description here

Full-sized image: https://i.stack.imgur.com/p6r1v.png

Update 2: Unfortunately, it turned out, that modifying the CssClass property doesn't affect MultipleLookupField control. Reflector analysis screenshot:

enter image description here

Hence, neither LookupField, nor MultipleLookupField use this property... :(

So the only acceptable approach left here, I reckon, is to stoop to client-side solution :( But at least we could use ClientID property rather than field title to reference the field control. Tentative javascript:

var clientId = '{0}_ctl00_MultiLookupPicker';
function hideMultiLookup()
{
   var x = document.getElementById(clientId).parentElement.parentElement.parentElement.style.display = 'none';
}
_spBodyOnLoadFunctionNames.push('hideMultiLookup');

Where {0} placeholder should be replaced with the actual client id (control.ClientID). In my case it was:

enter image description here

Note we need to add _ctl00_MultiLookupPicker to the control.ClientID, as it performed in the script sample.

I've tested the solution and it works in my environment.

7
  • I've tried this in the CreateChildControls() but without success, the controls for this field is still showing up. The parent do not have the CssClass property, I also try to get an hand on the parent table row to hide them, without success. Nov 1, 2011 at 13:33
  • Can you clarify, how do you get fields controls? Are you using SPContext.Current.FormContext.FieldControlCollection? Nov 1, 2011 at 14:03
  • I'm using SPContext.Current.FormContext.FieldControlCollection Nov 1, 2011 at 14:26
  • FieldControlCollection contains BaseFieldControl descendants. BaseFieldControl does have CssClass property: msdn.microsoft.com/en-us/library/… Nov 1, 2011 at 17:31
  • I've updated my answer, and added the screenshot of Visual Studio Watch window. So, I hope casting the control to BaseFieldControl will help you to solve this. Nov 1, 2011 at 17:36
1

Instead of hiding or disabling the field, you could use jQuery to hide the whole table row that contains that field. It'd be something like $("input[title='FieldName']").parent().parent().hide(); to grab the field, then navigate to the parent cell and row, and hide the row. Using hide() will append a style="display: none;" to the element, so it will still exist in the DOM, be completely scribtable, and be submitted normally--it just won't be viewable to the user.

3
  • Since it's a MultipleLookupField, it's not using input control for data entry, so the the title is not set for these controls. I need a way to identify the right control. The MultipleLookupField use 3 hidden inputs and 2 select control. The select control's title are changing depending of the current language, so I cannot based my code on them. Oct 31, 2011 at 21:21
  • 1
    @GabrielMongeon, there is a couple of ways to fetch MultipleLookupField with jquery, for instance you can gather a sample function for this from SPServices source code. But, determining control by field title is anyway a bad idea IMHO. Because, accidental change of field title will break down your functionality. And also, there are problems with on-fly localization. So, be aware :) Oct 31, 2011 at 21:40
  • You are correct that it doesn't use the "input" field type, but if you explore the DOM, you will still be able to grab the correct form object. The field elements will have a common element that wraps the field. I was providing that markup as a concept example.
    – webdes03
    Nov 1, 2011 at 23:03
1

Expanding on webdes03's jQuery suggestion, here's how you can access multiple lookup fields:

Assuming your field's display name is Field To Hide, you can use this:

$("nobr:contains('Field To Hide')").closest("tr").hide();

Let me know if you need more details or if you have trouble with this.

BTW - as omlin mentioned, if the field display name ever changes, this jQuery could break. But if you're working with a fairly stable environment where field renaming is unlikely, I don't see anything wrong with using the display name to access the DOM element this way. I could be the devil's advocate here and give a reason why using a Guid is a bad idea -- if you're keeping all of your code in source control, and you work with multiple tiers (development, validation, staging, production), you can't hard code Guids since they will vary from tier to tier. If you use display names and internal names, it's much easier to maintain IMHO.

1
  • i thought it was worth mentioning, in the spirit of optimization, that if you are using this type of element selector more than once, you should consider caching the collection of nobr elements at an appropriate level (locally if you only call the function once, or globally if the function will be called more than once). for example: var nobr = $("nobr"); nobr.filter(":contains('Field To Hide')").closest("tr").hide(); nobr.filter(":contains('Another Field To Hide')").closest("tr").hide();
    – ronx
    Dec 14, 2011 at 2:26
0

This is something that you could use SPUtility.js for (full disclosure, this is an open source JavaScript library that I maintain). As @webdes03 mentions, you can use JavaScript to do this. SPUtility.js tries to make the field lookups, gets, and sets easier on the developer. For example:

SPUtility.GetSPField('Title').SetValue('Hello world!').MakeReadOnly();

Or, you can use Hide() to make the entire row go away.

Currently, it depends on Prototype.js (instead of jQuery) but the easiest way is to just upload your script files to a document library and put a content editor with your code on the page.

Or, if you prefer, feel free to browse the source code to see how I select to fields. :)

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.