How to get a SharePoint-UserField with JavaScript? - javascript

Hallo,
i need to write some javascript that gets the contents of a userfield in a sharepoint-website. I can get most fields with the javascript-function 'getTagFromIdentifierAndTitle' of Using Javascript to Manipulate a List Form Field, but not UserFields.
So how can i get UserFields?
Thanks!

I traced how address book interacts with user field. To get values it uses function getUplevel(ctx) and to set values can be used function EntityEditorCallback(xml, ctx). First function will return html/xml mixed string with user information. Second function input must be special formatted xml string.
// Get values
var ctx='ctl00_m_g_e5a1501a_..._ctl04_ctl00_ctl00_UserField';
var values=getUplevel(ctx);
alert(values);
// Set values
var xml='<Entities Append="False" Error="" Separator=";" MaxHeight="3">'+
'<Entity Key="DOMAIN\\loginname" DisplayText="Display Name" IsResolved="True" Description="DOMAIN\\loginname">'+
'<ExtraData>'+
'<ArrayOfDictionaryEntry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">'+
'<DictionaryEntry><Key xsi:type="xsd:string">DisplayName</Key><Value xsi:type="xsd:string">Display Name</Value></DictionaryEntry>'+
'<DictionaryEntry><Key xsi:type="xsd:string">Email</Key><Value xsi:type="xsd:string">Display.Name#domain.ee</Value></DictionaryEntry>'+
'<DictionaryEntry><Key xsi:type="xsd:string">SPUserID</Key><Value xsi:type="xsd:string">1</Value></DictionaryEntry>'+
'<DictionaryEntry><Key xsi:type="xsd:string">PrincipalType</Key><Value xsi:type="xsd:string">User</Value></DictionaryEntry>'+
'</ArrayOfDictionaryEntry>'+
'</ExtraData>'+
'<MultipleMatches />'+
'</Entity>'+
'</Entities>';
EntityEditorCallback(xml,ctx);
Tricky part is ctx attribute that must be target field id. In user field html there is no title attribute, so to find right element by display name with js is very complex. I suggest to pass field id to the javascript from server side. For example you can create custom WebPart where you write to the page field id-s from collection SPContext.Current.FormContext.FieldControlCollection.

Here is the custom code that I put together. It relies on the exact HTML that SharePoint uses for the PeoplePicker. It does work on both IE and Firefox. For the columnName parameter, pass the "public" name of the column, not the internal name.
function getParentElementByTagName(baseNode, tagName)
{
var currNode;
if(baseNode !== null)
{
currNode = baseNode.parentNode;
while((currNode !== null) && (currNode.nodeName != tagName))
{
currNode = currNode.parentNode;
}
return currNode;
}
else
{
return null;
}
}
function getPeoplePickerCell(columnName)
{
var search = 'FieldName="' + columnName + '"';
var nodes = document.getElementsByTagName("TEXTAREA");
for(var i=0; i < nodes.length; i++)
{
if(nodes[i].title == "People Picker")
{
var outerCell = getParentElementByTagName(nodes[i], "SPAN").parentNode.parentNode;
if(outerCell.innerHTML.indexOf(search) > 0)
{
return nodes[i].parentNode;
}
}
}
return null;
}
function getSPPeoplePicker(columnName, value)
{
var cell = getPeoplePickerCell(columnName);
if(cell !== null)
{
return cell.childNodes[0].innerHTML;
}
else
{
return null;
}
}
function setSPPeoplePicker(columnName, value)
{
var cell = getPeoplePickerCell(columnName);
if(cell !== null)
{
cell.childNodes[0].innerHTML = value;
cell.childNodes[1].value = value;
}
}
function disableSPPeoplePicker(columnName)
{
var cell = getPeoplePickerCell(columnName);
if(cell !== null)
{
disableElement(cell.childNodes[0]);
disableElement(cell.childNodes[1]);
}
}
function enableSPPeoplePicker(columnName)
{
var cell = getPeoplePickerCell(columnName);
if(cell !== null)
{
enableElement(cell.childNodes[0]);
enableElement(cell.childNodes[1]);
}
}

Related

Pass Array as a parameter in Javascript

