CHUVASH.eu

CHunky Universe of Vigourous Astonishing SHarepoint :)

Tag Archives: jQuery

shorthand for jQuery(document).ready

jQuery(document).ready is used very often, why not use the shorthand variant of that?

$(function() {
    // Code here
});

fallback for html5 placeholders

Placeholders are very handy in html5, we don’t need to fool with input values. But in SharePoint and IE we must provide fallback for placeholders if we want use them in other browsers. Here is an jQuery extension to do that:

(function ($) {
  $.fn.extend({
    ensurePlaceholders: function () {
      var input = document.createElement('input');
      var placeholderSupported = ('placeholder' in input);
      if (placeholderSupported) {
        return;
      }
      function setHints(elem) {
        var $elem = $(elem);
        var value = $elem.val();
        if (value == "") {
          var placeholder = $elem.attr("placeholder");
          $elem.val(placeholder);
          $elem.addClass("empty-text");
        }
      }
      function removeHints(elem) {
        var $elem = $(elem);
        $elem.removeClass("empty-text");
        var value = $elem.val();
        var placeholder = $elem.attr("placeholder");
        if (value == placeholder) {
          $elem.val("");
        }
      }
      this.find("[placeholder]").each(function() {
        setHints(this);			
      });
      this.on("focus", "[placeholder]", function(e) {
        removeHints(this);
      });
      this.on("blur", "[placeholder]", function(e) {
        setHints(this);
      });
    }
  });
})(jQuery);

Then “ensure placeholders” by running this function on a wrapper element which contains fields with the placeholder attribute:

jQuery("#form-wrapper").ensurePlaceholders();

Or why not to ensure all placeholders:

jQuery(document).ready(function() {
  jQuery(document).ensurePlaceholders();
});

This only runs if placeholders are not supported. This code toggles the class “empty-text”. It’s just a visual hint for not to be confused, otherwise the users can not know which is just a hint and which is the real value.

.empty-text {
  color: grey;
}

New functions in jQuery 1.7+ on and off

A simpler interface for event handling in jQuery. Just read Dan Wahlin’s blog.

$ and jQuery in SharePoint

Do you still use $ for jQuery? Well, don’t. If your code with $ resides with a SharePoint Images webpart, it will stop working. You’ll get errors like

Uncaught TypeError: Cannot call method 'empty' of null

The reason is that SharePoint uses $ in its own javascript code: CMSSiteManager.js

function $()
{ULSjlC:;
   var elements=new Array();
   for (var i=0; i < arguments.length; i++)
   {
	  var element=arguments[i];
	  if (typeof element=='string')
	  element=document.getElementById(element);
	  if (arguments.length==1) return element;
	  elements.push(element);
   }
   return elements;
}

Simple select unselect all

I have a simple html table, every row in tbody has a checkbox. thead has a checkbox. When it is checked/unchecked, all checkboxes have to be selected/ unselected. Here is a very simple javascript to achieve this:

$("#mytable thead :checkbox").live({
  change: function () {
    var checked = $(this).is(":checked");
    $("#mytable tbody :checkbox").attr("checked", checked);
  }
});

Nested templates in jQuery.tmpl

I have used jQuery tmpl for a while and it is really awesome. Now I want to use some nested templates. And the thing is: it is very simple to do it:

Here is the code to achieve this:

<div onclick="doo()">test</div>
<div id="container"></div>
<script id="parent-template" type="text/html">
<li>
   {{tmpl t }}
</li>
</script>
<script id="red" type="text/html">
   <span style="color:red">{{= title}}</span>
</script>
<script id="green" type="text/html">
   <span style="color:green">{{= title}}</span>
</script>
<script type="text/javascript">
    var d = [];
    d.push({ title: "one", t: "red" });
    d.push({ title: "two", t: "green" });
    $.template("red", $("#red").template());
    $.template("green", $("#green").template());
    function doo() {
        $("#parent-template").tmpl(d).appendTo("#container");
    }
</script>

jQuery: select elements with a specific text

There are situations when you want to select only dom elements which only have a specific content. jQuery provides a beautiful selector :contains:

$("a:contains(Pages)")

But what if it isn’t enough to just get all the elements which contain some word?

Let’s check what we get if we traverse all anchors on http://sv.wikipedia.org containing “wiki”:

$("a:contains(wiki)").each(function(i) { console.log($(this).text()); });

There is another, a generic way, to filter out elements, and it is called “filter”. So a little regex check will do the trick.

$("a").filter(function() {
  return /look_for/i.test($(this).text());
}

To get an element with the exact text in a beatiful way, we have to create our own selector. I got an idea from a comment at old.nabble.com:

(function ($, undefined) {
    if ($ === undefined) {
        throw "Dependency: jQuery is not defined. Please check javascript imports.";
    }
    $.extend($.expr[':'],
    {
        // :textEquals(text)
        textEquals: function(current, index, metadata, elements) {
            var regex = new RegExp("^" + metadata[3] + "$");
            regex.ignoreCase = true;
            var text = current.textContent || current.innerText || jQuery(current).text() || "";
            return regex.test(text);
        }
    });
} (jQuery));

This selector is designed not to be case sensitive.

Parameterize a javascript object and create url

If you want to add some parameters to an url which you want to open, you can use jQuery.param function:

var url = "some_url";
var params = { 
   name: "Setner",
   email: "setner@narspi.name",
   mobile: "123456789"
};
var search = "?" + $.param(p);
url += search;

It is handy, indeed. In an environment without jQuery (are there some?:) ) you can just iterate an object and join properties:

