Mark list item as viewed/read in SharePoint 2013 - list

When a user views an item in SharePoint list, I need to capture that it has been viewed and who viewed the item (in additional columns). Is there a way to do that?

I did this by adding a script editor web part and inserting this script in there:
<script type="text/javascript" src="/jquery-1.10.2.min.js"></script>
<script src="/jquery.SPServices-2013.02a.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () { ExecuteOrDelayUntilScriptLoaded(loadConstants, "sp.js"); });
function loadConstants() {
var userid= _spPageContextInfo.userId;
var requestUri = _spPageContextInfo.webAbsoluteUrl + "/_api/web/getuserbyid(" + userid + ")";
var requestHeaders = { "accept" : "application/json;odata=verbose" };
$.ajax({
url : requestUri,
contentType : "application/json;odata=verbose",
headers : requestHeaders,
success : onSuccess,
error : onError
});
function onSuccess(data, request){
var loginName = data.d.Title;
var docurl = document.URL;
var beginindex = docurl.indexOf('?ID=') + 4;
var endindex = docurl.indexOf('&Source=');
var itemid = docurl.substring(beginindex, endindex);
var ctx = new SP.ClientContext("your website url");
var oList = ctx.get_web().get_lists().getByTitle('your library name');
this.oListItem = oList.getItemById(itemid);
this.oListItem.set_item('Read', loginName + ' ' + getTodayDate());
this.oListItem.update();
ctx.executeQueryAsync(
Function.createDelegate(this, this.onQuerySucceeded),
Function.createDelegate(this, this.onQueryFailed)
);
}
function onError(error) {
alert("error");
}
function getTodayDate() {
var today = new Date();
var dd = today.getDate();
var mm = today.getMonth()+1; //January is 0!
var yyyy = today.getFullYear();
if(dd<10){dd='0'+dd} if(mm<10){mm='0'+mm} today = mm+'/'+dd+'/'+yyyy;
return today;
}
}
</script>

Related

SharePoint weather web part

Can any one help me to find out free weather forecast on my sharepoint 2013 site?
I found some limited calls APIs, but not completely free.
I did simple test by Yahoo Weather API.
Create an app in Apps, so you could use id&key&secret to request.
<script type="text/javascript" src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/hmac-sha1.js">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/enc-base64.js">
</script>
<script type="text/javascript">
var url = 'https://weather-ydn-yql.media.yahoo.com/forecastrss';
var method = 'GET';
var app_id = '80ggw87i';
var consumer_key = 'yourkey';
var consumer_secret = 'yoursecret';
var concat = '&';
var query = { 'location': 'sunnyvale,ca', 'format': 'json' };
var oauth = {
'oauth_consumer_key': consumer_key,
'oauth_nonce': Math.random().toString(36).substring(2),
'oauth_signature_method': 'HMAC-SHA1',
'oauth_timestamp': parseInt(new Date().getTime() / 1000).toString(),
'oauth_version': '1.0'
};
var merged = {};
$.extend(merged, query, oauth);
// Note the sorting here is required
var merged_arr = Object.keys(merged).sort().map(function (k) {
return [k + '=' + encodeURIComponent(merged[k])];
});
var signature_base_str = method
+ concat + encodeURIComponent(url)
+ concat + encodeURIComponent(merged_arr.join(concat));
var composite_key = encodeURIComponent(consumer_secret) + concat;
var hash = CryptoJS.HmacSHA1(signature_base_str, composite_key);
var signature = hash.toString(CryptoJS.enc.Base64);
oauth['oauth_signature'] = signature;
var auth_header = 'OAuth ' + Object.keys(oauth).map(function (k) {
return [k + '="' + oauth[k] + '"'];
}).join(',');
$.ajax({
url: url + '?' + $.param(query),
headers: {
'Authorization': auth_header,
'X-Yahoo-App-Id': app_id
},
method: 'GET',
success: function (data) {
console.log(data);
debugger;
}
});
</script>
You need bind the data with proper CSS.

SharePoint 2013 - Attach file to custom list using drag and drop

