Sunday, December 1, 2013

Sharepoint Delete Hidden Site Columns

the errors you might get:
"Cannot change Hidden attribute for this field"
"cannot delete hidden column"


solution: run this Poweshell:

$web = Get-SPWeb http://YourSite/YourWeb
$list = $web.GetList("/YourWeb/Lists/YourList")
$field = $list.Fields.GetFieldByInternalName("YourFieldInternalName")
$type = $field.GetType()
$mi = $type.GetMethod("SetFieldBoolValue",
    [System.Reflection.BindingFlags]$([System.Reflection.BindingFlags]::NonPublic -bor
$mi.Invoke($field, @("CanToggleHidden",$true))


Tuesday, November 26, 2013

return a file, c#,

string filename = "myfile.typ";
string fileStr = "";
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
byte[] bytes = encoding.GetBytes(fileStr);
//or any other way to serialize your file

Response.ContentType = "application/ics;charset=utf-8";

//the general rule is (1) google (2) application/fileType (3) if is text then text/fileType
Response.AddHeader("content-disposition", "inline;filename=" + filename);

Thursday, November 21, 2013

usefull CSS tricks and tips

1. Style a Dropdown / Select:

2. Style Checkboxes and Radio:
the point is to hide the inputs and put spans with background images instead and use js to change the background-position at need.

Monday, November 11, 2013

Costumize Facebook, Twitter ad Google Plus Sharing

Facebook : beyond the great api they give for extra stuff they are the only ones still allowing title, description and image via href so the code is like this

function OpenFacebookShare(title, summary, url, imageUrl) {
  var url = '[title]=' +
        encodeURIComponent(title) +
    '&p[summary]=' + encodeURIComponent(summary) +
    '&p[url]=' + encodeURIComponent(url) +
    '&p[images][0]=' + encodeURIComponent(imageUrl);, 'mywindow', 'menubar=1,resizable=1,width=650,height=450');

as simple as that.

Twitter: twitter only allows url and text (only 140 chars) by href.
but they do request the url for their own meta tags, i.e. "twitter:title" ect.

to do this you must create a twitter account and create a "card" for your domain and allow that domain. its really not that much of a horror, just create an account, go here to the part of the tool validator and put in your domain and it will ask you to approve it. as simple as that.

about the tags you have a complete list of tags there, they all look like this:
<meta property="twitter:card" content="summary" />
<meta property="twitter:title" content="Bresleveloper's Blog" />
dont forget the card :)

all that leaves you with that simple code:
function OpenTwitterShare(url, text) {
    var url = '' + 
         encodeURIComponent(url) + '&text=' +     
         encodeURIComponent(text);, 'mywindow''menubar=1,resizable=1,width=650,height=450');

Google Plus: is even meaner - they allow only url.
so you, must, again, create an account and make some steps:
1. go here
2. go to "Service" and turn on "Google+ API"
3. go to "API access" and create there a clientID

the trick with google+ is that you dont "send" a request of something but instead you give the script the button (or other element) you want to be your button and he creates it alone.
your code will be like this

(function () {
    var po = document.createElement('script'); 
    po.type = 'text/javascript'
    po.async = true;
       po.src = '';//?onload=onLoadCallback';
    //?onload=onLoadCallback' this allows a callback when the google scripts loads if you need it
    var s = document.getElementsByTagName('script')[0]; 
    s.parentNode.insertBefore(po, s);

function SetGoogleShareButton(url, comment, buttonID) {
   var options = { contenturl : url,
                   clientid : 'your clientID here',
                   cookiepolicy : 'single_host_origin',
                   prefilltext : comment,
                   recipients: null,
                   calltoactionlabel : 'VIEW',
                   calltoactionurl : url
   gapi.interactivepost.render(buttonID, options);
   return false;

//callback for google - u cant give it up
function signinCallback(authResult) {
   if (authResult['access_token']) {
      // User successfully authorized the G+ App!
   } else if (authResult['error']) {
      // User has not authorized the G+ App!

and its almost the end. you need to call SetGoogleShareButton somewhere AFTER the google scripts loads, so in my case the buttons where inside a popup so i called it in the "LoadPopup" func, or you can just make a callback that will call it and send it as the ?onload= value.


Xml to Excel Via Xsl

there is a nice trick in XSL that allows us to Create XLS documents. therefor taking any object, serializing it to XML and then using the right XSL we will get our XLS just as we want it, so there is the XSL.

notice that if you serialize objects that comes from services the usually come with some

and if so the XML nodes will look like this
<node xmlns="http://xmlns.bla/bla/yourType">20:52:00</node>

and for some reason it wont read the nodes, so the solution is
allXmlStr = allXmlStr.Replace("xmlns=\"http://xmlns.bla/bla/yourType\"", "");

<xsl:stylesheet version="1.0

<xsl:template match="rootElement">

  <ss:Style ss:ID="Default" ss:Name="Normal">
    <ss:Alignment ss:Vertical="Bottom" ss:Horizontal="Center" ss:ReadingOrder="LeftToRight"/>
      <ss:Border ss:Position="Left" ss:Weight="1"/>
      <ss:Border ss:Position="Right" ss:Weight="1"/>
      <ss:Border ss:Position="Top" ss:Weight="1"/>
      <ss:Border ss:Position="Bottom" ss:Weight="1"/>

  <ss:Style ss:ID="BoldColumn">
     <ss:Font x:Family="Swiss" ss:Bold="1"/>
   <ss:Style ss:ID="MergeColumn">
      <ss:Font x:Family="Swiss" ss:Bold="1" ss:Color="#ff0000"/>
   <ss:Style ss:ID="StringLiteral">
      <ss:Alignment ss:Vertical="Bottom" ss:ReadingOrder="LeftToRight"/>
   <ss:NumberFormat ss:Format="@"/>
   <ss:Style ss:ID="Decimal">
      <ss:Alignment ss:Vertical="Bottom" ss:ReadingOrder="LeftToRight"/>
      <ss:NumberFormat ss:Format="#,##0.00"/>
   <ss:Style ss:ID="Integer">
      <ss:Alignment ss:Vertical="Bottom" ss:ReadingOrder="LeftToRight"/>
      <ss:NumberFormat ss:Format="#,##0"/>
   <ss:Style ss:ID="DateLiteral">
      <ss:Alignment ss:Vertical="Bottom" ss:ReadingOrder="LeftToRight"/>
      <ss:NumberFormat ss:Format="dd/mm/yyyy;@"/>

  <ss:Worksheet ss:Name="Worksheet 1">
         <ss:Column ss:AutoFitWidth="1" ss:Width="150"/>
         <ss:Column ss:AutoFitWidth="1" ss:Width="100"/>
             <ss:Cell ss:MergeAcross="1" ss:StyleID="MergeColumn">
                 <ss:Data ss:Type="String">Main Header</ss:Data>
             <ss:Cell ss:StyleID="BoldColumn">
                 <ss:Data ss:Type="String">Secondery Header</ss:Data>
             <ss:Cell ss:StyleID="BoldColumn">
                 <ss:Data ss:Type="String">Secondery Header</ss:Data>

         <xsl:for-each select="./Items/Item">
                 <ss:Cell ss:StyleID="StringLiteral">
                     <ss:Data ss:Type="String">
                         <xsl:value-of select="Name"/>
                 <ss:Cell ss:StyleID="Integer">
                     <ss:Data ss:Type="Number">
                         <xsl:value-of select="Value"/>

<ss:Worksheet ss:Name="Worksheet 2">


the result is the content of the excel file (XLS)