in telerik extenstion to pass additional data to ajax request I used
function onDataBinding(e)
{
e.data = {argument : 4};
}
where e was div cointainer with data object inside,
How can I do this using kendo ? I tried the same but for Kendo e arqument is sth totally different.
Finally i got the answer my own and it is :
$('#grid').data('kendoGrid').dataSource.read({name:value})
Sorry for the terrible late at the party, but i've got some special cake that you may find tasty:
function readData()
{
return {
anagId: selectedItem.ID
};
}
$("#grid").kendoGrid({
dataSource: {
type: "ajax",
transport: {
read: {"url":"#Url.Action("RecordRead", "Tools")","data":readData}
}
[ rest of the grid configuration]
I came across this code by inspecting the code generated by Kendo Asp.Net MVC helpers.
I don't know if this is a further implementation that didn't exist at the age of the post, but this way looks really the most flexible compared to the other answers that i saw. HTH
Try this:
Add this to your grid read function or any CRUD operation:
.Read(read => read.Action("ReadCompanyService", "Admin").Data("CompanyServiceFilter"))
Add javascript:
function CompanyServiceFilter()
{
return {
company: $("#ServiceCompany").val()
}
}
In your controller:
public ActionResult ReadCompanyService([DataSourceRequest]DataSourceRequest request, string company)
{
var gridList = repository.GetCompanyServiceRateList(company);
return Json(gridList.ToDataSourceResult(request));
}
Please note, only string type data is allowed to be passed on read, create, update and delete operations.
If you want to pass some param to ajax request, you can use parameterMap configuration on your grid.
This will get passed on to your Ajax request.
parameterMap: function (options, operation) {
if (operation === "read") {
var selectedID = $("#SomeElement").val();
return {ID: selectedID }
}
return kendo.stringify(options.models) ;
}
Try this:
.Read(read => read.Action("Controller", "Action")
.Data(#<text>
function() {
return {
searchModel: DataFunctionName(),
userName: '#=UserName#'
}
}
</text>)
)
JS function
function DataFunctionName() {
var searchModel = {
Active: $("#activityMonitorIsActive").data('kendoDropDownList').value(),
Login: $("#activityMonitorUsers").data('kendoComboBox').value()
};
return searchModel;
}
Related
I'm trying to send data to my view from an AJAX call to my API. I am able to successfully hit my API and get data, but I was having problems with the view rendering before the AJAX call came back.
I'm trying to wrap my AJAX call in a Promise but it's not working. Here's my layout
Controller
.controller('DashCtrl', function($scope, Tweets) {
$scope.tweets = Tweets.all()
})
Factory doing ajax call
.factory('Tweets', function($http) {
$http.get('http://localhost:3000/tweets')
.success(function(data) {
var tweets = data
debugger
})
return {
all: function() {
//should return the results of the AJAX call when it's complete
}
}
});
I've tried making wrapping the ajax call into a function and using .then(function(payload){ return payload.data }) - Payload.data has my data but its never returned when I call the function. I'm new to angular, so I would appreciate any help or insight.
You should define your factory as
.factory('Tweets', function($http) {
return {
all: function() {
return $http.get('http://localhost:3000/tweets')
.then(function(response) {
return reponse.data;
})
}
}
});
Then change your controller to
.controller('DashCtrl', function($scope, Tweets) {
Tweets.all().then(function(data) {
$scope.tweets = data;
});
})
Use the $resource service. The docs don't mention it, but comments in the source do.
$resolved: true after first server interaction is completed (either with success or rejection), false before that.
So in the controller:
$scope.tweets = $resource('/tweets').query()
And in the view:
<div ng-if="tweets.$resolved">
Loading data with ngResource or from factory promise callback are viable options, but there's one more way nobody mentioned yet: resolve data to controller via route definition. This approach allows to write simplistic controllers that don't know how to load data at all. In most cases it will be more than enough if you don't need to load data dynamically, like pagination or infinite scroll.
You will need to define route and resolve function:
angular
.module('app', ['ngRoute'])
.config(function ($routeProvider) {
$routeProvider
.when('/', {
controller: 'ctrl',
controllerAs: 'view',
templateUrl: 'view.html',
resolve: {
tweets: function (Tweets) {
return Tweets.all();
}
}
})
})
The tweets property on resolve will inject loaded data into controller as tweets, all you have to do is just assign received data:
.controller('ctrl', function (tweets) {
this.tweets = tweets;
});
In addition, here's how Tweets service might look like:
.factory('Tweets', function ($timeout) {
function all () {
return $timeout(function () {
return ["hey", "there"];
});
}
return {
all: all
};
})
Basically, it exposes methods that return promise, returning some data ($timeout returns promise too, so I've used it instead of $http for example purpose).
Full example on JS Bin.
I'm using Ember 1.2.0 and the latest Ember Data Beta and wonder, how to handle server side errors (from API calls).
This question is quite similar, but it doesn't work.
At first, the becameInvalid method doesn't triggered. I'm using ember-validations (do I have to?)
My API sends an 422 status code and responses like that:
{"errors":{"name":["has already been taken"],"initial":["has already been taken"]}}
model.js
Docket.Customer = DS.Model.extend( Ember.Validations, {
name: DS.attr('string'),
initial: DS.attr('string'),
description: DS.attr('string'),
validations: {
name: {
presence: true
}
},
becameError: function() {
alert('there was an error!');
},
becameInvalid: function(errors) {
alert("Record was invalid because: " + errors);
}
});
controller.js
Docket.OrganizationCustomersController = Ember.ArrayController.extend({
actions: {
save: function () {
var customer = this.store.createRecord('customer');
customer.set('name', this.get('name'));
customer.set('initial', this.get('initial'));
customer.set('description', this.get('description'));
customer.save().then(function() {
console.log('jeah')
}, function() {
console.log('nooo')
});
}
}
});
The becameError method gets fired, but the becameInvalid method doesn't.
The second problem: even if the error is triggered, Ember.js adds the new record to the DOM. How can I prevent this behaviour?
Your errors json is ok, I think you are using the DS.RESTAdapter, and it doesn't implement the becameInvalid based in json with errors.
Just DS.ActiveModelAdapter have implemented in the moment, so I recommend you to change your adapter configuration to:
Docket.ApplicationAdapter = DS.ActiveModelAdapter;
In order to keep DS.RestAdapter, you can override its ajaxError method with the one from ActiveModelAdapter.
As for today the code, slightly adapted because some dependencies are needed, would be :
App.ApplicationAdapter = DS.RESTAdapter.extend({
// ... your own customizations,
ajaxError: function(jqXHR) {
var error = this._super(jqXHR);
if (jqXHR && jqXHR.status === 422) {
var response = Ember.$.parseJSON(jqXHR.responseText),
errors = {};
if (response.errors !== undefined) {
var jsonErrors = response.errors;
Ember.EnumerableUtils.forEach(Ember.keys(jsonErrors), function(key) {
errors[Ember.String.camelize(key)] = jsonErrors[key];
});
}
return new DS.InvalidError(errors);
} else {
return error;
}
}
});
Obviously you have a chance here to adapt to your backend specifics: HTTP code (422 is not a standard one) and format.
Source :
http://discuss.emberjs.com/t/how-to-handle-failure-to-save-on-server/3789
I created a custom validator that check if a username is used on a DB.
The whole process of validation works. What is not working is result.
function createExistingUsernameValidator() {
var name = 'existingUsernameValidator';
var ctx = { messageTemplate: 'Questa partita I.V.A. o codice fiscale sono già stati inseriti.', displayName: "Partita IVA o Codice Fiscale" };
var val = new Validator(name, valFunction, ctx);
return val;
function valFunction(value, context) {
var result = ko.observable(true);
require('services/datacontext').getIsUserByUsername(value, result)
.then(function () {
debugger;
return !result();
});
}
}
The promise works: I know because it hits the debbugger line and the retunrnig value is correct.
But the validator always evaluate as false because I'm not returning anything when the validator is called. In other words: it won't wait for the promise.
Is it my bad javascript or something else?
Any help is welcome.
Thank you!
Edited after answer
I've come to a solution that involves Knockout Validation (very useful script).
function createIsExistingUserKoValidation() {
ko.validation.rules['existingUsername'] = {
async: true,
validator: function (val, params, callback) {
if (val) {
var result = ko.observable();
require('services/datacontext').getIsUserByUsername(val, result)
.then(function () {
callback(!result());
});
}
},
message: ' Existing username.'
};
ko.validation.registerExtenders();
}
In the entity creation:
var createDitta = function () {
var ditta = manager.createEntity(entityNames.ditta,
{
id: newGuid(),
legaleRappresentante: createPersona(),
isAttiva: true
});
ditta.pivaCodFiscale.extend({ existingUsername: { message: ' Existing username.', params: true } });
ditta.pivaCodFiscale.isValidating(false);
return ditta;
};
ditta.pivaCodFiscale.isValidating(false); this is needed because isValidating is initialized with true.
The problem is that your valFunction as written will ALWAYS return 'undefined'. ( which is 'falsy'.
The 'return !result()' expression is NOT the return value of 'valFunction', it is simply the result of an anonymous function that executes AFTER valFunction has already returned. This is the async nature of promises.
What you are trying is to write an 'asynchronous' validation which is NOT supported out of the box with Breeze, but the idea IS a good one.
I think that you might be able to accomplish what you want by having your async callback actually 'set' a value on the entity and have that set operation itself trigger a seperate 'synchronous' validation.
This IS a good idea for Breeze to support more naturally so please feel free to add a feature request to the Breeze User Voice for something like "asynchonous validation". We use this to gauge the communities interest in the various proposed features/extensions to Breeze.
I am calling MVC action something like below:
var RestaurantDetailsUIforForeignWidget = {
frmId: '',
onFormSubmit: function () {
var frm = $(RestaurantDetailsUIforForeignWidget.frmId);
var divResult;
$('.offerbox').hide();
$.post(frm.attr('action'), frm.serialize(), function (html) {
// $('#section-time-slots').html(html)
$('#contentAll').html(html);
DisplayOffer();
});
return false;
},
updateTimeDesc: function () {
$('#time').val($('#SittingTime option:selected').html());
},
init: function (frmId) {
RestaurantDetailsUIforForeignWidget.frmId = frmId;
$('#SittingTime').bind('change', RestaurantDetailsUIforForeignWidget.updateTimeDesc);
$(frmId).bind('submit', RestaurantDetailsUIforForeignWidget.onFormSubmit);
RestaurantDetailsUIforForeignWidget.updateTimeDesc();
}
};
As you can see $('#contentAll').html(html); updates whole view content with the result. What I want is to get a single div from html output and update the $('#section-time-slots') instead.
Please help me guys... thanks :)
Try this:
$.post(frm.attr('action'), frm.serialize(), function (html) {
$('#section-time-slots').html($("#IdOfRequiredElementInResponse", html).html());
DisplayOffer();
});
I have been looking into Backbone.js lately and i am now trying to hook it up with my server-side asp.net mvc 3.
This is when i discovered a issue. ASP.NET listens to different Actions, Ex: POST /Users/Create and not just POST /users/. Because of that, the Model.Save() method in backbone.js will not work.
How should we tackle this problem? Do i have to rewrite the Backbone.Sync?
The answer is not to override Backbone.sync. You rarely would want to do this. Instead, you need only take advantage of the model's url property where you can assign a function which returns the url you want. For instance,
Forum = Backbone.Model.extend({
url: function() {
return this.isNew() ? '/Users/Create' : '/Users/' + this.get('id');
}
});
where the url used for a model varies based upon whether the model is new. If I read your question correctly, this is all you need to do.
You either have to tell ASP.NET MVC to route proper REST urls or fix Backbone.sync so it sends the GET/POST requests at the proper URLs.
Backbone works with REST not with RESTful URLs. There may be an OS implementation of Backbone.sync that matches your urls though.
Recommend URLs that play more nicely with Backbone:
GET /forums -> index
GET /forums/new -> new
POST /forums -> create
GET /forums/:forum -> show
GET /forums/:forum/edit -> edit
PUT /forums/:forum -> update
DELETE /forums/:forum -> destroy
I wrote a blog post recently describing how to bind .NET MVC to the default Backbone service layer.
Like previous posters have mentioned, there are a number of approaches you could take. I prefer this approach because it requires little configuration.
The controller:
public class ZocController : Controller
{
public ActionResult Docs()
{
return Json(GetDocs(), JsonRequestBehavior.AllowGet);
}
[ActionName("Docs")]
[HttpPost]
public ActionResult HandlePostDoc(Doctor doc)
{
doc.id = Guid.NewGuid();
CreateDoc(doc);
return Json(doc);
}
[ActionName("Docs")]
[HttpPut]
public ActionResult HandlePutDoc(Doctor doc)
{
UpdateDoc(doc);
return new EmptyResult();
}
[ActionName("Docs")]
[HttpDelete]
public ActionResult HandleDeleteDoc(Guid id)
{
DeleteDoc(id);
return new EmptyResult();
}
}
The Backbone
window.Doctor = Backbone.Model;
window.Doctors = Backbone.Collection.extend({
model: Doctor,
url: '/zoc/docs'
});
i found the following code in https://github.com/sgentile/BackboneContacts
/// <reference path="backbone.js" />
ModelBase = Backbone.Model.extend({
defaults: {
id: null
},
url: function (type) {
//expecting the following conventions on the server:
//urlRoot should be the controller : controller/
//create → POST /action
//read → GET /action[/id]
//update → PUT /action/id
//delete → DELETE /action/id
var fqUrl = this.urlRoot;
switch (type) {
case "POST":
fqUrl += "create";
break;
case "PUT":
fqUrl += "update";
break;
case "DELETE":
fqUrl += "delete/" + this.get('id');
break;
case "GET":
fqUrl += "read/" + this.get('id');
break;
}
return fqUrl;
}
});
var methodMap = {
'create': 'POST',
'update': 'PUT',
'delete': 'DELETE',
'read': 'GET'
};
// Helper function to get a URL from a Model or Collection as a property
// or as a function.
var getUrl = function (object) {
if (!(object && object.url)) return null;
return _.isFunction(object.url) ? object.url() : object.url;
};
// Throw an error when a URL is needed, and none is supplied.
var urlError = function () {
throw new Error('A "url" property or function must be specified');
};
Backbone.sync = function (method, model, options) {
var type = methodMap[method];
options.url = _.isString(this.url) ? this.url : this.url(type);
// Default JSON-request options.
var params = _.extend({
type: type,
dataType: 'json'
}, options);
// Ensure that we have a URL.
if (!params.url) {
params.url = getUrl(model) || urlError();
}
// Ensure that we have the appropriate request data.
if (!params.data && model && (method == 'create' || method == 'update')) {
params.contentType = 'application/json';
params.data = JSON.stringify(model.toJSON());
}
// For older servers, emulate JSON by encoding the request into an HTML-form.
if (Backbone.emulateJSON) {
params.contentType = 'application/x-www-form-urlencoded';
params.data = params.data ? { model: params.data} : {};
}
// For older servers, emulate HTTP by mimicking the HTTP method with `_method`
// And an `X-HTTP-Method-Override` header.
if (Backbone.emulateHTTP) {
if (type === 'PUT' || type === 'DELETE') {
if (Backbone.emulateJSON) params.data._method = type;
params.type = 'POST';
params.beforeSend = function (xhr) {
xhr.setRequestHeader('X-HTTP-Method-Override', type);
};
}
}
// Don't process data on a non-GET request.
if (params.type !== 'GET' && !Backbone.emulateJSON) {
params.processData = false;
}
// Make the request.
return $.ajax(params);
};