kategorie Argief: jQuery en SharePoint

Oorkom irriterende probleem met relatiewe URL's in SharePoint Quick Launch

I wanted to add a link to the quick launch navigation the other day and SharePoint told me:

image

Pure text version of that is:

Ensure that the URL is valid and begins with either a valid character (a number sign (#) or forward slash (/)) or a valid supported protocol (byvoorbeeld, ‘http://", ‘https://", ‘file://", ‘ftp://", ‘mailto:", ‘news:").

“Blech and pox!” I said.

A workaround to this is to use JavaScript to find a known link in the quick launch and override its behavior.

To test this, add a new link to your test site thusly:

image

I used jQuery. Om dit op te los, get some JavaScript and jQuery onto the page using your favorite technique and with a line of code like this:

 

$(dokument).gereed( funksie () {

    $("1:contains('Test URL replacement')").kliek(funksie () { waarsku("changed click behavior!"); terugkeer valse;});

});

And Bob’s your uncle.

The jQuery selector finds every <1> tag that has “Test URL replacement” in its name. You may want to find-tune that depending on your link and such.

The .click(funksie() overrides whatever SharePoint would have done when the user clicked. Make sure you “return false” or else it will do your stuff and then try to the href thing too, which is almost certainly not your goal.

This was done and test in a SharePoint online environment but should work well in 2010 and earlier too.

</einde>

undefinedSkryf in op my blog.

Volg my op Twitter http://www.twitter.com/pagalvin

Vinnige en maklike: Los "Ongeldige URL Parameter” probleem met UpdateListItems in lists.asmx

When working with UpdateListItems via lists.asmx, it’s easy to generate the error:

Invalid URL Parameter.

The URL provided contains an invalid Command or Value. Please check the URL again.

You can get this error when you forget to include ID in the the list of fields to update.  Dit, like a lot of these SP web services, is a bit counterintuitive since you need to include the ID in the ID attribute of the <Metode> element.  And you’re not updated ID and probably never want to in the first place.

This SOAP envelope works:

<soapenv:Koevert xmlns:soapenv ='http://schemas.xmlsoap.org/soap/envelope/'>
  <soapenv:Liggaam>                      
    <UpdateListItems xmlns='http://schemas.microsoft.com/sharepoint/soap/'>                     
      <list name>{C712E2EA-54E1-47AD-9D99-1848C7773E2F}</list name>                     
        <updates>                     
         <Batch OnError="Continue">
          <Method ID="1" Cmd="Update">
            <Field Name="CooperativeLock">locked!</Field>
            <Field Name="ID">1</Field>
          </Metode>
        </Batch>                     
        </updates>                
      </UpdateListItems>             
  </soapenv:Liggaam>         
</soapenv:Envelope>

If you strip out the ID field reference then you’ll get the annoying “Invalid URL parameter” message.

</einde>

undefinedSkryf in op my blog.

Volg my op Twitter http://www.twitter.com/pagalvin

 

Arm man se Caching in JavaScript

[TL;DR version: use cookies to store the results of async calls; render the results of past async calls immediately and then validate them after page-load.]

I’ve been working on SharePoint intranet site for a client that features, onder andere, a stylized secondary navigation whose menu options are managed via a regular old custom list.  The idea is that the client gets to control “their” site’s menu without affecting or being affected by the global navigation put out by IT.

(there is something incredibly subversive about adding a CEWP that points to an HTML file that loads some CSS and JS to fundamentally alter almost everything about a site’s behavior… but that’s for another post)

The code for this pretty simple:

The sore spot here is that every time anyone hits one of the site’s pages, that user’s web browser is reaching out to get items from the list.  Once dev is complete and testing has proven things to be stable and complete, this call is unnecessary more than 99% of the time since the menu rarely changes.  It also has a weird UI affect which is common in this brave new world of hyper-ajaxy web sites – the page renders and only then does the menu render.  It’s jittery and distracting in my view.  And jittery. So, caching. 

I modified the logic thusly:

  • Look for a cookie in the browser that contains the menu as I last read it
    • If found, render it immediately.  Don’t wait for the page to finish loading.  (You need to make sure your HTML is strategically placed here, but it’s not hard to do).
  • Wait for the page to finish loading and make an async call to load up menu items from a list using REST or lists.asmx or whatever
  • Compare what I got against the cookie
    • If it matches, STOP
    • Anders, using jQuery, dynamically populate a bunch if <li>’s in a <Straat>
  • Use CSS to do all the formatting
  • Profit!

Some of you are going to say, “hey! there’s no real caching going on here since you’re reading the menu anyway every single time."  And you’re right – I’m not giving the server any kind of break.  But because the call is async and happens after the page’s initial HTML payload fully renders, it “feels” more responsive to the user.  The menu renders pretty much as the page draws.  If the menu happens to the change, the user is subjected to a jittery re-draw of the menu, but only that one time.

There are some ways to make this caching more effective and help out the server at the same time:

  • Put in a rule that the “cookie cache” is valid for a minimum of 24 hours or some other timeframe. As long as there is no expired cookie, use the cookie’s menu snapshot and never hit the server.

Well … that’s all that come to mind right now :). 

If anyone has any clever ideas here I’d love to know them.

And lastly – this technique can be used for other stuff.  This client’s page has a number of data-driven things on various pages, many of them changing relatively rarely (like once a week or once a month).  If you target specific areas of functionality, you can give a more responsive UI by pulling content from the local cookie store and rendering immediately.  It feels faster to the user even if you’re not saving the server any cycles.  Jy kan save the server cycles by deciding on some conditions and triggers to invalidate this local cookie cache.  That’s all situational and artsy stuff and really the most fun :). 

</einde>

undefinedSkryf in op my blog.

Volg my op Twitter http://www.twitter.com/pagalvin

XSLT en jQuery Monsters

Ek doen 'n baie van XSLT en jQuery en het gedink dat ek 'n paar stukkies wat ander kan nuttig wees in die toekoms wil deel.

Voorbeeld 1: Uitstraal eenvoudige JavaScript / jQuery in XSLT:

<xsl:sjabloon wedstryd = "iets" xml:ruimte = "bewaar">

  <!– Blank uit die soektog vriendelike filters verborge veld –>
  <script type = "text / JavaScript">
    $(dokument).gereed(funksie(){
      $("# QueryFriendlyFilters").Val("Leë");
    });
  </script>

</xsl:sjabloon>

Dit bietjie straal 'n paar JavaScript wat wag vir die bladsy laai te voltooi (as gevolg van die $(dokument).gereed(...)) en stel dan die waarde van 'n versteekte veld met die naam QueryFriendlyFilters aan die letterlike waarde "leë".

Voorbeeld 2: Gebruik <xsl:indien> om te kyk nie. "groter as",  "Minder as", ens..

<xsl:sjabloon wedstryd = "iets" xml:ruimte = "bewaar">

  <div id = "fdcAllFilters">
 
    <xsl:as toets = "@ Graaf>0">
      <span class = "fdcFilterLabel">Huidige filters:</span>
    </xsl:indien>

    <!– meer dinge gebeur hier. –>

</xsl:sjabloon>

Die bogenoemde uit nagegaan om te sien as 'n kenmerk met die naam "Count" van die "iets" element is groter as nul.  Die XML agter dit sou wees iets soos:"

<iets Count = "5" />

Voorbeeld 3: Itereer deur al die elemente, interspersing jQuery oproepe.

<!– Itereer deur al die filters en vertoon die korrekte  skakels. –>
<xsl:vir-elke kies = "UserFilter-">

  <a class = "FilterHref" href = "javascript:mySubmitPage(‘RemoveUserFilter’,"{@ ID}")">[X]</1>

  <span class = "fdcFilterLabel"><xsl:waarde van uitgesoekte = "@ FilterValue" /></span>

  <script type = "text / JavaScript">

    $(dokument).gereed(funksie(){
        <xsl:teks><![CDATA[$("# QueryFriendlyFilters").Val( ($("# QueryFriendlyFilters").Val() + " ]]></xsl:teks>\"<xsl:waarde van uitgesoekte = "@ FilterValue" />\"<xsl:teks><![CDATA["));]]></xsl:teks>
    });

  </script>

</xsl:vir-elke>

Die bogenoemde uit die mees komplekse en daar kan makliker wees om maniere om dit te doen.

Die XML agter dit lyk ongeveer soos hierdie:

<UserFilter ID = "123" FilterValue = "Xyzzy" />

Hierdie brokkie is iterating deur <UserFilter> nodes. 

Dit straal die eerste keer 'n anker tag dat wanneer gekliek beroept 'n JavaScript-funksie wat op die bladsy is reeds, "MySubmitPage" en gaan die waarde van 'n kenmerk van die <UserFilter> node met die naam "ID". 

Dit straal dan 'n paar jQuery wat wag vir die bladsy te laai.  JQuery updates 'n versteekte veld met die naam "QueryFriendlyFilters" deur die byvoeging van die waarde van die FilterValue kenmerk.  Let op al die gek <xsl:teks> en <![CDATA[ ... ]]> dinge.

Dit is dit, hoop dit help!

</einde>

Skryf in op my blog.

Volg my op Twitter http://www.twitter.com/pagalvin

Lists.asmx, GetListItems en dopgehou

Ek was 'n bietjie navorsing te doen vir iemand vandag rondom die list.asmx-web-diens verskaf as deel van SharePoint 2010 (en vroeër).  Sy was in staat om die lys items te kry om by die wortel gids (insluitend die name van die sub-gidse), maar kon dit nie kry items in die sub-gidse.  Ek het 'n paar kyk rond op die Inter en dit is 'n verbasend algemene vraag.  Tog, Ek kon nie 'n goeie antwoord op die eenvoudige vraag, "As ek weet die gids, Hoe kry ek die items in die gids?"  Om eerlik te wees, Ek het nie probeer om al die harde omdat ek wou hierdie een op my eie vir 'n rukkie om uit te vind Smile.

Om dit te kan opstel, Ek het 'n webwerf met die naam "Blogging scenario's" en 'n persoonlike lys met die naam "Custom Lys met sub dopgehou".  Ek het toe 'dopgehou:

  • Jaar 2005
  • Jaar 2006
  • Jaar 2007

Ek het ook 'n paar items tot die gids "Jaar 2006".  Dit is hoe dit lyk:

image

My vriend is nie 'n C # kode te skryf, maar eerder met behulp van Java, sodat die seep koevert was wat sy werklik nodig is.  Om dit te kry, Ek het 'n bietjie van jQuery en dan gebruik Fiddler die werklike HTTP gesprek te kry.

Hier is die betrokke jQuery (Ek kopieer die kode hieronder neer as jy wil kopieer / plak):

image

Hulle eerste sleutel is om in te sluit beide 'n <queryOptions> en <QueryOptions> knoop.  Die tweede sleutel is dat die <Folder> node is 'n URL wat die kliënt het toegang.

Daar mag dalk ander maniere om dit te kry, maar dit het goed gewerk vir my as die gebruik van jQuery.

Hier is die seep koevert vir die bogenoemde:

<soapenv:Koevert xmlns:soapenv =’http://schemas.xmlsoap.org / seep / koevert /’>                
  <soapenv:Liggaam>
    <GetListItems xmlns =’
http://schemas.microsoft.com / SharePoint / seep /’>
      <list name>Custom Lys met Sub dopgehou</list name>
      <viewFields>  
        <ViewFields>
          <FieldRef name = "Titel’ />
          <FieldRef Naam = "EncodedAbsUrl-’ />
        </ViewFields>
      </viewFields>
      <queryOptions>
        <QueryOptions>
          <Folder>
http://demoserver1/Blogging Scenarios / lyste / Custom Lys met sub dopgehou / Jaar 2006</Folder>
        </QueryOptions>
      </queryOptions>
   
</GetListItems>
  </soapenv:Liggaam>
</soapenv:Envelope>

Daar is baie voorbeelde en bespreking rondom hierdie het my gelei om te glo dat alles wat ek nodig het, was <QueryOptions> en 'n gids spesifiseer.  Vir my, Ek moet aan beide wrap dit binne <queryOptions> sowel as 'n ten volle gekwalifiseerde URL vir die spesifiseer <Folder> node.

Hier is die jQuery AJAX setup:

$(dokument).gereed(funksie() {
       soapEnv =
           "<soapenv:Koevert xmlns:soapenv =’http://schemas.xmlsoap.org / seep / koevert /’> \
               <soapenv:Liggaam> \
                    <GetListItems xmlns =’http://schemas.microsoft.com / SharePoint / seep /’> \
                       <list name>Custom Lys met Sub dopgehou</list name> \
                       <viewFields> \
                           <ViewFields> \
                              <FieldRef name = "Titel’ /> \
                              <FieldRef Naam = "EncodedAbsUrl-’ /> \
                          </ViewFields> \
                       </viewFields> \
                       <queryOptions> \
                         <QueryOptions> \
                           <Folder>http://demoserver1/Blogging Scenarios / lyste / Custom Lys met sub dopgehou / Jaar 2006</Folder> \
                         </QueryOptions> \
                       </queryOptions> \
                   </GetListItems> \
               </soapenv:Liggaam> \
           </soapenv:Envelope>";

</einde>

Skryf in op my blog.

Volg my op Twitter http://www.twitter.com/pagalvin

Lists.asmx, GetList en "Waarde kan nie nul wees”

Ek ontdek vandag dat die GetList() metode in lists.asmx Web diens het baie versigtig genoem word, of is dit geneig om 'n geheimsinnige "Waarde te gooi kan nie nul" uitsondering (en dit is die veronderstelling wat jy kan kry verby die nog erger algemene fout boodskap, “Exception of type ‘Microsoft.SharePoint.SoapServer.SoapServerException’ gegooi is. ")  Spesifiek, Ek het gevind dat jy nie kan enige soort van voorvoegsel op die GetList metode.  Die volgende jQuery uit illustreer die punt:

image

As jy dit doen, die web diens reageer met "Waarde kan nie null" soos vervat in hierdie Fiddler-met dien verstande HTTP transkripsie:

<?die xml weergawe = "1,0" encoding = utf-8 "?>
  <seep:Envelope
     xmlns:seep ="
http://schemas.xmlsoap.org / seep / koevert /"    
     xmlns:XSi = "
http://www.w3.org/2001/XMLSchema-instance"
     xmlns:xsd ="
http://www.w3.org/2001/XMLSchema">

  <seep:Liggaam>
    <seep:Fout>
      <faultcode>seep:Server</faultcode>
      <faultstring>
        Exception of type ‘Microsoft.SharePoint.SoapServer.SoapServerException’ gegooi.
      </faultstring>
      <detail>
        <String xmlns ="
http://schemas.microsoft.com / SharePoint / seep /">
Waarde kan nie nul wees.
        </String>
      </detail>
    </seep:Fout>
  </seep:Liggaam>
</seep:Envelope>

Natuurlik, jy sal waarskynlik nie byvoeg dat "s0" voorvoegsel op jou eie, maar 'n paar tools is geneig om dit te doen (soos Eclipse).

Dit is al hoe meer verwarrend / frustreer omdat ander metodes duld voorvoegsels.  Byvoorbeeld, die GetListCollection metode nie omgee as dit is voorafgegaan, selfs met nonsens voorvoegsels soos "Xyzzy":

image

Hierdie waarde kan nie null "lyk redelik gemeen met lists.asmx so hopelik sal dit help om iemand in die toekoms.

</einde>

Skryf in op my blog.

Volg my op Twitter http://www.twitter.com/pagalvin

Eindeloos nes <Div> Etikette en jQuery

Dit lyk soos 'n oddball onderwerp, Ek is nie seker dit is regtig die moeite werd blog oor, maar dit was nog nooit my gestop voor, so hier gaan ons Smile

Ek werk op 'n projek waar ek trek sommige data van 'n soektog, verpakking dit in 'n XML-boodskap en dan dat die XML is uiteindelik verander in HTML via XSLT.  Daar is 'n baie jQuery betrokke, n bietjie waarvan implemente tabbing funksionaliteit.  Wanneer jy op 'n blad (werklik, 1 <Div>), jQuery beroept. verberg() en show() op verskeie divs (die eerste bladsy vrag afgelaai Al die inhoud, sodat daar is geen postbacks in hierdie geval).

'N klomp ure gelede, die blad te skakel logika begin om ongereeld te tree en dit sou nie wys een van my tabs.  Ek het uiteindelik opgespoor het dit aan die feit dat Internet Explorer (ten minste) gedink het dat die <Div> tags genes ver, veel dieper as intended.The ontwikkelaar toolbar sal wys:

-<div id = "Tab1Content">
  -<Div>
    -<Div>
      -<div id = "Tab2Content">
        -<Div>
           ..............................
                   </Div>  <-Finaal deur is gesluit al die pad hier!

So, As ek dit het 'n $("# Tab1Content").verberg(), Ek wil ook wegsteek Tab2 en ek kon nooit wys Tab2 as ek het ook nie Tab1 wys.  Ek die kode gekopieer en geplak in Visual Studio en dit het gewys al die DIV se voering mooi, net soos hulle veronderstel was om te doen, soek soos hierdie:

-<div id = "Tab1Content">
  +<Div>
  +<Div>
-<div id = "Tab2Content">
  +<Div>
  +<Div>

Ek het my kop teen die muur vir 'n rukkie en het opgemerk dat in die HTML-kode is 'n baie leë genereer <Div> tags, soos:

<liggaam>

  <div id = "Tab1Content">

    <div id = "row1" />
    <div id = "row2" />

  </Div>

  <div id = "Tab2Content">

    <div id = "row1" />
    <div id = "row2" />

  </Div>

</liggaam>

(The above is waaaaaaaaaaaay oversimplified.  Die leë div tags is heeltemal geldig. Sommige van my <Div> tags was vol van die inhoud, maar baie meer was nie.  Ek het tot die besef gekom dat my <xsl:vir-elke> riglyne is die afgee van die kort vorm div tags toe die XSL:vir elkeen het 'nie enige data te vind nie.  Ek gedwing om 'n HTML-kommentaar in die uitset, soos aangedui:

image

 

Nadat ek dit gedoen het, al die div mooi is lined up en my blad skakeling begin werk.

Soos altyd, Ek hoop dit help iemand in 'n knippie.

</einde>

Skryf in op my blog.

Volg my op Twitter http://www.twitter.com/pagalvin

Nog Meer jQuery–Grootte van 'n image Voorbeeld

Ek geërf het van 'n web deel van 'n kliënt se ou ondernemer en dit het 'n beeld grootte probleem.  Die beelde is 60×50 maar vir sommige vreemd rede, die oorspronklike verskaffer gedwing om hulle in 42×42, so kyk hulle platgedruk:

 

N goeie beeld

Slegte beeld

Hier is die winsgrens (ietwat vereenvoudigde):

<table class = "Gevorderde-vooruitsigte>
  <thead>
    <tr>
      <ste  width = '100′>3 Dinsdag</ste>
    </tr>
  </thead>

  <tbody>
    <tr class = "voorspelling">
      <td width = '100′>
        <Straat>
          <li class = 'n hoë>Hoë: 72&jy;F</li>
          <li class = "low">Lae: 44&jy;F</li>
          <li class = "toestand">Sunny
            <img src =’
http://deskwx.weatherbug.com/images/Forecast/icons/localized/60×50/en/trans/cond007.png’ width = '42’ hoogte = '42’ alt =” />
          </li>
        </Straat>
      </td>
    </tr>

  </tbody>

</tafel>

Jy sal let dat hoewel die pad na die beeld self toon die korrekte dimensie (60×50) die oorspronklike verskaffer gedwing om dit in 42×42.  Hoekom?  Crazy.

In elk geval, Ek wou 'n vinnige en maklike oplossing vir hierdie kwessie en ek draai om jQuery.  Die geheim is om almal op te spoor van die toepaslike <img> tags.  Ek het nie wil die muck oor met enige ander img tags (wat daar is baie).  Hierdie bietjie van die jQuery het die truuk:

<script type = "text / javascript" src ="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>

<script type = "text / JavaScript">
     $(dokument).gereed(funksie () {

         $(‘li.condition > img ").elke(funksie (indeks, item)
           
{
             $(item).css("Width", "60"); 
             $(item).css("Hoogte", "50");
            });
     }); // dokument vrag
</script>

Daardie bietjie van die kode bevind dat die versameling <li> tags wie se klas is "toestand" en <img> kinders.  Dit iterate dan deur alles.  Soos 'n bom gewerk.

Ek kon dit waarskynlik meer vaartbelyn, maar ek was nog nooit die soort van die unix man wat opgelos π aan 18 syfers presisie met sed en AWK en ek is nie daardie soort indien jQuery man Smile.

</einde>

Skryf in op my blog.

Volg my op Twitter http://www.twitter.com/pagalvin

Implementering van 'n Globale Pop-up Kennisgewing

Ek het 'n artikel vir www.sharepoint.briefing.com getiteld "Implementering van 'n Globale Pop-up Kennisgewing."  Hierdie funksie is in werking gestel is vir 'n gemeenskap kollege skool gesluit is weens die sneeu en so meer te kommunikeer. 

Dit maak gebruik van 'n persoonlike lys, uit die boks SharePoint web dienste en 'n paar jQuery die werk te doen.

Hier is 'n teaser:

image

Lees die hele ding hier: http://www.sharepointbriefing.com/features/article.php/3918471/Implement-a-Global-Pop-up-Notification-System.htm

</einde>

Skryf in op my blog.

Volg my op Twitter http://www.twitter.com/pagalvin

Neem beheer van jou OK en kanselleer knoppies

Ek geskryf het hierdie artikel 'n rukkie terug, maar lyk soos ek nie skakel dit uit my blog op die oomblik, so hier gaan:

image

Hierdie artikel beskryf hoe om te dwing newform.aspx een bladsy te lei wanneer die gebruiker kliek op OK en 'n ander bladsy as sy klik kanselleer.

</einde>

Skryf in op my blog.

Volg my op Twitter http://www.twitter.com/pagalvin