Kendo UI - Datasource. pass parameters to server using mvvm - kendo-ui

I'm having trouble using the datasource the right way.
My Goal: create external widget for filtering kendo grid (server side filter).
I managed to make it work, but it's kind of a workaround and I am looking for the corrent approach
The filterGrid function do all the work but it doesn't look right,
I want the parametermap function to do all the work but I can't figure it out.
Please advise.
this is how my view model looks like (I omitted the less important parts):
var viewModel = kendo.observable({
selectedInterface: null,
selectedStatus: null,
toHilanDate: new Date(),
updateDate: new Date(),
employeeId: null,
factoryId: null,
eventId:null,
employees: new kendo.data.DataSource({
transport: {
parameterMap: function (data, type) {
return { criteria: data };//for the mvc controller
},
read: {
url: "tohilan/Employees",
type: "post",
data: {}
}
}
}),
filterGrid: function () {
var data = {
SelectedInterface: this.selectedInterface ? this.selectedInterface.Id:null,
SelectedStatus: this.selectedStatus? this.selectedStatus.Key:null,
ToHilanDate: kendo.toString(kendo.parseDate(this.toHilanDate), "d"),
UpdateDate: kendo.toString(kendo.parseDate(this.updateDate), "d"),
EmployeeId: this.get("employeeId"),
FactoryId: this.get("factoryId"),
EventId: this.eventId,
};
//set new data into datasource
$('#employeeGrid').data('kendoGrid').dataSource.transport.options.read.data = data;
//refresh grid
$('#employeeGrid').data('kendoGrid').dataSource.read();
$('#employeeGrid').data('kendoGrid').refresh();
}
});
kendo.bind($("#employees-view"), viewModel);
My markup looks like this: (again, only the important part)
<ul>
<li>
<label for="employeeId">מספר עובד:</label>
<input type="number" id="employeeId" data-role="maskedtextbox" data-bind="value:employeeId"/>
</li>
<li>
<label for="eventId">מספר אירוע:</label>
<input type="number" id="eventId" data-role="maskedtextbox" data-bind="value:eventId"/>
</li>
<li>
<label for="factoryId">מספר מפעל:</label>
<input type="number" id="factoryId" data-role="maskedtextbox" data-bind="value:factoryId"/>
</li>
<li>
<label for="toHilanDate">תאריך העברה לחילן:</label>
<input type="date" id="toHilanDate" data-role="datepicker" data-bind="value:toHilanDate" />
</li>
<li>
<label for="updateDate">תאריך עדכון:</label>
<input type="date" id="updateDate" data-role="datepicker" data-bind="value:updateDate" />
</li>
<li>
<label for="event-status">סטטוס אירוע:</label>
<select id="event-status" data-role="dropdownlist" data-bind="value: selectedStatus, source: statusList" data-text-field="Value" data-value-field="Key" data-option-label=" "></select>
</li>
<li>
<label for="interface">ממשק:</label>
<select id="interface" data-role="dropdownlist" data-bind="value: selectedInterface, source: interfaceList" data-text-field="Description" data-value-field="Id" data-option-label=" "></select>
</li>
<li>
<button type="submit" data-role="button" data-bind="events: {click:filterGrid}">סנן</button>
</li>
</ul>

I guess I found an answer, maybe I had a typo or something.
I created the data object in the parametermap function instead of the filterGrid function. I just replaced "this" with viewModel. I still think that there is even better way to deal with it but at the moment it serve me just right.

Related

PHP doesnt read textarea content sended by ajax call