This function is used to check if the checkbox is selected or not.Can somebody help how to pass the array as a parameter to URL which will call a stored procedure.
function js_remove_masters(theForm) {
var vCheckedCount = 0;
var vContinue = true;
var mycheckedarr = [];
var myuncheckedarr = [];
//check to see if anything is selected
if ((theForm.selected.length == null) && (!(theForm.selected.checked))) {
vContinue = false;
alert("Please select an item to be deleted.");
} else if (theForm.selected.length != null) {
for (var i = 0; i < theForm.selected.length; i++) {
if (theForm.selected[i].checked) {
vCheckedCount = 1;
mycheckedarr.push = theForm.selected[i].value;
} else {
myuncheckedarr.push = theForm.selected[i].value;
}
}
if (vCheckedCount == 0) {
vContinue = false;
alert("Please select an item to be deleted.");
}
}
if (vContinue) {
theForm.action = ("library_search_pkg_nv1.remove_checkin_masters");
-- - here how to pass array parameters
theForm.submit();
}
}
procedure remove_masters(
masterID in smallarray
default smallempty,
masterIDunselected in smallarray
default smallempty
);
Just get rid of the JavaScript entirely. You are submitting the form.
If a checkbox is checked then its name/value pair will be included in the form data.
If it isn't checked, then it won't be.
If you have a bunch of checkboxes (or other elements) with the same name, then most server side form data parsing libraries will express that as an array automatically. The main exception is PHP which requires that you put [] on the end of the name first.

javascript input value changes not taking effect? Calculation field value does not change?