In Sharepoint 2013, is it possible to drag and drop a file (.jpg , .pdf, .png) to a custom list as an attachment? If so, can this be achieved by using a script (JS, jquery)? So, if a user is reporting a bug (NewForm.aspx), and he has a screenshot of the error message saved as a .jpg, I would want him to be able to drop this file into a drop zone on the form.
Can this scenario work - I would be very grateful for your suggestions?
Here is my tested code.
<style type="text/css">
.droppable {
background: #08c;
color: #fff;
padding: 100px 0;
text-align: center;
}
.droppable.dragover {
background: #00CC71;
}
</style>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script type="text/javascript">
function makeDroppable(element, callback) {
var input = document.createElement('input');
input.setAttribute('type', 'file');
input.setAttribute('id', 'dragdropContent');
input.setAttribute('multiple', true);
input.style.display = 'none';
input.addEventListener('change', triggerCallback);
element.appendChild(input);
element.addEventListener('dragover', function (e) {
e.preventDefault();
e.stopPropagation();
element.classList.add('dragover');
});
element.addEventListener('dragleave', function (e) {
e.preventDefault();
e.stopPropagation();
element.classList.remove('dragover');
});
element.addEventListener('drop', function (e) {
e.preventDefault();
e.stopPropagation();
element.classList.remove('dragover');
triggerCallback(e);
});
element.addEventListener('click', function () {
input.value = null;
input.click();
});
function triggerCallback(e) {
var files;
if (e.dataTransfer) {
files = e.dataTransfer.files;
} else if (e.target) {
files = e.target.files;
}
callback.call(null, files);
}
}
$(function () {
String.prototype.format = function () {
var args = [].slice.call(arguments);
return this.replace(/(\{\d+\})/g, function (a) {
return args[+(a.substr(1, a.length - 2)) || 0];
});
};
var element = document.querySelector('.droppable');
function callback(files) {
// Here, we simply log the Array of files to the console.
//console.log(files);
var fileName = files[0].name;
// Construct the endpoint. mydoc is document library name
var reader = new FileReader();
reader.file = files[0];
reader.onload = function (event) {
var arrayBuffer = event.target.result;
//var fileData = '';
//var byteArray = new Uint8Array(arrayBuffer);
//for (var i = 0; i < byteArray.byteLength; i++) {
// fileData += String.fromCharCode(byteArray[i]);
//}
var fileEndpoint = String.format(
"{0}/_api/web/lists/getByTitle('{1}')/RootFolder/files" +
"/add(overwrite=true, url='{2}')",
_spPageContextInfo.webAbsoluteUrl, 'mydoc', fileName);
//Add the file to the SharePoint folder.
$.ajax({
url: fileEndpoint,
type: "POST",
data: arrayBuffer,//fileData,
processData: false,
headers: {
"X-RequestDigest": jQuery("#__REQUESTDIGEST").val(),
"accept": "application/json;odata=verbose",
"content-length": arrayBuffer.byteLength,
//"IF-MATCH": itemMetadata.etag,
//"X-HTTP-Method": "MERGE"
},
success: function (data, b, c) {
alert('File upload succeeded.');
},
error: function (a, b, err) {
alert('Error: ' + err.responseText);
}
})
};
reader.onerror = function (e) {
alert(e.target.error);
}
var arrayBuffer = reader.readAsArrayBuffer(files[0]);
}
makeDroppable(element, callback);
})
</script>
<div class="droppable">
<p>Drag files here or click to upload</p>
</div>
Update:
This is the control in my test sample:
You could try to debug is any JS error in your page.

How to get Facebook post likes?

