Arkivat e Kategorisë: jQuery dhe SharePoint

Kapërcyer problem i bezdisshëm me URL afërm në 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 (për shembull, ‘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. Për të zgjidhur atë, get some JavaScript and jQuery onto the page using your favorite technique and with a line of code like this:

 

$(dokument).gati( funksion () {

    $("një:contains('Test URL replacement')").klikoni(funksion () { vigjilent("changed click behavior!"); kthehem i rremë;});

});

And Bob’s your uncle.

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

The .click(funksion() 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.

</fund>

undefinedAbonohen në blogun tim.

Atëherë ejani pas meje në Twitter në http://www.twitter.com/pagalvin

Shpejtë dhe i thjeshtë: Zgjidhur "parametër URL e pavlefshme” Problemi me UpdateListItems në 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.  Kjo, 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 <Method> element.  And you’re not updated ID and probably never want to in the first place.

This SOAP envelope works:

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

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

</fund>

undefinedAbonohen në blogun tim.

Atëherë ejani pas meje në Twitter në http://www.twitter.com/pagalvin

 

Caching varfër njeriut në 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, ndër të tjera, 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. Kështu, 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
    • Otherwise, using jQuery, dynamically populate a bunch if <li>’s in a <st>
  • 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.  Ju mund 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 :). 

</fund>

undefinedAbonohen në blogun tim.

Atëherë ejani pas meje në Twitter në http://www.twitter.com/pagalvin

XSLT dhe Mostrat jQuery

Unë kam qenë duke bërë një shumë e XSLT dhe jQuery dhe mendova se do të ndajnë disa copra pak se të tjerët mund të gjeni të dobishme në të ardhmen.

Shembull 1: Lëshojnë JavaScript thjeshtë / jQuery në XSLT:

<XSL:template match="something" xml:space="preserve">

  <!– Bosh jashtë query miqësore fushë filtra fshehur –>
  <script type="text/javascript">
    $(dokument).gati(funksion(){
      $("#QueryFriendlyFilters").val("empty");
    });
  </dorëshkrim>

</XSL:shabllon>

Kjo pak lëshon disa JavaScript që pret për faqe për të përfunduar ngarkimit (për shkak të $(dokument).gati(...)) dhe pastaj përcakton vlerën e një fushë të fshehur emrin QueryFriendlyFilters me vlerën literal "bosh".

Shembull 2: Përdorim <XSL:nëse> për të kontrolluar "e madhe se",  "Më pak se", etj.

<XSL:template match="something" xml:space="preserve">

  <div id="fdcAllFilters">
 
    <XSL:if test="@Count>0">
      <span class="fdcFilterLabel">Filtra aktuale:</hapësirë>
    </XSL:nëse>

    <!– shumë gjëra që ndodh këtu. –>

</XSL:shabllon>

Snippet më sipër kontrollon për të parë nëse një atribut i quajtur "Count" e elementit "diçka" është më i madh se zero.  XML prapa kjo do të jetë diçka si:"

<diçka Count = "5" />

Shembull 3: Iterate nëpër të gjitha elementet, interspersing thirrje jQuery.

<!– Iterate nëpër të gjitha filtrat dhe të shfaqin saktë  Lidhje. –>
<XSL:for-each select="UserFilter">

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

  <span class="fdcFilterLabel"><XSL:value-of select="@FilterValue"/></hapësirë>

  <script type="text/javascript">

    $(dokument).gati(funksion(){
        <XSL:tekst><![CDATA[$("#QueryFriendlyFilters").val( ($("#QueryFriendlyFilters").val() + " ]]></XSL:tekst>\"<XSL:value-of select="@FilterValue"/>\"<XSL:tekst><![CDATA["));]]></XSL:tekst>
    });

  </dorëshkrim>

</XSL:për njëri->

Snippet e mësipërme është më komplekse dhe nuk mund të jetë mënyra më e lehtë për ta bërë atë.

XML prapa kjo duket afërsisht si kjo:

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

Kjo snippet është iterating përmes <UserFilter> nyjet. 

Ajo i parë lëshon një tag spirancë se kur klikohet thirret një funksion JavaScript që është tashmë në faqen, "MySubmitPage" dhe kalon vlerën e një atribut në <UserFilter> Nyja e quajtur "ID". 

Ajo pastaj lëshon disa jQuery që pret për faqe të ngarkesës.  Kjo jQuery përditësime një fushë fshehur quajtur "QueryFriendlyFilters" duke shtuar vlerën e atribut FilterValue.  Vini re të gjitha çmendur <XSL:tekst> dhe <![CDATA[ ... ]]> sende.

Kjo është ajo, shpresoj se kjo ndihmon!

</fund>

Abonohen në blogun tim.

Atëherë ejani pas meje në Twitter në http://www.twitter.com/pagalvin

Lists.asmx, GetListItems dhe dosjet

Unë kam qenë duke bërë disa kërkime për dikë sot rreth shërbimit të internetit list.asmx ofruara si pjesë e SharePoint 2010 (dhe më herët).  Ajo ishte në gjendje për të marrë sendet listë në dosjen rrënjë (duke përfshirë edhe emrat e sub-folders), por nuk mund të merrni artikuj në sub-folders.  I did some looking around on the internets and it’s a surprisingly common question.  Ende, I couldn’t get a good answer to the simple question, “if I know the folder, how do I get the items in the folder?"  To be honest, I didn’t try all that hard since I’ve wanted to figure this one out on my own for a while buzëqeshje.

To set this up, I created a site named “Blogging Scenarios” and a custom list named “Custom List with Sub Folders”.  I then created folders named:

  • Year 2005
  • Year 2006
  • Year 2007

I added a few items to the folder “Year 2006”.  Kjo është ajo që duket si:

image

My friend isn’t writing C# code but rather using Java, so the SOAP envelope was what she really needed.  To get that, I wrote a bit of jQuery and then used fiddler to get the actual HTTP conversation.

Here’s the relevant jQuery (I copied the code down below if you want to copy/paste):

image

They first key is to include both a <queryOptions> dhe <QueryOptions> node.  The second key is that the <Folder> node is a URL to which the client has access.

There may be other ways to get this, but this worked well for me when using jQuery.

Here is the SOAP envelope for the above:

<soapenv:Envelope xmlns:soapenv=’http://schemas.xmlsoap.org / sapun / Zarfi /’>                
  <soapenv:Trup>
    <GetListItems xmlns=’
http://schemas.microsoft.com / SharePoint / sapun /’>
      <listName>Custom List with Sub Folders</listName>
      <viewFields>  
        <ViewFields>
          <FieldRef Name=’Title’ />
          <FieldRef Name=’EncodedAbsUrl’ />
        </ViewFields>
      </viewFields>
      <queryOptions>
        <QueryOptions>
          <Folder>
http://demoserver1/Blogging Scenarios/lists/Custom List with Sub Folders/Year 2006</Folder>
        </QueryOptions>
      </queryOptions>
   
</GetListItems>
  </soapenv:Trup>
</soapenv:Zarf>

A lot of examples and discussion around this led me to believe that all I need was <QueryOptions> and specify a folder name.  Për mua, I need to both wrap it inside <queryOptions> as well as specify a fully qualified URL for the <Folder> node.

Here’s the jQuery AJAX setup:

$(dokument).gati(funksion() {
       var soapEnv =
           "<soapenv:Envelope xmlns:soapenv=’http://schemas.xmlsoap.org / sapun / Zarfi /’> \
               <soapenv:Trup> \
                    <GetListItems xmlns=’http://schemas.microsoft.com / SharePoint / sapun /’> \
                       <listName>Custom List with Sub Folders</listName> \
                       <viewFields> \
                           <ViewFields> \
                              <FieldRef Name=’Title’ /> \
                              <FieldRef Name=’EncodedAbsUrl’ /> \
                          </ViewFields> \
                       </viewFields> \
                       <queryOptions> \
                         <QueryOptions> \
                           <Folder>http://demoserver1/Blogging Scenarios/lists/Custom List with Sub Folders/Year 2006</Folder> \
                         </QueryOptions> \
                       </queryOptions> \
                   </GetListItems> \
               </soapenv:Trup> \
           </soapenv:Zarf>";

</fund>

Abonohen në blogun tim.

Atëherë ejani pas meje në Twitter në http://www.twitter.com/pagalvin

Lists.asmx, GetList dhe "Vlera nuk mund të jetë null”

Kam zbuluar sot se GetList() Metoda në lists.asmx web shërbim ka për t'u quajtur me shumë kujdes ose ajo është i prirur për të hedhur një misterioze "Vlera nuk mund të jetë null" përjashtim (dhe kjo është duke supozuar që ju mund të merrni kaluara mesazh gabimi edhe më keq gjenerik, “Exception of type ‘Microsoft.SharePoint.SoapServer.SoapServerException’ u hodh. ")  Në mënyrë të veçantë, Kam gjetur se ju nuk mund të japin asnjë lloj prefiksi mbi metodën GetList.  JQuery snippet vijim ilustron pikën:

image

Nëse ju bëni që, shërbim web përgjigjet me "Vlera nuk mund të jetë i pavlefshëm" si për këtë violinist-me kusht transkript HTTP:

<?xml version="1.0" encoding="utf-8"?>
  <sapun:Zarf
     xmlns:Sapun ="
http://schemas.xmlsoap.org / sapun / Zarfi /"    
     xmlns:XSi = "
http://www.w3.org/2001/XMLSchema-instance"
     xmlns:XSD ="
http://www.w3.org/2001/XMLSchema">

  <sapun:Trup>
    <sapun:Faj>
      <faultcode>sapun:Server</faultcode>
      <faultstring>
        Exception of type ‘Microsoft.SharePoint.SoapServer.SoapServerException’ u hodh.
      </faultstring>
      <hollësi>
        <xmlns string error ="
http://schemas.microsoft.com / SharePoint / sapun /">
Vlera nuk mund të jetë null.
        </errorstring>
      </hollësi>
    </sapun:Faj>
  </sapun:Trup>
</sapun:Zarf>

Sigurisht, ju ndoshta nuk do të shtoja se "s0" prefiks në tuaj, por disa mjete janë të prirur për të bërë atë (si Eclipse).

Kjo është e gjitha shumë konfuz / frustruese sepse metoda të tjera të tolerojë prefikset.  Për shembull, the GetListCollection metodë nuk parasysh nëse ajo është prefixed, madje edhe me prefikset pakuptimta si "xyzzy":

image

Kjo "nuk mund të jetë vlera null" duket mjaft e zakonshme me lists.asmx kështu që shpresojmë se kjo do të ndihmojë dikë në të ardhmen.

</fund>

Abonohen në blogun tim.

Atëherë ejani pas meje në Twitter në http://www.twitter.com/pagalvin

Pafund Folezojnë <div> Tags dhe jQuery

Kjo duket si një temë e tillë oddball, Unë nuk jam i sigurt se kjo është me të vërtetë me vlerë rreth Blogging, por që kurrë nuk është ndalur mua para, kështu që këtu ne do të shkojmë buzëqeshje

Unë jam duke punuar në një projekt ku unë jam tërhequr disa të dhëna nga një kërkim, paketimin atë deri në një mesazh XML dhe pastaj se XML është transformuar përfundimisht në HTML me anë XSLT.  Nuk është një shumë e jQuery përfshirë, një grimë e cila zbaton disa funksionalitetin tastit tab.  Kur ju klikoni mbi një tab (vërtet, një <div>), jQuery invokes. fshehin() dhe. show() on divs ndryshme (ngarkesa fillestare faqe shkarkon të gjithë përmbajtjen kështu që nuk ka postbacks në këtë rast).

Një bandë e orë më parë, logjika tab kalimi filluar të sillen erratically dhe ajo nuk do të tregojë një prej tabs mi.  Unë përfundimisht gjurmuar atë poshtë për faktin se internet explorer (të paktën) mendonin se <div> tags mbivendosur tani, shumë më të thellë se Developer Toolbar intended.The do të tregojë:

-<div id = "Tab1Content">
  -<div>
    -<div>
      -<div id = "Tab2Content">
        -<div>
           ..............................
                   </div>  <-Më në fund duke treguar ajo ishte e mbyllur të gjithë rrugën poshtë këtu!

Kështu, në qoftë se kam bërë një $("# Tab1Content").fsheh(), Unë do të fsheh Tab2 dhe unë kurrë nuk mund të tregojë Tab2 në qoftë se unë nuk e tregojnë gjithashtu Tab1.  I kopjuar dhe ngjit kodin e deri në studio vizuale dhe ajo i tregoi të gjitha rreshtim DIV-së deri bukur, ashtu si ata ishin menduar të jetë bërë, në kërkim si kjo:

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

I rrahur kokën time kundër murit për një kohë dhe të vënë re se në kodin aktual HTML është gjeneruar një shumë të zbrazët <div> tags, si:

<trup>

  <div id = "Tab1Content">

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

  </div>

  <div id = "Tab2Content">

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

  </div>

</trup>

(Sipër është waaaaaaaaaaaay thjeshtëzuar.  Tags boshe div janë krejtësisht të vlefshme. Disa nga tim <div> tags ishin plot e përmbajtjes, por shumë më tepër nuk ishin.  Unë kam ardhur në realizimin se im <XSL:për njëri-> Direktivat janë emitting-shkurtra formë tags div kur XSL:për njëri-nuk 'gjejnë ndonjë të dhënave.  I detyruar një koment HTML në dalje, siç tregohet:

image

 

Pasi unë e bëri atë, div të gjitha është rreshtuar bukur dhe switching im tab filluar pune.

Si gjithmonë, Unë shpresoj se kjo ndihmon dikush në një majë.

</fund>

Abonohen në blogun tim.

Atëherë ejani pas meje në Twitter në http://www.twitter.com/pagalvin

JQuery akoma më shumë–Ndrysho një shembull Image

Kam trashëguar një pjesë të internetit nga shitësi vjetër të klientit dhe ajo ka një problem me permasa të imazhit.  Imazhet duhet të jetë 60×50 por për disa arsye të çuditshme, shitësi origjinal detyruar ato në 42×42, kështu që ata shikojnë hequr:

 

Image Mirë

Image Bad

Ja markup (thjeshtuar disi):

<'zgjeruar-opinion' tabelë class =>
  <thead>
    <tr>
      <th  width = '100′>3 E martë</th>
    </tr>
  </thead>

  <tbody>
    <tr class = 'parashikimi'>
      <td width = '100′>
        <st>
          <li class = 'të lartë'>I lartë: 72&ju;F</li>
          <li class = 'të ulët'>Ulët: 44&ju;F</li>
          <'kusht' LI class =>Me diell
            <img src =’
http://deskwx.weatherbug.com/images/Forecast/icons/localized/60×50/en/trans/cond007.png’ width = '42’ height = '42’ alt =” />
          </li>
        </st>
      </td>
    </tr>

  </tbody>

</tryezë>

Ju do të vini re se edhe pse rruga për imazhin e vetë tregon dimensionin e duhur (60×50) shitësi origjinal të detyruar atë në 42×42.  Përse?  I çmendur.

Dosido, Doja një zgjidhje të shpejtë dhe të lehtë për këtë çështje dhe unë u kthye për të jQuery.  Qëllimi ishte për të gjetur të gjitha të përshtatshme <img> tags.  Unë nuk dua të endem me ndonjë tags img tjera (të cilat nuk janë shumë).  Kjo pak e jQuery ka mashtrim:

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

<script type="text/javascript">
     $(dokument).gati(funksion () {

         $(‘li.condition > 'img).çdo(funksion (indeks, artikull)
           
{
             $(artikull).css("width", "60"); 
             $(artikull).css("height", "50");
            });
     }); // on ngarkesës dokumentin
</dorëshkrim>

Se pak e kodit gjen mbledhjen <li> tags cilëve klasë është "kusht" dhe <img> fëmijët.  Ajo pastaj iterates nëpër të gjithë se.  Ka punuar si një hajmali.

Unë ndoshta mund të modernizojë atë, por unë kurrë nuk ishte një lloj i djalë unix që zgjidhet π në 18 shifrat saktësi duke përdorur sed dhe awk dhe unë nuk jam se lloji qoftë djalë jQuery ose buzëqeshje.

</fund>

Abonohen në blogun tim.

Atëherë ejani pas meje në Twitter në http://www.twitter.com/pagalvin

Zbatimi i një sistemi global të pop-up njoftimit

I shkroi një artikull për www.sharepoint.briefing.com titull "Zbatimi i një sistemi global të pop-up njoftimit."  Ky funksion është zbatuar për një kolegj të komunitetit për të komunikuar mbylljeve shkollë për shkak të dëborës dhe kështu me radhë. 

Ajo përdor një listë me porosi, nga shërbimet kuti web SharePoint dhe disa jQuery për të bërë punë.

Këtu është një ngacmues:

image

Lexoni të gjithë gjë këtu: http://www.sharepointbriefing.com/features/article.php/3918471/Implement-a-Global-Pop-up-Notification-System.htm

</fund>

Abonohen në blogun tim.

Atëherë ejani pas meje në Twitter në http://www.twitter.com/pagalvin

Merrni kontrollin e tuaj dhe OK Cancel Buttons

I shkroi ky artikull një prapa ndërsa, por si duket nuk e kam të lidhura me atë nga blogun tim në kohën, kështu që këtu shkon:

image

Ky artikull përshkruan se si për të detyruar newform.aspx të përcjellim në një faqe kur përdoruesi klikon OK dhe një faqe të ndryshme, kur ajo klikimeve anuloj.

</fund>

Abonohen në blogun tim.

Atëherë ejani pas meje në Twitter në http://www.twitter.com/pagalvin