backbone Model url with dynamic parameter - javascript

I'm in a situation where i want to populate Model url from Model attributes dynamically
here is my code
var MailboxModel = Backbone.Model.extend({
defaults: {
key: 'inbox',
filter: 'date',
orderby: 'desc',
mailPageSize: 10,
pageOffSet: 0
},
url: window.sessionStorage.getItem('mail_link') + "/" + this.key + "?order_by=" + this.filter + "&order=" + this.orderby + "&offset=" + parseInt(this.pageOffSet) + "&count=" + this.mailPageSize
// the output will be http://website.com/rest/users/123456/mail/inbox?order_by=date&order=desc&offset=0&count=10
// instead output is "http://website.com/rest/users/1926856/mail/inbox?order_by=undefined&order=undefined&offset=NaN&count=undefined"
});
or this way? both not working
var mailboxmodel =new MailboxModel({});
mailboxmodel.set('key', sessionStorage.getItem('message_key'));
mailboxmodel.set('filter', 'subject');
mailboxmodel.set('orderby', 'desc');
mailboxmodel.set('mailPageSize', 10);
mailboxmodel.set('pageOffSet', 0);
var mailboxlist = new MailboxList({
model: new MailboxModel,
render: function(){
// render function is working fine
}
});
mailboxlist.render();
Backbone.history.start();
});

The reason why it isn't working is because at the point where you are setting the url property the default values haven't been set yet. To work around this you can use a function that returns the url instead.
For example
var MailboxModel = Backbone.Model.extend({
defaults: {
key: 'inbox',
filter: 'date',
orderby: 'desc',
mailPageSize: 10,
pageOffSet: 0
},
url: function () {
return window.sessionStorage.getItem('mail_link') + "/" + this.key + "?order_by=" + this.filter + "&order=" + this.orderby + "&offset=" + parseInt(this.pageOffSet) + "&count=" + this.mailPageSize;
}
});
You can also just set it in the initialize method
var MailboxModel = Backbone.Model.extend({
//...
initlaize: function (options) {
this.url = ....
}
});

I solve this problem in my solution passing all the values when I instantiate the model.
Like this.
url : /somePath/' + #key + '/' + #filter
initialize:(options)->
#key = options.key
#filter = options.filtes
// ....
getSomeThing:->
#fetch()
Hope it helps.

Related

batch rest call in sharepoint online

