The previous post said that using reflection and ABPvNext's Dto implementation controls the front end with the back end for best CRUD practices!
I believe that has seen a PasteForm has understood how to achieve this, this article looks at how to achieve the specific
Form page implementation
After opening the pasteform/page, it will first request the data template of the current path from the API
_apiget(`/api/app/${_classPath}/readListModel`, true, (c, o) => {
if (c == 200) {
if () {
$(".ppbody .st").find(".sn").html();
= ;
}
if () {
$(".ppbody .st").find(".idesc").html();
}
//Template content for table headers
var _template_head_html = null;
_globadataProperties = ;
//model processing,How to Show Appearance for example
HandlerModelColumn();
//classList of attributes of the model
if () {
_globadataAttributes = ;
(_attribute => {
if (_attribute.name == 'disable') {
if (_attribute.args1) {
_config.disable_add = true;
$(".btnadd").hide();
}
if (_attribute.args2) {
_config.disable_edit = true;
}
if (_attribute.args3) {
_config.disable_del = true;
}
}
if (_attribute.name == "template") {
if (_attribute.args1) {
_template_head_html = $(`#${_attribute.args1}`).html();
}
if (_attribute.args2) {
_template_body_html = $(`#${_attribute.args2}`).html();
}
}
});
}
if (_template_head_html == null) {
_template_head_html = $("#template_header").html();
}
var _modelhtml = template(_template_head_html, { list: , config: _config });
//Class I model convert into Secondary models
if (_template_body_html == null) {
var _template_body = $("#template_body").html();
var _bodyhtml = template(_template_body, { list: , config: _config });
_template_body_html = _bodyhtml.replace(/{{/g, '<%').replace(/}}/g, '%>');
}
$(".table").find("thead").html(_modelhtml);
//Processing of queries
if () {
_globdataQueryProperties = ;
HandlerQueryItem();
} else {
_readpagedata(1);
}
//retrieve data
}
});
Looking at the code above, it's about getting the data model attributes of the search area of this page and the data model of the table below from the backend first
after that
_readpagedata(1);
Only to get the data of the table, that is, after the second page of data is as long as the request once, as long as the first time you open to get the data model attributes, if you use the local cache can also be omitted for the first time the model attributes of the data!
The UI is then rendered based on the model obtained by the JS
<!-- Information templates for queries -->
<script type="text/html" >
<% (item=>{ %>
<% if(=="String" || == 'Guid'){ %>
<label class="sitem" <%if(){%>style="display:none;"<%}%>>
<span><%:=%>:</span>
<input type="text" name="<%:=%>" class="inputword" placeholder="<%:= || ''%>">
<span class="spanclean" onclick="handlerClean(this)">x</span>
</label>
<% } %>
<% if(=="Int32" || =='Int64'){ %>
<label class="sitem" <%if(){%>style="display:none;"<%}%>>
<span><%:=%>:</span>
<input type="number" name="<%:=%>" class="inputword" placeholder="<%:= || ''%>">
<span class="spanclean" onclick="handlerClean(this)">x</span>
</label>
<% } %>
<% if(=='outer'){ %>
<div class="outer sitem" <%if(){%>style="display:none;"<%}%>>
<span><%:=%>:</span>
<% if(=='Int32' || =='Int64'){ %>
<input type="number" class="outerid" style="display:none;" value="<%:=%>" name="<%:=%>">
<%}else{%>
<input type="text" class="outerid" style="display:none;" value="<%:=%>" name="<%:=%>">
<%}%>
<input type="text" class="outerdisplay" dataname="<%:=%>" value="<%:=%>" onclick="handler_outer_value(this)" readonly placeholder="<%:=%>" >
<span class="spanclean" onclick="handlerCleanOuterInput(this)">x</span>
</div>
<% } %>
<% if(=="select"){ %>
<label class="sitem" <%if(){%>style="display:none;"<%}%>>
<span><%:=%>:</span>
<select name="<%:=%>">
<% if(){ %>
<% (_select=>{ %>
<option value="<%:=_select.value%>" <% if(_select.selected){ %>selected<% } %>><%:=_select.name%></option>
<% }) %>
<%}%>
</select>
</label>
<% } %>
<% if(=="DateTime"){ %>
<label class="sitem" <%if(){%>style="display:none;"<%}%>>
<span><%:=%>:</span>
<input type="text" name="<%:=%>" value="<%:= || ''%>" class="inputword" onClick="WdatePicker({el:this,dateFmt:'<%:=%>'})" placeholder="<%:= || ''%>">
<span class="spanclean" onclick="handlerClean(this)">x</span>
</label>
<% } %>
<% if(=="datalist"){ %>
<label class="sitem" <%if(){%>style="display:none;"<%}%>>
<span><%:=%>:</span>
<input type="text" name="<%:=%>" class="inputword" list="<%:=%>" placeholder="<%:= || ''%>">
<% if(){ %>
<datalist >
<% (_select=>{ %>
<option value="<%:=_select.value%>" ><%:=_select.name%>(<%:=_select.value%>)</option>
<% }) %>
</datalist>
<%}%>
<span class="spanclean" onclick="handlerClean(this)">x</span>
</label>
<% } %>
<% if(=='daterange'){%>
<label class="sitem" <%if(){%>style="display:none;"<%}%>>
<span><%:=%>:</span>
<input type="text" class="inputword" name="<%:=%>" readonly datas="" datae="" value="<%:= || ''%>" >
</label>
<% } %>
<% }) %>
</script>
<!-- Message template for the header -->
<script type="text/html" >
<tr>
<% (item=>{ %>
<% if(!){ %>
<td>
<%:=%>
<% if(!=null){ %>
<% (_attribute=>{ %>
<% if(_attribute.name=='orderby'){ %>
<span class="orderby">
<i class="Hui-iconfont ordersell icon-top" dataval="<%:=_attribute.args1%>"></i>
<i class="Hui-iconfont ordersell icon-bottom" dataval="<%:=_attribute.args2%>"></i>
</span>
<% } %>
<% }) %>
<% } %>
</td>
<% } %>
<% }) %>
<td>manipulate</td>
</tr>
</script>
<!-- Information templates for forms -->
<script type="text/html" >
<!-- Note that the bracketed percentages are the current template 2The brackets are placeholders.,The template code for the next one -->
{{ (item=>{ }}
<tr>
<% (item=>{ %>
<% if(!){ %>
<td <%if(){%>class="<%:=%>"<%}%>>
<% if(=='image' ){ %>
<img class="image" src="{{:=item.<%:=%>}}">
<% }else if(=='head' ){ %>
<img class="head" src="{{:=item.<%:=%>}}">
<% }else if(=='switch' ){ %>
<input type="checkbox" class="input-checkbox mui-switch mui-switch-anim" onchange="handlerSwitchChange(this)" data dataname="<%:=%>" {{ if(item.<%:=%>){ }}checked{{ } }} >
<% }else{ %>
<%if(){%>
<%:=%>
<%}else{%>
<span class="itd">
{{:=item?.<%:=%>}}
</span>
<%}%>
<% } %>
</td>
<% } %>
<% }) %>
<td class="fleft">
<!-- Fill in Edit or Other here -->
{{ if(=='view'){ }}
<% if(){%>
<a href="javascript:;" onclick="open_menu_box(this);" onmouseover="open_menu_box(this);" ><i class="Hui-iconfont Hui-iconfont-more"></i></a>
<div class="menubox" style="z-index: 100;" onmouseleave="$(this).fadeOut();">
<% (item=>{%>
<% if(=='menubox'){ %>
<% if(){ %>
<% (_attribute=>{ %>
<% if(_attribute.name=='menu'){ %>
<a onclick="<%:=_attribute.args2%>"><% if(_attribute.args3){%><i class="Hui-iconfont <%:=_attribute.args3%>"></i><%}%> <%:=_attribute.args1%></a>
<% } %>
<% }) %>
<% } %>
<% } %>
<% if(=='ifmenubox'){ %>
{{ if(<%:=%>){ }}
<%:=%>
{{ } }}
<% } %>
<% }) %>
</div>
<% } %>
<% if(!config.disable_edit){ %>
<a href="javascript:;" onclick="tap_view_item(this)" data><i class="Hui-iconfont Hui-iconfont-shuru"></i>compiler</a>
<% } %>
<!-- Handling customized types,Due to the nature of the table,Penetrating into the data of theclassName -->
<% (item=>{%>
<% if(=='menu'){ %>
<% if(){ %>
<% (_attribute=>{ %>
<% if(_attribute.name=='menu'){ %>
<a onclick="<%:=_attribute.args2%>"><% if(_attribute.args3){%><i class="Hui-iconfont <%:=_attribute.args3%>"></i><%}%> <%:=_attribute.args1%></a>
<% } %>
<% }) %>
<% } %>
<% } %>
<% if(=='ifmenu'){ %>
{{ if(<%:=%>){ }}
<%:=%>
{{ } }}
<% } %>
<% }) %>
<% if(!config.disable_del){ %>
<a href="javascript:;" onclick="handler_tap_del(this)" class="a-del" data><i class="Hui-iconfont Hui-iconfont-del3"></i>removing</a>
<% } %>
<!-- 自定义处理manipulate列菜单完成 -->
{{ } }}
{{ if(=='select'){ }}
<a href="javascript:;" class="mselect" onclick="tap_select_item(this)"
data><i class="Hui-iconfont Hui-iconfont-fabu"></i>option</a>
{{ } }}
</td>
</tr>
{{ }) }}
</script>
Note that the template in the table is transformed twice, that is, after acquiring the model, it is first transformed into a data model to obtain the template, and then combined with the actual page data to once again perform UI rendering
Form page implementation
Form page will be opened to determine whether the editor, in fact, the whole idea is the same, only the request interface is not the same, one is XXXAddDto one is UpdateDto
/**
* Reading models and default values,grade
*/
function FuncFilexModel() {
// (_id);
if (_id && _id != '0' && _id != 0) {
_apiget(`/api/app/${_classPath}/${_id}/readUpdateModel`, true, (c, o) => {
if (c == 200) {
loadHeader(o);
if () {
LoadModelProperity();
}
if () {
= "update" + ;
}
}
});
} else {
_apiget(`/api/app/${_classPath}/readAddModel`, true, (c, o) => {
if (c == 200) {
loadHeader(o);
if () {
LoadModelProperity();
}
if () {
= "additional" + ;
}
}
});
}
}
Actually, both requests end up in the LoadModelProperity function
/**
* Models for reading data Models for processing data
* @param {*} properties
*/
function LoadModelProperity(properties) {
_modelProperties = properties;
handlerExchangeDataTypeToUIType(properties);
var _template = $("#templatemodel").html();
var _ahtml = template(_template, { list: properties, config: _config });
$(".paste-form-body").html(_ahtml);
setTimeout(function () {
FormLoaded(properties);
funcAppendInputLength();
//Calculated Height,come (or go) back
var _height = $(".newform").height() + 140;
if (_has_outer) {
//If the calculated height is less than600,The form hasouterThen at least the height is guaranteed to be600
if (_height < 600) {
_height = 600;
}
}
var _index = (); //Get window index
if (.set_dialog_height) {
.set_dialog_height(_height, _index);
} else {
('Function not found at parent levelset_dialog_height');
}
$(".ulselects").on('click', 'li', function () {
if ($(this).hasClass('selected')) {
$(this).removeClass('selected');
} else {
$(this).addClass('selected');
}
});
}, 100);
}
Then there's the front-end HTML for UI rendering based on the data fetched by JS
<script type="text/html" >
<% (item=>{%>
<div class="row cl <% if(){ %>singlerow<% } %>" <%if(){%> style="display:none;" <%}%>>
<div class="itemrow">
<label class="form-label"><%:=%><%if(){%><span class="tapmark" onclick="global_tap_mark('<%:=%>','<%:=%>')">?</span><%}%><%if(){%><span class="form-required">*</span><%}%></label>
<div class="formControls">
<% if(=="text" || =='Guid'){ %>
<input name="<%:=%>" class="input-text" <%if(){%>required<%}%> type="text" value="<%:= || ''%>" maxlength="<%:=%>" placeholder="<%:=%>" />
<span class="spanclean" onclick="handlerClean(this)">x</span>
<%}%>
<% if(=="number"){ %>
<input name="<%:=%>" class="input-number" placeholder-class="p-form-placeholder" type="number" value="<%:= || ''%>" placeholder="<%:=%>" />
<%if(){%>
<span class="unit"><%:=%></span>
<%}%>
<%}%>
<% if(=="fentoyuan"){ %>
<input name="<%:=%>" class="input-number" step="0.01" min="0" max="99999999" placeholder-class="p-form-placeholder" type="number" value="<%:= || ''%>" placeholder="<%:=%>" />
<span>unit of money (in PRC: Chinese yuan, in USA: dollar, etc)</span>
<%}%>
<% if(=="Double" || =='Decimal'){ %>
<input name="<%:=%>" class="input-number" step="<%:=%>" placeholder-class="p-form-placeholder" type="number" value="<%:= || ''%>" placeholder="<%:=%>" />
<%if(){%>
<span class="unit"><%:=%></span>
<%}%>
<%}%>
<% if(=="textarea"){ %>
<textarea name="<%:=%>" class="input-textarea" <%if(){%>style="<%:=%>"<%}%> <%if(){%>required<%}%> <%if(>0){%>maxlength="<%:=%>"<%}%> placeholder="<%:=%>" ><%:= || ''%></textarea>
<span class="spanclean" onclick="handlerClean(this)">x</span>
<%}%>
<% if (=="switch"){ %>
<input type="checkbox" class="input-checkbox mui-switch mui-switch-anim" <%if(){%>checked<%}%> name="<%:=%>">
<span class="placeholder"><%:=item?.placeholder || ''%></span>
<%}%>
<% if(=="datetime"){ %>
<input type="text" value="<%:= || ''%>" name="<%:=%>" <%if(){%>required<%}%> maxlength="20" placeholder="<%:=%>" onClick="WdatePicker({el:this,dateFmt:'<%:=%>'})"
autocomplete="off" class="input-text input-form-date">
<%}%>
<% if(=="daterange"){ %>
<input type="text" value="<%:= || ''%>" name="<%:=%>" datas="" datae="" <%if(){%>required<%}%> placeholder="<%:=%>"
autocomplete="off" class="input-text input-form-date">
<%}%>
<% if( == "richtext"){ %>
<div class="editoryarea">
<div class="editor_toolbar" ></div>
<div class="editor_body" ></div>
</div>
<%}%>
<% if( == "file"){ %>
<input type="file" datanum="<%:=%>" onchange="handlerUploadOnlyFile(this)" <%if(){%>dataurl=<%:=%><%}%> datatype="<%:=%>" datasize="<%:=%>" style="display:none" />
<input type="text" name="<%:=%>" value="<%:=%>" placeholder="<%:=%>" onclick="$('[id=<%:=%>]').trigger('click');">
<span class="spanclean" onclick="handlerClean(this)">x</span>
<%}%>
<% if( == "image" || =="images"){ %>
<input type="text" style="display:none" name="<%:=%>" value="<%:=%>">
<input type="file" multiple datanum="<%:=%>" onchange="handlerUploadFile(this)" datatype="<%:=%>" datasize="<%:=%>" style="display:none;" />
<% if( ==1){%>
<label for="<%:=%>">
<img class="form-image-head" <%if(){%>src="<%:=%>"<%}%> >
<%if(!){%>
<span class="iconadd icon-add">
<i class="Hui-iconfont Hui-iconfont-add2 icon"></i>
</span>
<%}%>
</label>
<span class="placeholder"><%:=item?.placeholder || ''%></span>
<% }else{ %>
<span class="placeholder"><%:=item?.placeholder || ''%></span>
<ul class="imageul">
<li><label for="<%:=%>"><span class="icon-add">
<i class="icon Hui-iconfont Hui-iconfont-add2"></i>
</span></label></li>
<%if(){%>
<%(_img=>{%>
<li><img src="<%:=_img%>"><i class="Hui-iconfont Hui-iconfont-close2 icon-close" onclick="handlerRemoveImageItem(this)"></i></li>
<%})%>
<%}%>
<!-- <li>
<img>
<i class="iconfont icon-close" onclick="handlerRemoveImageItem(this)"></i>
</li> -->
</ul>
<% } %>
<%}%>
<% if(=='outer'){ %>
<div class="outer">
<% if(=='Int32' || =='Int64'){ %>
<input type="number" class="outerid" style="display:none;" value="<%:=%>" name="<%:=%>">
<%}else{%>
<input type="text" class="outerid" style="display:none;" value="<%:=%>" name="<%:=%>">
<%}%>
<input type="text" class="outerdisplay" dataname="<%:=%>" value="<%:=%>" onclick="handler_outer_value(this)" readonly placeholder="<%:=%>" >
<span class="spanclean" onclick="handlerClean(this)">x</span>
</div>
<% } %>
<% if(=='outers'){ %>
<div class="outers">
<input type="button" value="increase" class="btn btnaddouter" dataname="<%:=%>" onclick="handler_outer_value(this)">
<ul class="ulouter outers<%:=%>">
<% if(){%>
<% (_display=>{ %>
<li data>
<%:=_display[item.display_name]%>
<span class="outer_close" onclick="$(this).parents('li').remove();">x</span>
</li>
<% }) %>
<% } %>
</ul>
</div>
<% } %>
<% if(=="select"){ %>
<select name="<%:=%>">
<% if(){ %>
<% (_select=>{ %>
<option value="<%:=_select.value%>" <%if(_select.value==){%>selected<%}%>><%:=_select.name%></option>
<% }) %>
<%}%>
</select>
<% } %>
<%if(=="button"){%>
<input type="button" class="btn btnlink" value="<%:=%>" onclick="global_form_button_click(this,`<%:=%>`,`<%:=%>`);">
<span class="placeholder"><%:=item?.placeholder || ''%></span>
<%}%>
<% if(=="selects"){ %>
<ul class="ulselects" name="<%:=%>">
<% if(){ %>
<% (_select=>{ %>
<li class="selectli <%if(_select.selected){%>selected<%}%>" value="<%:=_select.value%>"><%:=_select.name%></li>
<% }) %>
<%}%>
</ul>
<% } %>
<% if(=="datalist"){ %>
<input type="text" name="<%:=%>" class="inputword" value="<%:=%>" list="<%:=%>" placeholder="<%:= || ''%>">
<% if(){ %>
<datalist >
<% (_select=>{ %>
<option value="<%:=_select.value%>" ><%:=_select.name%>(<%:=_select.value%>)</option>
<% }) %>
</datalist>
<%}%>
<span class="spanclean" onclick="handlerClean(this)">x</span>
<% } %>
</div>
</div>
</div>
<%})%>
</script>
So, for the different needs of different projects, or your personal habits, you can modify the code above in order to adapt to their own projects, such as my project will not generally use date, generally used is datetime, so I did not consider the case of date!
Next time, we'll cover the problems we encountered in practice, and how PasteForm handled them.