how to bind new kendo datasource to a existing kendo-web-UI listview? - kendo-ui

i create a kendo-datasource and assign it to a kendo-listview. its work fine. But i added a search functionality for the list-view. the problem is after search the datasoruce is updated but my listview does not reflect the changes. please help me here is the code bellow. thanks
<script type="text/javascript">
var shareDataSource; var title = $('#blogTitle').val() || "";
shareDataSource = new kendo.data.DataSource({
transport: {
read: {
url: "api/BlogPosts/?title=" + title
}
},
pageSize: 15
});
$("#listView").kendoListView({
dataSource: shareDataSource,
template: kendo.template($("#template").html()),
autoBind: true
});
function searchByTitle() {
var title = $('#blogTitle').val();
shareDataSource = new kendo.data.DataSource({
transport: {
read: {
url: "api/BlogPosts/?title=" + title
}
},
pageSize: 15
});
shareDataSource.read();
}</script>
<div>
<input type="text" id="blogTitle" size="5" />
<input type="button" value="Search" onclick="searchByTitle();" />
</div> <div id="listView"></div>
<script type="text/x-kendo-tmpl" id="template">
<div class="post">
<div class="post-meta">
<h2 class="post-title"> <a title="" rel="bookmark" href="">${Title}</a></h2>
<hr/>
<p class="post-metadata">November 29, 2012 in <a rel="category tag" title="View all posts in .net" href="">.net</a>,
<a rel="category tag" title="View all posts in SQL Server R2" href="">SQL Server R2</a> | Tags: <a rel="tag" href="">software</a>,
<a rel="tag" href="">technology</a> | <a title="" href="">Leave a comment</a></p>
</div> <div class="post-content"> ${Content}
</div>
</div>
</script>

Hasib,
you have already defined kendo datasource on the top, try not to recreate it again in your search method. In theory to update your ListView you need to call read on your data source :
function searchByTitle() {
shareDataSource.read();
}

update the datasource [read]. But should use parametrMap. Bobby_D mention above.
//---------------------------------------------------------------------------
var shareDataSource;
shareDataSource = new kendo.data.DataSource({
transport: {
read: {
url: function(){ var title = $('#blogTitle').val() || "";
return "api/BlogPosts/?title=" + title;}
}
},
pageSize: 15
});
//----------------- better -----------------------------
var shareDataSource;
shareDataSource = new kendo.data.DataSource({
transport: {
read: {
url:"api/BlogPosts/",// "api/Blogposts/",//
data: {
title: function () { return ($('#blogTitle').val() || ""); } // sends the value of the input as the title id
}
}
},
pageSize: 15
});

Related

Asp.Net Mvc Html.BeginFormSubmit ajax sends twice request (one's type xhr the other's document)