I am trying to understand how the batch rest calls work.
I could not find any simple example on the internet. I have found the examples from https://github.com/andrewconnell/sp-o365-rest but can't run these examples or I have no idea how yet. I am guessing you have to deploy the app to a sharepoint site.
Given that, I am just looking for the simplest example of a add list item and update list item in bulk/batch. Also if anyone knows how I can make the app from that git to run will be really appreciated.
Thanks.
The github project is a add-in project so you need deploy the add-in project, then you can use it.
You could check below script from here.
My test result in this thread
(function () {
jQuery(document).ready(function () {
jQuery("#btnFetchEmployees").click(function () {
addEmployees();
});
});
})();
function addEmployees() {
var employeesAsJson = undefined;
employeesAsJson = [
{
__metadata: {
type: 'SP.Data.EmployeeInfoListItem'
},
Title: 'Geetanjali',
LastName: 'Arora',
Technology: 'SharePoint'
},
{
__metadata: {
type: 'SP.Data.EmployeeInfoListItem'
},
Title: 'Geetika',
LastName: 'Arora',
Technology: 'Graphics'
},
{
__metadata: {
type: 'SP.Data.EmployeeInfoListItem'
},
Title: 'Ashish',
LastName: 'Brajesh',
Technology: 'Oracle'
}
];
addEmployeeInfoBatchRequest(employeesAsJson);
}
function generateUUID() {
var d = new Date().getTime();
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16);
return (c == 'x' ? r : (r & 0x7 | 0x8)).toString(16);
});
return uuid;
};
function addEmployeeInfoBatchRequest(employeesAsJson) {
// generate a batch boundary
var batchGuid = generateUUID();
// creating the body
var batchContents = new Array();
var changeSetId = generateUUID();
// get current host
var temp = document.createElement('a');
temp.href = _spPageContextInfo.webAbsoluteUrl;
var host = temp.hostname;
// iterate through each employee
for (var employeeIndex = 0; employeeIndex < employeesAsJson.length; employeeIndex++) {
var employee = employeesAsJson[employeeIndex];
// create the request endpoint
var endpoint = _spPageContextInfo.webAbsoluteUrl
+ '/_api/web/lists/getbytitle(\'EmployeeInfo\')'
+ '/items';
// create the changeset
batchContents.push('--changeset_' + changeSetId);
batchContents.push('Content-Type: application/http');
batchContents.push('Content-Transfer-Encoding: binary');
batchContents.push('');
batchContents.push('POST ' + endpoint + ' HTTP/1.1');
batchContents.push('Content-Type: application/json;odata=verbose');
batchContents.push('');
batchContents.push(JSON.stringify(employee));
batchContents.push('');
}
// END changeset to create data
batchContents.push('--changeset_' + changeSetId + '--');
// batch body
var batchBody = batchContents.join('\r\n');
batchContents = new Array();
// create batch for creating items
batchContents.push('--batch_' + batchGuid);
batchContents.push('Content-Type: multipart/mixed; boundary="changeset_' + changeSetId + '"');
batchContents.push('Content-Length: ' + batchBody.length);
batchContents.push('Content-Transfer-Encoding: binary');
batchContents.push('');
batchContents.push(batchBody);
batchContents.push('');
// create request in batch to get all items after all are created
endpoint = _spPageContextInfo.webAbsoluteUrl
+ '/_api/web/lists/getbytitle(\'EmployeeInfo\')'
+ '/items?$orderby=Title';
batchContents.push('--batch_' + batchGuid);
batchContents.push('Content-Type: application/http');
batchContents.push('Content-Transfer-Encoding: binary');
batchContents.push('');
batchContents.push('GET ' + endpoint + ' HTTP/1.1');
batchContents.push('Accept: application/json;odata=verbose');
batchContents.push('');
batchContents.push('--batch_' + batchGuid + '--');
batchBody = batchContents.join('\r\n');
// create the request endpoint
var endpoint = _spPageContextInfo.webAbsoluteUrl + '/_api/$batch';
var batchRequestHeader = {
'X-RequestDigest': jQuery("#__REQUESTDIGEST").val(),
'Content-Type': 'multipart/mixed; boundary="batch_' + batchGuid + '"'
};
// create request
jQuery.ajax({
url: endpoint,
type: 'POST',
headers: batchRequestHeader,
data: batchBody,
success: function (response) {
var responseInLines = response.split('\n');
$("#tHead").append("<tr><th>First Name</th><th>Last Name</th><th>Technology</th></tr>");
for (var currentLine = 0; currentLine < responseInLines.length; currentLine++) {
try {
var tryParseJson = JSON.parse(responseInLines[currentLine]);
$.each(tryParseJson.d.results, function (index, item) {
$("#tBody").append("<tr><td>" + item.Title + "</td><td>" + item.LastName + "</td><td>" + item.Technology + "</td></tr>");
});
} catch (e) {
}
}
},
fail: function (error) {
}
});
}

How can I use a XMLHttpRequest inside a jQuery autocomplete?

I need Data inside a jQuery autocomplete from a XMLHttpRequest
This is my code for XMLHttpRequest:
var jsonRequest = new XMLHttpRequest();
jsonRequest.open('GET', path);
jsonRequest.onload = function(){
var a = jsonRequest.removeEventListener;
}; jsonRequest.send();
This Code also works but how can I use the var a inside my jQuery autocomplete?
This is the jQuery:
$('#tags').autocomplete({
source: function(request, response) {
var data = a;
var datamap = data.map(function(i) {
return {
label: i.serial + ' - ' + i.mac,
value: i.serial + ' - ' + i.mac,
desc: i.cpe_ip
}
});
var key = request.term;
datamap = datamap.filter(function(i) {
return i.label.toLowerCase().indexOf(key.toLowerCase()) >= 0;
});
response(datamap.slice(0, 15));
},
minLength: 1,
delay: 100
});
If I use this with JSON-Data for the var data it works fine. But like this it won't work.
Now I have this:
$('#snmcAuto').autocomplete({
source: function(request, response) {
var jsonRequest = new XMLHttpRequest();
jsonRequest.open('GET', path);
jsonRequest.onload = function(data){
response(JSON.parse(data));
};
var datamap = data.map(function(i) {
return {
label: i.serial + ' - ' + i.mac,
value: i.serial + ' - ' + i.mac,
desc: i.cpe_ip
}
});
var key = request.term;
datamap = datamap.filter(function(i) {
return i.label.toLowerCase().indexOf(key.toLowerCase()) >= 0;
});
response(datamap.slice(0, 15));
jsonRequest.send();
},
minLength: 1,
delay: 100
});
This is the code which works for me and yeah its not the best performance but it's still fast.
$('#snmcAuto').autocomplete({
source: function(request, response) {
var jqxhr = $.getJSON( path, function() {
var data = jqxhr.responseJSON;
var datamap = data.map(function(i) {
return {
label: i.serial + ' - ' + i.mac,
value: i.serial + ' - ' + i.mac,
desc: i.cpe_ip
}
});
var key = request.term;
datamap = datamap.filter(function(i) {
return i.label.toLowerCase().indexOf(key.toLowerCase()) >= 0;
});
response(datamap.slice(0, 15));
})
},
});;
To use the remote datasource (accessed by AJAX) as the source of the autocomplete data you can do something like this. The key thing is that you must return the response to the autocomplete inside the "onload" callback of the AJAX request, so that it has access to the downloaded data. You also have to pass the search term entered by the user to the server via the querystring.
$('#tags').autocomplete({
source: function(request, response) {
var jsonRequest = new XMLHttpRequest();
jsonRequest.open('GET', path + "?term=" + request.term);
jsonRequest.onload = function(data){
response(JSON.parse(data.responseText));
};
jsonRequest.send();
},
minLength: 1,
delay: 100
});

