How to use URLs like '/update/:id' as KendoUI datasource? - rest

I read the documentation but found nothing related to setting parameters in dataSource urls. Is it possible to achieve that?
Thx in advance.

Yes, it is possible. The urls defined in the DataSource.transport might be a function. This function receives (for update) as first argument the data being updated (the model) and returns the string that should be used as URL.
Composing the URL for what you want to do is:
var ds = new kendo.data.DataSource({
transport: {
read: {
url: function () {
return 'read';
}
},
update: {
url : function (item) {
return 'update/' + item.id;
}
}
}
});

The answer seems to be vague on 'item.'
Just note that 'item' is an object. In fact anything passed in to read has to be an object, that's what Kendo expects. If you pass anything else into read, like a string, it will convert it into an object which isn't what you want. So, the solution is as follows:
_viewModel: kendo.observable({
items: new kendo.data.DataSource({
transport: {
read: {
url: function (args) {
var urlParm = '?take=' + 1 + '&skip=0&page=1&pageSize=' + 1;
return CGI_ISD._base + 'api/executionsummary/executiondetails/' + args.msgId + urlParm;
},
dataType: "json"
},
},
schema: {
data: function (response) {
return response.AggregateData.Data;
}
}
}),
}),
_reload: function (msgId) {
this._viewModel.items.read({msgId: msgId});
}

Short answer:
Nope.
Long answer:
Parameters are passed either inline with the url parameter of the transport object...
var id = 'abc123';
var ds = new kendo.data.DataSource({
transport: {
read: {
url: 'api/employees?id=' + id
}
}
});
...or they are passed in the data parameter of the transport object.
var id = 'abc123';
var ds = new kendo.data.DataSource({
transport: {
read: {
url: 'api/employees',
data: {
id: id;
}
}
}
});
or
var id = 'abc123';
var ds = new kendo.data.DataSource({
transport: {
read: {
url: 'api/employees',
data: function () {
return { id : id };
}
}
}
});

Related

I18Next TFunction translation not working in EJS template render

I have method that renders EJS templates and pass in the i18next.t function for the EJS template to do translations by setting the i18next t function as an attribute on the data object:
const data = {
email: user.email,
id: user.id,
t: i18nT
};
The data object is passed into ejs.renderFile(). The only way I can get the translation in the EJS template to work is when I set the i18nT variable to the t function from the i18next.init() functions call back. Otherwise it comes out blank. I see from the console output that the t function of the i18next instance, i18nInstance, is different to the t function set by the callback when initializing i18next.
function t() {
var _this$translator;
return this.translator && (_this$translator =
this.translator).translate.apply(_this$translator, arguments);
}
versus:
function () {
return _this4.t.apply(_this4, arguments);
}
Why is the t function of the i18nInstance object obtained from calling i18next.createInstance() different than the one from the callback? The one from the instance object doesn not work in the EJS template render.
The full code sample:
let i18nInstance: i18n;
let i18nT;
const i18nextInitOptions = {
backend: {
loadPath: path.join(__dirname, '/locales/{{lng}}/{{ns}}.json'),
addPath: path.join(__dirname, '/locales/{{lng}}/{{ns}}.missing.json')
},
debug: true,
fallbackLng: 'da',
preload: ['da', 'en', 'nl'],
returnEmptyString: false,
returnNull: false,
saveMissing: true
};
i18nInstance = await i18next
.createInstance();
await i18nInstance
.use(i18nextBackend)
.init(i18nextInitOptions, async function (error, t) {
if (error) {
console.log(error)
}
i18nT = t;
});
console.log("i18nT: " + i18nT)
/*
The console.log outputs below show that i18nT when set from the callback is different to the
i18nInstance.t.
i18nT: function () {
return _this4.t.apply(_this4, arguments);
}
*/
console.log("i18nInstance.t: " + i18nInstance.t)
/*
console output:
i18nInstance.t: function t() {
var _this$translator;
return this.translator && (_this$translator =
this.translator).translate.apply(_this$translator, arguments);
}
*/
const data1 = {
email: user.email,
id: user.id,
t: i18nT
};
// Calling htmlFromTemplate with data1 with t = i18nT the translation in the EJS template works.
html = await this.htmlFromTemplate('ejsTemplateName.ejs', data1);
const data2 = {
email: user.email,
id: user.id,
t: i18nextInstance.t
};
// Calling htmlFromTemplate with data2 with t = i18nextInstance.t the translation in the EJS is empty.
html = await this.htmlFromTemplate('ejsTemplateName.ejs', data2);
private htmlFromTemplate(templateName: string, data: Object): Promise<String> {
if (!templateName) return;
const htmlPath = path.join(__dirname, '../assets/mail-templates/' + templateName);
return new Promise((resolve, reject) => {
ejs.renderFile(htmlPath, data,(renderErr, str) => {
if (renderErr) {
appLogger.error('MAIL_RENDER: ' + renderErr, { templateName, data });
reject(renderErr);
} else resolve(str);
});
});
}
As soon as you pass the t function like this:
const data2 = {
email: user.email,
id: user.id,
t: i18nextInstance.t
};
the t function is not bound to its original "this" anymore...
pass it this way:
const data2 = {
email: user.email,
id: user.id,
t: i18nextInstance.t.bind(i18nextInstance)
};
more information here: https://github.com/i18next/i18next/issues/1528#issuecomment-748263313

