SPO Modern: How to inject and execute webpart programmatically, using js? - sharepoint

I have only the URL of webpart (example 'https://sitename.com/sites/site-colection/ClientSideAssets/hereisguid/webpartname.js') and I need to inject and run it programmatically via js, is it possible?

It's not officially supported but You can use global variable (available on every modern page) _spComponentLoader. The problem is - it requires You to provide WebPartContext which You cannot simply get outside of SPFx.
If You want to do it in SPFx here is a sample code:
webPartId = hereisguid from Your url
let component = await _spComponentLoader.loadComponentById(webPartId);
let manifest = _spComponentLoader.tryGetManifestById(webPartId);
let wpInstance = new component.default();
context.manifest = manifest;
//#ts-ignore
context._domElement = document.getElementById("<id-of-element-you-want-wp-to-render-in>")
await wpInstance._internalInitialize(context, {}, 1);
wpInstance._properties = webPart.properties;
await wpInstance.onInit();
wpInstance.render();
wpInstance._renderedOnce = true;
Again - I don't think it's supported so try it on Your own risk.
Note this web part must be available at the site You are going to execute this script.

Related

Can navigator give you the language/languages in Angular Universal?

My question stems from the fact that navigator works for the browser but we don't have that on the server but in our codebase at work I have seen code like this:
navigator.language.slice(0, 2);
and of course we are using domino to provide these window objects
win.Object = Object;
win.Math = Math;
global["window"] = win;
global["document"] = win.document;
global["branch"] = null;
global["object"] = win.object;
global["HTMLElement"] = win.HTMLElement;
global["navigator"] = win.navigator;```
No it cannot, domino provides a fake DOM server side.
You will need to either use a separate url for each language of your website, and/or save user preferences in cookies so that you can use the right language during SSR.

How to download documents from liferay from outside application ..using liferay jsonws or any other way

Hi i am using liferay/api/secure/jsonws services to upload documents, getting documents, from a outside application , in the same way i want to download the documents also, i checked my liferay jsonws , there is no method or service which i can use for download , or i don't know about it , please suggest me a way to download documents from outside application , by using jsonws or any other way is also fine.
Edit after i got to know how to download document.
Hi I tried to download liferay document from outside application by using getURl, but every time for all document i am getting liferay login page content
i have already tried get-file-as-stream json-rpc call but that also giving me null response
the code which i have used is:
final HttpHost targetHost = new HttpHost(hostname.trim());
System.out.println(targetHost.getHostName());
UsernamePasswordCredentials creds = new UsernamePasswordCredentials(username, password);
System.out.println(creds);
final AuthScope authscope = new AuthScope(targetHost);
httpclient.getCredentialsProvider().setCredentials(authscope, creds);
final AuthCache authCache = new BasicAuthCache();
final BasicScheme basicAuth = new BasicScheme();
authCache.put(targetHost, basicAuth);
final BasicHttpContext localContext = new BasicHttpContext();
localContext.setAttribute(ClientContext.AUTH_CACHE, authCache);
final HttpGet httpget = new HttpGet(hostname+"/documents/" + groupId + "/" + folderId + "/" + filename);
final HttpResponse response = httpclient.execute( httpget, localContext);
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
final org.apache.http.HttpEntity entity = response.getEntity();
if (entity != null) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
entity.writeTo(baos);
return baos.toByteArray();
}
}
return null;
} finally {
httpclient.getConnectionManager().shutdown();
}
}
i am adding basic auth header will correct username and password, don't know how this login page is coming, is there any permission which i need to change or any configurations issue, please help in this.
You could use the Liferay WebDav Services to download files from your document-library. The paths to download can be inspected inside of the control-panel when clicking on a file entry (WebDAV URL toogle link). The paths usually look like: /webdav/{site-name}/document_library/{folder-name}/{file-name}
Otherwise, you could mimic the request URLs Liferay creates inside the documents-media portlet to download the file entry.
But you should take care about authentication, when your files (and folders) are not visible to guests.

PNP-JS Create File from File Lib template

I need to create/add a new File from Files Lib, then i need to set the name of the file with an unique ID and update other fieds. I can update the fields without any problems, but i couldn't find a way to create the file.
How can i possibly achieve the New => Create from template like in the image below
I've tried many ways but nothing fullfill my request.
1
this.web.lists.getByTitle('myFilesLib').items.add() => i get an error about the need to use SPFileCollection.Add()
2
this.web.getFolderByServerRelativeUrl(url).files.addTemplateFile => there is nothing for custom template
3
this.web.getFolderByServerRelativeUrl(url).files.add => i need to provide a file.
For JSOM, you can try this:
newFile = parentList.get_rootFolder().get_files().add(fileCreateInfo);
For CSOM:
var creationInformation = new ListItemCreationInformation();
Microsoft.SharePoint.Client.ListItem listItem = list.AddItem(creationInformation);
listItem.FieldValues["Foo"] = "Bar";
listItem.Update();
clientContext.ExecuteQuery();
Some wiki for this way: https://social.technet.microsoft.com/wiki/contents/articles/37575.sharepoint-online-working-with-files-inside-document-library-using-jsom.aspx
this.web.getFolderByServerRelativeUrl(url).files.addTemplateFile is used to add page, so it is not suitable for your scenario.
http://www.ktskumar.com/2016/08/pnp-js-core-create-new-page-sharepoint-library/
The PnP JS method requires a File DOM or BLOB object for uploading a file to the SharePoint. Based on the those, we will try two options to upload a file to the SharePoint Library or folder in a library:BLOB/FileAPI
http://www.ktskumar.com/2016/09/pnp-js-core-upload-file-sharepoint/
More reference for you from Microsoft:
https://msdn.microsoft.com/en-us/library/office/dn450841.aspx
This is a sample code to use when you want to upload an existing ContentType to your content library on SharePoint.
const templateUrl = '/sites/App/Template/Forms/Template/test.docx'
const name = 'test.docx'
const depositUrl = '/sites/App/Template'
const web = new Web('http://localhost:8080/sites/App'); // Proxy URL for Dev
web.getFileByServerRelativeUrl(templateUrl)
.getBuffer()
.then((templateData: ArrayBuffer) => {
web.getFolderByServerRelativeUrl(depositUrl).files.add(name, templateData));
});
There is an issue if you use SP-Rest-Proxy at the moment (file is corrupted on SharePoint) but it should be fix soon.
If you Deploy your app on SharePoint, it work as expected.
Related links:
https://github.com/pnp/pnpjs/issues/196#issuecomment-410908170
https://github.com/koltyakov/sp-rest-proxy/issues/61

How to provision Branding files using SharePoint Hosted App in SharePoint Online/Office 365?

I am looking for SharePoint Hosted App Solution which will provision Branding files (JS/CSS/Images) into SharePoint Online/Office 365 environment.
I got a very good article to achive this and tried to implement the same as shown in below link: http://www.sharepointnutsandbolts.com/2013/05/sp2013-host-web-apps-provisioning-files.html
This solution is not working for me and while execution of app, I am getting below error:
Failed to provision file into host web. Error: Unexpected response data from server. Here is the code which is giving me error:
// utility method for uploading files to host web..
uploadFileToHostWebViaCSOM = function (serverRelativeUrl, filename, contents) {
var createInfo = new SP.FileCreationInformation();
createInfo.set_content(new SP.Base64EncodedByteArray());
for (var i = 0; i < contents.length; i++) {
createInfo.get_content().append(contents.charCodeAt(i));
}
createInfo.set_overwrite(true);
createInfo.set_url(filename);
var files = hostWebContext.get_web().getFolderByServerRelativeUrl(serverRelativeUrl).get_files();
hostWebContext.load(files);
files.add(createInfo);
hostWebContext.executeQueryAsync(onProvisionFileSuccess, onProvisionFileFail);
}
Please suggest me, what can be the issue in this code? Or else suggest me another way/reference in which I can Create a SharePoint-Hosted App to provision Branding Files.
Thanks in Advance!
I would use a different method to access host web context as follows:
//first get app context, you will need it.
var currentcontext = new SP.ClientContext.get_current();
//then get host web context
var hostUrl = decodeURIComponent(getQueryStringParameter("SPHostUrl"));
var hostcontext = new SP.AppContextSite(currentcontext, hostUrl);
function getQueryStringParameter(param) {
var params = document.URL.split("?")[1].split("&");
var strParams = "";
for (var i = 0; i < params.length; i = i + 1) {
var singleParam = params[i].split("=");
if (singleParam[0] == param) {
return singleParam[1];
}
}
}
Here are some references:
https://sharepoint.stackexchange.com/questions/122083/sharepoint-2013-app-create-list-in-host-web
https://blog.appliedis.com/2012/12/19/sharepoint-2013-apps-accessing-data-in-the-host-web-in-a-sharepoint-hosted-app/
http://www.mavention.com/blog/sharePoint-app-reading-data-from-host-web
http://www.sharepointnadeem.com/2013/12/sharepoint-2013-apps-access-data-in.html
Additionally, here is an example of how to deploy a master page, however as you might notice during your testing the method used to get host web context is not working as displayed in the video and you should use the one I described before.
https://www.youtube.com/watch?v=wtQKjsjs55I
Finally, here is a an example of how to deploy branding files through a Console Application using CSOM, if you are smart enough you will be able to convert this into JSOM.
https://channel9.msdn.com/Blogs/Office-365-Dev/Applying-Branding-to-SharePoint-Sites-with-an-App-for-SharePoint-Office-365-Developer-Patterns-and-P

How can I tell if a web client is blocking advertisements?

What is the best way to record statistics on the number of visitors visiting my site that have set their browser to block ads?
Since programs like AdBlock actually never request the advert, you would have to look the server logs to see if the same user accessed a webpage but didn't access an advert. This is assuming the advert is on the same server.
If your adverts are on a separate server, then I would suggest it's impossible to do so.
The best way to stop users from blocking adverts, is to have inline text adverts which are generated by the server and dished up inside your html.
Add the user id to the request for the ad:
<img src="./ads/viagra.jpg?{user.id}"/>
that way you can check what ads are seen by which users.
You need to think about the different ways that ads are blocked. The first thing to look at is whether they are running noscript, so you could add a script that would check for that.
The next thing is to see if they are blocking flash, a small movie should do that.
If you look at the adblock site, there is some indication of how it does blocking:
How does element hiding work?
If you look further down that page, you will see that conventional chrome probing will not work, so you need to try and parse the altered DOM.
AdBlock forum says this is used to detect AdBlock. After some tweaking you could use this to gather some statistics.
setTimeout("detect_abp()", 10000);
var isFF = (navigator.userAgent.indexOf("Firefox") > -1) ? true : false,
hasABP = false;
function detect_abp() {
if(isFF) {
if(Components.interfaces.nsIAdblockPlus != undefined) {
hasABP = true;
} else {
var AbpImage = document.createElement("img");
AbpImage.id = "abp_detector";
AbpImage.src = "/textlink-ads.jpg";
AbpImage.style.width = "0";
AbpImage.style.height = "0";
AbpImage.style.top = "-1000px";
AbpImage.style.left = "-1000px";
document.body.appendChild(AbpImage);
hasABP = (document.getElementById("abp_detector").style.display == "none");
var e = document.getElementsByTagName("iframe");
for (var i = 0; i < e.length; i++) {
if(e[i].clientHeight == 0) {
hasABP = true;
}
}
if(hasABP == true) {
history.go(1);
location = "http://www.tweaktown.com/supportus.html";
window.location(location);
}
}
}
}
I suppose you could compare the ad prints with the page views on your website (which you can get from your analytics software).

Resources