Fullcalendar only loading event after view changed, then wont remove events until view changed again

I am having issues on my live server with fullcalendar. It was working just fine on localhost.
Basically:
when the page loads, it does an ajax call to load all events into the calendar. When the user selects a location, it redoes that ajax request to update all the events in that location. Which it must a) remove the events and b) load the new events returned from the server.
Here is my code:
on page load:
$('#calendar').fullCalendar({
fixedWeekCount: false,
defaultView: 'month',
eventRender: function(event, element) {
element.html('');
var seats_available = (typeof counts[event.post_id] != 'undefined') ? event.seats - counts[event.post_id] : event.seats;
var dateString = moment(event.start).format('YYYY-MM-DD');
var cal = $('#calendar').find('.fc-day-number[data-date="' + dateString + '"]').css('background-color', 'red').addClass('tooltip-here');
var html = '<div><span>Course: </span><p>' + event.title + '</p><br /><span>Seats Available: </span><p>' + seats_available + ' / ' + event.seats + '</p><br /><span>Price: </span><p>R ' + event.cost.toCurrency(2, '.', ',') + '</p><br /><br /><div class="button"><button type="button" class="primary book-course" data-date="' + dateString + '" >Book Course</button></div></div>';
Tipped.create('.tooltip-here[data-date="' + dateString + '"]', html, {position: 'bottom'});
}
});
The get events method:
function getEventData() {
$.ajax({
url: EVENT.ajaxurl, // this is a variable passed through by wordpress
type: 'POST',
dataType: 'json',
data: {
action: 'get_event_data',
selected_location: $('#location-select').val(),
security: NINJA_EVNT.security
},
success: function( res ) {
console.log('#location-select', $('#location-select').val());
console.log('response', res);
var events_raw = JSON.parse(res.data.posts);
counts = res.data.counts;
var events = [];
console.log('events', events);
var seats_available = (typeof counts[events_raw.post_id] != 'undefined') ? events_raw.seats - counts[events_raw.post_id] : events_raw.seats;
$('#calendar').fullCalendar( 'removeEvents'); // this isn't removing the events anymore
for(var i = 0; i < events_raw.length; i++) {
console.log('events_raw[i]', events_raw[i]);
var obj = {
post_id: events_raw[i].post_id,
title: events_raw[i].title,
start: moment(events_raw[i].start_date).toDate(),
seats: events_raw[i].seats,
seats_available: seats_available,
description: events_raw[i].description,
cost: events_raw[i].cost,
eventMouseover : function(data, event, view) {
var content = '<span class="hint--bottom"><h3>'+events_raw[i].title+'</h3>' +
'<p><b>Start:</b> '+moment(events_raw[i].start_date).toDate()+'</p>' +
'<p><b>Seats:</b> '+ seats_available +' / ' + events_raw[i].seats + '</p>' +
'<p><b>Description</b> '+events_raw[i].description+ '</p></span>';
tooltip.set({
'content.text': content
})
.reposition(event).show(event);
}
};
events.push(obj);
console.log('obj', obj);
$('#calendar').fullCalendar('renderEvent', obj, true); // this adds the new events just fine
}
},
error: function( error ) {
console.log('error', error);
}
});
}
UPDATE:
Forgot to add, if I reload the events and the events don't remove, if I go to the next month and back, it loads just fine.
I realized that this was just a latency issue. Putting a loading overlay until it had loaded properly and populated the dropdown worked just fine.

Make slider call knockout js function on change

