Wednesday, March 21, 2012

8 bit Mario - Canvas style

I messing around with HTML5 canvas and decided to make an 8 bit mario :-) Here is the JS code for it:


window.onload = function() {
    var canvas = document.getElementById("batman");
    var context = canvas.getContext("2d");
   
    var blackX = [76, 76, 65, 43, 54, 65, 76];
    var blackY = [43, 54, 65, 76, 76, 76, 76];
    
      var tanX = [10, 21, 32, 43, 10, 21, 32, 43, 10, 21, 32, 54, 65, 87, 98, 54, 65, 87, 98, 109, 131, 32, 43, 54, 76, 87, 98, 131, 87, 98, 109, 120, 54, 65, 76, 87, 98, 109, 120, 175, 186, 153, 164, 175, 186, 164, 175];
      var tanY = [10, 10, 10, 10, 21, 21, 21, 21, 32, 32, 32, 43, 43, 43, 43, 54, 54, 54, 54, 54, 54, 65, 65, 65, 65, 65, 65, 65, 76, 76, 76, 76, 87, 87, 87, 87, 87, 87, 87, 120, 120, 131, 131, 131, 131, 142, 142];
        
    var redX = [65, 76, 87, 98, 109, 120, 43, 54, 65, 76, 87, 98, 109, 120, 131, 10, 21, 32, 43, 10, 21, 32, 43, 10, 21, 21, 32, 32, 43, 43, 54, 76, 87, 98, 120, 131, 142, 153, 164, 65, 76, 87, 109, 120, 131, 142, 153, 164, 175, 109, 120, 131, 142, 153, 164, 120];
    var redY = [21, 21, 21, 21, 21, 21, 32, 32, 32, 32, 32, 32, 32, 32, 32, 43, 43, 43, 43, 54, 54, 54, 54, 65, 65, 76, 76, 87, 87, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 120, 120, 120, 120, 120, 120, 131];
   
    var brownX = [109, 120, 131, 120, 142, 109, 120, 142, 131, 142, 10, 21, 10, 21, 10, 21, 32, 10, 21, 32, 153, 10, 21, 32, 142, 153, 164, 153, 164, 175, 164, 175];
    var brownY = [43, 43, 43, 54, 54, 65, 65, 65, 76, 76, 109, 109, 120, 120, 131, 131, 131, 142, 142, 142, 142, 153, 153, 153, 153, 153, 153, 164, 164, 164, 175, 175];
   
    var blueX = [65, 109, 43, 54, 98, 43, 54, 65, 76, 87, 98, 43, 65, 76, 98, 109, 131, 142, 43, 54, 65, 76, 87, 98, 109, 120, 131, 142, 43, 54, 65, 76, 87, 98, 109, 120, 131, 65, 76, 87, 98, 109, 120, 131, 142, 98, 109, 120, 131, 142];
      var blueY = [98, 98, 109, 109, 109, 120, 120, 120, 120, 120, 120, 131, 131, 131, 131, 131, 131, 131, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 153, 153, 153, 153, 153, 153, 153, 153, 153, 164, 164, 164, 164, 164, 164, 164, 164, 175, 175, 175, 175, 175];
      
      var yellowX = [54, 87];
      var yellowY = [131, 131];
      
    
      for (var i = 0; i <= blackX.length; i++) {
    context.fillRect(blackX[i],blackY[i],10,10);
    }
    
    context.fillStyle = "tan";
    
    for (var i = 0; i <= tanX.length; i++) {
        context.fillRect(tanX[i],tanY[i],10,10);
      }
    
      context.fillStyle = "red";
      
      for (var i = 0; i <= redX.length; i++) {
        context.fillRect(redX[i],redY[i],10,10);
      }
      
      context.fillStyle = "brown";
      
      for (var i = 0; i <= brownX.length; i++) {
        context.fillRect(brownX[i],brownY[i],10,10);
      }
      
      context.fillStyle = "blue";
      
      for (var i = 0; i <= blueX.length; i++) {
        context.fillRect(blueX[i],blueY[i],10,10);
      }
      
      context.fillStyle = "yellow";
      
      for (var i = 0; i <= yellowX.length; i++) {
        context.fillRect(yellowX[i],yellowZ[i],10,10);
      }
    }

