Display content picker field

Topics: Customizing Orchard
Oct 27, 2013 at 7:10 PM
Edited Oct 27, 2013 at 7:11 PM
Hey everyone,

I have a projection of employees (employees have the content picker field Domains), I've created an alternative for it and I'm displaying everything manually for better control.
For instance:
<p>Mail: @Model.ContentItem.Medewerker.Emailadres.Value * Tel: @Model.ContentItem.Medewerker.Telefoonnr.Value</p> Now I also want to display the content picker field. I've traced the shape template and pasted it in my view, I've added the @using Orchard.ContentPicker.Fields and even added the reference to the Orchard.Web

But if I run my code I get:

Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

Source Error:


Line 16: @{
Line 17: var field = (ContentPickerField) Model.ContentField;
Line 18: string name = field.DisplayName;
Line 19: var contentItems = field.ContentItems;
Line 20: }

Does anyone know how to solve this?

Kind regards,

Borrie
Coordinator
Oct 28, 2013 at 5:41 AM
Your field is null. What makes you think that Model.ContentField exists? Can you give some context? What is the name of the type, and the name of the field?
Oct 28, 2013 at 7:22 AM
Weird, if create a alternate for the contentpicker it works, if i paste it in a view it doesn't. I don't think I really understand how it works :)

Well, the contentitem that has the content picker field is called "Medewerker" the contentitem that's attached is "Domeinen" the field is also called "Domeinen"

More then one item can be attached

Borrie
Coordinator
Oct 28, 2013 at 8:33 AM
If you paste what in what view? What are you trying to do with the field?
Oct 28, 2013 at 8:45 AM
Hey,

Just display the attached content items. in the "normal view" you have @Display(Model.Content) and there the picker field is generated:

Domeinen: Domein1, Domein2 ....

But now that I take a closer look at it these are not generated in het list (projector) you have to click on the content item (Medewerker) to see the picker field.

So I want to display the Domeinen picker field per contentitem in the List, can this be done?
Coordinator
Oct 28, 2013 at 5:47 PM
Yes, but be aware that this can cause select N+1 problems, and is architecturally unsound as we are querying the database from the view here. It would be better to prepare the shapes for these related items through a handler, shape provider or something similar.
@using Orchard.ContentManagement
@using Orchard.ContentPicker.Fields
@using Orchard.Utility.Extensions;

@{
    var field = (ContentPickerField) Model.ContentField;
    string name = field.DisplayName;
    var contentItems = field.ContentItems;
    var contentManager = Model.ContentItem.ContentManager;

    if (contentItems.Any()) {
        <p class="content-picker-field content-picker-field-@name.HtmlClassify()">
            <h2 class="name">@name:</h2>
            <ul class="see-also">
                @foreach (var contentItem in contentItems) {
                    <li>
                        @Display(contentManager.BuildDisplay(contentItem, "SeeAlso"))
                    </li>
                }
            </ul>
        </p>
    }
}
Oct 28, 2013 at 6:11 PM
Bertrand,

I've tried your code but I get the same error, field is null, am I missing something?

Could this be because it's generating a list and the contentpickerfield isn't directly attached?

Borrie
Coordinator
Oct 28, 2013 at 6:14 PM
Where did you put the code?
Oct 28, 2013 at 6:18 PM
I've created an alternate to the content of a list (projector)

Content-Medewerker-Summary
Coordinator
Oct 28, 2013 at 7:01 PM
Yes, that's why. That code goes into an alternate for the content picker shape, not content.
Oct 28, 2013 at 7:10 PM
Damn I've never worked with the alternates for shapes before, can you guide me?
Coordinator
Oct 28, 2013 at 9:24 PM
Jan 7, 2014 at 4:43 PM
Edited Jan 7, 2014 at 5:00 PM
I've created the alternate for the content picker shape but how do call it now from my "medewerker" code?
Coordinator
Jan 8, 2014 at 8:11 AM
I don't understand the question, sorry.
Jan 8, 2014 at 10:12 AM
Well,

(first of all this project was on hold for a while, that explains the late response)

I render the seperate fields from my content item "Medewerker" (i've created an alternate) manually to have full html and css control:
<div id="medewerkerscontentDiv">
    <p>Title: @Model.ContentItem.Medewerker.TitlePart.Title</p>
    <p>Mail: @Model.ContentItem.Medewerker.Emailadres.Value * Tel: @Model.ContentItem.Medewerker.Telefoonnr.Value</p>
    <p>Body: @Model.ContentItem.Medewerker.BodyPart.Text</p>
</div>
The only thing I'm still missing is how to display the list of contentpicker field that's attached to it.

So how can I call this list in my alternate view?
Jan 9, 2014 at 6:59 PM
Anyone? This is really the last piece of the puzzle that I'm missing...
Jan 10, 2014 at 1:24 PM
Ok, this is really stupid,

After checking the database and testing some stuff out I found the solution:
@{
    var field = (ContentPickerField) Model.ContentItem.Medewerker.Domeinen;
    string name = field.DisplayName;
    var contentItems = field.ContentItems;
}
<p class="content-picker-field content-picker-field-@name.HtmlClassify()">
    <span class="name">@name:</span>
    @if (contentItems.Any())
    {
        foreach (var contentItem in contentItems)
        {
            <span class="value">@Html.ItemDisplayLink(contentItem)</span>
            if (contentItem != contentItems.Last())
            {
                <span>,</span>
            }
        }
    }
    else
    {
        <span class="value">@T("No content items.")</span>
    }
</p>
You just have to define the field the same way as the other fields on your contentitem.

Solved!
Marked as answer by borrierulez on 1/10/2014 at 7:09 AM