JSLink on Listitems disables sorting function - javascript

When trying to put following Script into a CEWP on a Listview:
; (function ()
{
var fieldJsLinkOverride = {};
fieldJsLinkOverride.Templates = {};
fieldJsLinkOverride.Templates.Fields =
{
'Title': { //Titelfeld
'View': function () {
return ''+ctx.CurrentItem.Title+''
}
}
};
// Register the rendering template
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(fieldJsLinkOverride);
})();
So this changes the Title field into my desired link, this works all fine, but when i try to sort the list, it returns following:
Unable to get property 'ItemID' of undefined or null
Does anyone know this problem or might find a solution for it?

You are using ctx in your code but you have not passed it to your function..
Remember Each of the functions you write for JS Link will be passed a “context” object as a parameter. From this object you can retrieve properties about the current list, current list item and other objects.
Refer below code. Here we are passing ctx to a function. Try this :
{
'Title': { //Titelfeld
'View': function (ctx) {
return ''+ctx.CurrentItem.Title+''
}
}
};

Related

How to add name to fabricjs object?

In order to get fabricjs canvas image by name, I need to set unique id or name to this iamge. I've created a new class fabric.NamedImage
That's how I did it.
fabric.NamedImage = fabric.util.createClass(fabric.Image, {
type: 'nameimage',
initialize: function (element, options) {
this.callSuper('initialize', element, options);
options && this.set('name', options.name);
},
toObject: function () {
return fabric.util.object.extend(this.callSuper('toObject'), { name: this.name });
},
_render: function (ctx) {
this.callSuper('_render', ctx);
}});
And fromObject
fabric.NamedImage.fromObject = function (object, callback) {
fabric.util.loadImage(object.src, function (img) {
var instance = new fabric.NamedImage(img, object);
callback && callback(instance);
});
};
fabric.NamedImage.async = true;
But when I'm trying to load canvas loadFromJSON for some reasons I keep getting error
cannot read property 'async' of undefined
Here is code where I'm trying to load JSON
for (i = 0; i <= canvas.length; i++) {
JSON.parse(imageQuery[i]);
canvas[i].loadFromJSON(imageQuery[i]);
canvas[i].renderAll();
console.log(' this is a callback. invoked when canvas is loaded!xxx ');
}
I've already read
cannot read property 'async' of undifined
and
save canvas to server with custom attribute
Is there some way to get object by name?
From the official docs,
var rect = new fabric.Rect();
rect.toObject = (function(toObject) {
return function() {
return fabric.util.object.extend(toObject.call(this), {
name: this.name
});
};
})(rect.toObject);
canvas.add(rect);
rect.name = 'trololo';
console.log(JSON.stringify(canvas));
and the logged output will be
'{"objects":[{"type":"rect","left":0,"top":0,"width":0,"height":0,"fill":"rgb(0,0,0)","overlayFill":null,"stroke":null,"strokeWidth":1,"strokeDashArray":null,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"selectable":true,"hasControls":true,"hasBorders":true,"hasRotatingPoint":false,"transparentCorners":true,"perPixelTargetFind":false,"rx":0,"ry":0,"name":"trololo"}],"background":"rgba(0, 0, 0, 0)"}'
Please refer this http://fabricjs.com/fabric-intro-part-3
Cheers!
Plesae change the type property of your class to 'namedImage' and it should go.
You can add custom properties to different objects in fabric js using the code given below:
obj.toObject = (function (toObject) {
return function () {
return fabric.util.object.extend(toObject.call(this),{
id : value
});
};
})(obj.toObject);
Here obj is the canvas object that you have created and id is the custom attribute we are adding to this object.
Suppose you have saved canvas in the form of a json file. So while using json.stringify consider the code below:
json_data = JSON.stringify(self.canvas.toJSON(['attribute1',
'attrubute2']));
Here in square brackets include all the custom attributes. Later on when you will use loadfromjson all the custom properties will automatically be included. Hope it will work. Have a nice day!!

Function name changes (?)

