提问人:Twisty 提问时间:11/4/2023 最后编辑:Twisty 更新时间:11/14/2023 访问量:72
用值填充 123FormBuilder 字段
Populate 123FormBuilder Field with value
问:
这个问题可能对 123FormBuilder 来说太具体了,但我把它放在那里是希望有人能有所了解。
我正在将自定义 HTML 与 jQuery 一起添加到表单中,以允许用户从可用停车位的图像中选择 1 个停车位(例如在剧院中选择座位)。包含以下代码。
var $drop = $("[data-id='109672317'] select");
var $rvSpot = $("[data-id='110061531'] input");
$("path.enabled").on("mouseover", function(){
$(this).toggleClass("highlight");
}).on("mouseout", function(){
$(this).toggleClass("highlight")
}).on("click", makeSelection);
function makeSelection(e){
var el = $(e.target);
var l = $drop.find("option:selected").data("index");
var s = el.attr("id");
console.log("Making Selection", l, s);
if($(".selected").length){
if(!confirm("Are you sure you want to change your Parking Selection?")){
return false;
}
removeSelected(l, e.target);
}
$.post("https://myurl.tld/take-spot.php", { land: l, spot: s }, function(results){
el.addClass("selected");
$rvSpot.trigger("focus").val(s).trigger("blur");
console.log($rvSpot.val());
startCountdown();
});
}
function removeSelection(l, el){
s = $(el).attr('id');
console.log("Removing Selection", l, s)
$.post("https://myurl.tld/release-spot.php", { land: l, spot: s }, function(){
$(".selected").removeClass("selected");
$rvSpot.trigger("focus").val(0).trigger("blur");
stopCountdown();
});
}
function startCountdown(){
var m = 09, s = 60, t, $ct = $(".countdown .timeleft");
$ct.html("10:00");
$ct.data("timer", setInterval(function(){
s--;
if(s == 00){
m--;
s = 59;
}
if(m < 2){
$ct.css("color", "red");
}
if(m == 00 && s == 00){
stopCountdown();
removeSelection($(".image-map", $(".selected")));
}
$ct.html(m + ":" + s);
}, 1000));
}
function stopCountdown(){
clearInterval($(".countdown .timeleft").data("timer"));
}
这里有一些文档,建议您必须设置控件与输入字段的值。下面是一个 HTML 片段:
<div data-role="container" data-type="virtual-form-table-row" data-hash="0000001d" data-type-id="0" data-colspan="20" data-num-children="1">
<div data-role="control" data-type="text" data-hash="0000001c" data-type-id="23" data-colspan="20" data-is-hidden="1" data-renderer-type="tln" data-id="110061531"><label data-role="label" id="text-0000001c-acc" data-i18n-text="control_label_110061531">Parking Spot</label><dt data-role="instructions" id="text-0000001c-instr-acc" data-is-empty="1" data-i18n-text="control_instructions_110061531"></dt>
<div data-role="input-row" data-is-first-row="1" data-is-last-row="1" data-fill-colspan="0">
<div data-role="input-container" data-ui-role="ui-element" data-size="full"><span data-role="prefix-label" id="price-0000001c-prefix-acc" style="display: none;"></span><input type="text" data-role="i123-input" data-no-theme="" aria-labelledby="text-0000001c-acc text-0000001c-error-acc text-0000001c-instr-acc" id="text-0000001c"
value="0" placeholder="" style="padding-left: 8px;"></div>
</div><label data-role="error" id="text-0000001c-error-acc" data-is-empty="1"></label></div>
</div>
我可以看到 Control 元素,但不清楚如何更新它,以便表单在提交时接受此数据。
更新
我让它工作过一次,但一直无法复制它。
我更新了代码如下:
$rvSpot.trigger("focus").attr("value", s).trigger("blur");
当我检查元素时,它似乎确实发生了属性更改,但是当我提交表单并查看结果时,我仍然有一个值。input
0
答:
在不了解 123FormBuilder 的情况下,我觉得很奇怪:我会使用 .val(s),
这是在 jQuery 中设置输入元素值的正确方法(例如,参见“jQuery 中 attr
() 和 val()
之间的区别”)。.attr("value", s)
仔细检查选择器是否正确,并且是否针对正确的元素。并确保 value 属性直接位于输入元素上,并且没有其他脚本或表单验证可能会在提交时将值重置为。$rvSpot
0
我还会使用 .on( “change” [, eventData ], handler)(因为 .change(
) 处理程序 API 已弃用)
在设置值后触发更改事件。这很重要,因为某些窗体会侦听 change 事件以注册值已更新。
+------------------+ +-----------------+
| User Interaction | --click-> | makeSelection() |
+------------------+ +-----------------+
| |
| |
v v
+------------------+ +------------------+
| Update $rvSpot | | startCountdown() |
+------------------+ +------------------+
更新后的代码为:
// rest of your code
function makeSelection(e){
// existing code
$.post("https://myurl.tld/take-spot.php", { land: l, spot: s }, function(results){
el.addClass("selected");
$rvSpot.val(s).trigger("change"); // use trigger to programmatically trigger the change event
console.log($rvSpot.val()); // for debugging
startCountdown();
});
}
// rest of your code
// Bind change event handler to $rvSpot if needed elsewhere in the code
$rvSpot.on("change", function() {
// Handler code here
});
这应该正确更新 的值,并通知任何其他事件侦听器该值已更改。$rvSpot
请记住验证输入元素的名称和 ID 属性,以确保表单在提交表单时能够识别输入。
另一种方法将在如何预填充表单字段中介绍:123FormBuilder 支持预填充表单字段,方法是使用与表单字段 ID 和要预填充的值相对应的参数构造自定义 URL。当您希望根据已知信息将用户定向到已填写某些字段的表单时,这很有用。
但是,此方法与您一直使用的方法不同,后者涉及在表单已加载到用户浏览器中后使用 JavaScript 动态设置表单字段的值。
根据 123FormBuilder 文档,表单字段不是通过使用 jQuery 操作 DOM 元素来直接填充的(就像您尝试使用 时所做的那样)。相反,您将使用表单的字段 ID 和所需的预填充值作为查询参数来构造 URL。$rvSpot.val(s).trigger("change")
对于 JavaScript 代码中描述的方案,您似乎希望在用户与表单交互时实时更新表单字段,而不是在表单加载之前通过 URL 预填充表单字段。因此,123FormBuilder 文档中的预填充 URL 方法不直接适用于您的情况。
在 JavaScript 代码中,当您动态设置输入的值并希望表单在提交时识别此值时,您需要确保:
- JavaScript 代码正确更新输入字段的值。
- 表单生成器用于检测更改的任何事件侦听器都会被触发。
- 表单的提交过程可识别动态设置的值。
如果表单提交无法识别 JavaScript 更新的值,则可能是由于表单生成器跟踪更改或验证输入的内部机制所致,这可能预示着 JavaScript 方法未复制的用户输入事件。.trigger("change")
上面提到的处理程序 () 与第 2 点有关。
一个例子是$rvSpot.on("change", function() {...}
$rvSpot.on("change", function() {
// That is the handler code that will run every time the value of $rvSpot changes.
var newValue = $(this).val();
// You might want to perform some validation, logging, or other functionality when the value changes.
console.log("New parking spot selected:", newValue);
// If the form relies on some validation or additional processing on change events,
// you would include that logic here. For example:
validateParkingSpot(newValue); // A hypothetical function to validate the selection.
// Or, if you need to enable/disable a submit button based on this value:
var isFormValid = newValue !== "0" && newValue !== ""; // Simple validation check.
$("#submit-button").prop("disabled", !isFormValid); // Enable/disable the button.
});
这就是确保表单的提交过程识别动态设置值的方式,因为处理程序确保在输入值更改时处理从验证到启用提交按钮的所有步骤,无论该更改是直接来自用户还是来自脚本。
.attr("value")
不是一个好方法,但我尝试了,没有得到改进的结果;所以我在尝试替代。.val()
检查元素,它具有从 123Forms 绑定到它的事件。我没有看到任何变化。
Input
focus
blur
for
我怀疑你是对的,我需要找到一些更高的形式验证。似乎仅仅将值添加到中并不足以让它被接受。
Input
如果输入元素绑定了 和 事件,则 123FormBuilder 可能会将这些事件用作其验证或状态管理系统的一部分。缺少直接更改事件处理程序并不一定意味着不会检测到对输入值的更改,但它确实表明表单可能依赖于 和 事件来触发其内部更改检测机制。focus
blur
focus
blur
将值设置为 后,可以尝试触发 和 事件来模拟用户交互:.val()
focus
blur
$rvSpot.val(s).trigger("focus").trigger("blur");
这与Mark Schultheiss的评论类似:
也许只是先更改以填充值,然后触发触发器,即
$rvSpot.trigger("focus").attr("value", s).trigger("blur");
$rvSpot.val(s).trigger("focus").trigger("blur");
这应该模仿用户选择一个值:输入获取值,用户“关注”输入(),然后远离它()。如果表单生成器正在寻找这些事件来验证或处理输入,则此序列更有可能被识别为合法的用户操作。(val(s))
trigger("focus")
trigger("blur")
表单可能将其他事件处理程序附加到其字段,以便进行验证或其他目的。您可以在浏览器的开发人员工具中检查该元素,以查看是否存在代码中未立即可见的事件侦听器。
如果表单生成器使用更复杂的机制来跟踪更改,则可能需要使用 MutationObserver
来监视对输入元素的更改并做出相应的反应。
确保输入字段具有与服务器预期内容相对应的属性。表单数据在提交时通常由属性键控。name
name
如果所有其他方法都失败,并且您可以控制服务器端逻辑,请考虑在提交表单后直接在服务器上更新值。这将是一个不太优雅的解决方案,只有在没有其他选项工作时才应该使用。
评论
.attr("value")
.val()
focus
blur
change
onControlValueChangedBecauseOfUserInput
value-change
我终于在这里找到了答案:
似乎有一个带有 Get 和 Set 方法的处理程序。
这是工作代码。
var $drop = $("[data-id='000000000']");
var $rvSpot = $("[data-id='000000000']");
var targetControlId = 000000000,
targetControlInstance = loader.getEngine().getDocument().getElementById(targetControlId);
$("path.enabled").on("mouseover", function(){
$(this).toggleClass("highlight");
}).on("mouseout", function(){
$(this).toggleClass("highlight")
}).on("click", makeSelection);
function makeSelection(e){
var el = $(e.target);
var l = $drop.find("select option:selected").data("index");
var s = el.attr("id");
if($(".selected").length){
if(!confirm("Are you sure you want to change your RV Selection?")){
return false;
}
removeSelected(l, el, function(){
console.log("Spot removed, callback executed");
makeSelection(e);
});
} else {
console.log("Making Selection", l, s);
$.post("https://www.unscruz.org/ticketing/take-spot.php", { land: l, spot: s }, function(results){
el.addClass("selected");
targetControlInstance.setValue({value: s});
$(".countdown").append("<span id='spot-selected'>Selected: " + s + "</span>");
startCountdown();
});
}
}
function removeSelected(l, el, callback){
var s = $(el).attr('id');
console.log("Removing Selection", l, s);
$.post("https://www.unscruz.org/ticketing/release-spot.php", { land: l, spot: s }, function(){
$(".selected").removeClass("selected");
targetControlInstance.setValue({value: ""});
stopCountdown();
if(callback != undefined && typeof callback == "function"){
callback();
}
});
}
评论
$rvSpot.trigger("focus").attr("value", s).trigger("blur");
$rvSpot.val(s).trigger("focus").trigger("blur");