I am using javascript to populate a page which has a calculation field. The calculation field only gets set when i click on the page or tab manually. I don't think javascript is populating the fields until i click tab.
Iv tried runing a methoud to foucus on all the inputs.
function PushTab()
{
//could not get this working as i could not select a input with js and run the trigger function of jq .. mixing js with jquery is bad.
//$(this).trigger({
// type: 'keypress',
// which: 9
//});
var doc = window.frames['main'].window.frames['content'].document;
var tabbables = doc.querySelectorAll("input");
for (var i = 0; i < tabbables.length; i++) {
tabbables[i].focus();
}
}
Could someone tell me how i could trigger all my javascript changes to take affect, something that simulates a users tab or click on page?
Edit
How i change the values.
function SetElementValue(name, value) {
var elementType = "input";
element = GetElement(elementType, name);
if (element != null) {
element.value = value;
return;
}
function GetElement(type, name) {
var doc = window.frames['main'].window.frames['content'].document;
if (doc != null) {
var aTags = doc.getElementsByTagName(type);
var searchText = name;
var found;
for (var i = 0; i < aTags.length; i++) {
if (aTags[i].name.trim() == searchText) {
found = aTags[i];
//alert(found.type);
return found;
break;
}
}
}
return found;
}

Access js array in another js file

I fill my array in the checklistRequest.js and I want to access it in my Termine_1s.html file which contains js code. I can access it but when I want to iterate through it, it gives me only single digits instead of the strings.
How can I solve this?
checklistRequest.js
//Calls the checkbox values
function alertFunction()
{
//Retrieve the object from storage
var retrievedObject = localStorage.getItem('checkboxArray');
console.log('retrievedObject: ', JSON.parse(retrievedObject));
return retrievedObject;
}
Termine_1s.html
//Checks if title was checked already
var checklistRequest = alertFunction();
var titleAccepted = true;
for (var a = 0; a < checklistRequest.length; a++)//Iterates through whole array
{
if(title != checklistRequest[i] && titleAccepted == true)//Stops if false
{
titleAccepted = true;
}
else
{
titleAccepted = false;
}
}
you need to parse the object at some point.
Try:
return JSON.parse(retrievedObject);

How to pass a value from code behind to javascript function in WP7

I am attempting to implement a search feature for text displayed in a webbrowser control. I have a search function which works correctly to highlight text, although it currently accomplishes this by creating a search bar in javascript in the webbrowser. The problem with this is that depending on the size of the page, the javascript search bar is always a different size, which is very confusing. I would like to be able to pass a search value entered by the user in a textbox in my WP7 application to this javascript function, and then have it simply highlight the values. I do not know how to pass a value to a javascript function though, and I am having much difficulty making this work.
Javascript search function (in a text file)
javascript:(
function()
{
function G()
{
var pf=doc.getElementById('pf');
var qt=doc.getElementById('qt');
if(null==pf)
{
pf=doc.createElement('div');
pf.id='pf';
var s=pf.style;
s.position='absolute';
s.zIndex='99';
s.top=(scT||scBT)+'px';
s.left=(scL||scBL)+'px';
s.width='100%';
s.backgroundColor='#FFFF00';
pf.appendChild(doc.createTextNode('Search: '));
qt=doc.createElement('input');
qt.id='qt';
qt.type='text';
pf.appendChild(qt);
var sb=doc.createElement('input');
sb.type='button';
sb.value='Find';
sb.onclick=function()
{
P(qt.value)
};
pf.appendChild(sb);
doc.body.appendChild(pf);
}
else
{
pf.style.display='inline';
count=0;
}
}
function P(s)
{
document.getElementById('pf').style.display='none';
if(s==='')
return;
var n=srchNode(document.body,s.toUpperCase(),s.length);
alert("Found "+count+" occurrence"+(count==1?"":"s")+" of '"+s+"'.");
pf.parentNode.removeChild(pf);
return n;
}
function srchNode(node,te,len)
{
var pos,skip,spannode,middlebit,endbit,middleclone;
skip=0;
if(node.nodeType==3)
{
pos=node.data.toUpperCase().indexOf(te);
if(pos>=0)
{
spannode=document.createElement("SPAN");
spannode.style.backgroundColor="red";
middlebit=node.splitText(pos);
endbit=middlebit.splitText(len);
middleclone=middlebit.cloneNode(true);
spannode.appendChild(middleclone);
middlebit.parentNode.replaceChild(spannode,middlebit);
++count;
skip=1;
}
}
else
{
if(node.nodeType==1&&node.childNodes&&node.tagName.toUpperCase()!="SCRIPT"&&node.tagName.toUpperCase!="STYLE")
{
for(var child=0;child<node.childNodes.length;++child)
{
child=child+srchNode(node.childNodes[child],te,len);
}
}
}
return skip;
}
var count=0,scL=0,scT=0,scBL=0,scBT=0;
var w=window,doc=document;
if(typeof doc.body!='undefined'&&typeof doc.body.scrollLeft!='undefined')
{
scBL=doc.body.scrollLeft;
scBT=doc.body.scrollTop;
}
if(typeof doc.documentElement!='undefined'&&typeof doc.documentElement.scrollLeft!='undefined')
{
scL=doc.documentElement.scrollLeft;
scT=doc.documentElement.scrollTop;
}
G();
})()
Find on Page method
public void FindOnPage()
{
var resource = Application.GetResourceStream(new Uri("Resources/FindOnPage/FindOnPage.txt", UriKind.Relative));
string text;
StreamReader sr = new StreamReader(resource.Stream);
//while((text = sr.ReadToEnd()) != null)
if ((text = sr.ReadToEnd()) != null)
{
TheWebBrowser.InvokeScript("eval", text);
}
}
Assuming that I had a searchbar named SearchBar, how would i pass the text to the user input through the javascript function, so that the text will be highlighted? I have no experience with javascript, so any assistance will be greatly appreciated on the subject!
There is no direct way of passing it.
You can string replace the parameter before calling eval, first modify your javascript like this
javascript:(
function(searchString)
{
function P(s)
{
if(s==='')
return;
var n=srchNode(document.body,s.toUpperCase(),s.length);
alert("Found "+count+" occurrence"+(count==1?"":"s")+" of '"+s+"'.");
return n;
}
function srchNode(node,te,len)
{
var pos,skip,spannode,middlebit,endbit,middleclone;
skip=0;
if(node.nodeType==3)
{
pos=node.data.toUpperCase().indexOf(te);
if(pos>=0)
{
spannode=document.createElement("SPAN");
spannode.style.backgroundColor="red";
middlebit=node.splitText(pos);
endbit=middlebit.splitText(len);
middleclone=middlebit.cloneNode(true);
spannode.appendChild(middleclone);
middlebit.parentNode.replaceChild(spannode,middlebit);
++count;
skip=1;
}
}
else
{
if(node.nodeType==1&&node.childNodes&&node.tagName.toUpperCase()!="SCRIPT"&&node.tagName.toUpperCase!="STYLE")
{
for(var child=0;child<node.childNodes.length;++child)
{
child=child+srchNode(node.childNodes[child],te,len);
}
}
}
return skip;
}
var count=0,scL=0,scT=0,scBL=0,scBT=0;
var w=window,doc=document;
if(typeof doc.body!='undefined'&&typeof doc.body.scrollLeft!='undefined')
{
scBL=doc.body.scrollLeft;
scBT=doc.body.scrollTop;
}
if(typeof doc.documentElement!='undefined'&&typeof doc.documentElement.scrollLeft!='undefined')
{
scL=doc.documentElement.scrollLeft;
scT=doc.documentElement.scrollTop;
}
P(searchString);
})("#search#")
Then in your C# replace #search# with your SearchString.
public void FindOnPage()
{
var resource = Application.GetResourceStream(new Uri("Resources/FindOnPage/FindOnPage.txt", UriKind.Relative));
string text;
StreamReader sr = new StreamReader(resource.Stream);
//while((text = sr.ReadToEnd()) != null)
if ((text = sr.ReadToEnd()) != null)
{
text = text.Replace("#search#",SearchBar.Text); //Replace SearchBar.Text with the string you want to search
TheWebBrowser.InvokeScript("eval", text);
}
}

Excel Type Filter popup for Jqgrid

I need to have a filter ( like in Excel spread Sheet) to embedded to the 'jquery' dialog popup. in this case i need to show all the unique values in the column and check box just before that value to select to the user. when user pressed filter button i need to filter only the values that user requested through the check boxes.
Can any one please let me any approach that i must follow.
Thanks in advance for your help and valuable time.
I was able to develop basic grid with excel kind of filter feature. any one who will come across this type of requirement can use this answer as a foundation.
I use this answer from 'Oleg' to embed the filter popup screen to the basic 'jqgrid'.
in the jqgrid page declare this array with the attributes (columns) that needs to display the filter screen popup.
var applyFilterColumnNames = ['Id','Type','custId','UserId'];
and the column model should be as follows -
colModel :[
{name:'Id', index:'Id',hidden: true,sortable: true},
{name:'custId', index:'custId', width:140,align:"left",sortable: true,search : false},
{name:'Type', index:'Type', width:120,align:"left",sortable: true,search : false},
{name:'UserId', index:'UserId', width:150,align:"left",sortable: true,search : false},
],
used that reference answer to embed the filter button function.
gr.closest("div.ui-jqgrid-view").find("div.ui-jqgrid-hdiv table.ui-jqgrid-htable tr.ui-jqgrid-labels > th.ui-th-column > div.ui-jqgrid-sortable")
.each(function () {
var idPrefix = "jqgh_" + gr[0].id + "_";
var idIndex = (this.id).substr(idPrefix.length,this.id.length) ;
if(includeInArray(applyFilterColumnNames,idIndex)){
jq('<button id=btn_'+idIndex+'>').css({float: "right", height: "17px"}).appendTo(this).button({
icons: {
primary: "ui-icon-gear"
},
text: false
}).click(function (e) {
var idPrefix = "jqgh_" + gr[0].id + "_";
// thId will be like "jqgh_list_name"
var thId = jq(e.target).closest('div.ui-jqgrid-sortable')[0].id ;
if (thId.substr(0, idPrefix.length) === idPrefix) {
var colName = thId.substr(idPrefix.length);
//alert('Clicked the button in the column "' + colName + '"');
constructFilter(colName);
return false;
}
});
//}
}
});
Below is the script i used to filter the jqgrid according to the filters
//Variables that use in filtering operation
var originalData = null;
var filteredData;
var selectedFilters = new Object();
var chkBoxElement;
var firstSortColumn;
function constructFilter(columnName){
// for the first initiation of the filter populate current grid data to an array
if(originalData == null || originalData == 'null'){
try{
// this array will hold the initail data set of the grid
originalData = gr.jqGrid('getGridParam','data');
// set the first sorting grid column
firstSortColumn = columnName;
// check if column is associated with a formatter. if so format the originalData values accordingly.
formatGridData(columnName);
}catch(e){}
}
var colData = new Array();
var filterDataSet;
// if current column is equal to initial sorted column set all posible values to the check boxes in the
// filter screen to select. ( since this is the master sorting column and other columns will filter according to that)
if(columnName == firstSortColumn){
filterDataSet = originalData;
}else{
// set current grid data set to show as checkboxes in the filter page
filterDataSet = gr.jqGrid('getCol',columnName,false);
}
for(key in filterDataSet){
// check box element object that will hold the checkbox label and its state ( true / false)
chkBoxElement = new Object();
chkBoxElement.id = getValueFromArray(filterDataSet[key],columnName);
if(typeof(chkBoxElement.id)== 'undefined'){
break;
}
// if this id is saved in previous filtering event checked option will set to true.
if(typeof(selectedFilters[columnName]) != 'undefined'){
if (includeInArray(selectedFilters[columnName],chkBoxElement.id)){
chkBoxElement.selected = true;
}else{
chkBoxElement.selected = false;
}
}
colData.push(chkBoxElement);
}
// removing duplicates
var uniqueValues = removeDuplicates(colData);
// sort the array without duplicate with the custom comparator
uniqueValues.sort(sortComparator);
// open the filter screen. return type will captured in the 'seletedElements' variable as pipe separated string
seletedElements = window.showModalDialog(filterUrl,uniqueValues,"dialogWidth:400px;dialogHeight:250px;center:yes;resizable:no;status:no;help:no;");
if(seletedElements != null && seletedElements != 'null'){
// get selected values to the array
selectedFilters[columnName] = seletedElements.split("|");
}else{
//user just close the popup (using close button) will return without doing anything
return;
}
if(columnName == firstSortColumn){
// refine filter with the non filtered data set
refillGrid(seletedElements,columnName,originalData);
}else{
// send current data set to refine
var currentDataSet = gr.jqGrid('getGridParam','data');
refillGrid(seletedElements,columnName,currentDataSet);
}
}
function formatGridData(columnName){
var isFormatter = gr.jqGrid("getColProp",columnName);
if(typeof isFormatter.formatter !== 'undefined') {
if(jq.isFunction( isFormatter.formatter ) ) {
for(key in originalData){
var plainValue = originalData[key][columnName];
var formattedVal = isFormatter.formatter.call(null,plainValue,null,null,null);
originalData[key][columnName] = formattedVal;
}
}
}
}
function resetFilters(){
for(key in applyFilterColumnNames){
jq("#btn_"+applyFilterColumnNames[key]).button("option", {
//icons: { primary: this.checked ? 'ui-icon-check' : 'ui-icon-closethick' }
icons: { primary: 'ui-icon-gear'}
});
}
gr.jqGrid("setCaption",gridCaption);
refreshGrid(originalData);
originalData = null;
firstSortColumn = null;
selectedFilters = new Object();
}
function refillGrid(seletedElements,columnName,filterDataSet){
var filteredData= new Array();
var elementsArray;
try{
elementsArray = seletedElements.split("|");
}catch(e){
// this exception happens when user simply open the filter screen
// do nothing and close it.
trace('Error in filter splitting -'+e);
return;
}
// When user de-select all check boxes from the popup screen
if(elementsArray == ""){
refreshGrid(originalData);
return;
}
// refine the grid data according to the filters
var mydata = filterDataSet;
for(i=0;i<elementsArray.length;i++){
var filterElement = elementsArray[i];
for(j = 0;j<mydata.length;j++){
if(filterElement==getValueFromArray(mydata[j],columnName)){
filteredData.push(mydata[j]);
}
}
}
// change the button icon to indicate that the column is filtered
changeButtonIcon(columnName);
// update the column header to indicate sort by column
changeGridCaption(columnName);
// fill the grid according to the passed array
refreshGrid(filteredData);
}
function changeGridCaption(columnName){
// get columns name array
var columnNames = gr.jqGrid('getGridParam','colNames');
// get column model array
var colModel = gr.jqGrid('getGridParam','colModel');
var colModelIndex=null;
if (firstSortColumn == columnName){
for(key in colModel){
try{
if (colModel[key].name == firstSortColumn){
colModelIndex = key;
break;
}
}catch(e){}
}
if(colModelIndex != null){
var columnName = columnNames[colModelIndex];
gr.jqGrid("setCaption",gridCaption + " - Filtered based on : "+columnName);
}
}
}
function changeButtonIcon(columnName){
//change the button Icon
jq("#btn_"+columnName).button("option", {
//icons: { primary: this.checked ? 'ui-icon-check' : 'ui-icon-closethick' }
icons: { primary: 'ui-icon-link'}
});
}
function getValueFromArray(obj,columnName){
if(obj !=null && typeof(obj)!='undefined'){
// if obj param is string just return it
if(typeof obj =='string'){
return obj;
}else{
return obj[columnName];
}
}
}
function sortComparator(a,b){
try{
var aId = a.id.toLowerCase();
var bId = b.id.toLowerCase();
if (aId < bId) {return 1}
if (aId > bId) {return -1}
}catch(e){
return 0;
}
}
function includeInArray(arr,obj) {
//alert(arr);
return (arr.indexOf(obj) != -1);
}
function refreshGrid(results) {
gr.jqGrid('clearGridData')
.jqGrid('setGridParam', { data: results })
.trigger('reloadGrid');
}
function removeDuplicates(valueArray){
var arr = {};
for ( i=0; i < valueArray.length; i++ ){
if(valueArray[i].id != null){
arr[valueArray[i].id] = valueArray[i];
}
}
valueArray = new Array();
for ( key in arr ){
valueArray.push(arr[key]);
}
return valueArray;
}
If something wrong here please let me know.this solution is working fine. but i really appreciate the comments in therms of performance and code best practices.

Categories

Resources