Kendo UI: Update transport doesn't trigger after calling datasource sync - ajax

Im struggling on this in hours now, I cant find a good documentation on how to implement simple ajax UPDATE on server using forms and Kendo MVVVM and datasource.
KENDO MVVM
$(function() {
var apiUrl = "http://a31262cd2f034ab8bcda22968021f3b8.cloudapp.net/api",
meetingDatasource = new kendo.data.DataSource({
transport: {
read: {
url: apiUrl + "/meetings/4",
dataType: "jsonp"
},
update: {
type: "PUT",
url: apiUrl + "/meetings",
contentType: "application/json; charset=utf-8",
dataType: 'json',
},
parameterMap: function(options, operation) {
return kendo.stringify(options);
}
},
batch: true,
change: function() {
},
schema: {
model: {
id: "Id",
fields: {
Title: { editable: true },
StartTime: { type: "date" },
EndTime: { type: "date" }
}
}
}
});
meetingDatasource.fetch(function () {
var viewModel = kendo.observable({
description: result.Description,
title: result.Title,
venue: result.Location,
startDate: result.StartTime,
endDate: result.EndTime,
saveChanges: function (e) {
//im not sure with this line
this.set("Title", this.Title);
meetingDatasource.sync();
e.preventDefault();
}
});
kendo.bind($("#view"), viewModel);
});
});
THE UI
<ul class="forms" id="ul-meeting">
<li>
<label for="title" >Title:</label>
<input data-bind="value: title" class="k-textbox" style="width:350px;"/>
</li>
<li>
<label for="description" >Description:</label>
<textarea data-bind="value: description" id="description" rows="6" cols="80" class="k-textbox" style="width:350px;"></textarea>
</li>
<li>
<label for="location">Venue:</label>
<textarea data-bind="value: venue" id="location" rows="4" cols="80" class="k-textbox" style="width:350px;"></textarea>
</li>
<li>
<p>
<label for="start-datetime">Start:</label>
<input data-bind="value: startDate" id="start-datetime" style="width:200px;" />
</p>
<p>
<label for="end-datetime">Finish:</label>
<input data-bind="value: endDate" id="end-datetime" style="width:200px;" />
</p>
</li>
</ul>
The problem is, the TRANSPORT READ triggers but the TRANSPORT UPDATE never triggers even if I explicity call the Datasource.sync(). Is is something I am missing here?

Your code is not complete (you are not showing what is result or how you trigger saveChanges but from what I see the problem is that you are not updating the content of the DataSource (meetingDataSource).
In your code that you copy the fields from result into and ObservableObject but you never update the content of the DataSource. When you do this.set, in that context this is not the DataSource so when you call sync you are doing nothing.
Try doing:
meetingDatasource.data()[0].set(`Title`, this.Title);
meetingDatasource.sync();
This should do the trick!

Related

Get value of submit button from Ajax call

The value of the submit buttons are always null in the Action.
What do I need to change to know which submit button has been clicked?
<form id="actionInvitation">
<div>
<ul>
<li>
#Model.TeamInviteBy
</li>
</ul>
</div>
<input type="submit" name="actionBtn" id="acceptBtn" value="Accept Invitation" />
<input type="submit" name="actionBtn" id="declineBtn" value="Decline Invitation" />
</form>
$('#actionInvitation').submit(function (e) {
e.preventDefault();
var formData = new FormData($('#actionInvitation')[0]);
$.ajax({
url: '#Url.Action("ActionInvitation", "Home")',
type: 'post',
cache: false,
processData: false,
contentType: false,
data: formData,
success: function (data) {
$("#invitationActionMessage").append('Invitation Accepted');
}
});
});
//Action
public async Task<IActionResult> ActionInvitation(UserViewModel userViewModel, string acceptBtn, string declineBtn)
Your formData will not contain the objects you need to pass.
You can change your code like below:
<form id="actionInvitation">
<div>
<ul>
<li>
#Model.TeamInviteBy
<input type="hidden" name="TeamInviteBy" value="#Model.TeamInviteBy">
</li>
</ul>
</div>
<input type="submit" name="actionBtn" onclick="Send(event,this)" value="Accept Invitation" />
<input type="submit" name="actionBtn" onclick="Send(event,this)" value="Decline Invitation" />
</form>
#section scripts{
<script>
function Send(ev,el) {
ev.preventDefault();
var data = $("input[name='TeamInviteBy']").val();
var value = $(el).val();
$.ajax({
url: '#Url.Action("ActionInvitation", "Home")',
type: 'post',
contentType: "application/x-www-form-urlencoded; charset=utf-8",
data: { TeamInviteBy: data, actionBtn: value},
success: function (data) {
$("#invitationActionMessage").append('Invitation Accepted');
}
});
}
</script>
}
Action:
public async Task<IActionResult> ActionInvitation( UserViewModel userViewModel , string actionBtn)
{
if(actionBtn="Accept Invitation")
{
//...
}
else
{
}
}
Result:

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

