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. 🙂

Set content-type on blob

Chris Nolet’s Question:

We’re transferring a Blob (image) down a websocket and rendering it to a canvas on the other end.

When I use createObjectURL with the blob, I get this error:

Resource interpreted as Image but transferred with MIME type text/plain: "blob:https%3A//staging.app.io/23f53ce3-5a52-4e12-8686-190eb15a9ede".

We create the object URL using the following code. The blob is send via a standard websocket with socket.binaryType = "blob"; on the client side:

socket.onmessage = function(e) {
  var blob = e.data;
  var url = (window.URL || window.webkitURL).createObjectURL(blob);

  var image = document.createElement('img');
  image.src = url;
}

The only way I can think to address this error is to create a copy of the blob with the following code, but I don’t want to introduce the overhead of copying all the data:

var blob = new Blob([e.data], {
  type: 'image/gif'
});

The method gets called dozens of times per second.

Any ideas on how to set the blob content-type without creating a duplicate Blob object with new Blob?

You can solve this problem from the end you are delivering the image. This problem is happening because of the wrong content-type, so you should configure your server to send image with image headers.

If this was in PHP, you should have something like

header("Content-Type: image/jpeg");
echo $image_blob;
exit;

(Just giving you an idea)

In case of Node.js, though I am not an expert you can set the content type on the response object like:

app.get('/image.gif', function(req, res) {
  res.set('Content-Type', 'image/gif');
  res.sendfile('./image.gif');
});
...

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