I am working on a survey application with Asp.Net MVC. I have a page named Index.cshtml which has a question table and a 'Add New' button.Once button clicked, a popup is opened with jQuery. I am calling a view from controller to fill jQuery dialog named as AddOrEdit.cshtml (child page). I am adding new question and options. Question is a textfield and its options are added in editable table. Once clicked submt button Submit form event (save or update) is fired. But ajax sends twice request. One of these requests send empty object, the other sends full object. Where am I making a mistake?
According to my research, what causes this problem is that the unobtrusive validator is placed on 2 different pages. But this is not the case for me.
When I debug with chrome in f12, the initiator of one of the 2 requests 'jquery' the initiator of the other 'other' The type of one of these 2 post requests appears as 'XHR' and the type of the other is 'document'.
Index.cshtml
#{
ViewBag.Title = "Soru Listesi";
}
<h2>Soru Oluşturma</h2>
<a class="btn btn-success" style="margin-bottom: 10px"
onclick="PopupForm('#Url.Action("AddOrEdit","Question")')"><i class="fa fa-plus"></i> Yeni Soru Oluştur</a><table id="questionTable" class="table table-striped table-bordered accent-blue" style="width: 100%">
<thead>
<tr>
<th>Soru No</th>
<th>Soru Adı</th>
<th>Oluşturma Tarihi</th>
<th>Güncelleme Tarihi</th>
<th>Güncelle/Sil</th>
</tr>
</thead>
</table>
<link
href="https://cdn.datatables.net/1.10.20/css/dataTables.bootstrap4.min.css" rel="stylesheet" />
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"
rel="stylesheet" />
#section Scripts{
<script src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.10.20/js/dataTables.bootstrap4.min.js"></script>
<script>
var Popup, dataTable;
$(document).ready(function() {
dataTable = $("#questionTable").DataTable({
"ajax": {
"url": "/Question/GetData",
"type": "GET",
"datatype": "json"
},
"columnDefs": [
{ targets: 2 }
],
"scrollX": true,
"scrollY": "auto",
"columns": [
{ "data": "QuestionId" },
{ "data": "QuestionName" },
{
"data": "CreatedDate",
"render": function(data) { return getDateString(data); }
},
{
"data": "UpdatedDate",
"render": function(data) { return getDateString(data); }
},
{
"data": "QuestionId",
"render": function(data) {
return "<a class='btn btn-primary btn-sm' onclick=PopupForm('#Url.Action("AddOrEdit", "Question")/" +
data +
"')><i class='fa fa-pencil'></i> Güncelle</a><a class='btn btn-danger btn-sm' style='margin-left:5px' onclick=Delete(" +
data +
")><i class='fa fa-trash'></i> Sil</a>";
},
"orderable": false,
"searchable": false,
"width": "150px"
}
],
"language": {
"emptyTable":
"Soru bulunamadı, lütfen <b>Yeni Soru Oluştur</b> butonuna tıklayarak yeni soru oluşturunuz. "
}
});
});
function getDateString(date) {
var dateObj = new Date(parseInt(date.substr(6)));
let year = dateObj.getFullYear();
let month = (1 + dateObj.getMonth()).toString().padStart(2, '0');
let day = dateObj.getDate().toString().padStart(2, '0');
return day + '/' + month + '/' + year;
};
function PopupForm(url) {
var formDiv = $('<div/>');
$.get(url)
.done(function(response) {
formDiv.html(response);
Popup = formDiv.dialog({
autoOpen: true,
resizable: true,
title: 'Soru Detay',
modal: true,
height: 'auto',
width: '700',
close: function() {
Popup.dialog('destroy').remove();
}
});
});
}
function SubmitForm(form) {
debugger;
if (form.checkValidity() === false) {
debugger;
event.preventDefault();
event.stopPropagation();
}
form.classList.add('was-validated');
if ($(form).valid()) {
var question = {};
question.questionId = 1111;
var options = new Array();
$("#questionForm TBODY TR").each(function() {
var row = $(this);
var option = {};
option.OptionId = row.find("TD").eq(0).html();
option.OptionName = row.find("TD").eq(1).html();
options.push(option);
});
question.options = options;
question.responses = new Array();
$.ajax({
type: "POST",
url: form.action,
data: JSON.stringify(question),
success: function(data) {
if (data.success) {
debugger;
Popup.dialog('close');
dataTable.ajax.reload();
$.notify(data.message,
{
globalPosition: "top center",
className: "success",
showAnimation: "slideDown",
gap: 1000
});
}
},
error: function(req, err) {
debugger;
alert('req : ' + req + ' err : ' + err.data);
},
complete: function(data) {
alert('complete : ' + data.status);
}
});
}
}
function ResetForm(form) {
Popup.dialog('close');
return false;
}
function Delete(id) {
if (confirm('Bu soruyu silmek istediğinizden emin misiniz?')) {
$.ajax({
type: "POST",
url: '#Url.Action("Delete", "Question")/' + id,
success: function(data) {
if (data.success) {
dataTable.ajax.reload();
$.notify(data.message,
{
className: "success",
globalPosition: "top center",
title: "BAŞARILI"
})
}
}
});
}
}
</script>
}
AddOrEdit.cshtml
#using MerinosSurvey.Models
#model Questions
#{
Layout = null;
}
#using (Html.BeginForm("AddOrEdit", "Question", FormMethod.Post, new { #class = "needs-validation",
novalidate = "true", onsubmit = "return SubmitForm(this)", onreset = "return ResetForm(this)", id =
"questionForm" }))
{
<div class="form-group row">
#Html.Label("QuestionId", "Soru No", new { #class = "col-form-label col-md-3" })
<div class="col-md-9">
#Html.TextBoxFor(model => model.QuestionId, new { #readonly = "readonly", #class = "form-control" })
</div>
</div>
<div class="form-group row">
#Html.Label("QuestionName", "Soru Adı", new { #class = "col-form-label col-md-3" })
<div class="col-md-9">
#Html.EditorFor(model => model.QuestionName, new { htmlAttributes = new { #class = "form-control", required = "true" } })
<div class="valid-feedback"><i class="fa fa-check">Süpersin</i></div>
<div class="invalid-feedback "><i class="fa fa-times"></i></div>
</div>
</div>
#*<div class="form-group row">
#Html.LabelFor(model => model.CreatedDate, new { #class = "form-control-label col-md-3"})
<div class="col-md-9">
#Html.EditorFor(model => model.CreatedDate, "{0:yyyy-MM-dd}", new { htmlAttributes = new { #class = "form-control", type = "date", #readonly = "readonly",required="false" } })
</div>
</div>*#
<div class="table-wrapper form-group table-responsive-md">
<div class="table-title">
<div class="form-group row">
<div class="col-md-9">Seçenekler</div>
<div class="col-md-3">
<a class="btn btn-success add-new" style="margin-bottom: 10px"><i class="fa fa-plus"></i>Seçenek Ekle</a>
</div>
</div>
</div>
<table class="table optionTable">
<thead>
<tr>
<th scope="col">Seçenek Id</th>
<th scope="col">Seçenek Adı</th>
<th scope="col">Güncelle/Sil</th>
</tr>
</thead>
<tbody>
#*#foreach (Options options in Model.Options)
{
<tr>
<td>#options.OptionId</td>
<td>#options.OptionName</td>
<td>
<a class="add btn btn-primary btn-sm" title="Add" data-toggle="tooltip">
<i class="fa fa-check">Onayla</i></a>
<a class="edit btn btn-secondary btn-sm" title="Edit" data-toggle="tooltip"><i class="fa fa-pencil">Güncelle</i></a>
<a class="delete btn-danger btn-sm" title="Delete" data-toggle="tooltip"><i class="fa fa-trash">Sil</i></a>
</td>
</tr>
}*#
</tbody>
</table>
</div>
<div class="form-group row">
<input type="submit" value="Submit" class="btn btn-primary" id="btnSubmit" />
<input type="reset" value="Reset" class="btn btn-secondary" />
</div>
}
<script>
$(document).ready(function () {
$('[data-toggle="tooltip"]').tooltip();
//var actions = $("table.optionTable td:last-child").html();
var actions =' <a class="add btn btn-primary btn-sm" title="Add" data-toggle="tooltip"><i
class="fa fa-check">Onayla</i></a>' + '<a class="edit btn btn-secondary btn-sm" title="Edit" data toggle="tooltip"><i class="fa fa-pencil">Güncelle</i></a>' +'<a class="delete btn-danger btn-sm" title="Delete" data-toggle="tooltip"><i class="fa fa-trash">Sil</i></a>';
// Append table with add row form on add new button click
$(".add-new").click(function () {
$(this).attr("disabled", "disabled");
var index = $("table.optionTable tbody tr:last-child").index();
var row = '<tr>' +
'<td><input type="text" class="form-control" name="optionId" id="optionId"></td>' +
'<td><input type="text" class="form-control" name="optionId" id="optionName"></td>' +
'<td>' + actions + '</td>' +
'</tr>';
$("table.optionTable").append(row);
$("table.optionTable tbody tr").eq(index + 1).find(".add, .edit").toggle();
$('[data-toggle="tooltip"]').tooltip();
});
// Add row on add button click
$(document).on("click", ".add", function () {
var empty = false;
var input = $(this).parents("tr").find('input[type="text"]');
input.each(function () {
if (!$(this).val()) {
$(this).addClass("error");
empty = true;
} else {
$(this).removeClass("error");
}
});
$(this).parents("tr").find(".error").first().focus();
if (!empty) {
input.each(function () {
$(this).parent("td").html($(this).val());
});
$(this).parents("tr").find(".add, .edit").toggle();
$(".add-new").removeAttr("disabled");
}
});
// Edit row on edit button click
$(document).on("click", ".edit", function () {
$(this).parents("tr").find("td:not(:last-child)").each(function () {
$(this).html('<input type="text" class="form-control" value="' + $(this).text() + '">');
});
$(this).parents("tr").find(".add, .edit").toggle();
$(".add-new").attr("disabled", "disabled");
});
// Delete row on delete button click
$(document).on("click", ".delete", function () {
debugger;
$(this).parents("tr").remove();
$(".add-new").removeAttr("disabled");
});
});
event.preventDefault(); move this line and place it immediately after function SubmitForm (form){
Like below:
function SubmitForm(form) {
debugger;
event.preventDefault();
if (form.checkValidity() === false) {
debugger;
event.stopPropagation();
}
form.classList.add('was-validated');
if ($(form).valid()) {
var question = {};
question.questionId = 1111;
var options = new Array();
$("#questionForm TBODY TR").each(function() {
var row = $(this);
var option = {};
option.OptionId = row.find("TD").eq(0).html();
option.OptionName = row.find("TD").eq(1).html();
options.push(option);
});
question.options = options;
question.responses = new Array();
$.ajax({
type: "POST",
url: form.action,
data: JSON.stringify(question),
success: function(data) {
if (data.success) {
debugger;
Popup.dialog('close');
dataTable.ajax.reload();
$.notify(data.message,
{
globalPosition: "top center",
className: "success",
showAnimation: "slideDown",
gap: 1000
});
}
},
error: function(req, err) {
debugger;
alert('req : ' + req + ' err : ' + err.data);
},
complete: function(data) {
alert('complete : ' + data.status);
}
});
}
}

Kendo UI Checkbox unclicable

Checkboxes when using class="k-checkbox" are unclickable. They are clickable if those classes ommited.
<script id="user-groups-li-edit" type="text/x-kendo-template">
<li>
<input type="checkbox" name="group[]" value="#:data.id#" id="#:data.id#" class="k-checkbox" # if (data.checked) { # checked # } #>
<label class="k-checkbox-label" for="#:data.id#">#:data.nazwa#</label>
</li>
</script>
<script id="document-edit-template" type="text/x-kendo-template">
<div id="document-groups">
<ul class="fieldlist-groups" data-role="listview"
data-template="user-groups-li-edit"
data-bind="source: groupsData">
</ul>
</div>
<script>
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: API_URL+"getusergroups/"+id,
dataType: "json"
}
}
});
var viewModel = kendo.observable({
groupsData: dataSource,
});
kendo.bind($("\#document-groups"), viewModel);
<\/script>
</script>

