June 28, 2017

Auto version your JavaScript or Stylesheet files using .htaccess

Usually, developers can maintain the cache they maintain themselves at the backend but cannot control the cache held by the browser as freely as they want unless there is proper version control. Here is a quick drop in solution in `.htaccess` file until you have proper versioning.

Most of the applications have one or many layers of cache for their system. The cache that application developer can maintain is at the backend (the server) level. However, you cannot control the cache held by the browser as freely as you want unless you version the files as well.

Versioning the files is definitely the best way to solve this problem because it is a very efficient solution which guarantees that browser will fetch the new resource when you want it to. But there are cases where this is not an easy step to be taken, for example, in a legacy app which resources are included in line the page.

So, is there a quick way to fix the problem until you go to proper versioning?

Yes! there is.

Using .htaccess we can auto version the files and force the browser to fetch files down to every second if we need to.

Here is how:

We can use server variables such as TIME_YEAR, TIME_MONTH to create an automatic version of your resource. These are variables that the web server provide to be used where suitable. And now, let’s see how to do this.

RewriteCond %{QUERY_STRING} !(v=(.<em>))
Rewriterule ^(js|scripts|css|styles)(.</em>)$ /$1$2?v=%{TIME_YEAR}%{TIME_MON}%{TIME_DAY}%{TIME_HOUR} [r=302,nc]`

Open your .htaccess files and paste those two lines in. What these are doing is:

  • If a request comes to the server that starts with js, scripts, css or styles then rewrite the request by appending an auto-created version at the end.
  • IF a request comes with the version already in the request then don’t do anything because we don’t want it to keep rewriting the request.

Simple as that. So for example: if the request comes to https://abc.com/js/main.js it gets served as https://abc.com/js/main.js?v=2017062811. Same goes for any request coming to other paths as well. This example ensures that browser will fetch the resource again every hour. But if you add variables like TIME_MINUTE or TIME_SECOND or TIME browser will keep fetching the content more frequently.

To see what other server variables can be used visit https://httpd.apache.org/docs/trunk/expr.html#vars

April 8, 2016

javascript switch statement/case expression

RGdent’s Question:

I am using a switch statement to search for undefined values to manually change it. but I am having trouble using boolean expressions as I would when using an if statement.

Like: if statemant

if(Item1 == undefined)
{
  item1 ="No";
}
else if (Item2 == undefined)
{
  item2 = "No";
}

etc..

I tried this with the switch statement:

 switch (array) {
 case (item1 == undefined):
 item1 = "No";
 console.log('item1 result', item1 );
 break;
 case item2 == undefined:
 item2 = "No";
 console.log('item2 result', item2 );
 break;
 default:

 }

It does not run through the switch statement, except for when I remove == undefined and only use item1. then it works?

The switch cannot evaluate values of the array like that and that is why it does not run through the switch statement. You need to define which value of that array you want to switch.

Inside case statement you also cannot use expression, you have to use a value there as well.

So, if you are dead set on using switch for what you are trying to accomplish, you can do something like this:

item1 = array[1];
switch(item1) {
    case "undefined":
        // so on
    break;
}

But, based on your example you are probably trying to check if the values are set or not, for that if statements are still the best choice rather than switch.

$arr = []; // Your array
if(typeof $arr[0] == "undefined") {
    $arr[0] = "No";
}
March 4, 2016

JS/HTML – onresize doesn't fire

LastSecondsToLive’s Question:

I wanted to add the resize event to an element (I know you can’t add resize to a specific element, but it would be fine if the JS-function would be triggered on a resize of any kind – not the specific element).

I was thinking about this:

<div onresize="wrapperResize();"></div>

This somehow doesn’t work (Safari user here). This however works:

<div onclick="wrapperResize();"></div>

Currently wrapperResize() only holds a simple console.log(). What could I do about this?

PS: This works great (traditional checked), what do I even do different?

EXTRA: The div has a fixed height and 33% of the body element wide. Even though the event should fire, when the window is resized I thought this may be the cause.

I think you should set onresize handler on window and do it in javascript, not inline html.. Like so

window.onresize = yourFunction

You cannot attach a onresize event on a <div> container. It is only available for window for most of the browsers.

February 8, 2016

Appending div to iframe

Jesus Christ’s Question:

What is wrong with this piece of code:

jQuery('<iframe id="groundplan_popup" class="groundplan_hidden" />').appendTo("#popup_holder");
var iframe = jQuery("#groundplan_popup");
iframe.attr("src","::censored::" + filename);
var iframe_body = iframe.contents().find('body').append('<div id="groundplan_popup_exit"></div>');
var exit_btn_gp = iframe_body.append(jQuery("#groundplan_popup_exit"));

So i have to dynamically create an iframe element which will open up .pdf file in a popup and that part works. What I can’t manage to do is create a div with an id of “groundplan_popup_exit” within that iframe. I don’t know exactly why this doesnt’ work and what exactly I’m doing wrong. When i inspect the iframe window console brings out this warning:

/deep/ combinator is deprecated. See https://www.chromestatus.com/features/6750456638341120 for more
details.

Dont know if it has anything to do with the reason why this isn’t working.

EDIT:

This is what my code looks like now.
enter image description here

Console prtscr:
enter image description here

Iframe console elements prtscr:

enter image description here

So i’m basically confused about the whole situation as I’m not that experienced in using jquery in general and this is my first time using it with iframes. I’m not even sure if the #groundplan_popup_exit div is even created and how do I find it if it is.

I see some problems:

var iframe_body = iframe.contents().find('body').append('<div id="groundplan_popup_exit"></div>');

Here you are already appending the element to the body.

var exit_btn_gp = iframe_body.append(jQuery("#groundplan_popup_exit"));

After you have appended above, you are trying to append again with jQuery("#groundplan_popup_exit") which does not even exists.

Fix (untested) would be something like this:

var iframe_body = iframe.contents().find('body');
var exit_btn_gp = iframe_body.append('<div id="groundplan_popup_exit"></div>');
December 4, 2015

Detect if JavaScript is Executing In a Sandboxed Iframe?

Omninternet’s Question:

I have a product that’s playing a video in Flash (if available), and falls back to HTML5 if Flash isn’t available.

I’m not able to find a way to determine if JavaScript is executing within an Iframe with the “sandbox” attribute, which is necessary for my solution because sandboxed iframes disable all plugins. The sandboxed iframe could be as simple as this:

<iframe src="http://www.cross-domain.com/" sandbox="allow-scripts">

To determine if Flash is enabled, I’m using swfobject’s method of checking navigator.plugins[“Shockwave Flash”].description, which is set even when in a sandboxed iframe. I can load the swf object, but it doesn’t play.

To reproduce this issue, visit http://jsfiddle.net/max_winderbaum/9cqkjo45/, open your chrome inspector and click “Run”. The script on the cross-domain site will pause in the context of the sandboxed iframe.

According to the W3 spec at http://dev.w3.org/html5/spec-preview/browsers.html#sandboxing-flag-set, there is supposed to be an “active sandboxing flag set” on the document that JavaScript can access (at least that’s how I’m reading the spec). There doesn’t seem to be any flag set on the iframe’s document.

Does anyone have any ideas / solutions on how to detect if JavaScript is executing from within a sandboxed iframe?

A project sandblaster can help you detect if you running being sandboxed.

Sandbox check if itself is framed first and then scans through the attributes of the frame element to detect several information about itself. These includes framed, crossOrigin, sandboxed, sandboxAllowances, unsandboxable, resandboxable, sandboxable.

To detect if itself is sandboxed in our case, it checks if the frame element has an attribute sandbox.

// On below `frameEl` is the detected frame element
try {
  result.sandboxed = frameEl.hasAttribute("sandbox");
}
catch (sandboxErr) {
  result.sandboxed = null;
  if (typeof errback === "function") {
    errback(sandboxErr);
  }
}

I tried to replicate your issue and to test if this solution works, I had to paste the script into the window itself due to the security issue.

<html>
    <head>
    </head>
    <body>

    <script>
        //Paste the contents of the script(https://raw.githubusercontent.com/JamesMGreene/sandblaster/master/dist/sandblaster.js) here

        var result = sandblaster.detect();
        if(result.sandboxed === true) {
            //sandboxed
        }
        debugger;
    </script>
    </body>
</html>

Here is a demo: http://jsfiddle.net/Starx/tzmn4088/ that shows this working.

October 14, 2015

Select2 drop-down for countries, with flags

Delavnog’s Question:

Does somebody have an easy to use example of a country drop-down, with country flags, for Select2? I am about to implement one based on this suggestion, but I would prefer to avoid reinventing the wheel.

I was working on a similar problem and here is how I solve it.

(function($) {
    $(function() {
        var isoCountries = [
            { id: 'AF', text: 'Afghanistan'},
            ...
        ];
        //Assuming you have a select element with name country
        // e.g. <select name="name"></select>

        $("[name='country']").select2({
            placeholder: "Select a country",
            data: isoCountries
        });
    });
})(jQuery);

I also have made a gist about it and following are the demos.

November 6, 2013

Copy table row data to a form in html

Joel Paxton’s Question:

I have a page which has a form/table.

I want to be able to click on a button at the end of a row, or the row itself and copy this data into another form on a separate html page, which can then be edited.

I know it probably has something to do with JQuery, however I have little to no experience with that.

If you require more details, I will happily provide.

EDIT:

Here is what it looks like now (it’s a table which has retrieved data from an xml file using SimpleXML):

<form name ="editEvent" method="post" action="editEvent.php">
    <table border="1">
        <tr bgcolor="#FFA500">
            <th>ID #</th>
            <th>Name</th>
            <th>Start Time</th>
            <th>End Time</th>
            <th>Category</th>
            <th>Description</th>
            <th>Location</th>
            <th>Picture Path</th>
            <th>Edit/Delete</th>
        </tr>   <tr>
          <td>1
          <td>Climbing</td>
          <td>09:00</td>
          <td>09:30</td>
          <td>Physical</td>
          <td>Description of what is going on</td>
          <td>where it is</td>
          <td>a photo link</td>
          <td><input type="submit" name="edit" class ="box" value="Edit/Delete"/></td>
      </tr> 
    </table>

I want it to end up in a table like this:

<tr>
        <td><input type="text" name="name" placeholder="Enter new event name..."/></td>
        <td><input type="text" name="time" placeholder="Enter event start time..."/></td>
        <td><input type="text" name="endtime" placeholder="Enter event end time..."/></td>
        <td><input type="text" name="category"/></td>
        <td><input type="text" name="description" placeholder="Enter a description of the event..."/></td>
        <td><input type="text" name="loc"/></td>
        <td><input type="text" name="picturePath" placeholder="Enter link to picture..."/></td>
        <td><input type="submit" name="create" class="box" value="Create"/></td>
    </tr>

Honestly, any help or even pointers in the right direction would be appreciated. I really don’t know what to do here. I’ve tried searching these forums and Google, but all I found is stuff on SQL and databases. I just want to transfer some HTML table row data on one page to a HTML form on another to be edited.

You need some methods of identification on the columns like class name. For eg: <td class="name">Climbing</td> then you can attach an event handler on the td of the row and fetch all the data and populate the form.

$("td").on('click', function() {
   var tr = $(this).parent('tr');
   var name = tr.find(".name").text();
   // Grab other values like this

   // and later populate the form
});

However, Instead of copying the data, an efficient solution would be to hold the primary key of the row in one of the td or on one of the data attributes and use it to fetch the record from the database and then fill up the form.

October 8, 2013

Using .on() and targeting elements with a specific ID

Brandon Durham’s Question:

I understand you can use .on() to attach a single click event to an element and then specify which child elements receive the click. So, for example:

$(this.el).on("click", "span", function () {
    alert("Bloop!");
});

I need to be a bit more specific and target selectors with a particular attribute, like this:

$(this.el).on("click", "span[data-placeholder]", function () {
    alert("Bloop!");
});

That doesn’t seem to work, though. As soon as I add the attribute it stops working. No errors, just doesn’t seem to find the elements.

Is that the expected behavior? Is there a way around it?

CLARITY

$(this.el) is just a div that contains a number of elements, some of which are <span data-placeholder="First Name"></span> tags. There could be dozens of those <span> tags and I didn’t want that many event listeners, so I thought I’d use .on() to add the click to the parent container.

You can choose to filter your spans

$('span', this.el).filter(function() {
     return $(this).hasAttr('data-placeholder');
}).on('click', function() {
   //This is for all the spans having data-placeholder
   //...
});

Or if the placeholder is set via data api:

$(this.el).filter(function() {
     return $(this).data('placeholder') != 'undefined';
}).on('click', function() {
   //This is for all the spans having data-placeholder
   //...
});

This functions above select those elements specifically, if event delegation on the OP is needed, then you can do the following:

$('span', this.el).on('click', 'span', function() {
     if($(this).data('placeholder') != 'undefined') {
         alert('bloop');
     }
});
September 29, 2013

How to turn variable name into string in JS?

Jehan’s Question:

I am trying to write a convenience wrapper for console.log, and I would like to print any variables passed in along with their contents.

Can I turn a variable name into a string in js?

There is a possibility. And here is how

var passed_variable = '65'; // The actual variable
var varname = 'passed_variable'; // The name of the variable in another variable

Now, pass the varname around but not the actual variable. When you need to the value of the variable you can simply do :

console.log(varname, ' : ', window[varname]); // Outputs, passed_variable : 65

I hope you find a way not to use this. 🙂

...

Please fill the form - I will response as fast as I can!