Autopopulate field in suitecrm

I have this ajax call that populate the fields to a related field.
YAHOO.util.Event.onDOMReady(function() {
YAHOO.util.Event.addListener(
"parent_module_another_module_ida",
"change",
ajaxReq
);
function ajaxReq() {
var propertyId = $("#parent_module_another_module_ida").val();
if (propertyId != "") {
$.ajax({
url: "/?entryPoint=ajaxEntryPoint&module=Parent_Module&id=" + propertyId,
success: function(result) {
var res = JSON.parse(result);
$("#price").val(res['price']);
}
});
}
}
});
The fields gets auto populated but the format becomes something like 1000.000000 ive tried to modify the precision in its vardefs to 0 but its still the same i want to format the number if possible to something like this 1,000.
You will need to use toFixed function of javascript to get the required results.
Following is the modified code:
YAHOO.util.Event.onDOMReady(function() {
YAHOO.util.Event.addListener(
"parent_module_another_module_ida",
"change",
ajaxReq
);
function ajaxReq() {
var propertyId = $("#parent_module_another_module_ida").val();
if (propertyId != "") {
$.ajax({
url: "/?entryPoint=ajaxEntryPoint&module=Parent_Module&id=" + propertyId,
success: function(result) {
var res = JSON.parse(result);
price_val = res['price'].toFixed(0);
$("#price").val(price_val);
}
});
}
}
});

Mapping List with Knockout Mapping

I have created view model
var catalog = ko.observableArray();
$.ajax({
type: "GET",
url: "http://localhost:8080/ticket-service/rest/ticket/list",
success: function(msg) {
catalog.push.apply(catalog, $.map(msg, function(data) {
return new Ticket(data)
}));
return catalog;
},
error: function(msg) {
console.log(msg)
}
});
and the model
function Ticket(data) {
this.ticketId = ko.observable(data.ticketId);
this.ticketNo = ko.observable(data.ticketNo);
this.ticketTitle = ko.observable(data.ticketTitle);
this.longDescription = ko.observable(data.longDescription);
this.createdBy = ko.observable(data.createdBy);
this.createdOn= ko.observable(data.createdOn);
this.assignTo = ko.observable(data.assignTo);
this.priority = ko.observable(data.priority);
this.dueDate = ko.observable(data.dueDate);
this.status = ko.observable(data.status);
this.projectId = ko.observable(data.projectId);
}
with at the end viewmodel like this
return {
ticket: newTicket,
searchTerm: searchTerm,
catalog: filteredCatalog,
newTicket: newTicket,
addTicket: addTicket,
delTicket: delTicket
};
})();
console.log(vm);
ko.applyBindings(vm);
produce list,add, and delete form.The question is how can i use knockout mapping that can list from get methode.
you need to do something like this
Demonstrated taking a single entity from your code .
view:
Output Preview :
<pre data-bind="text:ko.toJSON($data,null,2)"></pre>
viewModel:
function Ticket(data) {
this.ticketId = ko.observable(data.ticketId);
}
var mapping = {
create: function (options) {
return new Ticket(options.data);
}
};
var ViewModel = function () {
var self = this;
self.catalog = ko.observableArray();
var data = [{
'ticketId': 1
}, {
'ticketId': 2
}]
//under ajax call do the same but pass 'msg' in place of data
self.catalog(ko.mapping.fromJS(data, mapping)())
console.log(self.catalog()); // check console for output
};
ko.applyBindings(new ViewModel());
sample working fiddle here

