I am new into javascript and sharepoint.
Say, there are two lists, list1 (Process, ProcessImage), list2 (SubProcess, Process). In list2 "Process" is a lookup value from list1. The count of all three Process, SubProcess and ProcessImage is not fixed, so say n number.
Using JavaScript and HTML, I need to show the data on a Page like this:
List1
Process ProcessImage
Process1 ProcessImage1
Process2 ProcessImage2
Process3 ProcessImage3
: :
: :
ProcessN ProcessImageN
List2
SubProcess Process
SubProcess1 Process2
SubProcess2 Process2
SubProcess3 Process1
SubProcess4 Process4
: :
SubProcessN Process3
Result in Tabular Form Using Javascript and HTML
ProcessImage1 ProcessImage2 ProcessImage3 ProcessImage4
SubProcess3 SubProcess1 SubProcess4
SubProcess2
If you're using SharePoint 2010 or above, you can use the JavaScript Object Model (JSOM) to access the list items programmatically, as in the following example code.
<style>
/* Adjust this CSS as necessary to adjust the style of your table */
#custom_output{display:table; }
.column_outer{display:table-cell; font-weight:bold; min-width:100px;}
.column_inner{font-weight:normal; margin:4px;}
</style>
<div id="custom_output"></div>
<script>
SP.SOD.executeOrDelayUntilScriptLoaded(function(){
var output = document.getElementById("custom_output");
var clientContext = new SP.ClientContext();
var lists = clientContext.get_web().get_lists();
var query = new SP.CamlQuery(); // blank query to get all items
var parentListItems = lists.getByTitle("List1").getItems(query),
childListItems = lists.getByTitle("List2").getItems(query);
clientContext.load(parentListItems);
clientContext.load(childListItems);
clientContext.executeQueryAsync(
function(){ // on success callback function
var columnMap = createColumns(parentListItems);
createAndAppendCells(childListItems, columnMap);
},
function(sender, args){ // on error callback function
alert(args.get_message());
}
);
// this function builds HTML columns and returns a handy reference map
function createColumns(parentListItems){
var parentEnumerator = parentListItems.getEnumerator(),
columnMap = {};
while(parentEnumerator.moveNext()){
var item = parentEnumerator.get_current();
columnMap[item.get_item("ID")] = createColumn(item);
}
return columnMap;
}
// this function adds a column to the HTML and returns a reference to a div inside it (so we can add cells later)
function createColumn(item){
var outer = document.createElement("div"),
inner = document.createElement("div"),
title = item.get_item("Process");
outer.className = "column_outer";
inner.className = "column_inner";
output.appendChild(outer).appendChild(document.createTextNode(title));
outer.appendChild(inner);
return inner;
}
// this function creates a cell for each child list item and appends it to the appropriate column
function createAndAppendCells(childListItems, columnMap){
var childEnumerator = childListItems.getEnumerator();
while(childEnumerator.moveNext()){
item = childEnumerator.get_current();
var lookup = item.get_item("Process");
if(lookup){
columnMap[lookup.get_lookupId()].appendChild(createCell(item));
}
}
}
// this function creates a cell with text derived from the given list item
function createCell(item){
var cell = document.createElement("div");
cell.innerHTML = item.get_item("SubProcess");
return cell;
}
},"sp.js");
</script>
How you would go about embedding that code on a page depends on the version of SharePoint you're using.
In SharePoint 2010, you can save your HTML/CSS/JavaScript as an HTML file in a document library, then embed it on a page using a Content Editor web part (editing its "Content Link" property to be the URL of the HTML file).
In SharePoint 2013+ you can also use a script editor web part. You can also use SharePoint Designer to create and edit a page to add JavaScript.
Related
For some reason, my website still showing images that were already deleted from the specified folder and I have no idea why that's happening and how to solve that.
Process: When the button to delete all admins is pressed, it calls a PHP function that truncate the tables administration, adminimg and login, delete all images from a folder related to id's on table administration with unlink(), and create a registry on administration table with id=1(auto_increment) and name="abc".
Problem: I have a jQuery function that display a specific admin information on textboxes, verify the value in the textbox for the adminID, and display the image associated to that id. After executing the process above, when i call the jQuery function, it display correctly the id=1 and name="abc" but shows the deleted image associated to the admin with id=1 before truncate the tables.
jQuery function (if necessary)
$(".btneditadmin").click( e =>{
let textvalues = displayDataAdmin(e);
let id = $("input[name*='idadmin']");
let name = $("input[name*='nameadmin']");
id.val(textvalues[0]);
nome.val(textvalues[1]);
var img_url = 'Images/Administration/admin'+$("#idadmin").val()+'.jpg';
$("#admin-image").attr('src',img_url);
});
function displayDataAdmin(e) {
let id = 0;
const td = $("#tbody tr td");
let textvalues = [];
for (const value of td){
if(value.dataset.id == e.target.dataset.id){
textvalues[id++] = value.textContent;
}
}
return textvalues;
}
If you're sure that image isn't there anymore then it's caching issue and something like this would take care of it
let img_url = 'Images/Administration/admin'+$("#idadmin").val()+'.jpg';
img_url += '?' + new Date().getTime() ; // cache killer
$("#admin-image").attr('src', img_url);
However, you're calling that function no matter what so I would suggest a onload/error check
$('#admin-image').load(function(){ // when loaded successfully
console.log('success');
}).error(function(){ // when theres an error
$(this).remove()
// or you could replace it with a default image
$(this).attr('src', '/images/default.jpg');
});
I have a question I am working with a form based shopping cart add function and a livesearch (PHP) function where it requests new data with the same classes. I have seen multiple examples besides (document.ready) but none of them seemed to work correctly after the DOM Content has been modified by the PHP livesearch function. (The current method is on the document ready function as you guys can see.
Thanks in advance!
// Icon Click Focus
$('.product').on('click', function() {
var strId = '';
var strId = $(this).attr('class');
var strId2 = strId.replace(' product','');
var strId3 = strId2.replace('product-','');
var formData = "product"+strId3;
document.getElementById("product_toevoeg_id").value = strId3;
var productNaam = $("#"+formData+" .f-productnaam").val();
document.getElementById("productnaam").innerHTML = productNaam;
document.getElementById("product_naam_form").value = productNaam;
var productIngredienten = $("#"+formData+" .f-ingredienten").val();
document.getElementById("ingredienten").innerHTML = productIngredienten;
document.getElementById("ingredienten_form").value = productIngredienten;
I have this page where I have a ranking system. For the ranking to display I create some elements on a loop through javascript, according to the data that I fetch from the database. Then, I want the data to change when the database changes, but instead of having to reload the page, I want it to reload just the div related to the ranking content. The problem is that when I call the function $(#idOfRankingsParent).load("index.php #idOfRankingsChild), it doesn't load anything because the content is only created after the DOM is fully loaded (because of the document.createElement, and appendChild, etc). Is there any way for me to load the content after every element is created?
So, I have this function being called on a setInterval:
function loadContent() {
console.log("loaded");
$( "#ranking-container" ).load("index.php #ranking-wrapper");
rankingList.style.filter="blur(0)";
}
setInterval(loadContent, 5500);
Then I have this function creating the elements, and being called as soon as possible:
function createRanks() {
(...)
var pontosOrdered = x;
var equipasOrdered = y;
for (var t=0; t<equipasOrdered.length; t++) {
var rankLi = document.createElement("li");
rankingList.appendChild(rankLi);
if (t===0) {rankLi.id="first-place";}
if (t===1) {rankLi.id="second-place";}
if (t===2) {rankLi.id="third-place";}
var lugarP = document.createElement("p");
rankLi.appendChild(lugarP);
lugarP.classList.add("lugar");
lugarP.innerHTML=t+1;
var nomeEquipaP = document.createElement("a");
rankLi.appendChild(nomeEquipaP);
nomeEquipaP.innerHTML=equipasOrdered[t];
nomeEquipaP.href="/equipas/#"+nameToLowerCase(equipasOrdered[t]);
var pontosP = document.createElement("p");
rankLi.appendChild(pontosP);
pontosP.classList.add("pontos");
pontosP.innerHTML=pontosOrdered[t];
}
}
$(document).ready(function() {
createRanks();
});
(edited)
I have here some prints of the page when I load the first time:
And when the div loads:
I am trying to generate a view based on the current user's group name. Group Name I am gathering from the custom list.
My question is how to apply the gathered group name to 'Group Name' column as a view parameter.
The only solution I figured:
I have created a view with a parameter.
I have added an HTML Form Web Part into the same page and connected it to the list view (sending the value to the parameter via web part connection). Then with a window.onload function I gather the current user's group name and pass this value via Form Postback function. But since the Postback function triggers full page reload, it falls into the endless loop of form submission > page reload.
Another way I have tried is attaching a click event listener to the BY MY GROUPS tab and it works perfectly, but the only disadvantage is that the page reloads each time user clicks on this tab, which I would like to avoid.
So the solution that I need is a way to post the form without a page reload.
Another option suggested here is to use CSR (client side rendering), but that has its own problems:
This code does not work as it is supposed to. In the console it shows me correct items, but the view appears untouchable.
Even if it worked, the other column values are still viewable in the column filter, as in this screenshot:
So, it seems that CSR just hides items from the view (and they are still available). In other words its behavior is different from, for example, a CAML query.
Or am I getting it wrong and there's something wrong with my code?
Below you can find my CSR code:
<script type='text/javascript'>
(function() {
function listPreRender(renderCtx) {
SP.SOD.executeFunc('sp.js', 'SP.ClientContext', function() {
var currUserID = _spPageContextInfo.userId;
var cx = new SP.ClientContext('/sites/support');
var list = cx.get_web().get_lists().getByTitle('Group Members');
var items = list.getItems(SP.CamlQuery.createAllItemsQuery());
cx.load(items, 'Include(_x006e_x50,DepID)');
cx.executeQueryAsync(
function() {
var i = items.get_count();
while (i--) {
var item = items.getItemAtIndex(i);
var userID = item.get_item('_x006e_x50').get_lookupId();
var group = item.get_item('DepID').get_lookupValue();
if (currUserID === userID) {
var rows = renderCtx.ListData.Row;
var customView = [];
var i = rows.length;
while (i--) {
var show = rows[i]['Group_x0020_Name'] === group;
if (show) {
customView.push(rows[i]);
}
}
renderCtx.ListData.Row = customView;
renderCtx.ListData.LastRow = customView.length;
console.log(JSON.stringify(renderCtx.ListData.Row));
break;
}
}
},
function() {
alert('Something went wrong. Please contact developer')
}
);
});
}
function registerListRenderer() {
var context = {};
context.Templates = {};
context.OnPreRender = listPreRender;
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(context);
}
ExecuteOrDelayUntilScriptLoaded(registerListRenderer, 'clienttemplates.js');
})();
</script>
I'm having trouble getting Google's load feed to work. Example is supposed to be at www.eslangel.com
I put this code in the header
<script type="text/javascript"
src="https://www.google.com/jsapi?key=ABQIAAAAO2BkRpn5CP_ch4HtkkOcrhQRKBUhIk5KoCHRT6uc9AuUs_-7BhRyoJdFuwAeeqxoUV6mD6bRDZLjSw">
</script>
And then, just to test, I copied and pasted their sample code using a Digg feed into the body of my blog, but there's no result of any kind.
Does anyone have any idea what I might be doing wrong?
/*
* How to load a feed via the Feeds API.
*/
google.load("feeds", "1");
// Our callback function, for when a feed is loaded.
function feedLoaded(result) {
if (!result.error) {
// Grab the container we will put the results into
var container = document.getElementById("content");
container.innerHTML = '';
// Loop through the feeds, putting the titles onto the page.
// Check out the result object for a list of properties returned in each entry.
// http://code.google.com/apis/ajaxfeeds/documentation/reference.html#JSON
for (var i = 0; i < result.feed.entries.length; i++) {
var entry = result.feed.entries[i];
var div = document.createElement("div");
div.appendChild(document.createTextNode(entry.title));
container.appendChild(div);
}
}
}
function OnLoad() {
// Create a feed instance that will grab Digg's feed.
var feed = new google.feeds.Feed("http://www.digg.com/rss/index.xml");
// Calling load sends the request off. It requires a callback function.
feed.load(feedLoaded);
}
google.setOnLoadCallback(OnLoad);
Well, did you also create a container for the feed? :-)
Try placing
<div id="content"></div>
before the feed loading script.