i'm dealing with this ajax call:
HTML:
A form has a textarea in which user can type some text
<div id="step-3">
<h2 class="StepTitle">Testo</h2>
<form id="text" class="form-horizontal form-label-left">
<div class="item form-group">
<label class="control-label col-md-3 col-sm-3 col-xs-12">Textarea <span class="required">*</span>
</label>
<div class="col-md-6 col-sm-6 col-xs-12">
<textarea id="textarea" name="testo" data-parsley-required="true" class="form-control col-md-7 col-xs-12"></textarea>
</div>
</div>
</form>
<ul id="error3_ul" class="list-unstyled">
<li id="error3_li"></li>
</ul>
</div>
JS:
This function is called by smartwizard. When user types some text and pushes button, an ajax call starts to do a server side check before to effectively insert text into db.
function onFinishCallback()
{
var data = $('#textarea').val();
$.ajax({
method: 'post',
data: data,
dataType: 'html',
url: "include/library/pull_sim.php",
success: function(result) {
successmessage = 'Data was succesfully captured';
$("#error3_li").text(result);
},
});
}
PHP:
Php receives the posted textarea value, check if a similar_text is already into db and if yes, it alerts that to user by the ajax call result.
if((!ISSET($_POST['testo'])))
$val='';
else
$val=$_POST['testo'];
$q_sim='select nciarfata from nciarf.nciarfata';
$s_sim=mysqli_query($conn,$q_sim);
$n_sim=mysqli_num_rows($s_sim);
if ($n_sim>0)
{
$simil=array();
for ($i=0;$i<$n_sim;$i++)
{
$rou=mysqli_fetch_row($s_sim);
similar_text($val, $rou[0], $percent);
if ($percent>=95.0)
{
array_push($simil,$rou[0]);
}
}
echo"val=$val, rou[0]=$rou[0], percent=$percent";
}
Question:
In my opinion something goes wrong in server side, probably in the 1st if.
Php doesnt recognized the posted value and then assign val="" instead of real text typed by user before..
Why?
Thanks for helping me.
I find the solution here:
Can't figure out why PHP not receiving POST data from $.ajax call
It wasn't a textarea issue but an ajax jquery one (data option).

How to submit checked input?

I am using vuejs v.2, In my data structure I have products and keywords
they have many-to-many relationship. To attach keywords to product I have list of keyword's checkbox and when user submit only checked keyword should be attach to product
<div class="col-md-6" v-for="keyword in keywords">
<div class="checkbox">
<label>
<input type="checkbox" />
{{ keyword.name }}
</label>
</div>
</div>
Here I can not bind keyword.id as value (v-bind:value).
I just want to submit checked keyword ids to server
Please show me the correct way
I think the mistake you might be doing is not using v-model with an array data variable, following is working code:
vue component:
var demo = new Vue({
el: '#demo',
data: function(){
return {
keywords: [
{name: 'key1', id: 1 },
{name: 'key2', id: 2 },
{name: 'key3', id: 3 }
],
checked: []
};
}
})
and in HTML:
<div id="demo">
<div class="checkbox">
<label v-for="keyword in keywords">
<input type="checkbox" :id="keyword.name" v-bind:value="keyword.id" v-model="checked"/>
{{ keyword.name }}
<br>
</label>
<br>
checked value: {{checked}}
</div>
</div>
Working fiddle here

Select2 clone is working only twice