Was using .bind but now haved to use .delegate... have tried .undelegate?

Heres the jsfiddle, jsfiddle.net/kqreJ
So I was using .bind no problem for this function but then I loaded more updates to the page and found out that .bind doesn't work for content imported to the page but just for content already on the page! Great!
So I switched it up to .delegate which is pretty cool but now I can't figure out how to .bind .unbind my function the way it was???
Function using .bind which worked perfect... except didn't work on ajax content.. :(
$('.open').bind("mouseup",function(event) {
var $this = $(this), handler = arguments.callee;
$this.unbind('mouseup', handler);
var id = $(this).attr("id");
var create = 'nope';
var regex = /\d+$/,
statusId = $('#maindiv .open').toArray().map(function(e){
return parseInt(e.id.match(regex));
});
var divsToCreate = [ parseInt(id) ];
$.each(divsToCreate, function(i,e)
{
if ( $.inArray(e, statusId) == -1 ) {
create = 'yup';
}
});
if( create == 'yup' ) {
if(id) {
$.ajax({
type: "POST",
url: "../includes/open.php",
data: "post="+ id,
cache: false,
success: function(html) {
$('.open').html(html);
$this.click(handler);
}
});
}
}
});
New function using .delegate that is not binded and creates multiple instances?
$('#maindiv').delegate("span.open", "mouseup",function(event) {
var $this = $(this), handler = arguments.callee;
$this.unbind('mouseup', handler);
var id = $(this).attr("id");
var create = 'nope';
var regex = /\d+$/,
statusId = $('#maindiv .open').toArray().map(function(e){
return parseInt(e.id.match(regex));
});
var divsToCreate = [ parseInt(id) ];
$.each(divsToCreate, function(i,e)
{
if ( $.inArray(e, statusId) == -1 ) {
create = 'yup';
}
});
if( create == 'yup' ) {
if(id) {
$.ajax({
type: "POST",
url: "../includes/open.php",
data: "post="+ id,
cache: false,
success: function(html) {
$('.open').html(html);
$this.click(handler);
}
});
}
}
});
I've spent hours trying to figure this out because I like learning how to do it myself but I had to break down and ask for help... getting frustrated!
I also read that when your binding and unbinding .delegate you have to put it above the ajax content? I've tried using .die() and .undelegate()... Maybe I just don't know where to place it?
Take a look at undelegate
It does to delegate what unbind does to bind.
In your case, I think it'd be something like:
$('#maindiv').undelegate("span.open", "mouseup").delegate("span.open", "mouseup" ...
Then you can drop the $this.unbind('mouseup', handler); within the function.

Refresh a ListBox in ASP.NET MVC 2 with jQuery

I've looked around on SO to see if this has been asked before and couldn't find anything (so if it has indeed been asked before then I apologize.
Here's what I'm trying to do, a user can select from a list of skills for their profile, if a skill they want isn't in the list then they can add it to the database, I have that accomplished with WCF & jQuery AJAX. Here's the code for that:
$("#AddNewSkill").click(function () {
$("#AddNewSkill").attr("disabled", true);
$("#newSkill").attr("disabled", true);
var newSkill = $("#newSkill").val();
var data = { name: $("#newSkill").val(), description: "", type: "Skill" };
data = JSON.stringify(data)
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "../WeddingPhotographerService.svc/AddNew",
data: data,
dataType: "json",
success: function () {
successCall('#newSkill', '#AddNewSkill');
//$('#SkillListViewContainer').load('../Account/GetSkillControl');
},
error: function (msg) {
$("#AddSkillError").text(msg.d);
$("#AddSkill").attr("disabled", false);
$("#NewSkill").attr("disabled", false);
}
});
});
Here's the method in the AJAX-Enabled WCF service:
[OperationContract]
public bool AddNew(string name, string description, string type)
{
switch (type)
{
case "":
goto default;
case "skill":
IRepository<Skill> skillRepo = ObjectFactory.GetInstance<IRepository<Skill>>();
var skill = new Skill { Name = name, Description = (string.IsNullOrEmpty(description)) ? string.Empty : description };
skillRepo.Save(skill);
return true;
case "equipment":
IRepository<Equipment> eqRep = ObjectFactory.GetInstance<IRepository<Equipment>>();
var eq = new Equipment { Name = name, Description = (string.IsNullOrEmpty(description)) ? string.Empty : description };
eqRep.Save(eq);
return true;
case "occasion":
IRepository<Occassion> occRepo = ObjectFactory.GetInstance<IRepository<Occassion>>();
var oc = new Occassion { Name = name, Description = (string.IsNullOrEmpty(description)) ? string.Empty : description };
occRepo.Save(oc);
return true;
default:
IRepository<Skill> repo = ObjectFactory.GetInstance<IRepository<Skill>>();
var s = new Skill { Name = name, Description = (string.IsNullOrEmpty(description)) ? string.Empty : description };
repo.Save(s);
return true;
}
}
It's kind of ugly but I'll optimize it once I have this 2nd part working. Here's how the ListBox is being loaded in the view:
<%: Html.ListBox("Skills", Model.SkillList, new { #style = "width:157px; height:90px;background:#e2f0f1;", #size = "3", #class = "inputbox" })%>
Which comes from RegistrationModelView.cs, here's SkillList in my model view:
private MultiSelectList GetSkills(string[] selectedValues)
{
List<Skill> list = new List<Skill>();
IRepository<Skill> skills = ObjectFactory.GetInstance<IRepository<Skill>>();
foreach (Skill skill in skills.GetAll())
{
list.Add(new Skill()
{
Key = skill.Key,
Name = skill.Name,
Description = ""
});
}
return new MultiSelectList(list, "Key", "Name", selectedValues);
}
And the action in AccountController.cs that loads the view
[MoveFormsScript]
public ActionResult Index()
{
return View(new RegistrationModelView());
}
I'm pretty sure all the code I posted (other than how the new item is added with the WCF service and the jQuery for consuming said service is irrelevant but I thought I'd offer as much information as possible).
Like I said the new value is added to the database no problem, my issue is updating the ListBox to reflect the new values. Anyone got any ideas and can help with this?
Well I mucked around until I found something that does what I need it to do. It may not be the most efficient or elegant way to accomplish the task but it at least works (Maybe someone will come along with a different solution some day).
What I ended up doing was make another $,ajax() call in the success of the first call like this
$("#AddNewSkill").click(function () {
$("#AddNewSkill").attr("disabled", true);
$("#newSkill").attr("disabled", true);
var data = { name: $("#newSkill").val(), description: "", type: "skill" };
data = JSON.stringify(data)
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "../WeddingPhotographerService.svc/AddNew",
data: data,
dataType: "json",
success: function () {
$.ajax({
type:"POST",
datatype:"json",
url: "../Account/GetSkills",
success:updateSkillsListBox
});
},
error: function (msg) {
alert(msg.d);
}
});
});
function updateSkillsListBox(data, status) {
$("#Skills").html("");
for(var d in data) {
$("<option value=\"" + data[d].Value + "\">" + data[d].Name + "</option>").appendTo("#Skills");
}