Reputation: 255
I am loading data to grid dynamically and I am having 'Add' button in every row.
btn = "<a id='btnRow' data-bind='click: function()
{ ClickAdd(\"" + rowObject.Id+ "\")}'>" +
"<i ></i><span data-bind='text:$root.StrResources.BtnAdd'/></a>";
as shown above I am setting the text for button using data-bind
Now on clicking the button i want to change the text from 'Add' to 'Selected' I do have property in javascript object as
StrResources: {
BtnView: ko.observable("View"),
BtnAdd: ko.observable("Add"),
BtnSelected: ko.observable("Selected"),
},
In java script object i do have method to perform add operation
empObject.ViewModel.ClickAdd = function (objectDN, objectName) {
// here i want to write code to change the text.
};
How can i do it?
Upvotes: 2
Views: 8939
Reputation: 1502
I see what you're trying, but I'm not sure that's the right way to do things. Your resources object contains some observables, but the point of observables is that when you change them your previously bound UI changes to reflect the changes in the observable. My confusion is that your resources should be static.
Then I see you're binding to those resources however your method of binding the button text is hard coded to use the StrResources.BtnAdd
resource; and if you update that observable to 'Selected', then ALL the buttons bound to StrResources.BtnAdd
will then change to have the text of 'Selected'.
What you really need is a way to specify text per button rather than have all buttons bound to one observable.
Reading between the lines of your question, I implemented a simple grid here that I think meets your requirements:
http://jsbin.com/finucabo/1/edit?html,js,output
The parts of interest are:
var model = {
grid: {
row: ko.observableArray(),
selected: ko.observable()
},
buttonText: function (row) {
return model.grid.selected() === row ? 'Selected' : 'Add';
},
buttonClick: function (row) {
if (model.grid.selected() === row) {
model.grid.selected(null);
} else {
model.grid.selected(row);
}
}
};
And the binding:
<!-- ko foreach: grid.row -->
<tr>
<td data-bind="text: first"></td>
<td data-bind="text: last"></td>
<td data-bind="text: email"></td>
<td>
<button
type="button"
data-bind="click: $root.buttonClick, text: $root.buttonText($data)">
</button>
</td>
</tr>
<!-- /ko -->
Notice that clicking the button simply stores the current row into the model.grid.selected
observable. This will cause buttonText to re-evaluate for the text binding.
Hope this is of some help to you.
EDIT:
With respect to being able to select multiple rows, you could just change selected into an observable array.
I've updated the jsbin here: http://jsbin.com/finucabo/2/edit
The changes are:
// Helper function added.
function arrayContains(anArray, aValue) {
return ko.utils.arrayFirst(anArray(), function (v) {
return v === aValue;
}) !== null;
}
var model = {
grid: {
row: ko.observableArray(),
// Now using an observable array.
selected: ko.observableArray()
},
buttonText: function (row) {
// Modify to use observable array.
return arrayContains(model.grid.selected, row) ? 'Selected' : 'Add';
},
buttonClick: function (row) {
// Modify to use observable array.
if (arrayContains(model.grid.selected, row)) {
model.grid.selected.remove(row);
} else {
model.grid.selected.push(row);
}
}
};
Upvotes: 2
Reputation: 7958
You would just bind the text to an observable:
<button data-bind="click: changeButtonText, text: buttonText"></button>
then in the click function, you would change the text:
var Row = function(row) {
var self = this;
self.buttonText = ko.observable('Add');
self.changeButtonText = function() {
self.buttonText('Selected');
};
};
Upvotes: 3