Reputation: 1744
I have this simple div:
<div id="mainContent">
</div>
and it's empty. Now I'm trying to append this HTML
to the above div:
<div id="mainContent">
<label>Project Name</label>
<input type="text" id="projectName" data-bind="value: projectName"/>
<label>Tracker Name</label>
<input type="text" id="trackerName" data-bind="value: trackerName"/>
</div>
<button type="submit" data-bind="click: submitNewProject">Submit</button>
By using:
$.ajax({
type : 'POST',
url : 'newTracker.php',
dataType : 'html',
success : function(data){
$("#mainContent").html(data);
},
error : function(XMLHttpRequest, textStatus, errorThrown) {
alert('Something is wrong!');
}
});
Where data
is the HTML
I'm trying to assign by: $("#mainContent").html(data);
At first look everything looks pretty, but there is a problem - the bindings are not working.
What I mean is that in the newly assigned HTML
I have a button supposed to call a viewmodel function, but it does not...
BUT if I place the code directly inside of the div the bindings are working like a charm.
Why my bidings are not working when I'm assigning a new HTML
code inside of the div? I know that I'm missing something really small and basic here, but I can't spot it.
EDIT:
Button event:
submitNewProject = function(){
console.log("submit new project");
};
Upvotes: 3
Views: 2499
Reputation: 1680
Sometimes you need to create a secondary function on the parent page to apply the bindings and then call that function from within the appended text. All the functions defined on the original page as it loads will be available. I have used this method before, though you have to know in advance what functions you will need to build. Or you can just include the binding as part of the post-ajax process.
It makes ajax loads with decent functionality
function bindStuff() {
$(".class1").click(function() {
// do something with the bind
});
}
function ajaxLoad() {
// Perform ajax load
// on complete call your bindings
complete: function() {
bindStuff();
}
}
With your example:
$.ajax({
type : 'POST',
url : 'newTracker.php',
dataType : 'html',
success : function(data){
$("#mainContent").html(data);
},
complete: function(){
bindStuff();
},
error : function(XMLHttpRequest, textStatus, errorThrown) {
alert('Something is wrong!');
}
});
Upvotes: 2
Reputation: 2372
As most have pointed out. When you add the HTML dynamically with the append, the DOM isn't reevaluating the bindings. So, you need to either:
success
event handlerdocument
html onChange
handlerdisplay:none
, then change the style to display:block
, display:inline-block
, etc...append()
anything else that is not dependent on the bindingUpvotes: 2
Reputation: 49133
Knockout cannot track newly created elements, if your DOM changed using Ajax methods you'll have to explicitly bind a view-model to the newly created elements.
Something like:
$.ajax({
type: 'POST',
url: 'newTracker.php',
dataType: 'html',
success: function (data) {
var $mainContent = $("#mainContent");
$mainContent.html(data);
var existingViewModel = ko.dataFor(document.body);
ko.applyBindings(existingViewModel, $mainContent.get(0));
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert('Something is wrong!');
}
});
Upvotes: 5