Passing data between 2 MVC widgets

I've got created a widget(combobox) with data from an external server.
I just want the value that I select from that combobox see into the label from another widget.
Source of the widget from the combobox:
<div id="exampleCombo">
<div class="demo-section k-content">
<h4>Facility</h4>
<input id="fac" style="width: 30%;" />
</div>
<script>
$(document).ready(function (user) {
$("#fac").kendoComboBox({
dataTextField: "client",
dataValueField: "client",
order: "ascending",
height: 400,
dataSource: {
// type: "odata",
type: "json",
transport: {
read: "/mvc/controllers/UserfacilitiesCombo/get/" + user
},
group: { field: "facility" }
},
});
});
Source of the widget with the label on it:
<div id="exampleLabel">
<div class="demo-section k-content">
<ul class="forms">
<li>
<label>FacilityName</label>
<input id="FacPass" name="FacPass" value="Test" class="k-textbox" style="width: 100%;" />
</li>
</ul>
</div>
Can anybody help me on this?
You can use the change event. Put this after your dataSource and add a class name to your target label
change: function(e) {
var value = this.value();
$('.yourLabelClass').html(value);
}
Here is some more info about the available events
https://docs.telerik.com/kendo-ui/api/javascript/ui/combobox/events/change

Pass multiple Id's against multiple values in database