I Am trying to retrieve FB Post Likes and Reactions using Graph API. The code that I used to retrieve the 'LIKE','LOVE','HAHA' of a post is shared below.
<script type="text/javascript">
var postID = '';
var access_token = '';
var refreshTime = 1;
var defaultCount = 0;
var reactions = ['LIKE', 'LOVE', 'HAHA'].map(function (e) {
var code = 'reactions_' + e.toLowerCase();
return 'reactions.type(' + e + ').limit(0).summary(total_count).as(' + code + ')'
}).join(',');
function refreshCounts() {
var url = 'https://graph.facebook.com/v2.8/?ids=' + postID + '&fields=' + reactions + '&access_token=' + access_token;
$.getJSON(url, function(res){
var v1 = res[postID].reactions_like.summary.total_count;
var v2 = res[postID].reactions_love.summary.total_count;
var v3 = res[postID].reactions_haha.summary.total_count;
$('#counter1').text(v1);
$('#counter2').text(v2);
$('#counter3').text(v3);
});
}
$(document).ready(function(){
setInterval(refreshCounts, refreshTime * 3000);
refreshCounts();
});
</script>
But the code showing two {} instead of the result.
Why don't you using javascript SDK?
var postID = $('#post_id').val();
FB.api(
'/' + postID + '/',
'GET',
{
"fields": "reactions.type(LIKE).limit(0).summary(1).as(like),reactions.type(WOW).limit(0).summary(1).as(wow),reactions.type(SAD).limit(0).summary(1).as(sad),reactions.type(LOVE).limit(0).summary(1).as(love),reactions.type(HAHA).limit(0).summary(1).as(haha),reactions.type(ANGRY).limit(0).summary(1).as(angry)",
"access_token": "token"
},
function (response) {
console.log(response);
var like_count = response.like.summary.total_count;
var love_count = response.love.summary.total_count;
var wow_count = response.wow.summary.total_count;
var haha_count = response.haha.summary.total_count;
var sad_count = response.sad.summary.total_count;
var angry_count = response.angry.summary.total_count;
}
);
This worked for me

Sorted duration time for Google Table Chart

