Editable field

display a read only field that when clicked is editable

by Randy Crews

HTML

<script src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-2.2.1.js"></script>
<ul data-bind="foreach: items">
    <li class="divContainer"> <span title="filename" class="tbox" data-bind="text: name, click: $root.setName"></span>
 <span title="description" class="tbox" data-bind="text: description, click: $root.setDescription"></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="&#x2714;" />
    <input type="button" id="CancelChange" data-bind="click: $root.clearField" class="editbtn" value="&#x2716;" />
</div>

CSS

body {
    font-family: Arial;
    font-size:1em;
}
li {
    list-style: none;
}
.divContainer {
    width: 90%;
    padding:5px;
    margin:2px;
    border:1px solid #ccc;
    background-color: #ffcc00;
}
.tbox {
    cursor: pointer;
    margin-right: 50px;
}
.tbox:hover {
    text-decoration:underline;
}
.nameContainer {
    display:none;
    z-index:999;
    padding: 8px;
    background-color: #fbfbfb;
    border: 2px solid #B9D3E6;
    border-radius: 4px;
    -moz-border-radius: 4px;
    box-shadow: 0px 0px 8px #888888;
}
.mytextbox {
    width: 150px;
    height: 24px;
    border: 1px solid #B9D3E6;
    border-radius: 2px;
    -moz-border-radius: 2px;
}
.editbtn {
    background-color: #ECF4FA;
    padding: 3px 5px 3px 5px;
    border: 1px solid #B9D3E6;
    border-radius: 4px;
    -moz-border-radius: 4px;
    color: #8DBCDC;
    cursor:pointer;
}
.smallTitle {
    font-family: Arial;
    font-size: .9em;
    color:#999;
    display:block;
    margin-bottom:2px;
}

.watermark{
     font-style:italic;
     color: #ccc;
}

JavaScript

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', 'item 3 Description'),
        new Item('item 4', 'item 4 Description')]);

        //observable fields
        self.currentField = ko.observable("");

        //bind current item text to field
        self.setName = function (item) {
            self.currentField(item.name());
        };
        self.setDescription = function (item) {
            self.currentField(item.description());
        };
        self.clearField = function(){
          self.currentField('');  
        };
    }

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) {
   ...