Reputation: 3562
I have a sample I am trying to detect the text value of a selected element and have it populated in a popup window. I know how to do this using jQuery but I don't want to bring Ui awareness into the viewmodel. I know i am missing something simple but can someone explain what I need to do to bind the text value from an element selected in the UI and have it bound to another observable within Knockout.
Full working JsFiddle
Minus the CSS here is the html and JS that I have hooked up thus far
<ul data-bind="foreach: items">
<li class="divContainer"> <span title="filename" class="tbox" data-bind="text: name, click: $root.openControl "></span>
<span title="description" class="tbox" data-bind="text: description"></span>
</li>
</ul>
<div id="nameDiv" class="nameContainer"> <span class="smallTitle"></span>
<input type="textbox" class="mytextbox" data-bind="value: currentField" />
<input type="button" id="SaveChange" class="editbtn" value="✔" />
<input type="button" id="CancelChange" class="editbtn" value="✖" />
</div>
JS
var Item = function (name, description) {
this.name = ko.observable(name);
this.description = ko.observable(description);
}
function myViewModel() {
var self = this;
//sample list of items
self.items = ko.observableArray([
new Item('item 1', ' item 1 Description'),
new Item('item 2', 'item 2 Description'),
new Item('item 3', 'Report3 Description'),
new Item('item 4', 'Report4 Description')]);
//observable fields
self.currentField = ko.observable("");
//bind current item text to field
self.openControl = function () {
self.currentField($(this)); ///Here I need to pick up the text of the item that was clicked on
};
};
ko.applyBindings(new myViewModel());
function positionDiv(x_pos, y_pos) {
var d = document.getElementById('nameDiv');
d.style.display = 'none';
d.style.position = 'absolute';
d.style.left = x_pos + 'px';
d.style.top = y_pos + 'px';
$('#nameDiv').fadeIn('slow');
}
$('.tbox').click(function () {
var myText = $(this);
var t = $(this).attr('title');
if (t === 'filename') {
$('.smallTitle').text('Enter new filename');
} else {
$('.smallTitle').text('Enter new description');
}
displayEditBox(myText);
});
function displayEditBox(myText) {
//determine middle of span element
var offset = myText.offset();
var width = myText.width();
var height = myText.height();
var centerX = offset.left + width + 5;
var centerY = offset.top - 10;
positionDiv(centerX, centerY);
}
$('#CancelChange').click(function () {
$('#nameDiv').fadeOut('fast');
clearField($('.mytextbox'));
});
function clearField(field_name) {
field_name.val('');
}
Thanks in advance,
Upvotes: 0
Views: 482
Reputation: 79441
Change your definition of the openControl
function to take a parameter:
self.openControl = function (item) {
self.currentField(item.description());
};
This should be the item
(an element of the items
array) that the click was applied to, because at the location where the click
binding is made, the data context is the body of the foreach: items
binding.
Upvotes: 3