I'm working on a task that uses autocomplete textbox items containing names, stores in textbox or in listbox with their associated Id's(hidden) and inserted into the required table (only their related id's). I'm working on mvc 5 application. So far I've achieved to add value in listbox with names but not Id's. And trying to add the listbox values get stored in database. Below is my code.
Note:- I'm using partial view to display listbox when the button clicks. The current scenario is that it the listbox overwrites the first value when inserting second value.
StudentBatch.cs
public List<string> selectedids { get; set; }
public List<string> SelectedNames { get; set; }
Create.cshtml
<div class="form-group">
<div class="col-md-12">
#Html.EditorFor(model => model.StudentName, new { id = "StudentName" })
<input type="button" value="Add Text" id="addtypevalue" />
<div id="typevaluelist"></div>
</div>
</div>
<div id="new" style="display:none;">
<div class="typevalue">
<input type="text" name="typevalue" />
<button type="button" class="delete">Delete</button>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Add Students" class="btn btn-default" />
</div>
</div>
<script type="text/javascript">
$(document).ready(function () {
$("#StudentName").autocomplete({
//autocomplete: {
// delay: 0,
// minLength: 1,
source: function (request, response)
{
$.ajax({
url: "/Student/CreateStudent",
type: "POST",
dataType: "json",
data: { Prefix: request.term },
success: function(data) {
try {
response($.map(data,
function (item)
{
return { label: item.FirstName, value: item.FirstName };
}));
} catch (err) {
}
}
});
},
messages:
{
noResults: "jhh", results: "jhjh"
}
});
});
</script>
<script>
$('#addtypevalue').click(function () {
$(document).ready(function () {
var selValue = $('#StudentName').val();
$.ajax({
type: "GET",
url: '#Url.Action("GetListBox", "Student")',
dataType: "html",
data: { CourseId: selValue },
success: function (data) {
$("#partialDiv").html(data);
},
failure: function (data) {
alert('oops something went wrong');
}
});
});
});
</script>
GetListBox.cshtml
#model WebApplication1.Models.StudentBatch
#if (ViewBag.Value != null)
{
#Html.ListBoxFor(m => m.SelectedNames, new SelectList(Model.SelectedNames))
}
StudentController.cs
public PartialViewResult GetListBox(string CourseID)
{
Context.Student studCont = new Context.Student();
Models.StudentBatch student = new Models.StudentBatch();
student.SelectedNames = new List<string>();
student.SelectedNames.Add(CourseID);
ViewBag.Value = student;
return PartialView(student);
}

Refreshing Kendo UI viewModel

I have a very simply page at the moment. It has a first name input, last name input, and a list of names added. You can add your first and last name to the text box, press add. It adds it the peopleList I have and adds a new listItem with their name.
My issue is when I add to the peopleList in my code, it does not update the listView. I think I need to use observable, but I am not exactly sure how to do it. My list shows it has 25 items added to it after I click btnMany, which is how many it show have.
here is the body of my code:
<!--Load Some Data-->
<div id="peopleDefaultView"
data-role="view"
data-model="ViewModel"
data-layout="default">
<!--View-->
<input type="text" data-bind="value: firstName" id="fName" />
<input type="text" data-bind="value: lastName" id="lName" />
<a data-bind="click: addName" data-role="button" id="btnOne">Add</a>
<a data-bind="click: setValues" data-role="button" id="btnMany">Add Many</a>
<div style="margin-top: 10px">
People List:
<ul data-template="people-l-template" data-bind="source: peopleList" id="pList"></ul>
</div>
</div>
<!-- Kendo Template-->
<script id="people-l-template" type="text/x-kendo-template">
<li>
FirstName: <span data-bind="text: first"></span>
LastName: <span data-bind="text: last"></span>
<a data-bind="click: removeName" data-role="button" id="btnRemoveName">X</a>
</li>
</script>
And here is my script to go along with it
<script>
var ViewModel = {
firstName: '',
lastName: '',
peopleList: [],
addName: function (e) {
this.get("peopleList").push({
first: this.get("firstName"),
last: this.get("lastName"),
});
this.set("firstName", '');
this.set("lastName", '');
},
removeName: function (e) {
this.set("peopleList", jQuery.grep(this.peopleList, function (item, i) {
return (item.firstName != e.data.firstName && item.lastName != e.data.lastName);
}));
},
setValues: function (e) {
GetValueFromServer();
}
};
var GetValueFromServer = function () {
$.ajax({
type: "GET",
url: "GetPeopleService.svc/GetPersonById/",
data: {},
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
response.forEach(function (person) {
ViewModel["peopleList"].push({
first: person.firstName,
last: person.lastName
});
});
alert(ViewModel.peopleList.length);
},
error: function (response) {
console.log(response);
}
});
};
var application = new kendo.mobile.Application(document.body);
</script>
There were a few things wrong with the code you provided, the most notably being that you didn't set the role for your <ul> element. You need to change it to have the attribute data-role="listview". You also can't use an <li> element as the root element for a listview template (KendoUI automatically takes care of this for you), otherwise you'll get an error when the list is bound.
Here's an example on JS Bin.
And here's the code:
<!--Load Some Data-->
<div id="peopleDefaultView"
data-role="view"
data-model="viewModel"
data-layout="flat">
<!--View-->
<input type="text" data-bind="value: firstName" id="fName" />
<input type="text" data-bind="value: lastName" id="lName" />
<a data-bind="click: addName" data-role="button" id="btnOne">Add</a>
<div style="margin-top: 10px">
People List:
<ul id="pList"
data-role="listview"
data-template="people-l-template"
data-bind="source: peopleList">
</ul>
</div>
</div>
<!-- Kendo Template-->
<script id="people-l-template" type="text/x-kendo-template">
FirstName: <span>#:first#</span>
LastName: <span>#:last#</span>
<a id="btnRemoveName"
data-role="button"
data-bind="click: removeName"
data-first="#:first#" data-last="#:last#">
X
</a>
</script>
...
var viewModel = {
firstName: null,
lastName: null,
peopleList: [],
addName: function (e) {
var me = this;
me.get('peopleList').push({
first: me.get('firstName'),
last: me.get('lastName')
});
me.set('firstName', '');
me.set('lastName', '');
},
removeName: function (e) {
var me = this;
me.set('peopleList', $.grep(me.peopleList, function (item, i) {
return item.first != e.target.data('first')
&& item.last != e.target.data('last');
}));
}
};
var application = new kendo.mobile.Application(document.body);

Resources