AxleWack AxleWack - 1 month ago 6
Javascript Question

Set specific div contenteditable to true on button click using Javascript (MVC)

I am populating divs with data in it by use of a foreach :

@foreach (var item in Model.EmploymentDetailsList)
{
<li>
<i class="fa fa-user bg-aqua"></i>
<div class="timeline-item">
<span class="time"><i class="fa fa-clock-o"></i> Current</span>
<h3 class="timeline-header">@item.Position at <a href="@item.EmploymentCompanyWebsite">@item.EmploymentCompany</a></h3>
<div id="page-wrapper">
<section>
<div id="editor" class="diveditor timeline-body">
<input type="hidden" class="pkiEmploymentDetailID" value="@item.pkiEmploymentDetailID" />
@Html.Raw(item.PositionDetails)
</div>
</section>
</div>
<div class="timeline-footer">
<button id="editorBtn" type="button" class="edit-button btn btn-primary btn-xs">Edit</button>
@*<a class="btn btn-primary btn-xs">Edit</a>*@
</div>
</div>
</li>

<!-- timeline time label -->
<li class="time-label">
<span class="bg-red">
@item.StartDate
</span>
</li>
<!-- /.timeline-label -->
}


And I have the following JS that I am trying to use to set the specific div's contenteditable to true, based on the button clicked in that div :

<script>
//var editorBtn = document.getElementById('editorBtn');
//var element = document.getElementById('editor');

$('.edit-button').on('click', function () {
//editorBtn.addEventListener('click', function (e) {
// e.preventDefault();
//alert("Button Clicked");

if ($('.diveditor').attr('contenteditable', 'false')) {
// Disable Editing
//This code runs when you click Save
alert("Button Editable works");
//alert(element.innerHTML);

//TODO: Do Ajax call to save content to Database
var ProfileDetails =
{
"EmploymentDetails": element.innerHTML
};

$.ajax({
url: '/Profile/Save_Employment/',
data: JSON.stringify(ProfileDetails),
datatype: 'json',
type: 'POST',
contentType: 'application/json; charset=utf-8',
success: function (data) {
$('.diveditor').attr('contenteditable', 'false');
$('.edit-button').innerHTML = 'Edit';
// You could save any changes here.
}
});


} else {
//This code runs when you click Edit
$('.diveditor').attr('contenteditable', 'true');
$('.edit-button').innerHTML = 'Save';
$('.diveditor').focus();
}
});
</script>


So as you will see, all the Div's and buttons have the same names and I would like to edit only the specific Div that I click the button on(the edit button) - I have done something similar using a webgrid by using the class name.

Currently it sets focus to the last Div and not the one I want. It also does not change the button from "Edit" to "Save".

Is there a better way of doing this ? Or can someone possibly help me with what I am doing wrong.

Answer

You could use data- attributes to tell your script, which element should be now editable and give every div his own id attribute like this.

<div id="editor_@item.pkiEmploymentDetailID" class="diveditor timeline-body">
    <input type="hidden" class="pkiEmploymentDetailID" value="@item.pkiEmploymentDetailID" />
   @Html.Raw(item.PositionDetails)
</div>

<button id="editorBtn" type="button" class="edit-button btn btn-primary btn-xs" data-edit="@item.pkiEmploymentDetailID">Edit</button>

and in your jQuery script you know which element was clicked if you're passing argument to click handler. With this information you can read data-edit and make specific div editable.

$('.edit-button').on('click', function (event) {
    var clicked = $(event.target);
    var editableId = "editor_" + clicked.data("edit");
    // make element with id=editableId editable

    if ($('#'+editableId).attr('contenteditable', 'false')) {
        /* code */
    }
    else
    {
        $('#'+editableId).attr('contenteditable', 'true');
        clicked.html('Save');
        $('#'+editableId).focus();
    }
}

This approach allows you to change your HTML structure without worrying about breaking something in your JS.