=x= 🌵 建立 Overview Manager - Content Page 後台页面。
📌 进到 Yachts 页面可以看到上方的不同型号轮播图及左侧型号侧边栏,这个部分的资料我们已经在 Yacht Manager - Content Page 做完後台了,而操作 Yachts 页面内容後可以发现,上方的轮播页及红框的内容区块,都是依据左侧边栏的型号决定,而红框的内容区块,则会因为内部上方的小导览列操作改变内容,另外可以仔细操作会发现小导览列的 Video 并不是每个型号都有,所以内容区块才会把小导览列包含进去,今天的文章将专注在制作 Overview 页面内的资料,分别有 :
🧠 左上区块 - 型号下拉选单 + 尺寸附图上传 + PDF 上传。
🧠 右上区块 - 尺寸动态新增输入栏位 + 下载标题 + Video 连结。
🧠 下半区块 - 主要图文编辑器。
<h6>YachYacht Model :</h6>
<asp:DropDownList ID="DListModel" runat="server" DataSourceID="SqlDataSource1" DataTextField="yachtModel" DataValueField="id" AutoPostBack="True" Width="100%" Font-Bold="True" class="btn btn-outline-primary dropdown-toggle" OnSelectedIndexChanged="DListModel_SelectedIndexChanged" ></asp:DropDownList>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:TayanaYachtConnectionString %>" SelectCommand="SELECT [yachtModel], [id] FROM [Yachts]"></asp:SqlDataSource>
<hr />
<h6>Dimensions Image :</h6>
<asp:Literal ID="LiteralDimImg" runat="server"></asp:Literal>
<div class="input-group my-3">
<asp:FileUpload ID="DimImgUpload" runat="server" class="btn btn-outline-primary btn-block" />
<asp:Button ID="BtnUploadDimImg" runat="server" Text="Upload" class="btn btn-primary" OnClick="BtnUploadDimImg_Click" />
</div>
<span class="badge badge-pill badge-warning text-dark">*Upload by No Choose File Could Clean File!</span>
<hr />
<h6>Downloads File :</h6>
<asp:Literal ID="PDFpreview" runat="server" ></asp:Literal>
<div class="input-group my-3">
<asp:FileUpload ID="FileUpload" runat="server" class="btn btn-outline-primary btn-block" />
<asp:Button ID="BtnUploadFile" runat="server" Text="Upload" class="btn btn-primary" OnClick="BtnUploadFile_Click" />
</div>
<span class="badge badge-pill badge-warning text-dark">*Upload by No Choose File Could Clean File!</span>
<head>
内引用 PDF.js 用来在页面预览 PDF 内容<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.9.359/pdf.min.js"></script>
<h6>Dimensions Text :</h6>
<table class="table table-hover">
<thead>
<tr class="table-info">
<th>Item<asp:Button ID="AddRow" runat="server" Text="Add Row" class="btn btn-outline-primary btn-sm py-0 px-1 align-top mx-5" OnClick="AddRow_Click" /></th>
<th>Value<asp:Button ID="DeleteRow" runat="server" Text="Delete" class="btn btn-outline-danger btn-sm py-0 px-1 align-top mx-5" OnClick="DeleteRow_Click" /></th>
</tr>
</thead>
<tbody>
<asp:Literal ID="LitDimensionsHtml" runat="server"></asp:Literal>
<tr>
<th>
<p class="d-inline-block m-r-20">Dimensions Image</p>
</th>
<td>
<asp:TextBox ID="TBoxDimImg" runat="server" type="text" class="form-control" ReadOnly="True"></asp:TextBox>
</td>
</tr>
<tr>
<th>
<p class="d-inline-block m-r-20">Downloads Title</p>
</th>
<td class="table-info">
<asp:TextBox ID="TBoxDLTitle" runat="server" type="text" class="form-control"></asp:TextBox>
</td>
</tr>
<tr>
<th>
<p class="d-inline-block m-r-20">Downloads File</p>
</th>
<td>
<asp:TextBox ID="TBoxDLFile" runat="server" type="text" class="form-control" ReadOnly="True"></asp:TextBox>
</td>
</tr>
<tr>
<th>
<p class="d-inline-block m-r-20">Video URL</p>
</th>
<td class="table-info">
<asp:TextBox ID="TBoxVideo" runat="server" type="text" class="form-control" TextMode="Url"></asp:TextBox>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>
<asp:Label ID="LabUpdateTitle" runat="server" Text="Click for Update"></asp:Label>
</th>
<td>
<asp:Button ID="BtnUpdateDimensionsList" runat="server" Text="Update Dimensions List" class="btn btn-outline-primary btn-block" OnClick="BtnUpdateDimensionsList_Click" />
<asp:Label ID="LabUpdateDimensionsList" runat="server" Text="*Upload Success!" ForeColor="green" class="d-flex justify-content-center" Visible="False"></asp:Label>
</td>
</tr>
</tfoot>
</table>
<h6>Main Content :</h6>
<CKEditor:CKEditorControl ID="CKEditorControl1" runat="server" BasePath="/Scripts/ckeditor/"
Toolbar="Bold|Italic|Underline|Strike|Subscript|Superscript|-|RemoveFormat
NumberedList|BulletedList|-|Outdent|Indent|-|JustifyLeft|JustifyCenter|JustifyRight|JustifyBlock|-|BidiLtr|BidiRtl
/
Styles|Format|Font|FontSize
TextColor|BGColor
Link|Image"
Height="400px">
</CKEditor:CKEditorControl>
<asp:Label ID="LabUploadMainContent" runat="server" Visible="False" ForeColor="#009933" class="d-flex justify-content-center"></asp:Label>
<asp:Button ID="BtnUploadMainContent" runat="server" Text="Upload Overview Content" class="btn btn-outline-primary btn-block mt-3" OnClick="BtnUploadMainContent_Click" />
//宣告 List 方便用 Add 依序添加栏位资料
private List<RowData> saveRowList = new List<RowData>();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack) {
ckfinderSetPath();
DListModel.DataBind(); //先绑定取得选取值
loadContent(); //取得尺寸栏位区外的主要内容
loadRowList(); //取得尺寸栏位内容
renderRowList(); //渲染尺寸栏位内容
}
}
private void ckfinderSetPath()
{
FileBrowser fileBrowser = new FileBrowser();
fileBrowser.BasePath = "/ckfinder";
fileBrowser.SetupCKEditor(CKEditorControl1);
}
//栏位表 JSON 资料
public class RowData
{
public string SaveItem { get; set; }
public string SaveValue { get; set; }
}
List<T>
为栏位 JSON 资料用。
private void loadContent()
{
//清空画面资料
TBoxVideo.Text = "";
TBoxDLTitle.Text = "";
TBoxDimImg.Text = "";
TBoxDLFile.Text = "";
PDFpreview.Text = "";
LiteralDimImg.Text = "";
//依下拉选单选取型号取出资料
string selectModel_id = DListModel.SelectedValue;
SqlConnection connection = new SqlConnection(WebConfigurationManager.ConnectionStrings["TayanaYachtConnectionString"].ConnectionString);
string sql = "SELECT * FROM Yachts WHERE id = @selectModel_id";
SqlCommand command = new SqlCommand(sql, connection);
command.Parameters.AddWithValue("@selectModel_id", selectModel_id);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
while (reader.Read()) {
//渲染画面
CKEditorControl1.Text = HttpUtility.HtmlDecode(reader["overviewContentHtml"].ToString());
string imgPathStr = reader["overviewDimensionsImgPath"].ToString();
string filePathStr = reader["overviewDownloadsFilePath"].ToString();
TBoxDimImg.Text = imgPathStr;
LiteralDimImg.Text = $"<img alt='Dimensions Image' class='img-thumbnail rounded mx-auto d-block' src='/Tayanahtml/upload/Images/{imgPathStr}' Width='250px'/>";
TBoxDLFile.Text = filePathStr;
PDFpreview.Text = $"<object type='application/pdf' data='/Tayanahtml/upload/files/{filePathStr}' width='250px' height='385px' class='rounded mx-auto d-block' ></object>";
}
connection.Close();
}
<object>
标签放入画面。
private void loadRowList()
{
//依选取型号取得栏位资料更新 List<T>
string selectModel_id = DListModel.SelectedValue;
SqlConnection connection = new SqlConnection(WebConfigurationManager.ConnectionStrings["TayanaYachtConnectionString"].ConnectionString);
string sql = "SELECT * FROM Yachts WHERE id = @selectModel_id";
SqlCommand command = new SqlCommand(sql, connection);
command.Parameters.AddWithValue("@selectModel_id", selectModel_id);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
if (reader.Read()) {
string loadJson = HttpUtility.HtmlDecode(reader["overviewDimensionsJSON"].ToString());
saveRowList = JsonConvert.DeserializeObject<List<RowData>>(loadJson);
}
connection.Close();
}
private void renderRowList()
{
if (saveRowList?.Count > 0) {
string addRowHtmlStr = "";
int index = 0;
//从 List<T> 载入资料
foreach (var item in saveRowList) {
if (index == 0) {
TBoxVideo.Text = item.SaveValue;
}
if (index == 1) {
TBoxDLTitle.Text = item.SaveValue;
}
if (index > 1) {
addRowHtmlStr += $"<tr class='table-info'><th><input id='item{index}' name='item{index}' type='text' class='form-control font-weight-bold' value='{item.SaveItem}' /></th><td><input id='value{index}' name='value{index}' type='text' class='form-control' value='{item.SaveValue}' /></td></tr>";
}
index++;
}
//渲染画面
LitDimensionsHtml.Text = addRowHtmlStr;
}
}
🌵 JSON 资料前两笔是 Video 连结及 PDF 显示文字。
🌵 尺寸动态增删栏位用 HTML 的 <input>
标签并赋予 id。
protected void DListModel_SelectedIndexChanged(object sender, EventArgs e)
{
//隐藏上传成功提示
LabUploadMainContent.Visible = false;
LabUpdateDimensionsList.Visible = false;
//渲染画面
loadContent();
loadRowList();
renderRowList();
}
protected void BtnUploadDimImg_Click(object sender, EventArgs e)
{
string savePath = Server.MapPath("~/Tayanahtml/upload/Images/");
string fileName = DimImgUpload.FileName;
string selectModel_id = DListModel.SelectedValue;
SqlConnection connection = new SqlConnection(WebConfigurationManager.ConnectionStrings["TayanaYachtConnectionString"].ConnectionString);
//有选档案才可上传,没选档案则执行清空
if (DimImgUpload.HasFile) {
string sqlDel = "SELECT overviewDimensionsImgPath FROM Yachts WHERE id = @selectModel_id";
SqlCommand commandDel = new SqlCommand(sqlDel, connection);
commandDel.Parameters.AddWithValue("@selectModel_id", selectModel_id);
//删除旧图档
connection.Open();
SqlDataReader reader = commandDel.ExecuteReader();
if (reader.Read()) {
string delFileName = reader["overviewDimensionsImgPath"].ToString();
if (!String.IsNullOrEmpty(delFileName)) {
File.Delete(savePath + delFileName);
}
}
connection.Close();
//储存图片档案及图片名称
//检查专案资料夹内有无同名档案,有同名就加流水号
DirectoryInfo directoryInfo = new DirectoryInfo(savePath);
string[] fileNameArr = fileName.Split('.');
int count = 0;
foreach (var fileItem in directoryInfo.GetFiles()) {
if (fileItem.Name.Contains(fileNameArr[0])) {
count++;
}
}
fileName = fileNameArr[0] + $"({count + 1})." + fileNameArr[1];
DimImgUpload.SaveAs(savePath + fileName);
//更新资料
string sql = "UPDATE Yachts SET overviewDimensionsImgPath = @fileName WHERE id = @selectModel_id";
SqlCommand command = new SqlCommand(sql, connection);
command.Parameters.AddWithValue("@fileName", fileName);
command.Parameters.AddWithValue("@selectModel_id", selectModel_id);
connection.Open();
command.ExecuteNonQuery();
connection.Close();
//渲染画面
loadContent();
loadRowList();
renderRowList();
}
else {
//没选档案点上传则清空
string sql = "UPDATE Yachts SET overviewDimensionsImgPath = @imgPath WHERE id = @selectModel_id";
SqlCommand command = new SqlCommand(sql, connection);
command.Parameters.AddWithValue("@imgPath", "");
command.Parameters.AddWithValue("@selectModel_id", selectModel_id);
connection.Open();
command.ExecuteNonQuery();
connection.Close();
//渲染画面
loadContent();
loadRowList();
renderRowList();
}
}
protected void BtnUploadFile_Click(object sender, EventArgs e)
{
string savePath = Server.MapPath("~/Tayanahtml/upload/files/");
string fileName = FileUpload.FileName;
string selectModel_id = DListModel.SelectedValue;
SqlConnection connection = new SqlConnection(WebConfigurationManager.ConnectionStrings["TayanaYachtConnectionString"].ConnectionString);
//有选档案才可上传
if (FileUpload.HasFile) {
//先删除旧档
string sqlDel = "SELECT overviewDownloadsFilePath FROM Yachts WHERE id = @selectModel_id";
SqlCommand commandDel = new SqlCommand(sqlDel, connection);
commandDel.Parameters.AddWithValue("@selectModel_id", selectModel_id);
connection.Open();
SqlDataReader reader = commandDel.ExecuteReader();
if (reader.Read()) {
string delFileName = reader["overviewDownloadsFilePath"].ToString();
if (!String.IsNullOrEmpty(delFileName)) {
File.Delete(savePath + delFileName);
}
}
connection.Close();
//储存上传档案
//检查专案资料夹内有无同名档案,有同名就加流水号
DirectoryInfo directoryInfo = new DirectoryInfo(savePath);
int count = 0;
foreach (var fileItem in directoryInfo.GetFiles()) {
if (fileItem.Name.Contains(fileName)) {
count++;
}
}
string[] fileNameArr = fileName.Split('.');
fileName = fileNameArr[0] + $"({count + 1})." + fileNameArr[1];
FileUpload.SaveAs(savePath + fileName);
//更新资料库资料
string sql = "UPDATE Yachts SET overviewDownloadsFilePath = @fileName WHERE id = @selectModel_id";
SqlCommand command = new SqlCommand(sql, connection);
command.Parameters.AddWithValue("@fileName", fileName);
command.Parameters.AddWithValue("@selectModel_id", selectModel_id);
connection.Open();
command.ExecuteNonQuery();
connection.Close();
//渲染画面
loadContent();
loadRowList();
renderRowList();
}
else {
//没选档案则清空资料
string sqlDelPath = "UPDATE Yachts SET overviewDownloadsFilePath = @fileName WHERE id = @selectModel_id";
SqlCommand commandDelPath = new SqlCommand(sqlDelPath, connection);
commandDelPath.Parameters.AddWithValue("@fileName", "");
commandDelPath.Parameters.AddWithValue("@selectModel_id", selectModel_id);
connection.Open();
commandDelPath.ExecuteNonQuery();
connection.Close();
//渲染画面
loadContent();
loadRowList();
renderRowList();
}
}
protected void AddRow_Click(object sender, EventArgs e)
{
//将 JSON 资料载入 List<T>
loadRowList();
//增加新栏位
saveRowList.Add(new RowData { SaveItem = "", SaveValue = "" });
//更新资料库资料
uploadRowList();
//渲染画面
renderRowList();
//将画面移至出现上传按钮处
Page.SetFocus(BtnUpdateDimensionsList);
}
private void uploadRowList()
{
//先更新 List<T> 前两个资料 Video 及 Download File
saveRowList[0].SaveValue = TBoxVideo.Text;
saveRowList[1].SaveValue = TBoxDLTitle.Text;
//更新 List<T> 资料,栏位内容用 Request.Form
for (int i = 2; i < saveRowList.Count; i++) {
saveRowList[i].SaveItem = Request.Form[$"item{i}"];
saveRowList[i].SaveValue = Request.Form[$"value{i}"];
}
//依选取型号更新资料库资料
string selectModel_id = DListModel.SelectedValue;
//将 List<T> 资料转为 JSON 格式字串
string saveRowListJsonStr = JsonConvert.SerializeObject(saveRowList);
SqlConnection connection = new SqlConnection(WebConfigurationManager.ConnectionStrings["TayanaYachtConnectionString"].ConnectionString);
string sql = "UPDATE Yachts SET overviewDimensionsJSON = @saveRowListJsonStr WHERE id = @selectModel_id";
SqlCommand command = new SqlCommand(sql, connection);
command.Parameters.AddWithValue("@saveRowListJsonStr", saveRowListJsonStr);
command.Parameters.AddWithValue("@selectModel_id", selectModel_id);
connection.Open();
command.ExecuteNonQuery();
connection.Close();
}
🌵 传统 HTML 标签的 <input>
内容。
🌵 栏位区的 3 个按钮都要配合进行刷新资料库内容。
protected void DeleteRow_Click(object sender, EventArgs e)
{
//将 JSON 资料载入 List<T>
loadRowList();
//更新资料库资料
uploadRowList();
//删除尺寸栏位最末栏
saveRowList.RemoveAt(saveRowList.Count - 1);
//更新资料库资料
uploadRowList();
//渲染表格画面
renderRowList();
//将画面移至出现上传按钮处
Page.SetFocus(BtnUpdateDimensionsList);
}
protected void BtnUpdateDimensionsList_Click(object sender, EventArgs e)
{
//将 JSON 资料载入 List<T>
loadRowList();
//更新资料库资料
uploadRowList();
//渲染表格画面
renderRowList();
//渲染上传成功提示
DateTime nowtime = DateTime.Now;
LabUpdateDimensionsList.Visible = true;
LabUpdateDimensionsList.Text = "*Upload Success! - " + nowtime.ToString("G");
}
protected void BtnUploadMainContent_Click(object sender, EventArgs e)
{
//将文字编辑器 HTML 内容转为 HTML 字元编码
string mainContentHtmlStr = HttpUtility.HtmlEncode(CKEditorControl1.Text);
//依下拉选单选取型号存入型号介绍主要图文内容
string selectModel_id = DListModel.SelectedValue;
SqlConnection connection = new SqlConnection(WebConfigurationManager.ConnectionStrings["TayanaYachtConnectionString"].ConnectionString);
string sql = "UPDATE Yachts SET overviewContentHtml = @mainContentHtmlStr WHERE id = @selectModel_id";
SqlCommand command = new SqlCommand(sql, connection);
command.Parameters.AddWithValue("@mainContentHtmlStr", mainContentHtmlStr);
command.Parameters.AddWithValue("@selectModel_id", selectModel_id);
connection.Open();
command.ExecuteNonQuery();
connection.Close();
//渲染上传成功提示
DateTime nowtime = DateTime.Now;
LabUploadMainContent.Visible = true;
LabUploadMainContent.Text = "*Upload Success! - " + nowtime.ToString("G");
}
📢 本日的重点在重复使用的方法抽出来使用的好处,及动态增删栏位的作法,由於这个後台并非多人使用,因此使用连接资料库刷新的作法,也有看到用 ViewState 或其它方式实作的方法,可以自行研究;後续文章因为实作内容较多,并且接近收尾,都会如本文尽量将完整程序码放上来,而分层架构处理会在最後一天文章说明实作可以精修的部分。
👀 大神系列文章 ViewState 介绍参考 : 91之ASP.NET由浅入深 不负责讲座
>>: 【Day23】Git 版本控制 - 修改 commit 纪录:reset
今日目标 继续Debug Ray vs Rect的部分 MISSION FAILED! QAQ 今天...
本篇大纲:Generator、Component、Layout 截至目前,我们已经学会 D3 如何...
其实原本最初规画想要做Index方式的纪录,然後多增加一些没写到的面向 不过,总是计画赶不上变化 ...
本篇介绍透过bootstrap4直接使用tab切换功能,并且实作tab切换自动循环播放 我们在昨篇...
SSR — Server Side Rendering 服务器渲染 服务器端渲染 — 在服务器(Se...