Two-way bindings with Kendo MVVM from remote data source

I want to bind JSON that I fetch from a remote source to elements on a page. I was hoping to use the Kendo DataSource to manage the transport and use MVVM to display and update the data.
I need help as I cannot work out how to display the remote data:
http://jsfiddle.net/digory/zxoLpej9/
Here is my JS:
$(function(){
var dataSource = new kendo.data.DataSource({
transport: {
read: {
//using jsfiddle echo service to simulate JSON endpoint
url: "/echo/json/",
dataType: "json",
type: "POST",
data: {
json: JSON.stringify({
"ItemA": "A",
"ItemB": "B"
})
}
}
},
schema: {
model: {
fields: {
ItemA: { type: "string" },
ItemB: { type: "string" }
}
}
}
});
var vm = kendo.observable({
source: dataSource,
foo: 42,
change: function(e) {
console.log("Changed!");
},
save: function() {
console.log("Saved!");
}
});
kendo.bind($("#my-container"), vm);
vm.source.read();
});
And here is the UI display code that I am trying to use to render the data:
<div id="my-container">
<div>
<label for="ItemA">Item A</span>
<input id="ItemA" data-bind="value: source.data.ItemA, events: { change: change }" />
</div>
<div>
<label for="ItemB">Item B</span>
<input id="ItemB" data-bind="value: source.data.ItemB, events: { change: change }" />
</div>
<div>
<label for="Foo">Foo</span>
<input id="Foo" data-bind="value: foo, events: { change: change }" />
</div>
<div>
<button data-bind="click: save, enabled: hasChanges" class="k-button k-primary">Save</button>
</div>
</div>
I've been playing around a bit more and think I might have found a suitable approach.
The key finding was to set the data in the view model from within the dataSource's change function:
http://jsfiddle.net/digory/yyunxgcw/
change: function() {
var view = this.view()[0];
vm.set("data", view);
},
I'm sure it can be more elegant, but it seems to be working!

KendoUI: MVVM Autocomplete Events