I want to sort the column 2 (duration) descending or ascending.
This is the code:
https://jsfiddle.net/guilhermelight1/no7xvnLu/13/
#table_div tbody tr td:nth-child(3){
text-transform: uppercase;
}
<script type="text/javascript" src="https://www.google.com/jsapi?autoload={'modules':[{'name':'visualization','version':'1.1','packages':['table']}]}"></script>
<div id="table_div"></div>
google.setOnLoadCallback(drawTable);
function drawTable() {
var opts = {sendMethod: 'auto'};
var query = new google.visualization.Query('https://spreadsheets.google.com/tq?key=1mYtjx7_EP3k888Ep7oU92wk5J24EZn4UWwxKZAkFhHY&sheet=B', opts);
query.setQuery("select A,B,C ");
query.send(handleQueryResponse);
}
function handleQueryResponse(response) {
if (response.isError()) {
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
var data = response.getDataTable();
var formatter = new google.visualization.DateFormat({pattern: 'HH:mm'});
formatter.format(data, 2);
var table = new google.visualization.Table(document.getElementById('table_div'));
table.draw(data, {showRowNumber: true});
}
assuming the decimal column represents seconds
the following snippet uses a DataView to add a calculated column for sorting...
google.charts.load('current', {
callback: drawTable,
packages:['table']
});
function drawTable() {
var opts = {sendMethod: 'auto'};
var query = new google.visualization.Query('https://spreadsheets.google.com/tq?key=1mYtjx7_EP3k888Ep7oU92wk5J24EZn4UWwxKZAkFhHY&sheet=B', opts);
query.setQuery("select A,B,C ");
query.send(handleQueryResponse);
}
function handleQueryResponse(response) {
if (response.isError()) {
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
var data = response.getDataTable();
var formatter = new google.visualization.DateFormat({pattern: 'hh:mm:ss'});
var timeColumn = 2;
var viewColumns = [];
var view = new google.visualization.DataView(data);
for (var i = 0; i < data.getNumberOfColumns(); i++) {
viewColumns.push(i);
}
viewColumns.push({
label: data.getColumnLabel(timeColumn),
type: 'date',
calc: function (dt, row) {
var dateValue = new Date();
dateValue = new Date(dateValue.getFullYear(), dateValue.getMonth(), dateValue.getDate());
dateValue = new Date(dateValue.getTime() + (dt.getValue(row, timeColumn) * 1000));
return {
v: dateValue,
f: formatter.formatValue(dateValue)
};
}
});
view.setColumns(viewColumns);
var table = new google.visualization.Table(document.getElementById('table_div'));
table.draw(view, {showRowNumber: true});
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="table_div"></div>

Accessing an event's target in famo.us

How can one access the target of an event, say a click, form the code?
I have:
var eh = new EventHandler();
and
eh.on('click', function(obj) {
rc.setOptions(
{
inTransition: true,
outTransition: false
});
var surfaceProps = obj.origin.getProperties();
as part of a sample app. The surfaces created in a function before in the code pipe click events to this eh event handler as;
surf.pipe(eh);
However, The clicks does not work as expected. In JS console it gives the following error:
TypeError: undefined is not an object (evaluating 'obj.origin.getProperties')
In the sample app, they are referring to a custom event emitted from within the selection within their Scrollview to an EventHandler. The article you refer to was written early in the releases of Famo.us.
The code snippet below will show how this could be done using the 'click' as the custom event. Probably not best practices, because it is an event for the mouse click event (MouseEvent). I would rename it to something else in a production app.
define('main', function(require, exports, module) {
var Engine = require('famous/core/Engine');
var OptionsManager = require('famous/core/OptionsManager');
var Surface = require('famous/core/Surface');
var Modifier = require('famous/core/Modifier');
var EventHandler = require('famous/core/EventHandler');
var StateModifier = require('famous/modifiers/StateModifier');
var RenderNode = require('famous/core/RenderNode');
var View = require('famous/core/View');
var Transform = require('famous/core/Transform');
var SequentialLayout = require("famous/views/SequentialLayout");
var mainContext = Engine.createContext();
var sequentialLayout = new SequentialLayout();
var surfaces = [];
sequentialLayout.sequenceFrom(surfaces);
var eh = new EventHandler();
eh.on('click', function(obj) {
console.log('obj event', obj.event);
var surfaceProps = obj.origin.getProperties();
console.log('obj properties', JSON.stringify(surfaceProps));
});
function _eventHandler(e) {
console.log('event', e, this);
var surfaceProps = this.getProperties();
console.log('surfaceProps', surfaceProps);
this.setContent(JSON.stringify(surfaceProps));
eh.emit('click', {
event: e,
origin: this
});
};
var numberofItems = 10;
var itemHeight = 45;
var itemWidth = 20;
for (var i = 0; i < numberofItems; i++) {
var surface = new Surface({
properties: {
backgroundColor: "hsl(" + (i * 360 / 120) + ", 100%, 50%)",
}
});
surface._mod = new StateModifier({
size: [itemWidth, itemHeight], // <- Changed the width here!!!
origin: [0.5, 0],
align: [0.5, 0],
proportions: [i + 1, 1]
});
var view = new RenderNode();
view.add(surface._mod).add(surface);
view._surface = surface;
surfaces.push(view);
//surface.pipe(eh);
surface.on('click', _eventHandler);
}
mainContext.add(sequentialLayout);
Engine.on('click', function(e) {
for (var i = 0; i < surfaces.length; i++) {
var random = Math.random() * surfaces.length + itemWidth;
surfaces[i]._surface._mod.setProportions([random, 1], {
duration: 1000
});
}
});
});
require(['main']);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://requirejs.org/docs/release/2.1.16/minified/require.js"></script>
<script src="http://code.famo.us/lib/requestAnimationFrame.js"></script>
<script src="http://code.famo.us/lib/classList.js"></script>
<script src="http://code.famo.us/lib/functionPrototypeBind.js"></script>
<link rel="stylesheet" type="text/css" href="http://code.famo.us/famous/0.3.5/famous.css" />
<script src="http://code.famo.us/famous/0.3.5/famous.min.js"></script>
<div class="test-container">
<div id="famous-app"></div>
</div>
If I'm understanding your question correctly, this feature just landed in the latest release:Add the famous source object to forwarded events
Now you can just do:
eh.on('click', function(event) {
var famousSurface = event.target;
var domElement = famousSurface._currentTarget;
});