I'm trying to clone a select2 list and 2 text areas, but it's working only for the first clone, and I don't understand why..any new eye will certainly help !
(the cloning is OK, but the select2 is not applied to the 3rd clone)
HTML part
<fieldset>
<div id="test">
<div>
<label>Tool Name : </label>
<select class="toollist" name="FSR_tool_id[]" style="width: 350px" />
<option></option>
<option value="1" >bla 1</option>
</select>
<input type="Button" value="ADD ANOTHER TOOL" class="AddTool">
<label>Service Scope</label>
<textarea rows="5" style="width:99%" name="FSR_servicescope[]" class="validate[required]" />
</textarea>
</br>
<label>Service Description</label>
<textarea rows="10" style="width:99%" name="FSR_servicedesc[]" class="validate[required]" />
</textarea><hr>
</div>
</div>
<input type="hidden" value="0" id="countertool">
</fieldset>
JS part (I call jquery and select 2 before, of course)
$('#test .toollist').select2({ //apply select2 to my element
placeholder: "Search your Tool",
allowClear: true
});
$("input[type='button'].AddTool").live('click',
function() {
var index = $(this).closest('div').index();
if (index > 0) {
$(this).closest('div').remove();
} else {
$('#test .toollist').select2('destroy');
//we have to destroy the select2 before cloning
var $div = $(this).closest('div').clone(true);
$div.find('input.AddTool').val("DELETE THIS TOOL");
//to replace the button "add" by another "delete"
var $input = $div.find('input.exp');
var index = $('input#countertool').val();
var id = 'exp' + index;
index++;
$('input#countertool').val(index);
$input.attr('id', id).data('index', index);
$(this).closest('#test').append($div);
//then, we re-apply select2 to the lists
$('#test .toollist').select2({
placeholder: "Search your tool !",
allowClear: true
});
};
});
Any idea of my mistake ?
Thanks a lot in advance !
See this fiddle: http://jsfiddle.net/omugbdm1/3/ it's a bit of a mashup of code but should do the trick.
<div id="test">
<div id="tooltest0" class="tooltest0">
<label>Tool Name :</label>
<select class="toollist" name="FSR_tool_id[]" id="FSR_tool_id0" style="width: 350px" />
<option></option>
<option value="1">bla 1</option>
</select>
</div>
<div id="tool-placeholder"></div>
<div>
<input type="button" value="Add another" />
</div>
</div>
and
$('.toollist').select2({ //apply select2 to my element
placeholder: "Search your Tool",
allowClear: true
});
$('input[type=button]').click(function () {
$('.toollist').select2("destroy");
var noOfDivs = $('.tooltest0').length;
var clonedDiv = $('.tooltest0').first().clone(true);
clonedDiv.insertBefore("#tool-placeholder");
clonedDiv.attr('id', 'tooltest' + noOfDivs);
$('.toollist').select2({ //apply select2 to my element
placeholder: "Search your Tool",
allowClear: true
});
});

Kendo Mobile - Submit Entire Form

I have a kendo mobile form that I will be using to capture some information from my users.
I would like to post the data to a web service or aspx(test page) using ajax. It seems like overkill to use MVVM for a form that the user fills out and there will be no reads/updates/deletes.
The ajax call happens but I cannot figure out how to post the data . Nothing goes over if i use $(this).serialize(). If I hard code some data, then it works.
There are going to be a lot of controls on the page and i hope i don't have to manually build the form data. I cannot add a <form> tag as it breaks the styling of the page.
If there is a more "kendo" way of doing this please show me how. Thanks
Here is what I have so far.
//Submit Form
function submit_form(e) {
$.post('TestPost.aspx', $(this).serialize(), function (data) {
// This is executed when the call to web service was succesful.
// 'data' contains the response from the request
alert(data);
}).error(function (xhr, ajaxOptions, thrownError, request, error) {
alert('xrs.status = ' + xhr.status + '\n' +
'thrown error = ' + thrownError + '\n' +
'xhr.statusText = ' + xhr.statusText + '\n' +
'request = ' + request + '\n' +
'error = ' + error);
});
e.preventDefault();
}
//Example of html controls
<div id="checks" data-role="view" data-title="Foo" data-layout="checklayout">
<ul data-role="listview" data-style="inset" data-type="group">
<li>Floor
<ul>
<li>
<label for="Foo">
<input type="radio" name="Foo" id="FooOk" value="Ok" />
Ok</label>
</li>
<li>
<label for="Foo2">
<input type="radio" name="Foo" id="FooNotOk" value="NotOk" />
Not Ok</label>
</li>
<li id="Comment1" class="divComment" style="display: none;">
<label>
Comments
<input type="text" name="TextComment" id="TextComment" placeholder="Type Comments" autocomplete="off" tabindex="1" />
</label>
</li>
<li id="C1" class="divComment" style="display: none;">
<label>
Charges
<select id="Charges" name="Charges" >
<option value="nc">test</option>
</select>
</label>
</li>
</ul>
</li>
</ul>
<ul data-role="listview" data-style="inset" data-type="group">
<li>Picture
<ul>
<li>
<label>
Select a Photo
<input type="file" id="kitFile" style="display: none;" />
<a data-role="button" data-click="select" style="float: right;">Select</a>
</label>
</li>
</ul>
</li>
</ul>
</div>
//Submit button
<a data-align="right" data-role="button" class="nav-button" data-click="submit_form">Save</a>
Here $(this) will give u only the button element. The easy way to do this is use the built in MVVM feature in Kendo UI Mobile. create an model as JS object and set data-model attribute of your view as this object. Now on click of the submit button, just send this object to your server using ajax. This way u are reducing the amount of data sent to the server.
Documentation on mobile and mVVM integration: http://docs.kendoui.com/getting-started/mobile/mvvm .
I have used a PageMethod previously.
http://encosia.com/using-jquery-to-directly-call-aspnet-ajax-page-methods/
Would something like this help your cause?
Let's take an example of such a method in the code behind:
[WebMethod]
public static string MyMethod(string Id)
{
return string.Format("Thanks for calling me with id: " + Id);
}
Things to note: the method must be static and decorated with the [WebMethod] attribute.
And on the client side you could invoke this method using the jQuery.ajax() function like this:
$.ajax({
url: 'default.aspx/MyMethod',
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({ ID : ID }),
success: function (result) {
alert(result.d);
}
});
Make sure that in your WebForm you have actually added reference to the jQuery library before using it.
For example:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js" type="text/javascript"></script>

