Display the module item using thiswidget and add the following attributes to the markup:
data-sf-provider – the provider of the item,
data-sf-id – the id of the item,
data-sf-type – item type,
data-sf-field – field name,
data-sf-ftype – field type
Example:
<
ItemTemplate
>
<
div
data-sf-provider
=
'<%# Eval('
Provider')%>' data-sf-id='<%# Eval('Id') %>' data-sf-type="CarsModule.Models.CarsModuleItem">
<
label
><
strong
>Title: </
strong
></
label
>
<
span
data-sf-field
=
"Title"
data-sf-ftype
=
"ShortText"
><%# Eval('Title') %></
span
>
<
label
><
strong
>Brand: </
strong
></
label
>
<
span
data-sf-field
=
"Brand"
data-sf-ftype
=
"ShortText"
><%# Eval('Brand') %></
span
>
<
label
><
strong
>Registration Number: </
strong
></
label
>
<
span
data-sf-field
=
"RegistrationNumber"
data-sf-ftype
=
"Number"
><%# Eval('RegistrationNumber') %></
span
>
</
br
>
</
div
>
</
ItemTemplate
>
4. Add custom requireJS module (this step is optional)
If you are in scenario where the field types in the custom module are not supported from the inline editing you can add a custom field support. In order to do this you need to create custom requireJS module – which will implement EditableField or EditableWindowField. You can choose which base class to implement depending on the way you will edit the new field. If you will edit inline without opening any dialog windows inherit EditableField, otherwise inherit EditableWindowField
Example inheriting the EditableField:
define([
"EditableField"
],
function
(EditableField) {
function
EditableShortText(options) {
// Call the super constructor.
EditableField.call(
this
, options);
// Return this object reference.
return
(
this
);
}
EditableShortText.prototype = {
showEditMode:
function
() {
//Implement custom logic
},
disableEditing:
function
() {
//Implement custom logic
},
isChanged:
function
() {
//Implement custom logic
}
};
EditableShortText.prototype = $.extend(Object.create(EditableField.prototype), EditableShortText.prototype);
return
(EditableShortText);
});
Example inheriting the EditableWindowField:
define([
"EditableWindowField"
,
"text!YesNoTemplate!strip"
],
function
(EditableWindowField, html) {
function
EditableYesNo(options) {
// Call the super constructor.
EditableWindowField.call(
this
, options);
this
.fieldType =
"YesNo"
;
this
.editWindowContentTemplate = html;
this
.editWindowTitle = $(html).find(
'.editWindowTitle'
).html();
this
.editWindowViewModel = kendo.observable({
titleText:
''
,
isChecked:
false
,
currentValue:
""
});
// Return this object reference.
return
(
this
);
}
EditableYesNo.prototype = {
success:
function
(data, textStatus, jqXHR) {
this
.editWindowViewModel.set(
"isChecked"
, data.Selected);
this
.editWindowViewModel.set(
"currentValue"
, data.Text);
this
.originalValue = data.Selected;
this
.value =
this
.originalValue;
kendo.bind(
this
.dialog.getContentPlaceHolder(),
this
.editWindowViewModel);
this
.dialog.viewModel.set(
'titleText'
,
this
.editWindowViewModel.titleText);
this
.isInitialized =
true
;
this
.viewModel.set(
"showEditButton"
,
true
);
},
onDone:
function
(event, sender) {
this
.value =
this
.editWindowViewModel.isChecked;
EditableWindowField.prototype.onDone.call(
this
, event, sender);
},
onClose:
function
(event, sender) {
this
.value =
this
.originalValue;
this
.editWindowViewModel.set(
"isChecked"
,
this
.originalValue);
EditableWindowField.prototype.onClose.call(
this
, event, sender);
}
};
EditableYesNo.prototype = $.extend(Object.create(EditableWindowField.prototype), EditableYesNo.prototype);
return
(EditableYesNo);
});
The newly defined requireJS module should be registered in RequireJS Modules section in Administration ->Settings ->Advanced -> InlineEditing -> RequireJs Module
Key is the name of the module and Value is the path which will be required. In the example the Key is "Number" meaning that all fields marked with property data-sf-ftype="Number" will require this module for editing. The value is "Number" meaning that the request for the module will be similar to: ~/Res/Number.js
To configure the request to return our newly created script module, we need to add this path to:
VirtualPathSettings > Virtual paths
Where:
- VirtualPath is the request that will be made.
- ResouceLocation is the virtual path to the script module on the server
- ResolverName is the name of the resolver that is needed to resolve this file. In this example FileSystemResolver is the resolver thast will return the file from the file system. If your file is in an assembly as an embedded resource, you need to use EmbeddedResourceResolver.
5. Add the strategy to resolve the new type in InlineEditingService
First you need to override the GetStrategy method of the InlineEditingStrategyFactory class.
Example:
public
class
OrdersFactory : InlineEditingStrategyFactory
{
public
override
IInlineEditingStrategy GetStrategy(Type itemType)
{
if
(itemType ==
typeof
(OrdersModule.Models.OrdersModuleItem))
{
var strategy = ObjectFactory.Resolve<IInlineEditingStrategy>(
typeof
(OrdersStrategy).Name);
return
strategy;
}
else
{
return
base
.GetStrategy(itemType);
}
}
}
If the item type is not of your module type call the base method. The factory returns your strategy and you need to implement it as well. The strategy needs to implement the
using
Telerik.Sitefinity.InlineEditing;
using
Telerik.Sitefinity.Services.InlineEditing;
public
class
CarsStrategy : IInlineEditingStrategy
{
public
string
GetDetailsViewUrl(Type itemType, Telerik.Sitefinity.Pages.Model.PageNode pageNode)
{
return
string
.Empty;
}
public
object
GetItem(Guid id, Type type,
string
provider)
{
//Get the manager and return the item by id
var manager = CarsModule.CarsModuleManager.GetManager();
return
manager.GetCarsModuleItem(id);
}
public
LifecycleStatusModel GetItemStatus(
object
item)
{
//We need to handle the correct lifecycle status only for items which support lifecycle
//Otherwise we return the this status by default
LifecycleStatusModel status =
new
LifecycleStatusModel()
{
DisplayStatus = String.Empty,
IsEditable =
true
,
IsLocked =
false
,
IsLockedByMe =
false
,
IsStatusEditable =
true
};
status.IsPublished =
true
;
return
status;
}
public
LifecycleStatusModel GetItemStatus(Guid id, Type type,
string
provider)
{
var manager = CarsModule.CarsModuleManager.GetManager();
var item = manager.GetCarsModuleItem(id);
return
this
.GetItemStatus(item);
}
public
void
DeleteEditableItem(Guid itemId, Type itmeType,
string
provider)
{
//Do nothing if the item does not support lifecycle
}
public
WorkflowOperationResultModel ExecuteOperation(Guid itemId, Type itmeType,
string
provider, InlineEditingOperation operation,
string
customOperation =
null
)
{
WorkflowOperationResultModel result =
new
WorkflowOperationResultModel();
result.RequiresPageOperation =
false
;
result.IsExecutedSuccessfully =
true
;
return
result;
}
public
Guid GetEditableItemId(Guid itemId, Type itmeType,
string
provider)
{
//Returns the id of the item
//If the item supports lifecycle we return the temp item id
return
itemId;
}
public
void
SaveEditableItemFields(FieldValueModel[] fields, Guid itemId, Type itmeType,
string
provider)
{
var manager = CarsModule.CarsModuleManager.GetManager();
var item = manager.GetCarsModuleItem(itemId);
//Calling this method that internali uses the ddefault setter or our custom setter if we have created one
InlineEditingHelper.SetItemFields(item, fields);
manager.SaveChanges();
}
}