我正在开发一个 Grails Web 应用程序,其模块大部分必须实现主从接口(interface)。作为一种方法,我想将以下代码供您考虑:
大师类:
import org.codehaus.groovy.grails.web.json.JSONArray
class MyForm {
String name
String address
String detail
BigDecimal total
static hasMany = [details: MyFormDetail]
static constraints = {
name()
address()
detail()
total()
}
static mapping = {
detail type: 'text'
}
def beforeInsert = {
def detailJSON = new JSONArray(detail)
detailJSON.each {
def quantity = it.getAt("quantity").toString().toBigDecimal()
def description = it.getAt("description").toString()
def unitaryPrice = it.getAt("unitaryPrice").toString().toBigDecimal()
def subtotal = it.getAt("subtotal").toString().toBigDecimal()
def myFormDetail = new MyFormDetail(
quantity: quantity,
description: description,
unitaryPrice: unitaryPrice,
subtotal: subtotal
)
this.addToDetails(myFormDetail)
}
}
}
详分割类:
class MyFormDetail {
Integer quantity
String description
BigDecimal unitaryPrice
BigDecimal subtotal
static belongsTo = [myForm: MyForm]
static constraints = {
quantity()
description()
unitaryPrice()
subtotal()
}
}
myFormUtilities.js 帮助文件:
$(document).ready(function() {
$("#detailTable").jqGrid({
datatype: "local",
height: 100,
colNames: ["QUANTITY","DESCRIPTION","UNIT. PRICE","SUBTOTAL"],
colModel:[
{name:'quantity',index:'quantity', width:100},
{name:'description',index:'description', width:400},
{name:'unitaryPrice',index:'unitaryPrice', width:100},
{name:'subtotal',index:'subtotal', width:100}],
caption: "DETAIL"
});
createTable();
$("#addRow").bind("click",addRow);
$("#removeRow").bind("click",removeRow);
$("#quantity, #unitaryPrice").bind("keyup",calculateTotal);
function calculateTotal(){
let quantity = parseFloat($("#quantity").val());
let unitaryPrice = parseFloat($("#unitaryPrice").val());
let subtotal = quantity*unitaryPrice;
$("#subtotal").val(subtotal);
}
function addRow(){
let row = new Object();
row.quantity = $("#quantity").val();
row.description = $("#description").val();
row.unitaryPrice = $("#unitaryPrice").val();
row.subtotal = $("#subtotal").val();
let detailJSON = ($("#detail").val()=="")?"[]":$("#detail").val();
let mydata = $.parseJSON(detailJSON);
mydata.push(row);
$("#detail").val(JSON.stringify(mydata));
createTable();
}
function removeRow(){
let filaId = parseInt($('#detailTable').jqGrid('getGridParam','selrow')) - 1;
let mydata = $.parseJSON($("#detail").val());
let nuevoMydata = new Array();
for(let i=0;i<mydata.length;i++){
if(filaId!=i)
nuevoMydata.push(mydata[i]);
}
$("#detail").val(JSON.stringify(nuevoMydata));
createTable();
}
function createTable(){
let total = 0;
let aRow = new Object();
let detailJSON = ($("#detail").val()=="")?"[]":$("#detail").val();
let mydata = $.parseJSON(detailJSON);
$("#detailTable").jqGrid("clearGridData", true);
for(let i=0;i<mydata.length;i++){
aRow = mydata[i];
total += parseFloat(aRow.subtotal);
$("#detailTable").jqGrid('addRowData',i+1,aRow);
}
$("#total").val(total);
}
});
这是显示的表单(我知道这是一个自动生成的 View ,但请把它看作一个非常基本的 GUI 模型):
所以,这些是问题:
Subtotal
和 Total
字段是设置的计算字段read-only
防止用户修改他们的内容,但我发现使用浏览器元素检查器它们的内容和属性
(如只读)可以修改。
detail
也是如此.如果其内容被更改,服务器端保存实例时会产生错误,因为
beforeInsert
block 需要一个有效的用于创建
detail
的 JSON 字符串实例。此字段还用于生成详细信息 JqGrid。该字段将是隐。
此示例中的所有内容都按预期工作,但好奇的用户可能会导致错误。
检查员?
detail
字段来保存 JSON 字符串,这是我实现主从模式的解决方案。有没有别的改进此实现的方法,避免定义一个
这个字符串的字段?
最佳答案
如果您的用户可以访问检查器/Web 控制台,那么他们就可以访问您所做的所有客户端数据(他们只受限于他们对如何使用浏览器开发工具的了解)。他们可以更改任何元素的文本或输入的值。因此,唯一可以 100% 安全存储这些数据的地方是服务器端。
您可以尝试的方法是隐藏每个输入(例如使用 CSS)并在可见的 HTML 中替换为一个 <span>
元素(或其他一些非形式元素)。然后确保每当 <input>
value 改变了,你更新对应 span 的文本。就像是:
$("#subtotalSpan").html( $("#subtotal").val() );
在 calculateTotal 函数中添加。如果您希望他们甚至无法编辑跨度的 HTML,您可以更进一步,将值绘制到
<canvas>
。而不是 <span>
.他们将无法更改绘制到 Canvas 元素中的文本。
关于javascript - 防止更改 HTML 只读文本字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59904158/