What is the proper way to edit items in a listview when using Kendo UI Mobile & MVVM?

What is the proper way to edit items in a listview when using Kendo UI Mobile & MVVM?
I don't get the expected results when using the following:
HTML
<div id="itemsView"
data-role="view"
data-model="vm">
<ul data-role="listview" data-bind="source: items"
data-template="itemsTemplate">
</ul>
<script id="itemsTemplate" type="text/x-kendo-template">
<li>
#=Name#
</li>
</script>
<input type="text" data-bind="value: newValue" />
<button data-role="button" data-bind="click: update">update</button>
</div>​
JavaScript
var vm = kendo.observable({
items: [{
Name: "Item1"}],
newValue: '',
update: function(e) {
var item = this.get("items")[0];
item.set("Name", this.get("newValue"));
//adding the follwoing line makes it work as expected
kendo.bind($('#itemsView'), vm);
}
});
kendoApp = new kendo.mobile.Application(document.body, {
transition: "slide"});​
I expect the listview to reflect the change to the Name property of that item. Instead, a new item is added to the listview. Examining the array reveals that there is no additional item, and that the change was made. (re)Binding the view to the view-model updates the list to reflect the change. Re-Binding after a change like this doesn't seem to make any sense.
Here is the jsfiddle:
http://jsfiddle.net/5aCYp/2/
Not sure if I understand your question properly: but this is how I did something similar with Kendo Web UI, I expect mobile is not so different from Web UI from API perspective.
$element.kendoListView({
dataSource: list,
template: idt,
editTemplate: iet,
autoBind: true
});
The way I bind the listview is different, but I guess you can get similar results with your method as well.
I pass two templates to the list view, one for displaying and one for editing.
Display template contains a button (or any element) with css class k-edit to which kendo will automatically bind the listview edit action.
display template:
<div class="item">
# if (city) { #
#: city #<br />
# } #
# if (postCode) { #
#: postCode #<br />
# } #
<div class="btn">
<span class="k-icon k-edit"></span>Edit
<span class="k-icon k-delete"></span>Delete
</div>
</div>
Edit template
<div class="item editable">
<div>City</div>
<div>
<input type="text" data-bind="value: city" name="city" required="required" validationmessage="*" />
<span data-for="city" class="k-invalid-msg"></span>
</div>
<div>Post Code</div>
<div>
<input type="text" data-bind="value: postCode" name="postCode" required="required" validationmessage="*" />
<span data-for="postCode" class="k-invalid-msg"></span>
</div>
<div class="btn">
<span class="k-icon k-update"></span>Save
<span class="k-icon k-cancel"></span>Cancel
</div>
</div>
Clicking that element will put the current element on edit mode using the editTemplate.
Then on the editTemplate there is another button with k-update class, again to which kendo will automatically bind and call the save method on the data source.
Hopefully this will give you more ideas on how to solve your issue.
The problem was caused by the <li> in the template. The widget already supplies the <li> so the additional <li> messes up the rendering. This question was answered by Petyo in the kendo ui forums

Resources