var url = "some_url";
var params = { 
   name: "Setner",
   email: "setner@narspi.name",
   mobile: "123456789"
};
if (url.match("/\?/g") == null) {
   url += "?";
}
else {
   url += "&";
}
var search = "";
for(var p in params) {
   search += [p, params[p]].join("=");
}
url += search;

This solution parameterizes an object and appends it to an url in a smart way (by adding a question mark or an ampersand depending on the situation).

SharePoint javascript API

There is a nice sharepoint javascript api we can use as well. Consider this example:

var u = new SP.Utilities.UrlBuilder("http://takana.com");
u.addKeyValueQueryString("id", "2");
u.addKeyValueQueryString("time", new Date().toISOString());
u.get_url();
//"http://takana.com?id=2&time=2012%2D02%2D24T12%3A30%3A53%2E339Z"

Save an excel sheet as a clean table

To save an excel sheet as a html table is very easy. Just select the needed area, then go to Save as and check the selection and choose html as output format.

It works fine. It even looks like it did in Excel. But what if you don’t want all this junk, you want only the plain html table (e.g. for pasting into WP). When I saved my permission levels to html, I used this javascript code. First open the html page which Excel has created in Chrome, open the Dev Tools console, load the latest jQuery into the page, and remove all unnecessary attributes and styling, remove the comments, after that you can just copy the outerHTML of the table and paste into a text editor:

var script = document.createElement("script");
script.setAttribute("type","text/javascript");
script.setAttribute("src","http://code.jquery.com/jquery-latest.min.js")
document.body.appendChild(script);

//wait a second, then run the remainder

var $table = $("table");
var table = $table.get(0);
for (var i = table.attributes.length-1; i >= 0; i--) {
  $table.removeAttr(table.attributes[i].nodeName);
}
$("colgroup").remove();
$("tr, td").removeAttr("class").removeAttr("height").removeAttr("height").removeAttr("style");
$table.contents().each(function() {
	if(this.nodeType == 8) {
		$(this).remove();
	}
});
//dev tools command:copy
copy(table.outerHTML);

Simplifying jQuery tmpl interface

In one of my previous posts I showed a simple example how to retrieve data from a web service and render it with jQuery tmpl. To render this I used an id for a template and the container:

<script id="contactTemplate" type="text/html">
    <div>
        Name: {{= Name }} <br>
        Phone: {{= Phone }}
    </div>
</script>

<div id="contactContainer"></div>

To render we select the template and container with jQuery selectors:

function onSuccess(data) {
	$("#contactTemplate").tmpl(data.d.results).appendTo("#contactContainer");
}

On a page with multiple templates and containers it can be a djungle of different ids you have to track. Johan Leino in his great blog post provides a better and simpler way to organize containers and templates. The solution is to extend jQuery selectors (like :even, :odd and more) and introduce two new: :template and :container. This code comes from Johan Leino:

(function ($, undefined) {
    if ($ === undefined) {
        throw "Dependency: jQuery is not defined. Please check javascript imports.";
    }
    $.extend($.expr[':'],
    {
        // :template(name)
        template: function (current, index, metadata, elements) {
            var arg = metadata[3],
                d = $(current).data("template-for");
            if (d === undefined) {
                return false;
            }
            return arg ? arg === d : true;
        },
        // :container(name)
        container: function (current, index, metadata, elements) {
            var arg = metadata[3],
                d = $(current).data("container-for");
            if (d === undefined) {
                return false;
            }
            return arg ? arg === d : true;
        }
    });
} (jQuery));

Now we can forget the ids:

<script type="text/html" data-template-for="contacts">
    <div>
        Name: {{= Name }} <br>
        Phone: {{= Phone }}
    </div>
</script>

<div data-container-for="contacts"></div>

Our onSuccess method will look like:

function onSuccess(data) {
    var $container = $(":container(contacts)");
    var $template = $(":template(contacts)");
    $template.tmpl(data.d.results).appendTo($container);
}

Much simpler, isn’t it? More possibilities to write more generic js code, like extracting “contacts” into a variable. One thing I would like to know how performance is in older IE browsers for custom jQuery selectors.

See my post about nested templates where I implement these selectors.

Вула Чăвашла

VulaCV - Чăвашла вулаттаракан сайт

Discovering SharePoint

And going crazy doing it

Bram de Jager - Coder, Speaker, Author

Office 365, SharePoint and Azure

SharePoint Dragons

Nikander & Margriet on SharePoint

Cameron Dwyer

Office 365, SharePoint, Azure, OnePlace Solutions & Life's Other Little Wonders

paul.tavares

Me and My doings!

Share SharePoint Points !

By Mohit Vashishtha

Jimmy Janlén "Den Scrummande Konsulten"

Erfarenheter, synpunkter och raljerande om Scrum från Jimmy Janlén

Aryan Nava

DevOps, Cloud and Blockchain Consultant

SPJoel

SharePoint for everyone

SharePointRyan

Ryan Dennis is a SharePoint Solution Architect with a passion for SharePoint and PowerShell

SharePoint 2020

The Vision for a Future of Clarity

Aharoni in Unicode

Treacle tarts for great justice

... And All That JS

JavaScript, Web Apps and SharePoint

blksthl

Mostly what I know about SharePoint - CommunicoCuspis

SharePointDiver

SharePoint på ren svenska