I was searching all over but couldn't find an answer to my question. I'm initializing an autocomplete widget as the following:
This code is loaded into my DOM as a result of an Ajax request:
<div id="view_ticketCreate">
<form id="jar_ticketing_create"action="" class="k-block jar-container">
<fieldset class="login">
<legend>Kontaktinformationen</legend>
<p class="notice">Definieren Sie hier die Kontaktinformationen zu diesem Ticket.</p>
<p>
<label>Kunde</label>
<input data-role="autocomplete" data-bind="source: customers, events{click: inject}" data-text-field="CName" placeholder="Suchen Sie nach dem Kunde" type="text" id="jtc_cID" class="k-textbox sourced">
</p>
<p>
<label>Kontakt</label>
<input type="text" name="jtc_cName" class="k-textbox">
</p>
<p>
<label>E-Mail</label>
<input data-bind="value: cMail" type="text" name="jtc_cMail" class="k-textbox">
</p>
<p>
<label>Telefon</label>
<input data-bind="value: cPhone" type="text" name="jtc_cPhone" class="k-textbox">
</p>
<p>
<label>Gerät</label>
<select name="dID" class="k-textbox sourced">
<option value="000">Nicht geräte spezifisch</option>
<option value="001">CFBS01</option>
<option value="002">CFBS02</option>
<option value="003">CFBS03</option>
<option value="004">CFBS04</option>
</select>
</p>
<p>
<label>Login</label>
<input type="text" name="cLogin" class="k-textbox">
</p>
</fieldset>
</form>
</div>
<script>
kendo.bind($("#view_ticketCreate"), view_ticketCreate);
</script>
in my main (an always loaded) JS file i got:
var view_ticketCreate = kendo.observable({
customers: new kendo.data.DataSource({
transport: {
read: {
url: "http://server/API/customers/search/",
dataType: "jsonp",
contentType: "application/json; charset=utf-8"
},
parameterMap: function(options, operation) {
return {
SearchTag: options.filter.filters[0].value
}
}
},
schema: {
data: "data"
},
serverFiltering: true,
dataTextField: "CName",
select: function(e){
if (e.item == null) return;
var DataItem = this.dataItem(e.item.index())
cPhone: DataItem.Telefon
}
}),
inject: function(e){
alert('ok')
},
cPhone: "0123456789",
cMail: "asd#asd.de"
});
However, the autocomplete search works perfect. But now I want to populate the fields jtc_cMail and jtc_cPhone with values from my autocomplete request. But either the select: Function is working (not allowed here (guess because MVVM?), also the custom event inject is fireing.
I couldn't find anything how I need to go on. Please help me out.
Greetings
Just have to use e.sender.dataItem function and pass in the index of the item selected.
selectPerson: function(e) {
var item = e.sender.dataItem(e.item.index());
viewModel.set("selectedPerson", item);
}
See jsbin http://jsbin.com/iLaK/3/edit

kendo crud listview change model value after insert

Here is my code.
$(document).ready(function() {
var kendoWindow_room = $("#window_room");
kendoWindow_room.hide();
$("#roombut").on(
'click',
function()
{
home_id = $("#home_id").val();
if (home_id) {
kendoWindow_room.data("kendoWindow").open();
$('.k-window').css({'marginLeft': -$('.k-window').width() / 2});
dataSource.read();
$("#room_listview_pager .k-link:first").hide();
$("#room_listview_pager .k-link:last").hide();
$("#room_listview_pager a.k-link").each(function(index) {
$(this).addClass("pager_new_icons");
$(this).addClass("mortgage");
});
}
}
);
home_datasource = new kendo.data.DataSource({
transport: {
read: {
url: "<?php echo BASE_URL . 'user/get_edit_home_name' ?>",
dataType: "json"
}
}
});
room_datasource = new kendo.data.DataSource({
transport: {
read: {
url: "<?php echo BASE_URL . 'common/get_dropdown_entries' ?>",
dataType: "json",
data: {thisisfor: "floortype"}
}
}
});
var crudServiceBaseUrl = "<?php echo BASE_URL . 'user/room_crud_listview_' ?>",
dataSource = new kendo.data.DataSource({
transport: {
read: {
url: function() {
return crudServiceBaseUrl + "read?home_id=" + $("#home_id").val()
},
dataType: "json",
contentType: "application/json"
},
update: {
url: crudServiceBaseUrl + "update",
dataType: "json",
type: "POST"
},
destroy: {
url: crudServiceBaseUrl + "destroy",
dataType: "json",
type: "POST"
},
create: {
url: crudServiceBaseUrl + "create",
dataType: "json",
type: "POST"
}
},
batch: true,
pageSize: 1,
schema: {
model: {
id: "id",
fields: {
rd_home_id: "rd_home_id",
homename: "homename",
nickname: "nickname",
type: "type",
wallcolor: "wallcolor",
trimcolor: "trimcolor",
floorcolor: "floorcolor",
floortype: "floortype",
windows: "windows"
}
}
}
});
$("#room_listview_pager").kendoPager({
dataSource: dataSource,
info: false,
numeric: false
});
var room_listview = $("#room_listview").kendoListView({
dataSource: dataSource,
template: kendo.template($("#room_listview_template").html()),
editTemplate: kendo.template($("#room_editview_template").html())
}).data("kendoListView");
// Add Row
$("#room_add_row").on("click", function(event) {
event.preventDefault();
room_listview.add();
});
// Delete Row
$("#room_delete_row").on("click", function(event) {
event.preventDefault();
room_listview.remove(room_listview.element.children().first());
if (dataSource.total() < 1) {
room_listview.add();
} else {
dataSource.read();
}
});
// edit row
$("#room_edit_row").on("click", function(event) {
event.preventDefault();
room_listview.edit(room_listview.element.children().first());
});
// save row
$("#room_save_row").on("click", function(event) {
event.preventDefault();
room_listview.save();
});
if (!kendoWindow_room.data("kendoWindow")) {
kendoWindow_room.kendoWindow({
width: "520px",
title: "Room Designer"
});
}
});
<div style="background-color: #FFFFFF; border: 0; max-width: 90px; float: left;" id="room_listview_pager"></div>
<span style="float: right; margin-top: 4px;">
<a id="room_add_row" class="k-add" href="#"><img src="<?php echo STATIC_DIR; ?>images/icon7.png" alt="" height="36" width="37"></a>
<a id="room_delete_row" class="k-delete" href="#"><img src="<?php echo STATIC_DIR; ?>images/icon8.png" alt="" height="36" width="37"></a>
<a id="room_edit_row" class="k-edit" href="#"><img src="<?php echo STATIC_DIR; ?>images/icon9.png" alt="" height="36" width="37"></a>
<a id="room_save_row" class="k-insert" href="#"><img src="<?php echo STATIC_DIR; ?>images/icon10.png" alt="" height="36" width="37"></a>
</span><div class="clear"></div>
This is the kendo template with id - "room_listview_template"
<div class="product-view k-widget">
<dl>
<dt>Home</dt>
<dd>#:homename#</dd>
<dt>Nickname</dt>
<dd>#:nickname#</dd>
<dt>Type</dt>
<dd>#:type#</dd>
<dt>Wall Color</dt>
<dd>#:wallcolor#</dd>
<dt>Trim Color</dt>
<dd>#:trimcolor#</dd>
<dt>Floor Color</dt>
<dd>#:floorcolor#</dd>
<dt>Floor Type</dt>
<dd>#:floortype#</dd>
<dt>Windows</dt>
<dd>#:windows#</dd>
</dl>
</div>
This is the kendo template with id - "room_editview_template"
<div class="product-view k-widget">
<dl>
<dt>Home</dt>
<dd>
<select id="home"
data-role="dropdownlist"
data-text-field="nickname"
data-value-field="id"
data-source="home_datasource"
data-bind="value:rd_home_id"
name="rd_home_id"
required="required"
validationMessage="required">
</select>
<span data-for="rd_home_id" class="k-invalid-msg"></span>
</dd>
<dt>Nickname</dt>
<dd>
<input type="text" class="k-textbox" data-bind="value:nickname" name="nickname" required="required" validationMessage="required" />
<span data-for="nickname" class="k-invalid-msg"></span>
</dd>
<dt>Type</dt>
<dd>
<input type="text" class="k-textbox" data-bind="value:type" name="type" required="required" min="1" validationMessage="required" />
<span data-for="type" class="k-invalid-msg"></span>
</dd>
<dt>Wall Color</dt>
<dd>
<input type="text" class="k-textbox" data-bind="value:wallcolor" name="wallcolor" required="required" validationMessage="required" />
<span data-for="wallcolor" class="k-invalid-msg"></span>
</dd>
<dt>Trim Color</dt>
<dd>
<input type="text" class="k-textbox" data-bind="value:trimcolor" name="trimcolor" required="required" validationMessage="required" />
<span data-for="trimcolor" class="k-invalid-msg"></span>
</dd>
<dt>Floor Color</dt>
<dd>
<input type="text" class="k-textbox" data-bind="value:floorcolor" name="floorcolor" required="required" validationMessage="required" />
<span data-for="floorcolor" class="k-invalid-msg"></span>
</dd>
<dt>Floor Type</dt>
<dd>
<select
data-role="dropdownlist"
data-text-field="name"
data-value-field="value"
data-source="room_datasource"
data-bind="value:floortype"
name="floortype"
required="required"
validationMessage="required">
</select>
<span data-for="floortype" class="k-invalid-msg"></span>
</dd>
<dt>Windows</dt>
<dd>
<input type="text" class="k-textbox" data-bind="value:windows" name="windows" required="required" validationMessage="required" />
<span data-for="windows" class="k-invalid-msg"></span>
</dd>
</dl>
</div>
I have a listview inside a kendowindow with options to create, read, update and delete.
It uses one template to list the records and another template to edit.
In the fields, I have a dropdown list, with the field name "rd_home_id" its data-text-field and data-value-field are different. It displays home name in as the option and each option has its integer value.
The insert, and update is working fine, I get the integer value in the server side.
While reading, obviously I would like to display the home name - so, I have the field name "homename" - and from the server, I pass this value and I am able to see it in the listing template - which works perfectly fine.
The only problem remaining is - after I insert a record, the "homename" is not showing up - its null - all the other values are showing up and is correct.
How could I show the value "homename" right after the insert?
I know I can call the call the read function of the datasource in the room_save_row's onclick right after calling the save function of the listview - which would fix the issue, but doing that would make the validation not work.
Is there any way to change the value of the fields which is rendered in the template?
Thank you
Just solved the problem
If the inserted record is sent as a response from the server ( from the create URL ) - it would get updated - and the value would be reflected in the listing template - before I was not sending anything from the server. that was the problem.

Resources