Hidden/not visible property

Topics: Developer Forum
Nov 14, 2008 at 1:57 PM
Hi

Is it possible to create property that will be hidden/not visible for setting from edit mode aka is there a way to mark item to behave like that so to be able to set and use its value only from codebehind?
Nov 14, 2008 at 2:18 PM
I'm really curious what you want to use this for...
The properties you set in N2 are used for contentitem's are they not, to edit them and, if necessary show them on a page.
If you do not wish to show them on a page, why set it as a contentitem? Why not use a variable?
Nov 14, 2008 at 3:18 PM
Ok this is why i need to use hidden property...
In my application the editors will be able to create an exam page. This page has a tab 'Questions' something similar to the Form page/tab in N2 templates where the exam questions are created and stored.
There is one proprety that the exam needs to have which should not be chnaged either by the editor or the user who will take the exam and that is the ExamDateTimeTaken aka the date and time when the user has finished the exam.
So this is why i need the functionality. If there is some other way I am open to suggestions.

Thanks.
Nov 14, 2008 at 3:44 PM
I know that one way is to use DetailAuthorizedRoles attribute and set nonexisting role but I must check if it is possible to use the detail/property from codebehind...
Nov 14, 2008 at 5:16 PM
I suppose the ExamDateTimeTaken is set in another way.
Why not show it read only by using [EditorModifier("ReadOnly", true)] or show it as a label with [Editable("", typeof(Label), "Text", 1)]?

Or is the information really useless for the editor?
Nov 14, 2008 at 7:42 PM
Indeed, i see clearly one situation when something like described in the first post would be really necessary. It's when you are using ItemEditor (super)control to allow editing of a certain Item: if you assign ItemEditor.CurrentItem with your instance of a given type, then you can expect to survice only such item's properties that are exposed as "editables" via [Editable*] family attributes. In another words: it's not enough to implement your property with ContentItem.GetDetails/SetDetail pattern to be able to assign it before editing item and than get back it's value afterwards. If we really need such property to persist inside ItemEditor and, at the same time, do not want to expose it for editing through UI, we should consider storing it in a form hidden field. I suppose it can be done by decorating our property by something like [EditableAttribute(ControlType = typeof(HiddenField))], but i'm not 100% sure about that.

As to a possible implementation of what zokizlatanov is talking about, i'd go this way (actually and coincidently, i was working on a similar, test-evaluation logic just some days ago :-):

1) Establish 2 items: parent Test and child TestQuestion (the latter can be further discriminated by a question type, i.e.: multichoice, single, text)
2) Implement a non-editable FinishedOn property in a Test item:

public DateTime FinishedOn
{
get { return this.GetDetail<DateTime>("FinishedOn", DateTime.Now); }
set { this.SetDetail<DateTime>("FinishedOn", value); }
}

3) Implement a statically-typed "Questions" collection accessor in a Test item:

public virtual IEnumerable<TestQuestion> Questions
{
get { return
this.GetChildren(new TypeFilter(typeof(TestQuestion)))
.Cast<TestQuestion>();
}
}

4) Render questions inside Test's item .ascx template with a Wizard control (i prefer doing it by hand/code through CreateChildControls(..) override, though N2 encourages using Zone control for such task):

protected Wizard wz;
...
protected override void CreateChildControls()
{
...
foreach(var _question in this.CurrentItem.Questions) {
...
WizardStep _step = new WizardStep {
ID = _question.ID.ToString(),
Title = _question.Title,
StepType = WizardStepType.Auto,
};

this.wz.WizardSteps.Add(_step);

//Inject CurrentItem into child control manually
(
(TemplateUserControl<AbstractContentPage, TestQuestion>)((IContainable)_question).AddTo(_step)
).CurrentItem = _question;
...
}
...
5) Add a control that will trigger test finalization inside Test's template, e.g.: a <asp:Button/> and in it's event handler assign and persist a desired property:

...
var _btn = new Button { Title = "Finish" }; // create button in code
this.Controls.Add(_btn);
this.btn.Click += (sender, e) => {//inline event handler via lambda
this.CurrentItem.FinishedOn = DateTime.Now;
N2.Context.Persister.Save(this.CurrentItem);
};
...