The problems with posting comments have now been fixed – let the comments come!
Alexander
The problems with posting comments have now been fixed – let the comments come!
Alexander
Something is broken and it’s not possible to post comments. I’ll try to fix it later tonight.
Alexander
Hi all followers!
I have decided to move the blog from wordpress.com to a self-hosted WordPress server for better control.
To ensure your receive email notifications when I post new articles, please enter your email address in the form in the top right corner of my blog
I have added a redirect on my old URL, but if you accessed this site trough the old URL, you should update your bookmark for direct access. The new blog is found here:
Stay tuned,
Alexander
May 06. 2013
I have released v2.95 – you find it hereMarch 19. 2013
v2.81 fixes a bug occurring when you set a boolean column as required.March 01. 2013
I have released v2.8 with some new features, and a few bugfixes.
New features:
- Add the ability to insert custom CSS and JavaScript (in the Misc tab)
- Added “URL Query string parameter” as trigger for a rule.
Bug fixes:
- Validating an empty lookup column with the text (none) failed. This has been fixed by checking the val() property which will be 0.
- “showFieldDescriptionWhenReadonly” had a bug preventing it from functioning.
- If you selected the same field twice in a tab, it misbehaved. I now strip away any duplicates by removing the last occurrence.
Refer these articles for background information and setup instructions:
Dynamic Forms for SharePoint: Production
Dynamic Forms for SharePoint – Now with Tabs
The Dynamic Forms for SharePoint solution now supports SharePoint 2013. Please note that I have just started looking at SharePoint 2013, and have tested the solution in a “Microsoft Office 365 Developer Preview” only.
There might be issues with a “non office 365” install, but you will have to tell me about it in the comments section below.
The code is shared between SharePoint 2007, SharePoint 2010 and SharePoint 2013.
Changes from v2.65
Setup
The setup for SP 2013 is similar to that for SP 2010. Please note that you need to update spjs-utility.js to use Dynamic Forms for SharePoint v2.7 – not only for SP 2013: get spjs-utility.js here.
See change log where you download spjs-utility.js. For setup instruction, see the first article linked in the top of this article.
Please post any findings below this article.
25.02.2013 Updated the code and changed the variable “fields” to “localizeFields” to avoid interference with other scripts.
I got a request for a solution for translating choice column values in a form.
This solution changes the text in the drop-down list, radio button or checkbox in NewForm or EditForm, leaving the “value” untouched. In DispForm the field value is “localized” directly.
This means that the text the user sees is changed, but the value that SharePoint sees is the original. This means that the value shown in the form is localized, but the value stored in the SharePoint list when saving the form is not.
Add this code to a CEWP or HTML Form web part BELOW the list form web part in NewForm, DispForm and EditForm of your list.
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script type="text/javascript"> var translationSettings = { "MyDropDownMenu": { "Yes":{"1044":"Ja","default":"Yes"}, "No":{"1044":"Nei","default":"No"} }, "MyMultiChoice": { "Choice 1":{"1044":"Valg 1","default":"Choice 1"}, "Choice 2":{"1044":"Valg 2","default":"Choice 2"}, "Choice 3":{"1044":"Valg 3","default":"Choice 3"} } }; var localizeFields = init_fields_v2(); var isDispForm = $("input:button[id$='SaveItem']").length===0; $.each(translationSettings,function(fin,t){ if(localizeFields[fin] !== undefined){ var fType, arr, txt, tTxt; fType = ""; txt = ""; tTxt = ""; if($(localizeFields[fin]).attr("fieldtype") === "SPFieldChoice"){ if(!isDispForm){ if($(localizeFields[fin]).find("select").length > 0){ fType = "select"; }else if($(localizeFields[fin]).find("select").length === 0 && $(localizeFields[fin]).find("input:radio").length > 0){ fType = "radio"; } }else{ fType = "dispform"; } }else if($(localizeFields[fin]).attr("fieldtype") === "SPFieldMultiChoice"){ if(!isDispForm){ fType = "multichoice"; }else{ fType = "dispform"; } }else{ return; } switch(fType){ case "dispform": arr = $(localizeFields[fin]).find('.ms-formbody').text().replace(/[ xA0]+$/,'').split("; "); tTxt = []; $.each(arr,function(i,txt){ if(t[txt] !== undefined){ tTxt.push(t[txt][L_Menu_LCID] !== undefined ? t[txt][L_Menu_LCID] : t[txt]["default"]); } }); $(localizeFields[fin]).find('.ms-formbody').text(tTxt.join("; ")); break; case "select": $(localizeFields[fin]).find("select option").each(function(i,opt){ txt = $(this).text(); if(t[txt] !== undefined){ tTxt = t[txt][L_Menu_LCID] !== undefined ? t[txt][L_Menu_LCID] : t[txt]["default"]; $(this).text(tTxt); } }); break; case "radio": case "multichoice": $(localizeFields[fin]).find("input").each(function(i,opt){ txt = $(this).next().text(); if(t[txt] !== undefined){ tTxt = t[txt][L_Menu_LCID] !== undefined ? t[txt][L_Menu_LCID] : t[txt]["default"]; $(this).next().text(tTxt); } }); break; } } }); // This function is found in spjs-utility.js and can be removed from here if you already have referred this library. function init_fields_v2(){ var res = {}; $("td.ms-formbody").each(function(){ var myMatch = $(this).html().match(/FieldName="(.+)"s+FieldInternalName="(.+)"s+FieldType="(.+)"s+/); if(myMatch!=null){ // Display name var disp = myMatch[1]; // FieldInternalName var fin = myMatch[2]; // FieldType var type = myMatch[3]; if(type=='SPFieldNote'){ if($(this).find('script').length>0){ type=type+"_HTML"; }else if($(this).find("div[id$='_TextField_inplacerte']").length>0){ type=type+"_EHTML"; } } if(type=='SPFieldLookup'){ if($(this).find('input').length>0){ type=type+"_Input"; } } // Build object res[fin] = this.parentNode; $(res[fin]).attr('FieldDispName',disp); $(res[fin]).attr('FieldType',type); } }); return res; } </script>
The translation is set up in the variable “translationSettings” like this:
var translationSettings = {
“FieldInternalName”:
{
“Actual value 1”:{“1044″:”Norwegian value 1″,”default”:”Default value 1″},
“Actual value 1”:{“1044″:”Norwegian value 1″,”default”:”Default value 2″}
}
};
You can add alternate languages by using the LCID. The selected LCID must be among the installed language packs on your SharePoint server.
Ask if something is unclear.
Alexander
I have previously posted a solution that, among other features, lets you relink a lookup column. This article introduces a new tool that does lookup column relinking only.
SharePoint 2007
SharePoint 2010
Get the code here, and ensure you use the correct version.
The difference between the 2007 and the 2010 version is that in 2007, you must place the code in a web part in the site where the lookup column resides.
You can target another site, but must run the code in the site where the column you want to alter is located.
In the 2010 version, you can change the source web as long as you target a web within the site collection.
If you like the solution, buy me a beer using the Beer button on the top right of this page.
Alexander
27.09.2012 v3.3.6 includes these changes:
var chartOptionOverride = {"MyChart1":{"title":"This is the chart title!"}};
See the CEWP code example for v3.3.6 in the download section
In v3.3.5 I have added these features:
What happens under the hood is that the chart is created in a separate container – dynamically created within the container defined in the CEWP. For those interested, this container is named containerId_chart. Where “containerId” is the id defined in the array “arrOfChartContainers” in the CEWP.
You can delay the loading of the chart by 4000ms (4 seconds) like this:
<div id="MyChart1"></div> <script type="text/javascript"> /***************************************************** Address all containers *****************************************************/ // All charts must be represented by a container with a unique id. // This container must be present in the page var arrOfChartContainers = ["MyChart1"]; var loadRC = false; var allowEval = false; var loadManually = true; function manualLoad(){ loadManually = false; spjs_GenerateChart(); } setTimeout(function(){ manualLoad(); },4000); </script> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script type="text/javascript" src="https://www.google.com/jsapi"></script> <script type="text/javascript" src="/test/English/Charts/Javascript/3.3/SPJS_ChartsForSharePoint_v3.3.5.js"></script>
Or you can make a button and call the chart manually like this:
<input type="button" onclick="manualLoad()" value="Load chart"> <div id="MyChart1"></div> <script type="text/javascript"> /***************************************************** Address all containers *****************************************************/ // All charts must be represented by a container with a unique id. // This container must be present in the page var arrOfChartContainers = ["MyChart1"]; var loadRC = false; var allowEval = false; var loadManually = true; function manualLoad(){ loadManually = false; spjs_GenerateChart(); } </script> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script type="text/javascript" src="https://www.google.com/jsapi"></script> <script type="text/javascript" src="/test/English/Charts/Javascript/3.3/SPJS_ChartsForSharePoint_v3.3.5.js"></script>
To have a placeholder like this while the chart loads:
You must add this code to your CEWP:
<style type="text/css"> .chartLoadingOverlay{ font-style:italic; color:gray; border:1px silver solid; background-color:#F5F5F5; line-height:250px; height:250px; width:500px; text-align:center; margin:2px; } </style> <div id="MyChart1"></div> <script type="text/javascript"> /***************************************************** Address all containers *****************************************************/ // All charts must be represented by a container with a unique id. // This container must be present in the page var arrOfChartContainers = ["MyChart1"]; var loadRC = false; var allowEval = false; var loadManually = true; function manualLoad(){ loadManually = false; spjs_GenerateChart(); } </script> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script type="text/javascript" src="https://www.google.com/jsapi"></script> <script type="text/javascript" src="/test/English/Charts/Javascript/3.3/SPJS_ChartsForSharePoint_v3.3.5.js"></script> <script type="text/javascript"> $.each(arrOfChartContainers,function(i,id){ $("#"+id).html("<div class='chartLoadingOverlay'>Loading chart please be patient...</div>"); }); setTimeout(function(){ manualLoad(); },100); </script>
The setTimeout is necessary to let the browser render the overlay before it freezes while retrieving the data for the chart.
Please note the these features require v3.3.5 of SPJS Charts for SharePoint.
You find the files, and additional information in this article
Alexander
I have preciously posted a solution for wrapping checkboxes or radio buttons in multiple rows. This one is a bit sleeker and easier to implement.
I have added a slightly modified version of “init_fields” to accommodate for lists and surveys.
Add this code to a CEWP below the form:
<style type="text/css"> .ms-RadioText label{ white-space:nowrap; } </style> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script> <script type="text/javascript"> var fields = init_fields_v3(); multichoiceVertical(['Checkboxes'],4); function multichoiceVertical(arr,breakAfter){ var toFind, index, counter, table; toFind = "td.ms-formbody"; if($("td.ms-formbodysurvey").length>0){ toFind = "td.ms-formbodysurvey"; } $.each(arr,function(i,fin){ if(fields[fin]!==undefined){ index = 0; counter = 0; table = $(fields[fin]).find(toFind+' table:first'); $(table).prepend("<tr id='vertical_"+fin+"_"+index+"'></tr>"); $(table).find('tr:first').nextAll().each(function(){ if(counter%breakAfter===0){ $("#vertical_"+fin+"_"+index).after("<tr id='vertical_"+fin+"_"+(index+1)+"'></tr>"); index += 1; } $(this).find('td:first').appendTo($("#vertical_"+fin+"_"+index)); $(this).remove(); counter += 1; }); } }); } function init_fields_v3(){ var toFind, res, myMatch, disp, fin, type res = {}; toFind = "td.ms-formbody"; if($("td.ms-formbodysurvey").length>0){ toFind = "td.ms-formbodysurvey"; } $(toFind).each(function(){ myMatch = $(this).html().match(/FieldName="(.+)"\s+FieldInternalName="(.+)"\s+FieldType="(.+)"\s+/); if(myMatch!=null){ disp = myMatch[1]; fin = myMatch[2]; type = myMatch[3]; if(type=='SPFieldNote'){ if($(this).find('script').length>0){ type=type+"_HTML"; }else if($(this).find("div[id$='_TextField_inplacerte']").length>0){ type=type+"_EHTML"; } } if(type=='SPFieldLookup'){ if($(this).find('input').length>0){ type=type+"_Input"; } } res[fin] = this.parentNode; $(res[fin]).attr('FieldDispName',disp); $(res[fin]).attr('FieldType',type); } }); return res; } </script>
Change the script src to use a local copy of jQuery if you prefer that.
You call the function with an array of the FieldInternalNames you want top apply this solution to, and the number of columns to distribute the choices over like this:
multichoiceVertical(['Checkboxes'],4);
Alexander