And the Markup:

<!DOCTYPE html> 
<html lang="en"> 
<head>

</head>
<body>
<canvas width="300" height="300" id="batman"></canvas>
</body>
</html>

Tuesday, March 20, 2012

Batman logo in CSS3 - no images

I was playing with the CSS3 rounded corners and thought that a neat challenge to give myself would be to try to create the Batman logo without images.

the markup:

<div id="main_wrap">
    <div id="left_side">
      <div id="left_wing" >
        <div id="left_middle_top" ></div>
        <div id="left_middle_bottom" >
          <div id="left_bottom_one"></div>
          <div id="left_bottom_two"></div>
        </div>
      </div>
    </div>
    <div id="middle">
      <div id="middle_top"></div>
    </div>
    <div id="right_side">
      <div id="right_wing" >
        <div id="right_middle_top" ></div>
        <div id="right_middle_bottom" >
          <div id="right_bottom_one"></div>
          <div id="right_bottom_two"></div>
        </div>
      </div>
    </div>
  </div>

it even kinda looks like a bat just with the markup lol... but this is all nothing without the CSS

    #main_wrap {
      width:80%
      margin:15px auto;
    }
    #left_side #left_wing {
      height:300px
      width:230px;
      background-color:#000000;
      float:left
      position:relative
      left:12px
      -moz-border-radius-bottomleft: 75px 150px
      border-bottom-left-radius: 75px 150px
      -moz-border-radius-topleft: 75px 150px
      border-top-left-radius: 75px 150px
    }
    #left_side #left_middle_top {
      height:130px
      width:200px
      background-color:#ffffff
      float:left
      z-index:10
      position:relative
      left:40px;
      -moz-border-radius-bottomleft: 120px 120px
      border-bottom-left-radius: 120px 120px
      -moz-border-radius-bottomright: 100px 120px
      border-bottom-right-radius: 100px 120px
      -moz-border-radius-topleft: 100px 120px
      border-top-left-radius: 100px 120px
    }
    #left_side #left_bottom_one {
      height:130px
      width:95px
      background-color:#ffffff
      float:left
      z-index:10
      position:relative
      left:40px
      top:40px;
      -moz-border-radius-bottomleft: 90px 120px
      border-bottom-left-radius: 90px 120px
      -moz-border-radius-topright: 90px 120px
      border-top-right-radius: 90px 120px
      -moz-border-radius-topleft: 90px 120px
      border-top-left-radius: 90px 120px
    }
    #left_side #left_bottom_two {
      height:150px
      width:126px
      background-color:#ffffff
      z-index:11
      position:relative
      float:left
      top:50px
      left:40px;
      -moz-border-radius-topright: 90px 120px
      border-top-right-radius: 90px 120px
      -moz-border-radius-topleft: 90px 120px
      border-top-left-radius: 90px 120px
    }
    #middle{
      width:90px
      height:300px
      background-color:#000000
      float:left
      z-index:5
      position:relative
    }
    #middle #middle_top {
      height:50px
      width:38px
      background-color:#ffffff
      z-index:10
      position:relative
      float:left
      left:26px
      -moz-border-radius-bottomleft: 25px 150px
      border-bottom-left-radius: 25px 150px;
      -moz-border-radius-bottomright: 25px 150px
      border-bottom-right-radius: 25px 150px;
    } 
    #right_side #right_wing {
      height:300px
      width:230px
      background-color:#000000;
      float:left
      position:relative
      left:-12px;
      -moz-border-radius-bottomright: 75px 150px
      border-bottom-right-radius: 75px 150px
      -moz-border-radius-topright: 75px 150px
      border-top-right-radius: 75px 150px
    }
    #right_side #right_middle_top {
      height:130px
      width:200px
      background-color:#ffffff
      float:right
      z-index:10
      position:relative
      right:40px;
      -moz-border-radius-bottomright: 90px 120px
      border-bottom-right-radius: 90px 120px
      -moz-border-radius-bottomleft: 90px 120px
      border-bottom-left-radius: 90px 120px
      -moz-border-radius-topright: 90px 120px
      border-top-right-radius: 90px 120px
    }
    #right_side #right_bottom_one {
      height:130px
      width:95px
      background-color:#ffffff
      float:right
      z-index:10
      position:relative
      right:40px
      top:40px;
      -moz-border-radius-bottomright: 90px 120px
      border-bottom-right-radius: 90px 120px
      -moz-border-radius-topright: 90px 120px
      border-top-right-radius: 90px 120px
      -moz-border-radius-topleft: 90px 120px
      border-top-left-radius: 90px 120px
    }
    #right_side #right_bottom_two {
      height:150px
      width:126px
      background-color:#ffffff
      z-index:11
      position:relative
      float:right
      top:50px
      right:40px;
      -moz-border-radius-topright: 90px 120px
      border-top-right-radius: 90px 120px
      -moz-border-radius-topleft: 90px 120px
      border-top-left-radius: 90px 120px
    }

