I'm using Kendo UI Autocomplete with an ASMX Service which returns a string array like this :
<ArrayOfString>
<string>One string</string>
...
</ArrayOfString>
All works fine except that the items list opens twice. One click close one list and the "second behind" is still open.
When the list's opening we can see the second list opens behind the first.
Any idea ?
JS Code:
<input id="autoCompleteTest" />
<script>
var dataSource = new kendo.data.DataSource({
serverFiltering: true,
transport: {
read: {
data: {
startswith: function(){
return $("#autoCompleteTest").data("kendoAutoComplete").value();
}
},
url: "WebService.asmx/GetStrings",
type: "POST",
}
},
schema: {
// specify the the schema is XML
type: "xml",
// the XML element which represents a single data record
data: "/ArrayOfString/string",
// define the model - the object which will represent a single data record
model: {
// configure the fields of the object
fields: {
// the "title" field is mapped to the text of the "title" XML element
value: "text()"
}
}
}
});
$("#autoCompleteTest").kendoAutoComplete({
minLength: 3,
dataValueField : "value",
dataTextField : "value",
dataSource: dataSource
});
</script>
C# Code:
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public String[] GetStrings(string startswith)
{
using (var dataContext = new DataClassesDataContext())
{
var query = from x in dataContext.product where x.shortName.StartsWith(startswith) select x.shortName;
return query.ToArray();
}
}
I've run into a similar issue and posted here
Please confirm that your autocomplete control is not located inside of another control that forces the Kendo control to render a second time.
do you client code when dom is ready for kendo multiselect:
$(document).ready(function () {
..yourcode.});
see: http://docs.telerik.com/kendo-ui/controls/editors/multiselect/overview#accessing-an-existing-multiselect
Related
I noticed some weird behavior in all comboboxes in my application and after some time I noticed that the Kendo UI ComboBoxes are making or firing the change event two times and so they make two http requests if the code inside has one
I searched alot but found nothing to help
I use comboboxes with angularjs k-options (for general options) and k-on-change attribute for the change event handler
I tried to implement the combo box without angularjs attributes just as normal usage of the kendo ui combobox and it gave the same behavior
I didn't use alert for debugging this issue and used console.log for it
I used fiddler to watch for http requests and found that any change has two requests
I even tried and changed the requests to post and params to data but the same issue was found too
code sample:
html;
<select id="id" kendo-combo-box k-options="options" k-on-change="change(kendoEvent)" class="class" required></select>
code in 'script tag'
var app = angular.module('app', ['blockUI', 'kendo.directives']);
app.controller("controller",
function($scope, $http) {
$scope.GetAllData = function() {
$scope.comboDataSource = new kendo.data.DataSource({
data: #Html.Raw(Json.Encode(ViewBag.listFromC#)) // before loading view we're assigning the viewbag with alist of data
});
$scope.options = {
autoWidth: true,
filter: "contains",
ignoreCase: true,
placeholder: "Choose ...",
syncValueAndText: true,
dataTextField: "Name",
dataValueField: "Id",
dataSource: $scope.comboDataSource
};
}
}
$scope.change = function (kendoEvent) {
// kendoEvent.preventDefault(); // this line was added to test if it will prevent the second request or change event firing
console.log('change fired');
var cbAnother = $("#cbAnother").data("kendoComboBox"); // those two lines has no effect if removed
cbAnother.setDataSource([]);
if (!kendoEvent.sender.value()) { // this if statement has no effect if removed
return;
}
$http({
method: "get",
url: "#Url.Action("Action", "MVCControler", new {area = "Area"})",
params: { Id: kendoEvent.sender.value() }
}).then(function(response) {
var dataS = new kendo.data.DataSource({
data: response.data.ourData
});
$("#cbAnother").data("kendoComboBox").setDataSource(dataS);
},
function() {
....
}
);
};
rest of code ....
i'm pretty sure I'm ending all braces right
I found it was a bug so I rolled back to previous version and it went great.
I want to do Something like
$.ajax({
url: '/Home/AjaxTest',
data: {
id: #Model.Prop
},
type: 'post',
cache: false,
success: function (response) {
console.log(response);
}
...
However, It didn't work. I know that if I have a hidden field for it, like
#Html.HiddenFor(model => model.Id)
then I can get the property value by
data: { id: $('input[name="Id"]').val() },
Still I wonder. Are there any way else to access the Model property more directly?
data: { id: "#Model.Prop" } // may or may not need quotes depending on data type.
If you do this, it will be the value of the Model.Prop field at the time of rendering the page so any modifications to inputs using that property will not be reflected.
If you want the actual data from an input control that has been rendered using EditorFor, etc:
data: { #(Model.Prop.GetType().Name): $('input[name="#(ViewData.TemplateInfo.HtmlFieldPrefix + "." + Model.Prop.GetType().Name)"]').val() }
This will render the javascript using the property name as the json index and the same name but including the model (and any containing models) prefix as the name of the element to find the value of.
Yes you can do if you follow the Model pattern of java script.
This is your java script file.
var JSModel = (function(){
var model = {};
var init = function(){
//Perfome your operations
};
return {
init:init,
model :model //return beacuse we want to acccess it in cshtml
};
})();
$(document).ready(function() {
JSModel .init();
});
Now in cshtml, you will do this:
//Invlude your JS file here and then
<script>
JSModel.model = #Html.Raw(Json.Encode(Model)); // You will get the model in your js file. it will in JSON form
</script>
I am trying to do a look up with Ajax and a dropdown list, The user enters a postcode in a text box, then clicks search.
From here I want to populate a dropdown list, with the values coming from the database,
The action is in a separate controller :-
public ActionResult Search(string Pcode)
{
return Json(new[] {
new { value = '1', text = "text 1" },
new { value = '2', text = "text 2" },
new { value = '3', text = "text 3" }
});
}
My HTML:
Pcode:- #Html.TextBox("GPPOST")
GP Practice:
#Html.EditorFor(model => model.Patient.GPSurgery)
<br/>
#Html.DropDownListFor(m =>m.Patient.GPSurgery Enumerable.Empty<SelectListItem>(),"-- Select GP --")
GP : <input type="button" id="SearchPcode" value="Search">
And finally the Ajax:
$(function () {
$('#SearchPcode').click(function () {
// get the new value
var value = $(this).val();
// and send it as AJAX request to the action
$.ajax({
url: '/GP_Practices/Search', //'<%= Url.Action("Search", "GP_Practices") %>',
type: 'POST',
data: { pcode: value },
success: function (result) {
// when the AJAX succeeds refresh the dropdown list with
// The JSON values returned from the controller action
var GPNames = $('#Patient.GPSurgery');
GPNames.empty();
$.each(result, function(index, item) {
alert(item.text);
});
$.each(result, function (index, item) {
GPNames.append(
$('<option/>', {
value: item.value,
text: item.text
}));
});
}
});
});
});
When I run the code I do get the Json results back, (which I can see in the alert box).
My 2 problems are:
1)I cannot seem to pass the value from the text box Html.TextBox("GPPOST")
2)The Dropdown list is not refreshing with the new values.
1)I cannot seem to pass the value from the text box Html.TextBox("GPPOST")
That's because your Javascript passes pcode, yet your controller expects Pcode (casing matters).
Also as Ehsan Sajjad mentions, you're not sending the value of the textbox, but this unearths a bigger problem: You're binding two fields to the same model property, you can't do that. You'll have to use a separate field for your dropdown and your search input.
2)The Dropdown list is not refreshing with the new values.
That's because your jQuery selector is incorrect:
var GPNames = $('#Patient_GPSurgery');
I have five dropdownlists in form of html selects. The first binds at page load using jQuery, and the rest bind when the previous dropdown has been selected. I also have five hidden fields for each dropdown which stores the selected values.
My problem is that when I do a post back, i.e. click the "Search" button, I have to re-populate the dropdowns and select the correct values again by using the ID's in the hidden fields. So far, I've come up with no good way to do this.
In the .aspx page:
<select name="boxFunktionsnedsattning" id="boxFunktionsnedsattning" multiple="multiple </select>
<asp:TextBox ID="HiddenBoxFunktionsnedsattning" runat="server" />
<script type="text/javascript">
function boxFunktionsnedsattningPopulate() {
$.ajax({
type: "POST",
url: "Sok.aspx/getFunktionsnedsattningar",
data: {},
contentType: "application/json; charset=utf-8",
dataType: "json",
success: LoadBoxFunktionsnedsattning,
failure: function (response) {
alert(response);
}
});
}
//============================================================================================================
function LoadBoxFunktionsnedsattning(response) {
var result = response.d;
var options = $("#boxFunktionsnedsattning");
options.text(''); // clear the box content before reloading
if ($('#boxFunktionsnedsattning').val != '') {
options.removeAttr("disabled");
options.multipleSelect("enable");
}
else {
options.attr("disabled", true);
options.multipleSelect("disable");
}
$.each(result, function () {
options.append($("<option />").val(this.id).text(this.name));
});
UpdateBoxEnabledState();
options.multipleSelect("refresh");
}
</script>
Backend code:
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public static Funktionsnedsattning[] getFunktionsnedsattningar()
{
GetDataService.IgetDataClient gdc = new IgetDataClient();
return gdc.getFunktionsnedsattningAll();
}
I should add that I'm a beginner when it comes to jQuery, so there is probably something I've overlooked.
IF your using webforms use an onclick function to post back to the server instead of a submit. I think this is the functionality you want because the variables in the inputs of the form will keep its value. Is the search button returning results on the same page or a different one because it will determine the ease in which you can keep varibles during a post back. Good luck!
Got it working with the following solution:
function fillFunktionsnedsattning() {
//stores the value of selected items
var $fn = $('#<%=HiddenBoxFunktionsnedsattning.ClientID%>');
//creates an array of the values in the hidden field
var fnSplit = $fn.val().split(",");
//val() accepts an array which it uses to select items in the list (go figure)
$("#boxFunktionsnedsattning").val(fnSplit);
$("#boxFunktionsnedsattning").multipleSelect("refresh");
//function that triggers the binding of the next dropdown
boxFunktionsnedsattningOnChange();
}
For it to work, this function needs to be called in the function that populates the dropdown. Each dropdown needs it's own fillFunction to be called in the same place, like this, for an example:
function LoadBoxFunktionsnedsattning(response) {
var result = response.d;
var options = $("#boxFunktionsnedsattning");
options.text(''); // clear the box content before reloading
if ($('#boxFunktionsnedsattning').val != '') {
options.removeAttr("disabled");
options.multipleSelect("enable");
}
else {
options.attr("disabled", true);
options.multipleSelect("disable");
}
$.each(result, function () {
options.append($("<option />").val(this.id).text(this.name));
});
fillFunktionsnedsattning();
UpdateBoxEnabledState();
options.multipleSelect("refresh");
It's probably possible to simplify this, but this works for me.
I have the following code in an MVC controller:
public JsonResult ARequest()
{
Dictionary<string, object> AnObject = new Dictionary<string,object>();
AnObject["foo"] = new object[] {"item 1", "item 2", "item 3"};
return Json(AnObject, JsonRequestBehavior.AllowGet);
}
And it works as expected; when I call it from a browser, I get the following JSON object:
{"foo":["item 1","item 2","item 3"]}
I have another file, this time with a Kendo UI Autocomplete Widget. Here is the code:
<input id="products" style="width: 250px" />
/*...*/
$("#products").kendoAutoComplete({
filter: "contains",
minLength: 3,
dataTextField: foo,
dataSource: {
type: "odata",
pageSize: 10,
transport: {
read: {
url: "education-portal/ARequest"
}
}
}
});
As per the official examples here and here.
The problem is, when I load the page I don't get anything. The AutoComplete is blank and it stays blank. No results show up when I type anything in the box. Any idea what went wrong? I can't see it for the life of me.
There are several problems:
You should not define dataTextField since your array of value are not objects but strings.
You should say where in the received data is actually the array of items.
Is the type odata or JSON?
It should be something like:
$("#products").kendoAutoComplete({
filter: "contains",
minLength: 3,
dataSource: {
type: "json",
pageSize: 10,
transport: {
read: {
url: "education-portal/ARequest"
},
schema : {
data: "foo"
}
}
}
});
Example here : http://jsfiddle.net/OnaBai/rSjpS/
Since you are wrapping the collection inside a field called foo, you should specify this via the dataSource.schema.data options.
e.g.
dataSource: {
schema: {
data: "foo"
}
}
You do not have to specify any datavaluefield or datatextfield