EasyE EasyE - 1 month ago 16
jQuery Question

Unable to get the proper value inside a Keno Panel Bar using jquery

General information

I have built a kendo panel bar that is populated with data, it has an option that gives a user the ability to edit pre-populated data that is shown when a panel is expanded. The panel bar is nested inside a listview, and the HTML which is displayed when a panel is expanded comes from a Kendo template.

Current Issue

When ever the a panel is expanded and the user chooses to edit the the content and add it, they press the approve button to add, however the text that I receive is incorrect. I am only getting the information which is suppose to be located in the first panel. No matter what panel I choose to edit and add, I only push the data which is located in the first panel.

Html

<div class="padding" style="display:none;" id="ApprovalFormWindow">
<div class="container">
<!--<div id="descriptionColumn" style="display:none"><b id="description">Title</b><b id="date">Modified Date</b></div>-->
<div id="descriptionColumn" style="display:none">
<div style="width: 95%; display: table;">
<div style="display: table-row">
<div style="width: 40px; display: table-cell; vertical-align:top;"><b>Title</b></div>
</div>
</div>
</div>
<ul id="listView" style="display:none"></ul>
<div id="pager" style="display:none"></div>
</div>
</div>

<script type="text/x-kendo-tmpl" id="ApprovalContentTemplate">
<li>
<table style="width: 95%;">
<tr>
<td class="selectedValue" style="width:40%; vertical-align:top;">#:Description#</td>
</tr>
</table>
<div id="topTabPanel" style="margin-top: -4px; padding-top: 5px; padding-bottom: 5px; border: 1px solid lightgray !important">
<label style="margin-left : 5px;" for="EditCheckBox">
Edit<input class="editBox" type="checkbox" id="EditCheckBox" value="true" style="margin-left: 5px;">
</label>
<button type="button" class="PreviewItem" style="border: 2px none; border-radius: 25px; margin-left: 15px;">Preview</button>
<button type="button" class="ApproveItem" style="border: 2px none; border-radius: 25px; margin-left: 15px;">Approve</button>
</div>
<div id ="PanelSelected" class="row demo-section k-content" style="border-top: 4px solid dodgerblue; border-bottom: 4px solid dodgerblue;">
<div class="col-xs-11" style="margin-top: 5px;">
<form class="form-inline">
<div class="form-group">
<label for="Title" class="required">Title</label>
<div><textarea class="k-textbox ApproversPanel" id="Title" name="Title" style="width: 220px;" readonly>#:Name#</textarea></div>
</div>
<div class="form-group">
<label for="KeyWords" class="required">KeyWords</label>
<div><textarea class="k-textbox ApproversPanel" id="KeyWords" name="KeyWords" style="width: 220px;" readonly>#:KeyWords#</textarea></div>
</div>
<div class="form-group">
<label for="jandra" class="required">Description</label>
<div><textarea class="k-textbox ApproversPanel" id="jandra" name="jandra" style="width: 220px;" readonly>#:jandra#</textarea></div>
</div>
<div class="form-group">
<label for="Summary" class="required">Summary</label>
<div><textarea class="k-textbox ApproversPanel" id="Summary" name="Summary" style="height: 100px; width: 220px;" readonly>#:Summary#</textarea></div>
</div>
</form>
</div>
</div>
</li>


Javascript

serverResponse = [
{
Name: "Test1",
KeyWords: "KeyWord1",
jandra: "Country",
Summary: "Test Item 1",
},
{
Name: "Test2",
KeyWords: "KeyWord2",
jandra: "Rap",
Summary: "Test Item 2",
},
{
Name: "Test3",
KeyWords: "KeyWord3",
jandra: "Pop",
Summary: "Test Item 3",
},
{
Name: "Test4",
KeyWords: "KeyWord4",
jandra: "Rock",
Summary: "Test Item 4",
},
{
Name: "Test5",
KeyWords: "KeyWord5",
jandra: "Blues",
Summary: "Test Item 5",
},

];

var selectedContent;

$("#listView").kendoListView({
dataSource: serverResponse,
autoBind: false,
pageable: true,
template: kendo.template($("#ApprovalContentTemplate").html()),
dataBound: function () {
$("#listView").kendoPanelBar({
// Made it single, however multiple would be nice
expandMode: "single",
select: function (e) {
var retrievedContent = serverResponse._data;

for (var x = 0; x < retrievedContent.length; x++) {
if (e.item.dataset.uid === retrievedContent[x].uid) {
selectedContent = retrievedContent[x];
}
}
},

});

$(".editBox").each(function (e) {
$(this).click(function (d) {
if ($(this).is(":checked")) {
$(".ApproversPanel").attr("readonly", false);
}
else {
$(".ApproversPanel").attr("readonly", true);
$("#ListItemTitle").val(selectedContent.Name);
$("#ListItemKeyWords").val(selectedContent.KeyWords);
$("#ListItemDescription").val(selectedContent.Description);
$("#ListItemSummary").val(selectedContent.ContentSummary);
var testThis = 0;
}
});
});

$(".PreviewItem").each(function (e) {
$(this).click(function (d) {
// Logic not built
});
});

$(".ApproveItem").each(function (e) {
$(this).click(function (d) {
var value = $("#PanelSelected").find(".ApproversPanel").children();
/*
* when a person push this to the datasource it will always push
* the first object in the array no mattyer what panel they selected to edit
* Name: "Test1",
* KeyWords: "KeyWord1",
* jandra: "Country",
* Summary: "Test Item 1",
*/

GetCurrentValue();
});
});

function GetCurrentValue() {
$(".ApproversPanel").each(function (e) {
var title = $("#Title").val();
var KeyWords = $("#KeyWords").val();
var Description = $("#jandra").val();
var ContentSummary = $("Summary").val();

/*
* This gives me the same results. not matter what panel I selected to edit and
* add I always get the first object.
* Name: "Test1",
* KeyWords: "KeyWord1",
* jandra: "Country",
* Summary: "Test Item 1",
*/

});
};
},


});

Answer

Well...you have 5 panels, each containing a set of textboxes that all have the same id and name. id must be unique. Your jquery selector in GetCurrentValue() on the id's will always return the first one and first one only as jquery assumes a unique id and stops(it has no idea you want the 4th input with the identical id). You have to make each of your panels unique in some way and use the appropriate selector.

For instance, you could change your Approve button click to

$(".ApproveItem").each(function (e) {
    $(this).click(function (d) {
      var panel = $($(this).closest("li"));
      var data = {
        Name: panel.find("#Title").val(),
        KeyWords: panel.find("#KeyWords").val(),
        jandra: panel.find("#jandra").val(),
        Summary: panel.find("#Summary").val()
      }
      console.log(data);

        //var value = $("#PanelSelected").find(".ApproversPanel").children();
        /*
         * when a person push this to the datasource it will always push
         * the first object in the array no mattyer what panel they selected to edit 
         *   Name: "Test1",
         *   KeyWords: "KeyWord1",
         *   jandra: "Country",
         *   Summary: "Test Item 1",
         */

        //GetCurrentValue();
    });
});

This gets a reference to the panel associated with the button clicked (using closest), then uses that to refine the data selectors to find the children of the correct panel.

http://dojo.telerik.com/@Stephen/avitO

I'm positive there are better ways to do this using Kendo's MVVM(similar, but not identical, to the techniques here:http://stackoverflow.com/a/37998096/4825632) or adding/removing classes to the selected panel to use to build the more specific selector.

Comments