I am working on a script and everythink worked fine, until a few days ago. I have an object, created with function(), where I work with several methods.
To access properties inside the object, I use the this keyword and that works fine.
As example:
var SeralCore = SeralCore || function ()
{
this.initSeral();
return this;
};
SeralCore.prototype = {
page = null;
initSeral = function ()
{
alert(this.page);
}
}
Full code: http://pastebin.com/81Zn9276
jsFiddle example: https://jsfiddle.net/g2ahu6ob/10/
When I have an event, where a callback is fired and I have to access the property page, I used the following, because I can't use this anymore:
$('.button').click(function () {
SeralCore.page = 'Some value';
});
This worked well, but suddenly there is an error saying I cannot reach an property (or object, in my case*) used like in the exameple above. The output is undefined.
I decided to investigate what the output would be if I log SeralCore. Surprisingly, it says the following:
As you can see, there is a < at the end of SeralCore, which doesn't belong there.
Is this normal? And is this the cause of not being able to access properties using the "full name" (SeralCore.page)? If so, is there a way to fix it?
Many, many thanks in advance because I can't figure out what I am doing wrong.
Snippet:
var SeralCore = SeralCore || function () {
this.initSeral();
return this;
};
window.onload = function () {
this.SeralCore = new SeralCore();
};
SeralCore.prototype = {
page: 'Page',
initSeral: function ()
{
this.registerPage.start();
},
registerPage: {
start: function ()
{
$('.output').text(typeof SeralCore.page + ' (Should show \'String\' when it can read SeralCore.page)');
}
}
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<span class="output"></span>

Custom JQuery Plugin Method error

I've been working on writing a custom jquery plugin for one of my web applications but I've been running into a strange error, I think it's due to my unfamiliarity with object-oriented programming.
The bug that I've been running into comes when I try to run the $(".list-group").updateList('template', 'some template') twice, the first time it works just fine, but the second time I run the same command, I get an object is not a function error. Here's the plugin code:
(function($){
defaultOptions = {
defaultId: 'selective_update_',
listSelector: 'li'
};
function UpdateList(item, options) {
this.options = $.extend(defaultOptions, options);
this.item = $(item);
this.init();
console.log(this.options);
}
UpdateList.prototype = {
init: function() {
console.log('initiation');
},
template: function(template) {
// this line is where the errors come
this.template = template;
},
update: function(newArray) {
//update code is here
// I can run this multiple times in a row without it breaking
}
}
// jQuery plugin interface
$.fn.updateList = function(opt) {
// slice arguments to leave only arguments after function name
var args = Array.prototype.slice.call(arguments, 1);
return this.each(function() {
var item = $(this), instance = item.data('UpdateList');
if(!instance) {
// create plugin instance and save it in data
item.data('UpdateList', new UpdateList(this, opt));
} else {
// if instance already created call method
if(typeof opt === 'string') {
instance[opt](args);
}
}
});
}
}(jQuery));
One thing I did notice when I went to access this.template - It was in an array so I had to call this.template[0] to get the string...I don't know why it's doing that, but I suspect it has to do with the error I'm getting. Maybe it can assign the string the first time, but not the next? Any help would be appreciated!
Thanks :)
this.template = template
Is in fact your problem, as you are overwriting the function that is set on the instance. You end up overwriting it to your args array as you pass that as your argument to the initial template function. It basically will do this:
this.template = ["some template"];
Thus the next time instance[opt](args) runs it will try to execute that array as if it were a function and hence get the not a function error.
JSFiddle

How do i add a value to javascript object with a function?

bender: function () {
var context = {
pageName: 'Chocolatte candy'
},
partials = {
header: this.globalPartials.header,
tabbar: this.globalPartials.tabbar
};
addBackbuttonIphone();
$(this.el).html(templates["monkey"].render(context, partials));
return this;
}
});
return monkeyView;
});
in another location i have a js file that has the following function
function addBackbuttonIphone () {
context.backButton="#more";
}
If i just add context.backButton="more" in var context directly it works . However if i use the addBackButtonIphone function to do the same it does not work . I am sure that this function is being called however, it is not giving the "#more" value to context.backButton.
Please help
Thanks
modify your function signature to accept an argument called context, like this:
function addBackbuttonIphone(context) {
context.backButton="#more";
}
then pass context into your function, like this:
addBackbuttonIphone(context);

Creating methods on the fly

