kendo crud listview change model value after insert - kendo-ui

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.

Related

How to send other variable datas along with new FormData() inside AJAX?

Here I am sending the upload files into FormData() to be accessed in expressjs. And it is working perfectly.
$(".commonForm").submit(function (e) { //For Submitting the Uploaded Files
e.preventDefault();
if(validateForm($(this).attr('name'), text))
{
$.LoadingOverlay("show");
var formData = new FormData(this);
$.ajax({
type: "POST",
url: $(this).attr('action'),
data: formData,
processData: false,
contentType: false,
dataType: "json",
success: function(response){
if (response.status == '200') {
$.LoadingOverlay("hide");
swal({
title: "Excellent!",
text: "Files submitted successfully!",
icon: "success",
button: "Ok",
showCancelButton: true
}).then((result) => {
if (result) {
window.location.reload();
}
});
}
},
error: function (e) {
console.log("some error", e);
}
});
}
});
But along with that I want to send one another field data along with formData.
var text = 'Done';
How to send this along with formData in data ?
I am trying this:
data : {
formData:formData,
text:text
}
But then I don't think that I will be able to retrieve the uploaded files data directly with req.files
UPDATE:
route code/expressjs
router.post('/api/upload/:cid',function(req,res,next){
console.log("req.body.text = " + req.body.text + req.query.text);
upload2(req,res,function(err) {
if(err) {
console.log("Error is important = "+ err);
}
else
{
console.log("Uploaded successfully.");
}
})
})
MULTER CODE:
var upload2 = multer({storage: storage2, limits: { fileSize: 1024 * 1024 * 1 }}).array('FileUploadForClient',4);
HTML HANDLEBAR FORM CODE:
<form name="{{this.status}}" class="commonForm" enctype="application/x-www-form-urlencoded" action="/api/upload/{{this.commonID}}" method="post">
<td class="col-sm-2">
<div class="center">
<select name="sourcesSelect" id="{{this.commonID}}" data-notUse="{{this._id}}" data-Id4AddtasksBigpaths="{{this.Id4AddtasksBigpaths}}" class="custom-select sources" placeholder="{{this.status}}" style="font-size:20px; background: {{this.background}}; color: white;" {{this.statusDisabled}}>
<option value="0" >In Progress</option>
<option value="1" >Done</option>
<option value="2" >Rejected</option>
</select>
</div>
</td>
<!-- <td class="col-sm-2"><span id="deadline" style="font-size:14px"><input type="text" class="form-control" value="{{this.deadline}}" readonly/></span></td> -->
<td class="col-sm-1">
<!-- <input type="file" class="btn btn-light" name="FileUploadForClient" multiple required/> -->
<input type="file" id="{{this._id}}" class="form-control" name="FileUploadForClient" multiple required {{this.statusDisabled}} />
</td>
<td>
<button type="submit" class="btn btn-primary btn-block col-sm-2" style="font-size:16px" {{this.statusDisabled}}>Submit</button>
</td>
</form>
Use the method append to add another parameter to the request
var formData = new FormData(this);
formData.append('text', 'text to send in the request ');

Ajax request for delete image doesnt work in laravel

I want to delete the image in the preview box, as well as delete it in the database using ajax. Deleting the image in the preview box was successful, but deleting it from the database didn't work.
here my ajax:
$(document).ready(function() {
document.getElementById('pro-image').addEventListener('change', readImage, false);
$(".preview-images-zone").sortable();
$(document).on('click', '.image-cancel', function() {
let no = $(this).data('no');
let idData = $(this).data('id');
$(".preview-image.preview-show-" + no).remove();
$.ajax({
type: 'POST',
url: '{{url("unit/API/simpan")}}',
data: {
'id': idData
},
success: function(data) {
alert('success');
}
});
});
});
My Html:
<!-- Percobaan Preview -->
<fieldset class="form-group">
<div class="offset-md-2 col-md-6">
Upload Gambar
<input type="file" id="pro-image" name="gambarku[]" style="display: none;" class="form-control" multiple>
</div>
</fieldset>
<div class="preview-images-zone offset-md-2 col-md-8">
<!-- Gambar Utama -->
<div class="preview-image preview-show-1">
<div class="image-cancel" data-no="1">x</div>
<div class="image-zone"><img id="pro-img-1" src="{{asset('storage/rumah/'.$rumahku->gambar_rumah)}}"></div>
</div>
<!-- Gambar Tambahan -->
<?php $counter = 2 ?>
#foreach($rumahku->gambar as $rows)
<div class="preview-image preview-show-{{$counter}}">
<div class="image-cancel" data-no="{{$counter}}" data-id="{{$rows->id_gambar}}">x</div>
<div class="image-zone"><img id="pro-img-{{$counter}}" src="{{asset('storage/rumah/'.$rows->gambar_unit)}}"></div>
</div>
<?php $counter++ ?>
#endforeach
</div>
<!-- /preview -->
my route
Route::post('unit/API/simpan/{id}', 'partner\UnitController#simpanGambar');
my controller
public function simpanGambar($id)
{
$gambar = Gambar::find($id);
$gambar->delete();
}
you can try this
Route::post('unit/API/simpan', 'partner\UnitController#simpanGambar');
and
public function simpanGambar(Request $request)
{
$gambar = Gambar::find($request->id);
$gambar->delete();
}
or in ajax
$.ajax({
type: 'POST',
url: '{{url("unit/API/simpan")}}' +'/'+ id, <---------- pass id here

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);

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

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!

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

Resources