SplendidCRM is both database driven and data driven. SplendidCRM uses database schema information
during the design phase and in the reporting module. SplendidCRM uses layout data to determine the
fields to display in edit, detail or list views. Creating a new module requires that you
create the underlying tables, the views, the procedures and the layout data.
The following is the sequence of operations when you create a
new module:
1.
Create the table scripts.
2.
Create the view scripts.
3.
Create the procedure scripts.
4.
Create the data scripts.
a.
Create the data scripts for the MODULES table.
b.
Create the data scripts for the SHORTCUTS table.
c.
Create the data scripts for the TERMINOLOGY table.
d.
Create the data scripts for the GRIDVIEWS_COLUMNS
tables.
e.
Create the data scripts for the EDITVIEWS_FIELDS
tables.
f.
Create the data scripts for the DETAILVIEWS_FIELDS
tables.
g.
Create the data scripts for the DYNAMIC_BUTTONS table.
h.
Create the data scripts for the
DETAILVIEW_RELATIONSHIPS table.
5.
Create the ASP.NET code.
a.
Create the ListView code.
b.
Create the EditView code.
c.
Create the DetailView code.
d.
Create the PopupView code.
e.
Create the relationship controls.
SplendidCRM is a database application, so the creation of a
new module will require that you create a database table to store the module
information. The quickest way to create
a new module is to start with an existing module and perform search-and-replace
operations. The source code included in
this document is intended to be complete, so that you can treat this code as a
template.
This document will use the SplendidCRM Teams module as a
real-world example of how a module is created.
A SplendidCRM table will always start with the following six
fields:
ID
|
Primary
Key
|
DELETED
|
Flag used
to mark the record as deleted.
|
CREATED_BY
|
User ID
who created the record.
|
DATE_ENTERED
|
Date the
record was created.
|
MODIFIED_USER_ID
|
User ID
who last modified the record.
|
DATE_MODIFIED
|
Date the
record was last modified.
|
All tables will have an ID field to serve as its primary
key. We always provide a default value
for the primary key so that records can be inserted without having to first
define a unique value for the ID field.
We also provide default values for the deleted field and the
date-related auditing fields. We refer
to the date and user tracking fields as auditing fields because they are used
to track changes to the record.
In our Teams module, the only other fields in the table are
NAME, DESCRIPTION and PRIVATE. Observe
that we use nvarchar instead of varchar and ntext instead of text. The letter “n” is used because SplendidCRM
uses Unicode UTF-8 to ensure full multi-lingual support.
TEAMS.1.sql
if not exists (select * from dbo.sysobjects where id =
object_id(N'dbo.TEAMS') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
begin
print
'Create Table dbo.TEAMS';
Create Table
dbo.TEAMS
(
ID uniqueidentifier not null default(newid())
constraint PK_TEAMS primary key
,
DELETED bit not null default(0)
,
CREATED_BY uniqueidentifier null
,
DATE_ENTERED datetime not null
default(getdate())
,
MODIFIED_USER_ID uniqueidentifier null
,
DATE_MODIFIED datetime not null
default(getdate())
,
NAME nvarchar(128) not null
,
DESCRIPTION ntext null
,
PRIVATE bit null
)
end
GO
SplendidCRM allows the dynamic creation of fields in most
modules. When a field is created, we
place that field in a table whose name matches the module name, but ends in
_CSTM. If the module allows custom
fields, we must create this table.
The custom table has no auditing fields because we rely upon
the base table for that information. The
custom table has an ID_C field instead of an ID field so that we can easily
join the two tables and ensure that no fields would overlap. You will see how we do this in the next
section.
TEAMS_CSTM.2.sql
if not exists (select * from dbo.sysobjects where id =
object_id(N'dbo.TEAMS_CSTM') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
begin
print
'Create Table dbo.TEAMS_CSTM';
Create Table
dbo.TEAMS_CSTM
(
ID_C
uniqueidentifier not null constraint PK_TEAMS_CSTM primary key
)
end
GO
Any time the SplendidCRM application retrieves data from the
database, it does so using a view. The
primary reason why we use a view is to join the base table with the most-often
used relationships. We always join the
base view to the users table so that we can include the user name of the
creator of the record and the last user to modify the record. If the module allows custom fields, then we
also join to the custom table for that module.
The use of TEAMS_CSTM.* is our trick to allow the view to
grow as fields are added to the custom table.
vwTEAMS.1.sql
if exists (select * from dbo.sysobjects where id =
object_id(N'dbo.vwTEAMS') and OBJECTPROPERTY(id, N'IsView') = 1)
Drop View
dbo.vwTEAMS;
GO
Create View dbo.vwTEAMS
with encryption
as
select TEAMS.ID
, TEAMS.NAME
,
TEAMS.DESCRIPTION
, TEAMS.PRIVATE
,
TEAMS.DATE_ENTERED
,
TEAMS.DATE_MODIFIED
,
USERS_CREATED_BY.USER_NAME as CREATED_BY
,
USERS_MODIFIED_BY.USER_NAME as MODIFIED_BY
, TEAMS_CSTM.*
from TEAMS
left outer join
USERS USERS_CREATED_BY
on
USERS_CREATED_BY.ID = TEAMS.CREATED_BY
left outer join
USERS USERS_MODIFIED_BY
on
USERS_MODIFIED_BY.ID = TEAMS.MODIFIED_USER_ID
left outer join
TEAMS_CSTM
on
TEAMS_CSTM.ID_C = TEAMS.ID
where TEAMS.DELETED
= 0
GO
Grant Select on dbo.vwTEAMS to public;
GO
As a general rule, we always create three views for each
module. The first is the base view, the
second is the view that is used in the ListView area and the third view is used
in both the DetailView and EditView areas.
While creating three views is not absolutely necessary, it does provide
the opportunity to provide additional joins or calculated fields in either the
ListView or DetailView areas.
In our example, we select all fields from the base view.
vwTEAMS_List.2.sql
if exists (select * from dbo.sysobjects where id =
object_id(N'dbo.vwTEAMS_List') and OBJECTPROPERTY(id, N'IsView') = 1)
Drop View
dbo.vwTEAMS_List;
GO
Create View dbo.vwTEAMS_List
with encryption
as
select *
from vwTEAMS
GO
Grant Select on dbo.vwTEAMS_List to public;
GO
vwTEAMS_Edit.2.sql
if exists (select * from dbo.sysobjects where id =
object_id(N'dbo.vwTEAMS_Edit') and OBJECTPROPERTY(id, N'IsView') = 1)
Drop View
dbo.vwTEAMS_Edit;
GO
Create View dbo.vwTEAMS_Edit
with encryption
as
select *
from vwTEAMS
GO
Grant Select on dbo.vwTEAMS_Edit to public;
GO
Anytime the SplendidCRM application inserts data into the
database, it does so using a stored procedure.
Most of the stored procedures in the system are as simple as the one in
our example. Observe that we have
combined the insert and update operations into a single stored procedure. Also observe that the @ID field is an
input/output parameter and that we assign it a new value if it is empty. Finally, observe that we insert a record
into the custom table if such a record does not already exist.
spTEAMS_Update.1.sql
if exists (select * from dbo.sysobjects where id =
object_id(N'spTEAMS_Update') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
Drop
Procedure dbo.spTEAMS_Update;
GO
Create Procedure dbo.spTEAMS_Update
@ID uniqueidentifier output
@MODIFIED_USER_ID uniqueidentifier
@NAME nvarchar(128)
@DESCRIPTION ntext
)
with encryption
as
begin
set nocount
on
if not
exists(select * from TEAMS where ID = @ID) begin -- then
if
dbo.fnIsEmptyGuid(@ID) = 1 begin -- then
set
@ID = newid();
end
-- if;
insert
into TEAMS
(
ID
,
CREATED_BY
,
DATE_ENTERED
,
MODIFIED_USER_ID
,
DATE_MODIFIED
,
NAME
,
DESCRIPTION
)
values
@ID
@MODIFIED_USER_ID
, getdate()
@MODIFIED_USER_ID
, getdate()
@NAME
@DESCRIPTION
);
end else
begin
update
TEAMS
set MODIFIED_USER_ID = @MODIFIED_USER_ID
, DATE_MODIFIED =
getdate()
, NAME = @NAME
, DESCRIPTION = @DESCRIPTION
where ID = @ID ;
end -- if;
if not
exists(select * from TEAMS_CSTM where ID_C = @ID) begin -- then
insert
into TEAMS_CSTM ( ID_C ) values ( @ID );
end -- if; end
GO
Grant Execute on dbo.spTEAMS_Update to public;
GO
Every module has a stored procedure to delete a record. It most cases, we do not actually delete the
record, we just set the DELETED flag to 1.
In the Teams example, observe how we do the additional work of cleaning
up related tables. This is an example of
our use of the stored procedures to contain business logic. As much as possible, we prefer to put the business
logic in the database.
spTEAMS_Delete.1.sql
if exists (select * from dbo.sysobjects where id =
object_id(N'spTEAMS_Delete') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
Drop
Procedure dbo.spTEAMS_Delete;
GO
Create Procedure dbo.spTEAMS_Delete
@ID uniqueidentifier
@MODIFIED_USER_ID
uniqueidentifier
)
with encryption
as
begin
set nocount
on
-- BEGIN
Oracle Exception
update
TEAMS
set DELETED = 1
, DATE_MODIFIED = getdate()
, MODIFIED_USER_ID = @MODIFIED_USER_ID
where ID = @ID;
-- END
Oracle Exception
-- BEGIN Oracle
Exception
update
TEAM_NOTICES
set DELETED = 1
, DATE_MODIFIED = getdate()
, MODIFIED_USER_ID = @MODIFIED_USER_ID
where TEAM_ID = @ID;
-- END
Oracle Exception
-- BEGIN
Oracle Exception
update
TEAM_MEMBERSHIPS
set DELETED = 1
, DATE_MODIFIED = getdate()
, MODIFIED_USER_ID = @MODIFIED_USER_ID
where TEAM_ID = @ID;
-- END
Oracle Exception
end
GO
Grant Execute on dbo.spTEAMS_Delete to public;
GO
SplendidCRM is heavily data-driven, so in order to display
or edit a module record, you must first define the data for the module. The place to start is the MODULES table. Any time we insert configuration data, we
almost always do so using an Insert Only stored procedure. The purpose of an Insert Only stored
procedure is to ensure that the record is inserted only if it does not
exist.
The MODULES table stores critical information about the
module, for example, if it is for administration purposes, or if it is
customizable.
exec dbo.spMODULES_InsertOnly null, 'Teams',
'.moduleList.Teams', '~/Administration/Teams/', 1, 0, 0, 0, 0, 0, 0, 1, 'TEAMS', 0;
exec dbo.spACL_ACTIONS_Initialize;
The following is the definition of each field in the spMODULES_InsertOnly stored procedure:
@MODIFIED_USER_ID
|
uniqueidentifier
|
This field
is typically null.
|
@MODULE_NAME
|
nvarchar(25)
|
Name of
the module. It will be used in all the
other data scripts.
|
@DISPLAY_NAME
|
nvarchar(50)
|
Typically
a reference to a moduleList terminology entry.
|
@RELATIVE_PATH
|
nvarchar(50)
|
The
relative path to the module in the web application.
|
@MODULE_ENABLED
|
bit
|
Enabled
flag. It is typically enabled.
|
@TAB_ENABLED
|
bit
|
Tab menu
enabled flag. Show or hide the module
on the tab menu of the application.
|
@TAB_ORDER
|
int
|
Tab order
for the menu of the application.
|
@PORTAL_ENABLED
|
bit
|
This flag
is not used.
|
@CUSTOM_ENABLED
|
bit
|
Enable the
custom field editor for this module.
|
@REPORT_ENABLED
|
bit
|
Enable
reports on this module.
|
@IMPORT_ENABLED
|
bit
|
Enable
importing data into this module.
|
@IS_ADMIN
|
bit
|
Mark the
module as admin-only.
|
@TABLE_NAME
|
nvarchar(30)
|
Base table
for the module.
|
@MOBILE_ENABLED
|
bit
|
Enable the
module to be visible on the mobile tab menu.
|
The shortcuts typically appear on the left panel of the web
application. Most modules have two
shortcuts, one to create a new module record and the other to list all records.
if not exists (select * from SHORTCUTS where MODULE_NAME =
'Teams' and DELETED = 0) begin -- then
exec
dbo.spSHORTCUTS_InsertOnly null, 'Teams', 'Teams.LNK_NEW_TEAM',
'~/Administration/Teams/edit.aspx', 'CreateTeams.gif', 1, 1, 'Teams', 'edit';
exec
dbo.spSHORTCUTS_InsertOnly null, 'Teams', 'Teams.LNK_TEAM_LIST',
'~/Administration/Teams/default.aspx', 'Teams.gif', 1, 2, 'Teams', 'list';
end -- if;
The following is the definition of each field in the spSHORTCUTS_InsertOnly stored
procedure:
@MODIFIED_USER_ID
|
uniqueidentifier
|
This field
is typically null.
|
@MODULE_NAME
|
nvarchar(25)
|
Name of
the module that this shortcut belongs to.
|
@DISPLAY_NAME
|
nvarchar(150)
|
Typically
a reference to a terminology entry.
|
@RELATIVE_PATH
|
nvarchar(255)
|
Relative
path shortcut.
|
@IMAGE_NAME
|
nvarchar(50)
|
Image name
for the shortcut.
|
@SHORTCUT_ENABLED
|
bit
|
Enable the
shortcut.
|
@SHORTCUT_ORDER
|
int
|
Display order
for the shortcuts.
|
@SHORTCUT_MODULE
|
nvarchar(25)
|
Target
module. It is typically the same
module, but a shortcut list can have links to other modules.
|
@SHORTCUT_ACLTYPE
|
nvarchar(100)
|
Access
right that will be required.
|
All text strings come from the TERMINOLOGY table. When the application starts, all terms are
loaded into the application cache for all languages that are enabled.
When referencing a term in the database, use the format
MODULE_NAME + “.” + NAME. As a general
rule, the lists do not define a module name, so the format for a list entry is
“.” + LIST_NAME + “.” + NAME.
exec dbo.spTERMINOLOGY_InsertOnly N'Teams' , N'en-US', null,
N'moduleList', 44, N'Teams';
exec dbo.spTERMINOLOGY_InsertOnly N'LBL_DESCRIPTION' , N'en-US', N'Teams', null, null,
N'Description:';
exec dbo.spTERMINOLOGY_InsertOnly
N'LBL_LIST_DESCRIPTION' , N'en-US',
N'Teams', null, null, N'Description';
exec dbo.spTERMINOLOGY_InsertOnly
N'LBL_LIST_FORM_TITLE' , N'en-US',
N'Teams', null, null, N'Team List';
exec dbo.spTERMINOLOGY_InsertOnly
N'LBL_LIST_MEMBERSHIP' , N'en-US',
N'Teams', null, null, N'Membership';
exec dbo.spTERMINOLOGY_InsertOnly N'LBL_LIST_NAME' , N'en-US', N'Teams', null, null,
N'Team Name';
exec dbo.spTERMINOLOGY_InsertOnly N'LBL_LIST_PRIVATE' , N'en-US', N'Teams', null, null,
N'Private';
exec dbo.spTERMINOLOGY_InsertOnly N'LBL_LIST_TEAM' , N'en-US', N'Teams', null, null,
N'Team';
exec dbo.spTERMINOLOGY_InsertOnly N'LBL_NAME' , N'en-US', N'Teams', null, null,
N'Team Name:';
exec dbo.spTERMINOLOGY_InsertOnly N'LBL_PRIVATE' , N'en-US', N'Teams', null, null,
N'Private:';
exec dbo.spTERMINOLOGY_InsertOnly N'LBL_SEARCH_FORM_TITLE'
, N'en-US', N'Teams', null, null, N'Team Search';
exec dbo.spTERMINOLOGY_InsertOnly N'LBL_TEAM' , N'en-US', N'Teams', null, null,
N'Team:';
exec dbo.spTERMINOLOGY_InsertOnly N'LBL_TEAMS' , N'en-US', N'Teams', null, null,
N'Teams';
exec dbo.spTERMINOLOGY_InsertOnly N'LBL_ENABLE' , N'en-US', N'Teams', null, null,
N'Enable';
exec dbo.spTERMINOLOGY_InsertOnly N'LBL_DISABLE' , N'en-US', N'Teams', null, null,
N'Disable';
exec dbo.spTERMINOLOGY_InsertOnly N'LBL_REQUIRE' , N'en-US', N'Teams', null, null,
N'Require';
exec dbo.spTERMINOLOGY_InsertOnly N'LBL_OPTIONAL' , N'en-US', N'Teams', null, null,
N'Optional';
exec dbo.spTERMINOLOGY_InsertOnly N'LNK_NEW_TEAM' , N'en-US', N'Teams', null, null,
N'Create Team';
exec dbo.spTERMINOLOGY_InsertOnly N'LNK_TEAM_LIST' , N'en-US', N'Teams', null, null,
N'Teams';
The following is the definition of each field in the spTERMINOLOGY_InsertOnly stored
procedure:
@NAME
|
nvarchar(50)
|
Name for
the term.
|
@LANG
|
nvarchar(10)
|
Language
code.
|
@MODULE_NAME
|
nvarchar(25)
|
Module
name.
|
@LIST_NAME
|
nvarchar(50)
|
List name.
|
@LIST_ORDER
|
int
|
List
order.
|
@DISPLAY_NAME
|
nvarchar(2000)
|
Display name.
|
if not exists(select * from GRIDVIEWS_COLUMNS where
GRID_NAME = 'Teams.ListView' and DELETED = 0) begin -- then
print
'GRIDVIEWS_COLUMNS Teams.ListView';
exec
dbo.spGRIDVIEWS_InsertOnly 'Teams.ListView', 'Teams',
'vwTEAMS_List';
exec
dbo.spGRIDVIEWS_COLUMNS_InsHyperLink 'Teams.ListView', 1,
'Teams.LBL_LIST_NAME', 'NAME', 'NAME', '20%', 'listViewTdLinkS1', 'ID',
'~/Administration/Teams/view.aspx?id={0}', null, 'Teams', null;
exec
dbo.spGRIDVIEWS_COLUMNS_InsBound
'Teams.ListView', 2, 'Teams.LBL_LIST_DESCRIPTION', 'DESCRIPTION',
'DESCRIPTION', '50%';
end -- if;
The following is the definition of each field in the spGRIDVIEWS_InsertOnly stored
procedure:
@NAME
|
nvarchar(50)
|
Name for
the grid view.
|
@MODULE_NAME
|
nvarchar(25)
|
Module
that this view applies to.
|
@VIEW_NAME
|
nvarchar(50)
|
SQL view
for the grid view.
|
The following is the definition of each field in the spGRIDVIEWS_COLUMNS_InsHyperLink stored
procedure:
@GRID_NAME
|
nvarchar(50)
|
Name of
the grid view.
|
@COLUMN_INDEX
|
int
|
Index of
the field.
|
@HEADER_TEXT
|
nvarchar(150)
|
Terminology
name used in the header.
|
@DATA_FIELD
|
nvarchar(50)
|
Field
name.
|
@SORT_EXPRESSION
|
nvarchar(50)
|
Field that
will be sorted. Usually the same as
the DATA_FIELD.
|
@ITEMSTYLE_WIDTH
|
nvarchar(10)
|
HTML table
column width.
|
@ITEMSTYLE_CSSCLASS
|
nvarchar(50)
|
HTML style
sheet class name.
|
@URL_FIELD
|
nvarchar(50)
|
Field used
in the URL.
|
@URL_FORMAT
|
nvarchar(100)
|
Format for
the URL with {0} style replacements.
|
@URL_TARGET
|
nvarchar(20)
|
HTML
target for the URL.
|
@URL_MODULE
|
nvarchar(25)
|
Target
module. Used for access control.
|
@URL_ASSIGNED_FIELD
|
nvarchar(30)
|
Target
module Assigned field. Used for access
control.
|
The following is the definition of each field in the spGRIDVIEWS_COLUMNS_InsBound stored
procedure:
@GRID_NAME
|
nvarchar(50)
|
Name of
the grid view.
|
@COLUMN_INDEX
|
int
|
Index of
the field.
|
@HEADER_TEXT
|
nvarchar(150)
|
Terminology
name used in the header.
|
@DATA_FIELD
|
nvarchar(50)
|
Field
name.
|
@SORT_EXPRESSION
|
nvarchar(50)
|
Field that
will be sorted. Usually the same as
the DATA_FIELD.
|
@ITEMSTYLE_WIDTH
|
nvarchar(10)
|
HTML table
column width.
|
if not exists(select * from EDITVIEWS_FIELDS where
EDIT_NAME = 'Teams.EditView' and DELETED = 0) begin -- then
print
'EDITVIEWS_FIELDS Teams.EditView';
exec
dbo.spEDITVIEWS_InsertOnly
'Teams.EditView', 'Teams', 'vwTEAMS_Edit', '15%', '85%', null;
exec
dbo.spEDITVIEWS_FIELDS_InsBound
'Teams.EditView', 0,
'Teams.LBL_NAME', 'NAME', 1, 1, 128, 35, null;
exec
dbo.spEDITVIEWS_FIELDS_InsBlank
'Teams.EditView', 1, null;
exec
dbo.spEDITVIEWS_FIELDS_InsMultiLine 'Teams.EditView', 2, 'Teams.LBL_DESCRIPTION', 'DESCRIPTION', 0,
2, 4, 60, null;
end -- if;
The following is the definition of each field in the spEDITVIEWS_InsertOnly stored
procedure:
@NAME
|
nvarchar(50)
|
Name for
the edit view.
|
@MODULE_NAME
|
nvarchar(25)
|
Module
that this view applies to.
|
@VIEW_NAME
|
nvarchar(50)
|
SQL view
for the edit view.
|
@LABEL_WIDTH
|
nvarchar(10)
|
Width of
the label. Typically 15%.
|
@FIELD_WIDTH
|
nvarchar(10)
|
Width of
the field. Typically 35%.
|
@DATA_COLUMNS
|
int
|
Number of
data columns. Typically 2.
|
The following is the definition of each field in the spEDITVIEWS_FIELDS_InsBound stored
procedure:
@EDIT_NAME
|
nvarchar(50)
|
Name of
the edit view.
|
@FIELD_INDEX
|
Int
|
Index of
the field.
|
@DATA_LABEL
|
nvarchar(150)
|
Terminology
name used for the label.
|
@DATA_FIELD
|
nvarchar(100)
|
Field
name.
|
@DATA_REQUIRED
|
bit
|
Required
field flag.
|
@FORMAT_TAB_INDEX
|
int
|
HTML tab
index.
|
@FORMAT_MAX_LENGTH
|
int
|
HTML
maximum length for textbox.
|
@FORMAT_SIZE
|
int
|
HTML size
of the textbox.
|
@COLSPAN
|
int
|
HTML
column span.
|
if not exists(select * from DETAILVIEWS_FIELDS where
DETAIL_NAME = 'Teams.DetailView' and DELETED = 0) begin -- then
print
'DETAILVIEWS_FIELDS Teams.DetailView';
exec
dbo.spDETAILVIEWS_InsertOnly
'Teams.DetailView', 'Teams', 'vwTEAMS_Edit', '15%', '35%', null;
exec dbo.spDETAILVIEWS_FIELDS_InsBound 'Teams.DetailView', 0, 'Teams.LBL_NAME', 'NAME', '{0}', 3;
exec
dbo.spDETAILVIEWS_FIELDS_InsertOnly
'Teams.DetailView', 1, 'TextBox',
'Teams.LBL_DESCRIPTION', 'DESCRIPTION', null, null, null, null, null, 3, null;
end -- if;
The following is the definition of each field in the spDETAILVIEWS_InsertOnly stored
procedure:
@NAME
|
nvarchar(50)
|
Name for
the detail view.
|
@MODULE_NAME
|
nvarchar(25)
|
Module
that this view applies to.
|
@VIEW_NAME
|
nvarchar(50)
|
SQL view
for the edit view.
|
@LABEL_WIDTH
|
nvarchar(10)
|
Width of
the label. Typically 15%.
|
@FIELD_WIDTH
|
nvarchar(10)
|
Width of
the field. Typically 35%.
|
@DATA_COLUMNS
|
int
|
Number of
data columns. Typically 2.
|
The following is the definition of each field in the spDETAILVIEWS_FIELDS_InsBound stored
procedure:
@DETAIL_NAME
|
nvarchar(50)
|
Name of
the detail view.
|
@FIELD_INDEX
|
int
|
Index of
the field.
|
@DATA_LABEL
|
nvarchar(150)
|
Terminology
name used for the label.
|
@DATA_FIELD
|
nvarchar(100)
|
Field
name.
|
@DATA_FORMAT
|
nvarchar(100)
|
Display
format. Uses ASP.NET formatting rules,
such as {0}, {1} and {0:c}.
|
@COLSPAN
|
int
|
HTML
column span.
|
The following is the definition of each field in the spDETAILVIEWS_FIELDS_InsertOnly stored
procedure:
@DETAIL_NAME
|
nvarchar(50)
|
Name of
the detail view.
|
@FIELD_INDEX
|
int
|
Index of
the field.
|
@FIELD_TYPE
|
nvarchar(25)
|
|
@DATA_LABEL
|
nvarchar(150)
|
Terminology
name used for the label.
|
@DATA_FIELD
|
nvarchar(100)
|
Field
name.
|
@DATA_FORMAT
|
nvarchar(100)
|
Display
format. Uses ASP.NET formatting rules,
such as {0}, {1} and {0:c}.
|
@URL_FIELD
|
nvarchar(50)
|
Field used
in the URL.
|
@URL_FORMAT
|
nvarchar(100)
|
Format for
the URL with {0} style replacements.
|
@URL_TARGET
|
nvarchar(20)
|
HTML
target for the URL.
|
@LIST_NAME
|
nvarchar(50)
|
List name.
|
@COLSPAN
|
Int
|
HTML column
span.
|
@TOOL_TIP
|
nvarchar(150)
|
Terminology
name used for the tool tip.
|
exec dbo.spDYNAMIC_BUTTONS_CopyDefault '.DetailView',
'Teams.DetailView', 'Teams';
exec dbo.spDYNAMIC_BUTTONS_CopyDefault '.EditView' , 'Teams.EditView' , 'Teams';
The following is the definition of each field in the spDYNAMIC_BUTTONS_CopyDefault stored
procedure:
@SOURCE_VIEW_NAME
|
nvarchar(50)
|
Source
name.
|
@NEW_VIEW_NAME
|
nvarchar(50)
|
Destination
name.
|
@MODULE_NAME
|
nvarchar(25)
|
Destination
module.
|
if not exists(select * from DETAILVIEWS_RELATIONSHIPS where
DETAIL_NAME = 'Teams.DetailView' and DELETED = 0) begin -- then
print
'DETAILVIEWS_RELATIONSHIPS Teams.DetailView Professional';
exec
dbo.spDETAILVIEWS_RELATIONSHIPS_InsertOnly 'Teams.DetailView', 'Users',
'Users', 0, 'Users.LBL_MODULE_NAME';
end -- if;
The following is the definition of each field in the spDETAILVIEWS_RELATIONSHIPS_InsertOnly
stored procedure:
@DETAIL_NAME
|
nvarchar(50)
|
Name of
the detail view.
|
@MODULE_NAME
|
nvarchar(50)
|
Module
that this relationship belongs to so that access rights can be applied.
|
@CONTROL_NAME
|
nvarchar(50)
|
Name of
the control, without the .ascx file extension.
|
@RELATIONSHIP_ORDER
|
int
|
Order of
the relationship panel.
|
@TITLE
|
nvarchar(100)
|
Terminology
name for the panel. We do not
currently display this value.
|
default.aspx
<%@ Page language="c#" MasterPageFile="~/DefaultView.Master"
Codebehind="default.aspx.cs" AutoEventWireup="false"
Inherits="SplendidCRM.Administration.Teams.Default" %>
<%@
Register TagPrefix="SplendidCRM" Tagname="Shortcuts"
Src="/portals/0/~/_controls/Shortcuts.ascx" %>
<%@
Register TagPrefix="SplendidCRM" Tagname="ListView"
Src="/portals/0/ListView.ascx" %>
default.aspx.cs
using System;
using System.Data;
using System.Data.Common;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Diagnostics;
namespace SplendidCRM.Administration.Teams
{
///
/// Summary
description for Default.
///
public class
Default : SplendidAdminPage
{
private
void Page_Load(object sender, System.EventArgs e)
{
}
#region
Web Form Designer generated code
override
protected void OnInit(EventArgs e)
{
//
//
CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}
///
///
Required method for Designer support - do not modify
///
the contents of this method with the code editor.
///
private
void InitializeComponent()
{
this.IsAdminPage
= true;
this.Load
+= new System.EventHandler(this.Page_Load);
}
#endregion
}
}
ListView.ascx
<%@ Control CodeBehind="ListView.ascx.cs"
Language="c#" AutoEventWireup="false"
Inherits="SplendidCRM.Administration.Teams.ListView" %>
<%@
Register TagPrefix="SplendidCRM" Tagname="ModuleHeader"
Src="/portals/0/~/_controls/ModuleHeader.ascx" %>
<%@
Register TagPrefix="SplendidCRM" Tagname="ListHeader"
Src="/portals/0/~/_controls/ListHeader.ascx" %>
" />
')">
CommandName="Teams.Delete"
CommandArgument='<%# DataBinder.Eval(Container.DataItem, "ID")
%>' OnCommand="Page_Command"
CssClass="listViewTdToolsS1" Text='<%#
L10n.Term(".LNK_DELETE") %>' Runat="server" />
<%@
Register TagPrefix="SplendidCRM" Tagname="CheckAll"
Src="/portals/0/~/_controls/CheckAll.ascx" %>
<%@
Register TagPrefix="SplendidCRM" Tagname="MassUpdate"
Src="/portals/0/MassUpdate.ascx" %>
<%@
Register TagPrefix="SplendidCRM" Tagname="DumpSQL"
Src="/portals/0/~/_controls/DumpSQL.ascx" %>
ListView.ascx.cs
using System;
using System.Data;
using System.Data.Common;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Diagnostics;
//using Microsoft.VisualBasic;
namespace SplendidCRM.Administration.Teams
{
///
/// Summary description for
ListView.
///
public class
ListView : SplendidControl
{
protected
DataView vwMain ;
protected
SplendidGrid grdMain ;
protected
Label lblError ;
protected
PlaceHolder plcSearch ;
protected
SearchControl ctlSearch ;
protected
MassUpdate ctlMassUpdate ;
protected
void Page_Command(object sender, CommandEventArgs e)
{
try
{
if
( e.CommandName == "Clear" )
{
ctlSearch.ClearForm();
Server.Transfer("default.aspx");
}
else
if ( e.CommandName == "Search" )
{
//
10/13/2005 Paul. Make sure to clear the
page index prior to applying search.
grdMain.CurrentPageIndex
= 0;
grdMain.ApplySort();
grdMain.DataBind();
}
else
if ( e.CommandName == "Teams.Delete" )
{
Guid
gID = Sql.ToGuid(e.CommandArgument);
SqlProcs.spTEAMS_Delete(gID);
grdMain.CurrentPageIndex
= 0;
grdMain.ApplySort();
grdMain.DataBind();
Response.Redirect("default.aspx");
}
else
if ( e.CommandName == "MassDelete" )
{
string[]
arrID = Request.Form.GetValues("chkMain");
if
( arrID != null )
{
string
sIDs = Utils.ValidateIDs(arrID);
if
( !Sql.IsEmptyString(sIDs) )
{
SqlProcs.spTEAMS_MassDelete(sIDs);
Response.Redirect("default.aspx");
}
}
}
}
catch(Exception
ex)
{
SplendidError.SystemError(new
StackTrace(true).GetFrame(0), ex);
lblError.Text
= ex.Message;
}
}
private
void Page_Load(object sender, System.EventArgs e)
{
SetPageTitle(L10n.Term(m_sMODULE
+ ".LBL_LIST_FORM_TITLE"));
//
06/04/2006 Paul. Visibility is already
controlled by the ASPX page, but it is probably a good idea to skip the load.
this.Visible
= SplendidCRM.Security.IS_ADMIN;
if
( !this.Visible )
return;
try
{
DbProviderFactory
dbf = DbProviderFactories.GetFactory();
using
( IDbConnection con = dbf.CreateConnection() )
{
string
sSQL;
sSQL
= "select * " +
ControlChars.CrLf
+ "
from vwTEAMS_List" + ControlChars.CrLf
+ " where 1 = 1 " + ControlChars.CrLf;
using
( IDbCommand cmd = con.CreateCommand() )
{
cmd.CommandText
= sSQL;
ctlSearch.SqlSearchClause(cmd);
if
( bDebug )
RegisterClientScriptBlock("SQLCode",
Sql.ClientScriptBlock(cmd));
using
( DbDataAdapter da = dbf.CreateDataAdapter() )
{
((IDbDataAdapter)da).SelectCommand
= cmd;
using
( DataTable dt = new DataTable() )
{
da.Fill(dt);
vwMain
= dt.DefaultView;
grdMain.DataSource
= vwMain ;
if
( !IsPostBack )
{
if
( String.IsNullOrEmpty(grdMain.SortColumn) )
{
grdMain.SortColumn
= "NAME";
grdMain.SortOrder = "asc" ;
}
grdMain.ApplySort();
grdMain.DataBind();
}
}
}
}
}
}
catch(Exception
ex)
{
SplendidError.SystemError(new
StackTrace(true).GetFrame(0), ex);
lblError.Text
= ex.Message;
}
if
( !IsPostBack )
{
//
06/09/2006 Paul. Remove data binding in
the user controls. Binding is required,
but only do so in the ASPX pages.
//Page.DataBind();
}
}
#region
Web Form Designer generated code
override
protected void OnInit(EventArgs e)
{
//
//
CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}
///
/// Required method for Designer support
- do not modify
/// the contents of this method with
the code editor.
///
private
void InitializeComponent()
{
this.Load
+= new System.EventHandler(this.Page_Load);
m_sMODULE
= "Teams";
SetMenu(m_sMODULE);
this.AppendGridColumns(grdMain,
m_sMODULE + ".ListView");
//
We have to load the control in here, otherwise the control will not initialized
before the Page_Load above.
ctlSearch
= (SearchControl) LoadControl("SearchBasic.ascx");
plcSearch.Controls.Add(ctlSearch);
ctlSearch.Command
= new CommandEventHandler(Page_Command);
ctlMassUpdate.Command
= new CommandEventHandler(Page_Command);
}
#endregion
}
}
edit.aspx
<%@ Page language="c#"
MasterPageFile="~/DefaultView.Master" Codebehind="edit.aspx.cs"
AutoEventWireup="false"
Inherits="SplendidCRM.Administration.Teams.Edit" %>
<%@
Register TagPrefix="SplendidCRM" Tagname="Shortcuts"
Src="/portals/0/~/_controls/Shortcuts.ascx" %>
<%@
Register TagPrefix="SplendidCRM" Tagname="EditView"
Src="/portals/0/EditView.ascx" %>
edit.aspx.cs
using System;
using System.Data;
using System.Data.Common;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Diagnostics;
namespace SplendidCRM.Administration.Teams
{
///
/// Summary
description for Edit.
///
public class
Edit : SplendidAdminPage
{
private
void Page_Load(object sender, System.EventArgs e)
{
}
#region
Web Form Designer generated code
override
protected void OnInit(EventArgs e)
{
//
//
CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}
///
///
Required method for Designer support - do not modify
///
the contents of this method with the code editor.
///
private
void InitializeComponent()
{
this.IsAdminPage
= true;
this.Load
+= new System.EventHandler(this.Page_Load);
}
#endregion
}
}
EditView.ascx
<%@ Control Language="c#"
AutoEventWireup="false" Codebehind="EditView.ascx.cs"
Inherits="SplendidCRM.Administration.Teams.EditView"
TargetSchema="http://schemas.microsoft.com/intellisense/ie5" %>
<%@
Register TagPrefix="SplendidCRM" Tagname="ModuleHeader"
Src="/portals/0/~/_controls/ModuleHeader.ascx" %>
<%@
Register TagPrefix="SplendidCRM" Tagname="DynamicButtons"
Src="/portals/0/~/_controls/DynamicButtons.ascx" %>
EditView.ascx.cs
using System;
using System.Data;
using System.Data.Common;
using System.Drawing;
using System.Web;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Diagnostics;
namespace SplendidCRM.Administration.Teams
{
///
/// Summary description for
EditView.
///
public class
EditView : SplendidControl
{
protected
_controls.ModuleHeader
ctlModuleHeader ;
protected
_controls.DynamicButtons ctlDynamicButtons;
protected
Guid gID ;
protected
HtmlTable tblMain ;
protected
void Page_Command(Object sender, CommandEventArgs e)
{
if
( e.CommandName == "Save" )
{
try
{
//
01/16/2006 Paul. Enable validator before
validating page.
this.ValidateEditViewFields(m_sMODULE
+ ".EditView");
if
( Page.IsValid )
{
DbProviderFactory
dbf = DbProviderFactories.GetFactory();
using
( IDbConnection con = dbf.CreateConnection() )
{
con.Open();
string
sSQL;
string
sCUSTOM_MODULE = "TEAMS";
DataTable
dtCustomFields = SplendidCache.FieldsMetaData_Validated(sCUSTOM_MODULE);
using
( IDbTransaction trn = con.BeginTransaction() )
{
try
{
SqlProcs.spTEAMS_Update
(
ref gID
,
new DynamicControl(this, "NAME"
).Text
,
new DynamicControl(this, "DESCRIPTION").Text
,
trn
);
SplendidDynamic.UpdateCustomFields(this,
trn, gID, sCUSTOM_MODULE, dtCustomFields);
trn.Commit();
}
catch(Exception
ex)
{
trn.Rollback();
SplendidError.SystemError(new
StackTrace(true).GetFrame(0), ex);
ctlDynamicButtons.ErrorText
= ex.Message;
return;
}
}
}
Response.Redirect("view.aspx?ID="
+ gID.ToString());
}
}
catch(Exception
ex)
{
SplendidError.SystemError(new
StackTrace(true).GetFrame(0), ex);
ctlDynamicButtons.ErrorText
= ex.Message;
}
}
else
if ( e.CommandName == "Cancel" )
{
if
( Sql.IsEmptyGuid(gID) )
Response.Redirect("default.aspx");
else
Response.Redirect("view.aspx?ID="
+ gID.ToString());
}
}
private
void Page_Load(object sender, System.EventArgs e)
{
SetPageTitle(L10n.Term(m_sMODULE
+ ".LBL_LIST_FORM_TITLE"));
//
06/04/2006 Paul. Visibility is already
controlled by the ASPX page, but it is probably a good idea to skip the load.
this.Visible
= SplendidCRM.Security.IS_ADMIN;
if
( !this.Visible )
return;
try
{
gID
= Sql.ToGuid(Request["ID"]);
if
( !IsPostBack )
{
//
03/20/2008 Paul. Dynamic buttons need to
be recreated in order for events to fire.
ctlDynamicButtons.AppendButtons(m_sMODULE
+ ".EditView", Guid.Empty, null);
Guid
gDuplicateID = Sql.ToGuid(Request["DuplicateID"]);
if
( !Sql.IsEmptyGuid(gID) || !Sql.IsEmptyGuid(gDuplicateID) )
{
DbProviderFactory
dbf = DbProviderFactories.GetFactory();
using
( IDbConnection con = dbf.CreateConnection() )
{
string
sSQL ;
sSQL
= "select * " +
ControlChars.CrLf
+ "
from vwTEAMS_Edit" + ControlChars.CrLf
+
" where ID = @ID " +
ControlChars.CrLf;
using
( IDbCommand cmd = con.CreateCommand() )
{
cmd.CommandText
= sSQL;
if
( !Sql.IsEmptyGuid(gDuplicateID) )
{
Sql.AddParameter(cmd,
"@ID", gDuplicateID);
gID = Guid.Empty;
}
else
{
Sql.AddParameter(cmd,
"@ID", gID);
}
con.Open();
if
( bDebug )
RegisterClientScriptBlock("SQLCode",
Sql.ClientScriptBlock(cmd));
using
( IDataReader rdr = cmd.ExecuteReader(CommandBehavior.SingleRow) )
{
if
( rdr.Read() )
{
ctlModuleHeader.Title
= Sql.ToString(rdr["NAME"]);
SetPageTitle(L10n.Term(".moduleList."
+ m_sMODULE) + " - " + ctlModuleHeader.Title);
ViewState["ctlModuleHeader.Title"]
= ctlModuleHeader.Title;
this.AppendEditViewFields(m_sMODULE
+ ".EditView", tblMain, rdr);
}
}
}
}
}
else
{
this.AppendEditViewFields(m_sMODULE
+ ".EditView", tblMain, null);
}
}
else
{
//
12/02/2005 Paul. When validation fails,
the header title does not retain its value.
Update manually.
ctlModuleHeader.Title
= Sql.ToString(ViewState["ctlModuleHeader.Title"]);
SetPageTitle(L10n.Term(".moduleList."
+ m_sMODULE) + " - " + ctlModuleHeader.Title);
}
}
catch(Exception
ex)
{
SplendidError.SystemError(new
StackTrace(true).GetFrame(0), ex);
ctlDynamicButtons.ErrorText
= ex.Message;
}
}
#region
Web Form Designer generated code
override
protected void OnInit(EventArgs e)
{
//
//
CODEGEN: This Task is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}
///
/// Required method for Designer
support - do not modify
/// the contents of this method with
the code editor.
///
private
void InitializeComponent()
{
this.Load
+= new System.EventHandler(this.Page_Load);
ctlDynamicButtons.Command
+= new CommandEventHandler(Page_Command);
m_sMODULE
= "Teams";
SetMenu(m_sMODULE);
if
( IsPostBack )
{
//
12/02/2005 Paul. Need to add the edit
fields in order for events to fire.
this.AppendEditViewFields(m_sMODULE
+ ".EditView", tblMain, null);
//
03/20/2008 Paul. Dynamic buttons need to
be recreated in order for events to fire.
ctlDynamicButtons.AppendButtons(m_sMODULE
+ ".EditView", Guid.Empty, null);
}
}
#endregion
}
}
view.aspx
<%@ Page language="c#" MasterPageFile="~/DefaultView.Master"
Codebehind="view.aspx.cs" AutoEventWireup="false"
Inherits="SplendidCRM.Administration.Teams.View" %>
<%@
Register TagPrefix="SplendidCRM" Tagname="Shortcuts"
Src="/portals/0/~/_controls/Shortcuts.ascx" %>
<%@
Register TagPrefix="SplendidCRM" Tagname="DetailView"
Src="/portals/0/DetailView.ascx" %>
view.aspx.cs
using System;
using System.Data;
using System.Data.Common;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Diagnostics;
namespace SplendidCRM.Administration.Teams
{
///
/// Summary
description for View.
///
public class
View : SplendidAdminPage
{
private
void Page_Load(object sender, System.EventArgs e)
{
if
( !IsPostBack )
{
//
03/11/2008 Paul. Move the primary binding
to SplendidPage.
//Page
DataBind();
}
}
#region
Web Form Designer generated code
override
protected void OnInit(EventArgs e)
{
//
//
CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}
///
///
Required method for Designer support - do not modify
///
the contents of this method with the code editor.
///
private
void InitializeComponent()
{
this.IsAdminPage
= true;
this.Load
+= new System.EventHandler(this.Page_Load);
}
#endregion
}
}
DetailView.aspx
<%@ Control Language="c#"
AutoEventWireup="false" Codebehind="DetailView.ascx.cs"
Inherits="SplendidCRM.Administration.Teams.DetailView"
TargetSchema="http://schemas.microsoft.com/intellisense/ie5" %>
<%@
Register TagPrefix="SplendidCRM" Tagname="ModuleHeader"
Src="/portals/0/~/_controls/ModuleHeader.ascx" %>
<%@
Register TagPrefix="SplendidCRM" Tagname="DynamicButtons"
Src="/portals/0/~/_controls/DynamicButtons.ascx" %>
<%@ Register TagPrefix="SplendidCRM"
Tagname="DumpSQL" Src="/portals/0/~/_controls/DumpSQL.ascx" %>
DetailView.aspx.cs
using System;
using System.Data;
using System.Data.Common;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Diagnostics;
namespace SplendidCRM.Administration.Teams
{
///
/// Summary
description for DetailView.
///
public class
DetailView : SplendidControl
{
protected
_controls.ModuleHeader ctlModuleHeader ;
protected
_controls.DynamicButtons ctlDynamicButtons;
protected
Guid gID ;
protected
HtmlTable tblMain ;
protected
PlaceHolder plcSubPanel;
protected
void Page_Command(Object sender, CommandEventArgs e)
{
try
{
if
( e.CommandName == "Edit" )
{
Response.Redirect("edit.aspx?ID="
+ gID.ToString());
}
else
if ( e.CommandName == "Duplicate" )
{
Response.Redirect("edit.aspx?DuplicateID="
+ gID.ToString());
}
else
if ( e.CommandName == "Delete" )
{
SqlProcs.spTEAMS_Delete(gID);
Response.Redirect("default.aspx");
}
}
catch(Exception
ex)
{
SplendidError.SystemError(new
StackTrace(true).GetFrame(0), ex);
ctlDynamicButtons.ErrorText
= ex.Message;
}
}
private
void Page_Load(object sender, System.EventArgs e)
{
SetPageTitle(L10n.Term(m_sMODULE
+ ".LBL_TEAMS"));
//
06/04/2006 Paul. Visibility is already
controlled by the ASPX page, but it is probably a good idea to skip the load.
this.Visible
= SplendidCRM.Security.IS_ADMIN;
if
( !this.Visible )
return;
try
{
gID
= Sql.ToGuid(Request["ID"]);
//
11/28/2005 Paul. We must always populate
the table, otherwise it will disappear during event processing.
//
03/19/2008 Paul. Place
AppendDetailViewFields inside OnInit to avoid having to re-populate the data.
if
( !IsPostBack )
{
if
( !Sql.IsEmptyGuid(gID) )
{
DbProviderFactory
dbf = DbProviderFactories.GetFactory();
using
( IDbConnection con = dbf.CreateConnection() )
{
string
sSQL ;
sSQL
= "select * " +
ControlChars.CrLf
+ "
from vwTEAMS_Edit" + ControlChars.CrLf
+ " where ID = @ID " + ControlChars.CrLf;
using
( IDbCommand cmd = con.CreateCommand() )
{
cmd.CommandText
= sSQL;
Sql.AddParameter(cmd,
"@ID", gID);
con.Open();
if
( bDebug )
RegisterClientScriptBlock("SQLCode",
Sql.ClientScriptBlock(cmd));
using
( IDataReader rdr = cmd.ExecuteReader(CommandBehavior.SingleRow) )
{
if
( rdr.Read() )
{
ctlModuleHeader.Title
= Sql.ToString(rdr["NAME"]);
SetPageTitle(L10n.Term(".moduleList."
+ m_sMODULE) + " - " + ctlModuleHeader.Title);
this.AppendDetailViewFields(m_sMODULE
+ ".DetailView", tblMain, rdr);
//
03/20/2008 Paul. Dynamic buttons need to
be recreated in order for events to fire.
ctlDynamicButtons.AppendButtons(m_sMODULE
+ ".DetailView", Guid.Empty, rdr);
}
else
{
//
11/25/2006 Paul. If item is not visible,
then don't show its sub panel either.
plcSubPanel.Visible
= false;
//
03/20/2008 Paul. Dynamic buttons need to
be recreated in order for events to fire.
ctlDynamicButtons.AppendButtons(m_sMODULE
+ ".DetailView", Guid.Empty, null);
ctlDynamicButtons.DisableAll();
ctlDynamicButtons.ErrorText
= L10n.Term("ACL.LBL_NO_ACCESS");
}
}
}
}
}
else
{
//
03/20/2008 Paul. Dynamic buttons need to
be recreated in order for events to fire.
ctlDynamicButtons.AppendButtons(m_sMODULE
+ ".DetailView", Guid.Empty, null);
ctlDynamicButtons.DisableAll();
//ctlDynamicButtons.ErrorText
= L10n.Term(".ERR_MISSING_REQUIRED_FIELDS") + "ID";
}
}
//
06/09/2006 Paul. Remove data binding in
the user controls. Binding is required,
but only do so in the ASPX pages.
//Page.DataBind();
}
catch(Exception ex)
{
SplendidError.SystemError(new
StackTrace(true).GetFrame(0), ex);
ctlDynamicButtons.ErrorText
= ex.Message;
}
}
#region
Web Form Designer generated code
override
protected void OnInit(EventArgs e)
{
//
//
CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}
///
///
Required method for Designer support - do not modify
///
the contents of this method with the code editor.
///
private
void InitializeComponent()
{
this.Load
+= new System.EventHandler(this.Page_Load);
ctlDynamicButtons.Command
+= new CommandEventHandler(Page_Command);
m_sMODULE
= "Teams";
SetMenu(m_sMODULE);
this.AppendDetailViewRelationships(m_sMODULE
+ ".DetailView", plcSubPanel);
if
( IsPostBack )
{
this.AppendDetailViewFields(m_sMODULE
+ ".DetailView", tblMain, null);
//
03/20/2008 Paul. Dynamic buttons need to
be recreated in order for events to fire.
ctlDynamicButtons.AppendButtons(m_sMODULE
+ ".DetailView", Guid.Empty, null);
}
}
#endregion
}
}
Popup.aspx
<%@ Page language="c#"
MasterPageFile="~/PopupView.Master"
Codebehind="Popup.aspx.cs" AutoEventWireup="false"
Inherits="SplendidCRM.Administration.Teams.Popup" %>
<%@
Register TagPrefix="SplendidCRM" Tagname="PopupView"
Src="/portals/0/PopupView.ascx" %>
Popup.aspx.cs
using System;
using System.Data;
using System.Data.Common;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Diagnostics;
namespace SplendidCRM.Administration.Teams
{
///
/// Summary
description for Popup.
///
public class
Popup : SplendidPopup
{
private
void Page_Load(object sender, System.EventArgs e)
{
}
#region
Web Form Designer generated code
override
protected void OnInit(EventArgs e)
{
//
//
CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}
///
///
Required method for Designer support - do not modify
///
the contents of this method with the code editor.
///
private
void InitializeComponent()
{
this.Load
+= new System.EventHandler(this.Page_Load);
}
#endregion
}
}
PopupView.ascx
<%@ Control CodeBehind="PopupView.ascx.cs"
Language="c#" AutoEventWireup="false"
Inherits="SplendidCRM.Administration.Teams.PopupView" %>
PopupView.ascx.cs
using System;
using System.Data;
using System.Data.Common;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Diagnostics;
namespace SplendidCRM.Administration.Teams
{
///
/// Summary description for
PopupView.
///
public class
PopupView : SplendidControl
{
protected
SplendidCRM._controls.SearchView
ctlSearchView ;
protected
_controls.DynamicButtons ctlDynamicButtons;
protected
UniqueStringCollection arrSelectFields;
protected
DataView vwMain ;
protected
SplendidGrid grdMain ;
protected
bool bMultiSelect ;
public
bool MultiSelect
{
get
{ return bMultiSelect; }
set
{ bMultiSelect = value; }
}
protected
void Page_Command(object sender, CommandEventArgs e)
{
try
{
if
( e.CommandName == "Search" )
{
//
10/13/2005 Paul. Make sure to clear the
page index prior to applying search.
grdMain.CurrentPageIndex
= 0;
//
04/27/2008 Paul. Sorting has been moved
to the database to increase performance.
grdMain.DataBind();
}
//
12/14/2007 Paul. We need to capture the
sort event from the SearchView.
else
if ( e.CommandName == "SortGrid" )
{
grdMain.SetSortFields(e.CommandArgument
as string[]);
//
04/27/2008 Paul. Sorting has been moved
to the database to increase performance.
arrSelectFields.Add(grdMain.SortColumn);
}
}
catch(Exception
ex)
{
SplendidError.SystemError(new
StackTrace(true).GetFrame(0), ex);
ctlDynamicButtons.ErrorText
= ex.Message;
}
}
private
void Page_Load(object sender, System.EventArgs e)
{
SetPageTitle(L10n.Term(m_sMODULE
+ ".LBL_LIST_FORM_TITLE"));
//
07/05/2009 Paul. We don't use access
control on the team list as all users can assign a record to any team.
//this.Visible
= (SplendidCRM.Security.GetUserAccess(m_sMODULE, "list") >= 0);
if
( !this.Visible )
return;
try
{
DbProviderFactory
dbf = DbProviderFactories.GetFactory();
using
( IDbConnection con = dbf.CreateConnection() )
{
string
sSQL;
//
11/25/2006 Paul. An admin can see all
teams, but most users will only see the teams which they are assigned to.
if
( Security.IS_ADMIN )
{
sSQL
= " from vwTEAMS_List" +
ControlChars.CrLf
+ " where 1 = 1 " + ControlChars.CrLf;
}
else
{
sSQL
= " from vwTEAMS_MyList" +
ControlChars.CrLf
+ " where MEMBERSHIP_USER_ID =
@MEMBERSHIP_USER_ID" + ControlChars.CrLf;
}
using
( IDbCommand cmd = con.CreateCommand() )
{
cmd.CommandText
= sSQL;
if
( !Security.IS_ADMIN )
Sql.AddParameter(cmd,
"@MEMBERSHIP_USER_ID", Security.USER_ID);
//
04/27/2008 Paul. A ListView will need to
set and build the order clause in two setps
//
so that the SavedSearch sort value can be taken into account.
grdMain.OrderByClause("NAME",
"asc");
ctlSearchView.SqlSearchClause(cmd);
//
04/27/2008 Paul. The fields in the
search clause need to be prepended after any Saved Search sort has been
determined.
cmd.CommandText
= "select " + Sql.FormatSelectFields(arrSelectFields)
+ cmd.CommandText
+ grdMain.OrderByClause();
if
( bDebug )
Page.ClientScript.RegisterClientScriptBlock(System.Type.GetType("System.String"),
"SQLCode", Sql.ClientScriptBlock(cmd));
using
( DbDataAdapter da = dbf.CreateDataAdapter() )
{
((IDbDataAdapter)da).SelectCommand
= cmd;
using
( DataTable dt = new DataTable() )
{
da.Fill(dt);
vwMain
= dt.DefaultView;
grdMain.DataSource
= vwMain ;
if
( !IsPostBack )
{
grdMain.DataBind();
}
}
}
}
}
}
catch(Exception
ex)
{
SplendidError.SystemError(new
StackTrace(true).GetFrame(0), ex);
ctlDynamicButtons.ErrorText
= ex.Message;
}
if
( !IsPostBack )
{
//
03/11/2008 Paul. Move the primary
binding to SplendidPage.
//Page
DataBind();
}
}
#region
Web Form Designer generated code
override
protected void OnInit(EventArgs e)
{
//
//
CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}
///
///
Required method for Designer support - do not modify
///
the contents of this method with the code editor.
///
private
void InitializeComponent()
{
this.Load
+= new System.EventHandler(this.Page_Load);
ctlDynamicButtons.Command
+= new CommandEventHandler(Page_Command);
ctlSearchView.Command
= new CommandEventHandler(Page_Command);
m_sMODULE
= "Teams";
arrSelectFields
= new UniqueStringCollection();
arrSelectFields.Add("NAME");
this.AppendGridColumns(grdMain,
m_sMODULE + ".PopupView", arrSelectFields);
ctlDynamicButtons.AppendButtons(m_sMODULE
+ ".Popup" + (bMultiSelect ? "MultiSelect" :
"View"), Guid.Empty, Guid.Empty);
if
( !IsPostBack && !bMultiSelect )
ctlDynamicButtons.ShowButton("Clear",
!Sql.ToBoolean(Request["ClearDisabled"]));
}
#endregion
}
}
Users.ascx
<%@ Control CodeBehind="Users.ascx.cs"
Language="c#" AutoEventWireup="false"
Inherits="SplendidCRM.Administration.Teams.Users" %>
function ChangeUser(sPARENT_ID, sPARENT_NAME)
{
document.getElementById('<%=
txtUSER_ID.ClientID %>').value =
sPARENT_ID ;
document.forms[0].submit();
}
function UserMultiSelect()
{
window.open('../../Users/PopupMultiSelect.aspx','UserPopup','width=600,height=400,resizable=1,scrollbars=1');
return
false;
}
<%@
Register TagPrefix="SplendidCRM" Tagname="ListHeader"
Src="/portals/0/~/_controls/ListHeader.ascx" %>
<%@
Register TagPrefix="SplendidCRM" Tagname="DynamicButtons"
Src="/portals/0/~/_controls/DynamicButtons.ascx" %>
DataTextField="FULL_NAME" SortExpression="FULL_NAME" ItemStyle-Width="18%"
ItemStyle-CssClass="listViewTdLinkS1"
DataNavigateUrlField="USER_ID"
DataNavigateUrlFormatString="~/Users/view.aspx?id={0}" />
HeaderText="Users.LBL_LIST_USER_NAME" DataField="USER_NAME" SortExpression="USER_NAME" ItemStyle-Width="18%" />
HeaderText="Teams.LBL_LIST_MEMBERSHIP"
DataField="MEMBERSHIP"
SortExpression="MEMBERSHIP" ItemStyle-Width="18%"
/>
HeaderText="Users.LBL_LIST_EMAIL" DataField="EMAIL1" SortExpression="EMAIL1" ItemStyle-Width="18%" />
HeaderText=".LBL_LIST_PHONE"
DataField="PHONE_WORK"
SortExpression="PHONE_WORK" ItemStyle-Width="15%"
ItemStyle-Wrap="false" />
HeaderText=""
ItemStyle-Width="1%" ItemStyle-HorizontalAlign="Left"
ItemStyle-Wrap="false">
">
CommandName="Users.Remove"
CommandArgument='<%# DataBinder.Eval(Container.DataItem,
"USER_ID") %>' OnCommand="Page_Command"
CssClass="listViewTdToolsS1" Text='<%#
L10n.Term(".LNK_REMOVE") %>' Runat="server" />
Users.ascx.cs
using System;
using System.Data;
using System.Data.Common;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Diagnostics;
namespace SplendidCRM.Administration.Teams
{
///
/// Summary description for Users.
///
public class
Users : SplendidControl
{
protected
_controls.DynamicButtons ctlDynamicButtons;
protected
UniqueStringCollection arrSelectFields;
protected
Guid gID ;
protected
DataView vwMain ;
protected
SplendidGrid grdMain ;
protected
Label lblError ;
protected
HtmlInputHidden txtUSER_ID ;
protected
void Page_Command(object sender, CommandEventArgs e)
{
try
{
switch
( e.CommandName )
{
case
"Users.Remove":
{
Guid
gUSER_ID = Sql.ToGuid(e.CommandArgument);
SqlProcs.spTEAM_MEMBERSHIPS_Delete(gID,
gUSER_ID);
//Response.Redirect("view.aspx?ID="
+ gID.ToString());
//
05/16/2008 Paul. Instead of redirecting,
just rebind the grid and AJAX
will repaint.
BindGrid();
break;
}
default:
throw(new
Exception("Unknown command: " + e.CommandName));
}
}
catch(Exception
ex)
{
SplendidError.SystemError(new
StackTrace(true).GetFrame(0), ex);
ctlDynamicButtons.ErrorText
= ex.Message;
}
}
protected
void BindGrid()
{
DbProviderFactory
dbf = DbProviderFactories.GetFactory();
using ( IDbConnection con =
dbf.CreateConnection() )
{
string
sSQL;
sSQL
= "select " + Sql.FormatSelectFields(arrSelectFields)
+ "
from vwTEAM_MEMBERSHIPS_List" + ControlChars.CrLf
+ " where 1 = 1 " + ControlChars.CrLf;
using
( IDbCommand cmd = con.CreateCommand() )
{
cmd.CommandText
= sSQL;
Sql.AppendParameter(cmd,
gID, "TEAM_ID");
cmd.CommandText
+= grdMain.OrderByClause("FULL_NAME", "asc");
if
( bDebug )
RegisterClientScriptBlock("vwTEAM_MEMBERSHIPS_List",
Sql.ClientScriptBlock(cmd));
try
{
using
( DbDataAdapter da = dbf.CreateDataAdapter() )
{
((IDbDataAdapter)da).SelectCommand
= cmd;
using
( DataTable dt = new DataTable() )
{
da.Fill(dt);
dt.Columns.Add("MEMBERSHIP");
string
sMember =
L10n.Term(".team_membership_dom.Member");
string
sMemberReportsTo = L10n.Term(".team_membership_dom.Member
Reports-to");
foreach
( DataRow row in dt.Rows )
{
if
( Sql.ToBoolean(row["EXPLICIT_ASSIGN"]) )
row["MEMBERSHIP"]
= sMember;
else
row["MEMBERSHIP"]
= sMemberReportsTo;
}
vwMain
= dt.DefaultView;
grdMain.DataSource
= vwMain ;
grdMain.DataBind();
}
}
}
catch(Exception
ex)
{
SplendidError.SystemError(new
StackTrace(true).GetFrame(0), ex);
ctlDynamicButtons.ErrorText
= ex.Message;
}
}
}
}
private
void Page_Load(object sender, System.EventArgs e)
{
gID
= Sql.ToGuid(Request["ID"]);
if
( !Sql.IsEmptyString(txtUSER_ID.Value) )
{
try
{
SqlProcs.spTEAM_MEMBERSHIPS_MassUpdate(gID,
txtUSER_ID.Value);
//
05/16/2008 Paul. Instead of redirecting,
just rebind the grid and AJAX
will repaint.
//Response.Redirect("view.aspx?ID="
+ gID.ToString());
txtUSER_ID.Value
= String.Empty;
}
catch(Exception
ex)
{
SplendidError.SystemError(new
StackTrace(true).GetFrame(0), ex);
ctlDynamicButtons.ErrorText
= ex.Message;
}
}
BindGrid();
if
( !IsPostBack )
{
ctlDynamicButtons.AppendButtons("Teams."
+ m_sMODULE, Guid.Empty, gID);
}
}
#region
Web Form Designer generated code
override
protected void OnInit(EventArgs e)
{
//
//
CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}
///
/// Required method for Designer
support - do not modify
/// the contents of this method with
the code editor.
///
private
void InitializeComponent()
{
this.Load
+= new System.EventHandler(this.Page_Load);
ctlDynamicButtons.Command
+= new CommandEventHandler(Page_Command);
m_sMODULE
= "Users";
arrSelectFields
= new UniqueStringCollection();
arrSelectFields.Add("DATE_ENTERED" );
arrSelectFields.Add("USER_ID" );
arrSelectFields.Add("USER_NAME" );
arrSelectFields.Add("FULL_NAME" );
arrSelectFields.Add("EMAIL1" );
arrSelectFields.Add("PHONE_WORK" );
arrSelectFields.Add("EXPLICIT_ASSIGN");
if
( IsPostBack )
ctlDynamicButtons.AppendButtons("Teams."
+ m_sMODULE, Guid.Empty, Guid.Empty);
}
#endregion
}
}
The SplendidCRM Application Platform is constantly being
improved. Please visit the SplendidCRM
Software website to obtain the most recent version of the software:
http://www.splendidcrm.com
If you have any questions, please post them to the
SplendidCRM Support forum:
http://www.splendidcrm.com/Forums/tabid/66/Default.aspx
If you discover any errors or omissions in this document,
please email support@splendidcrm.com.