Hi I'm trying to author a jQuery plugin and I need to have methods accessible to elements after they are initialized as that kind of object, e.g.:
$('.list').list({some options}); //This initializes .list as a list
//now I want it to have certain methods like:
$('.list').find('List item'); //does some logic that I need
I tried with
$.fn.list = function (options) {
return this.each(function() {
// some code here
this.find = function(test) {
//function logic
}
}
}
and several other different attempts, I just can't figure out how to do it.
EDIT:
I'll try to explain this better.
I'm trying to turn a table into a list, basically like a list on a computer with column headers and sortable items and everything inbetween. You initiate the table with a command like
$(this).list({
data: [{id: 1, name:'My First List Item', date:'2010/06/26'}, {id:2, name:'Second', date:'2010/05/20'}]
});
.list will make the <tbody> sortable and do a few other initial tasks, then add the following methods to the element:
.findItem(condition) will allow you to find a certain item by a condition (like findItem('name == "Second"')
.list(condition) will list all items that match a given condition
.sort(key) will sort all items by a given key
etc.
What's the best way to go about doing this?
If you want these methods to be available on any jQuery object, you will have to add each one of them to jQuery's prototype. The reason is every time you call $(".list") a fresh new object is created, and any methods you attached to a previous such object will get lost.
Assign each method to jQuery's prototype as:
jQuery.fn.extend({
list: function() { .. },
findItem: function() { .. },
sort: function() { .. }
});
The list method here is special as it can be invoked on two occasions. First, when initializing the list, and second when finding particular items by a condition. You would have to differentiate between these two cases somehow - either by argument type, or some other parameter.
You can also use the data API to throw an exception if these methods are called for an object that has not been initialized with the list plugin. When ('xyz').list({ .. }) is first called, store some state variable in the data cache for that object. When any of the other methods - "list", "findItem", or "sort" are later invoked, check if the object contains that state variable in its data cache.
A better approach would be to namespace your plugin so that list() will return the extended object. The three extended methods can be called on its return value. The interface would be like:
$('selector').list({ ... });
$('selector').list().findOne(..);
$('selector').list().findAll(..);
$('selector').list().sort();
Or save a reference to the returned object the first time, and call methods on it directly.
var myList = $('selector').list({ ... });
myList.findOne(..);
myList.findAll(..);
myList.sort();
I found this solution here:
http://www.virgentech.com/blog/2009/10/building-object-oriented-jquery-plugin.html
This seems to do exactly what I need.
(function($) {
var TaskList = function(element, options)
{
var $elem = $(element);
var options = $.extend({
tasks: [],
folders: []
}, options || {});
this.changed = false;
this.selected = {};
$elem.sortable({
revert: true,
opacity: 0.5
});
this.findTask = function(test, look) {
var results = [];
for (var i = 0,l = options.tasks.length; i < l; i++)
{
var t = options['tasks'][i];
if (eval(test))
{
results.push(options.tasks[i]);
}
}
return results;
}
var debug = function(msg) {
if (window.console) {
console.log(msg);
}
}
}
$.fn.taskList = function(options)
{
return this.each(function() {
var element = $(this);
if (element.data('taskList')) { return; }
var taskList = new TaskList(this, options);
element.data('taskList', taskList);
});
}
})(jQuery);
Then I have
$('.task-list-table').taskList({
tasks: eval('(<?php echo mysql_real_escape_string(json_encode($tasks)); ?>)'),
folders: eval('(<?php echo mysql_real_escape_string(json_encode($folders)); ?>)')
});
var taskList = $('.task-list-table').data('taskList');
and I can use taskList.findTask(condition);
And since the constructor has $elem I can also edit the jQuery instance for methods like list(condition) etc. This works perfectly.
this.each isn't needed. This should do:
$.fn.list = function (options) {
this.find = function(test) {
//function logic
};
return this;
};
Note that you'd be overwriting jQuery's native find method, and doing so isn't recommended.
Also, for what it's worth, I don't think this is a good idea. jQuery instances are assumed to only have methods inherited from jQuery's prototype object, and as such I feel what you want to do would not be consistent with the generally accepted jQuery-plugin behaviour -- i.e. return the this object (the jQuery instance) unchanged.

Categories

Resources