admin管理员组文章数量:1333490
<script>
(function( $ ) {
$.widget( "my.dropbox", {
errorText: function(text) {
$(this.element).next().html(text);
},
_create: function() {
var id = $(this.element).attr("id");
var customDropbox = $(
"<div class='form-group'>"+
"<label for='"+id+"'>"+getLabelFor(id)+"</label>"+
"<select id='"+id+"'></select>"+
"<div class='errors'></div>"+
"</div>"
);
customDropbox.attr("id", id);
$(this.element).replaceWith(customDropbox); // This removes original element from DOM
populateOptions(id);
},
});
}( jQuery ));
$(document).ready(function(){
$("#field1").dropbox(); //blank input field turns into a select with a label, populated options e.t.c..
$("#button1").on("click", function(){
$("#field1").dropbox("errorText", "This is a validation error message"); //throws an error saying dropbox is not initialized
});
});
</script>
<html>
<body>
<input id="field1" />
<button id="button1">Press me</button>
</body>
</html>
So I want a widget with public methods that will replace the original element with all the widget data associated with it. The problem with the above code is that the <select..>
element is just a DOM element and if you call .dropbox(..)
on it, it will say the widget is not initialized. Is there a way to make the select element into the widget object with the .errorText() method? All widget examples online add stuff around the original element but never replace it. As for the bigger picture, I'm trying to make a generic tool to configure forms dynamically. It's going to be all <input id="...">
in html but then javascript will query a database, get configuration for the field and turn it into a dropbox
, checkbox
or, say, a date picker
with all the labels
, validation
, and other bells and whistles.
<script>
(function( $ ) {
$.widget( "my.dropbox", {
errorText: function(text) {
$(this.element).next().html(text);
},
_create: function() {
var id = $(this.element).attr("id");
var customDropbox = $(
"<div class='form-group'>"+
"<label for='"+id+"'>"+getLabelFor(id)+"</label>"+
"<select id='"+id+"'></select>"+
"<div class='errors'></div>"+
"</div>"
);
customDropbox.attr("id", id);
$(this.element).replaceWith(customDropbox); // This removes original element from DOM
populateOptions(id);
},
});
}( jQuery ));
$(document).ready(function(){
$("#field1").dropbox(); //blank input field turns into a select with a label, populated options e.t.c..
$("#button1").on("click", function(){
$("#field1").dropbox("errorText", "This is a validation error message"); //throws an error saying dropbox is not initialized
});
});
</script>
<html>
<body>
<input id="field1" />
<button id="button1">Press me</button>
</body>
</html>
So I want a widget with public methods that will replace the original element with all the widget data associated with it. The problem with the above code is that the <select..>
element is just a DOM element and if you call .dropbox(..)
on it, it will say the widget is not initialized. Is there a way to make the select element into the widget object with the .errorText() method? All widget examples online add stuff around the original element but never replace it. As for the bigger picture, I'm trying to make a generic tool to configure forms dynamically. It's going to be all <input id="...">
in html but then javascript will query a database, get configuration for the field and turn it into a dropbox
, checkbox
or, say, a date picker
with all the labels
, validation
, and other bells and whistles.
-
You say your widget has public methods
.show()
and.hide()
. What object are those methods on? I think we need to see your jQuery widget code to better understand what your situation is and what you're asking. – jfriend00 Commented Dec 13, 2013 at 6:53 - The widget is huge I don't think I can post it here but you're absolutely right, what object are those methods on? The problem is, I probably don't understand widgets 100%. What happens now is the widget factory adds .input() method to $, when I call it on a DOM element ._create() gets called, it creates new DOM elements and replaces this.element with them. But what is left after it exits? The DOM was modified and the element on which .input() was originally called is removed and replaced with new DOM elements. So how to turn them into "the widget"? – Maxim Suponya Commented Dec 16, 2013 at 3:58
- Consulting the documentation for your widget library and looking at coding examples is probably in order. Not much I can do to help without seeing the doc/code for the widget library. – jfriend00 Commented Dec 16, 2013 at 4:07
- Rewritten the question with basic code for the widget, please give it one more chance :) – Maxim Suponya Commented Dec 16, 2013 at 5:15
3 Answers
Reset to default 6 +25There is more than one issue with your widget code. I'll try to summarize them:
1. Copy the data
You're not copying the data
to the newly created customDropbox
, so before
this.element.replaceWith(customDropbox);
you should copy the data
:
customDropbox.data(this.element.data());
Now the widget will remember that it was initialized.
2. this.element is gone
After
this.element.replaceWith(customDropbox);
you should update this.element
so that it points to the newly created customDropbox
:
this.element = customDropbox;
3. errorText message takes wrong element
Since the widgets element (this.element
) is now pointing to the <div class='form-group'></div>
element, the errorText
function must be slightly modified to:
this.element.find(".errors").html(text);
4. id should be unique
Now, both the wrapper <div>
and the <select>
have the same id, which is not allowed in HTML so remove the one on the <select>
tag. Luckily, <label>
can work without the for
attribute, just write it like this:
<label>labelForId <select></select></label>
Then to get the <select>
-element, use this.element.find("select")
in the widget.
Side note
`this.element` is already a jQuery element, so no need for the additional `$()` wrapping.
See this jsFiddle
function show(){
$("#field1").input({....});
}
function hide(){
$("#field1").input("hide");
}
<button onclick="show()">show</button>
<button onclick="hide()">hide</button>
i think to replace the origin element which initial dropbox() is not a good solution,
because this will force you to rely on the implemention details of jQuery ui factory,
it is easy to make a mistake or introduce bugs, sometimes harder for other people to understand your code
if jquery ui factory change the implemention in the future, you have to modify all your code to make it work
(sorry for my limit understand of jquery ui)
i think we can put the <input/>
into a container and initial dropbox() on the container which inturn
replace <input/>
with <select>
datepicker
..etc.. we can build modules easily by doing so:
<form>
<div class="dropbox"><label for="someID">aaaaaa</label><input id="someID"/></div>
<div class="datepicker"></div>
<div class="othermodule"></div>
</form>
js:
$(".dropbox").dropbox(); // init dropbox you defined
$(".datepicker").datepicker(); // ...
$(".othermodule").othermodule(); // ...
$(".dropbox").dropbox("errorText", "error"); // invoke it smoothly
here is a simple demo: http://jsfiddle/m4A3D/
@Wouter Huysentruit's answer provides a list of good suggestion for me
<form>
<div class="dropbox">
<label for="someID">aaaaaa</label>
<input id="someID"/>
</div>
<div class="datepicker"></div>
<div class="othermodule"></div>
</form>
<button id="button1">Press me</button>
<script>
(function ($){
$.widget("my.dropbox", {
_create: function () {
var $input = this.element.find("input");
var sID = $input.attr("id");
var $select = $("<select>");
$select.attr("id", sID);
$input.replaceWith($select);
this.element.append("<div class='errors'></div>");
}, // end _create()
errorText: function (text) {
this.element.find(".errors").text(text);
} // end errorText()
});
}(jQuery));
$(".dropbox").dropbox();
$("#button1").click(function () {
$(".dropbox").dropbox("errorText", "this is error");
});
</script>
本文标签: javascriptReplacing widget element with a newly constructed DOM structureStack Overflow
版权声明:本文标题:javascript - Replacing widget element with a newly constructed DOM structure - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742341623a2456719.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论