A placeholder text for chosen.js selects

As soon as you click a chosen select the search input is selected and you cannot add a placeholder anymore, or can you ? 🙂

var $input = $('.chzn-search input');
$placeholder = $('
Type something...
'); $input.after($placeholder); $input.keyup(function(){ $placeholder.toggle($(this).val() === ''); }); .chzn-search .placeholder{ margin-top: -25px; margin-bottom: 15px; margin-left: 7px; color: $gray; }

Displaying collections and sorting them with ember-data

We had a lot of pain sorting our collections, since they are not there when the page is opened you need to continually re-sort…

App.Controller.Events = Ember.ArrayController.extend({
    init: function() {
      this._super();
      Helper.assignSortedCollection(this, 'content', Oceans.store.findAll(Oceans.Model.Event), function(item){
        return -1 * item.get('created_at').getTime();
      });
    }
  });

Helper = {
  assignSortedCollection: function(to, path, items, sorter){
    items.addObserver('length', function(){
      var temp = Ember.A();
      this.forEach(function(item) { temp.pushObject(item); });
      to.set(path, _(temp).sortBy(sorter));
    });
  }
}

Save & validation callbacks for ember-data/ember.js

You want to do something when your record got saved/validations failed.

Usage

user.observeSaveOnce(success: function(){
  // go to next page
}, error: function(){
  // show validation errors
})

Code

  # your model.js 
  observeSaveOnce: function(options) {
    function callback() {
      var outcome = 'success';
      if (this.get('isDirty')) {
        if (this.get('isValid')) return; // not submitted yet
        outcome = 'error';
      }

      (options[outcome] || Ember.K).call(this);

      this.removeObserver('isDirty', callback);
      this.removeObserver('isValid', callback);
    }

    this.addObserver('isDirty', callback);
    this.addObserver('isValid', callback);
  }

Logic inside of Handlebars templates for Ember.js is possible, just not pretty

We had a few occasions where we needed something like count > 0 or other simple logic, that should live inside the template, but its impossible… until now 🙂

Code

{{#ifEval "this.getPath('content.click_count') >= 0"}}
   The content has been clicked {{content.click_count}} times!
{{/ifEval}}

Usage

Handlebars.registerHelper('ifEval', function(code, options) {
  if(eval(code)){
    return options.fn(this);
  }
});

Testing geolocation with capybara + selenium + firefox

Just built this little snippet in a hacknight, it simulates a geolcation via capybara, so you can test if you geo-magic actually works 🙂

View

<p>Finding your location... <span id="status">checking...</span></p>
<script>
  jQuery(function () {
    var timeout = (document.location.href.indexOf('test_location') >= 0 ? 100 : 0);

    setTimeout(function(){
      navigator.geolocation.getCurrentPosition(function(){
        jQuery('#status').html("found you!");
      });
    }, timeout)
  });
</script>

Capybara test via selenium in rspec

  def simulate_location(lat, lng)
    page.driver.browser.execute_script <<-JS
      window.navigator.geolocation.getCurrentPosition = function(success){
        var position = {"coords" : { "latitude": "#{lat}", "longitude": "#{lng}" }};
        success(position);
      }
    JS
  end

  it "can use location", :js => true do
    visit '/?test_location=true'
    simulate_location 20, 20
    sleep 0.2
    page.should have_content "found you!"
  end