which gives you the completed image of:



Thursday, February 2, 2012

Detecting the sObject type of Id's from ambiguous fields

When dealing with the OwnerId field, it is important to check if it is a User or a Group sObject you are dealing with before you start using it or you'll get errors. The Task object also has a few ambiguous fields that match up multiple Objects like the WhoId and the WhatId. In triggers and in other logic you will sometimes need to detect what the object is to either exclude or include it in the next bit of code. We dont want to iterate through code and update records if we don't need to, it will bog down the system. 


I have seen some of the ways out there that are used, particularly the one where you check if the first 3 letters of the ID is '500' or '300' but i do not think this is an accurate way of detection. I want one that the system tells me for sure what object it is. Unfortunately its not as dynamic as i would like it to be due to limitations in APEX, but it is still a much better detection than the above. 


I first made a helper class called GlobalHelper_IsSobjectType and populated it with a few methods that look like the following. It takes in the Id and after a check to make sure that an Id was actually passed and is not null, it try's to create an Object of that Type. If it can it will not fall into the Catch and will return true, other wise it will error and return false, but it will not error in a way that will halt your program from finishing(thus why its in a try catch). 




I made one for Account, Contact, Lead, User, and Opportunity since those are the ones I typically have to detect. When it comes to the OwnerId field I can just use the one for User since if it returns false i know its a group. I also found that I needed to Overload the method so it would work with string as well as Id: 




Ideally I was hoping to make the above but make it more dynamic so you pass the object type you wanted to detect as well as the id for the detecting. That way you would only need one method instead of one for each Object, but I have yet to find a way to make it work. Now of course you need to test the code, and I prefer as close to 100% coverage as possible so:






Questions?  
Twitter: @SalesForceGirl  or Facebook


Wednesday, February 1, 2012

APEX Trigger to Prevent Duplicate Object Records

One of the biggest issues in Org's that I have seen is with duplicate records. But what is the best way to prevent this? With an easy trigger of course! 


Let take the Contact object, in my Org, everything is keyed off email, so we shouldn't have more than one contact with the same email address. And we need to not only protect against new Contacts, but we also need to ensure that if a User updates the email on the Contact that it too is not already in use before the update occurs. In order for the User to know that they are trying to Insert or Update incorrectly we will have a field error show next to the email of the contact stating that one already exists.


Lets make(or update) a Contact trigger for before insert and before update. 






We are going to use a Map to store the id and email of each contact that comes into the trigger so we can use that to do a SOQL query later when its time to see if it already exists.  add the 'trigger.isBefore' even though we know this will only occur before, so that this can be easily extended in the future and we wont have to go back and change code.




Now we need to populate the map with the Contact info so we can use it in the SOQL query next. We should also send up an error if the batch of Contacts that is being iterated over in the trigger contains more than one of the same email. 




Now that we have the Map populated, or at least in theory it should be, we will query the DB to see if a Contact already exists with that email, and if so, show an error to the User, other wise do nothing and allow it to be inserted/updated. 






And thats it. You can of course make this much more robust, so it not only compares email but also name and phone number too. 


Questions?  
Twitter: @SalesForceGirl  or Facebook