, I have a slider on my html page which has a databind to an observable.
Like this.
<input id="ex2" data-slider-id="ex2Slider" type="text" data-bind="sliderValue: {value: borrowOrInvestAmount, min:0, max: 5000, step: 1, formatter:formatter2}"
style="display: none;">
And as well as I have a table which shows interest like this.
<td <input data-bind=" valueUpdate: 'afterkeydown'"><input data-bind="value: amount1"/></td>
Basically what I want is that, when I change the value on the slider, it should call this function which takes in value from the observable borrowOrInvestAmount
and should return the interest rate which will be put into the observable and shown on the table. And each time the slider value changes it should call this function again.
function DoBusinessViewModel(root) {
var self = this;
self.items = ko.observableArray();
self.itemsNotFoundMsg = ko.observable(null);
var borrowOrInvestAmount_tmp = 0;
var moneyBorrOrInvUri;
if (root.boolInvestments()) {
moneyBorrOrInvUri = BASEURL + 'index.php/moneyexchange/SearchRequestsOrInvestments/' + auth + '/' + root.borrowOrInvestAmount() + '/' + root.borrowOrInvestCurrency() + '/' + 0 + '/' + 1;
} else {
moneyBorrOrInvUri = BASEURL + 'index.php/moneyexchange/SearchRequestsOrInvestments/' + auth + '/' + root.borrowOrInvestAmount() + '/' + root.borrowOrInvestCurrency() + '/' + 0 + '/' + 0;
}
$.ajax({
type: 'GET',
url: moneyBorrOrInvUri,
contentType: 'application/json; charset=utf-8'
})
.done(function(BorrowOrInvestDetails) {
$.each(BorrowOrInvestDetails, function (index, item) {
self.items.push(item);
/* here is where I am trying to get the value of interest from for the table*/
self.interest(self.item()[0].Interest);
borrowOrInvestAmount_tmp += parseFloat(item.borrowOrInvestAmount);
/* If we are reading borrowing request and thee are any requests with payment_term = 2 = Monthly,
* we must set root.paymentTerm observable to 2 = Monthly. */
if (!root.boolInvestments()) {
if (item.payment_term == 2) {
if (root.paymentTerm() == 1) {
root.paymentTerm(2);
}
}
}
});
root.borrowOrInvestAmount(borrowOrInvestAmount_tmp.toFixed(2));
root.borrowOrInvestAbbreviation(self.items()[0].Abbreviation);
if (root.boolInvestments()) {
root.getFee(root.borrowOrInvestAmount(), root.borrowOrInvestCurrency(), 'money_request', 'borrow');
} else {
root.getFee(root.borrowOrInvestAmount(), root.borrowOrInvestCurrency(), 'money_offer', 'invest');
}
root.getPaymentPlanForMultibleItems(self.items());
})
.fail(function(jqXHR, textStatus, errorThrown) {
self.itemsNotFoundMsg(errorThrown);
})
.always(function(data){
});
};
Since I added the value borrowOrInvestAmount to the slider I Am not sure if its actually calling the dobusinessfunction. Dont know what I am missing.

Set order of functions to execute

I have two Jquery function. How do I set the execution order so that function B would only be called after function A, (reason behind is that Function A set a value to a variable IdstoExclude that is getting passed as a parameter to function B.
Below is what i tried but no luck:
var IDstoExclude = "123";
callListService('getArticleTypelistById', 'Atid', 87, 5, '#MainStory', '#tmplFeaturePanel', IDstoExclude);
callListService('getArticleTypelistById', 'Atid', 87, 10, '#LeftSideContent1', '#tmplLeftSideContent1', IDstoExclude);
function callListService(webServiceName, parameterName, parameterValue, noOfItems, domElement, templName, exclIDs) {
//set a default value for the template name * exclIDs
templName = templName || "#FeaturedSubStories";
//exclIDs = exclIDs || "123,12";
var inputParameters = webServiceName.toLowerCase() + ':' + parameterName.toLowerCase() + ':' + parameterValue + ':noofitems:' + noOfItems + ':excludeids:' + exclIDs;
var clientcode = getCryptoToken(inputParameters);
//Build JSONp query
eval("data={" + parameterName.toLowerCase() + ":" + parameterValue + ", noofitems: " + noOfItems + ", excludeids:" + exclIDs + ", clientcode:'" + clientcode + "' }");
$.getJSON('https://abc.com/Service.svc/' + webServiceName + '?callback=?', data, function (data2) {
var template = $.templates(templName);
var htmlOutput = template.render(data2);
$(domElement).append(htmlOutput);
IDstoExclude = data2.IdsInThisList;
});
Tried below but no luck: var IDstoExclude = "123";
function callService1() {
return $.ajax()
.then(function(response) {
callListService('getArticleTypelistById', 'Atid', 87, 10, '#LeftSideContent1', '#tmplLeftSideContent1', IDstoExclude);
});
}
function callService2() {
callListService('getArticleTypelistById', 'Atid', 87, 10, '#LeftSideContent1', '#tmplLeftSideContent1', IDstoExclude)
}
$.when(callService1()).then(callService2);
For this solution to work as you expect your code should look like something below:
function callService1(p1, p2, ...) {
return $.ajax(...)
.then(function(response) {
return something;
});
}
function callService2(something_from_s1) {
// work with something_from_s1 var
}
$.when(callService1(...)).then(callService2);
References:
http://joseoncode.com/2011/09/26/a-walkthrough-jquery-deferred-and-promise/
http://api.jquery.com/category/deferred-object/
http://api.jquery.com/deferred.then/

Categories

Resources