Search code examples
javascripttwittergeneratortwitter-share

How can I add a Twitter Share feature to use a string dynamically generated into a div by JavaScript?


There's a JavaScript-based compliment generator that generates new compliments at the click of a button. Users can continually generate new compliments until they get one they like.

I'd like to add the option to share any generated compliment via Twitter but am not sure how to add the compliment text to the Twitter sharer link. Currently, the compliment text only gets displayed within a div with a specific ID.

The generated compliment is output to the DIV with an id of "compliment" and is working as I require. However, I don't know how to ALSO output the compliment text into the Twitter share link -- especially if the text needs to be formatted differently from how it is displayed within the div).

I've setup two jsfiddles with the progress I've made so far.

Here is my first attempt:

http://jsfiddle.net/LosHantos/g04u3qxa/

Here is the JavaScript from that fiddle:

var Complimenter = primish({
  a: 'lovely,beautiful,gorgeous,kind,wonderful,nice,perfect'.split(','),
  b: 'good-looking,super-duper,awesome'.split(','),
  c: 'pal,friend,person,human'.split(','),
  d: 'improver,supporter,juggler'.split(','),

  combos: ['a,b,c', 'a,b,d', 'b,c', 'b,d'],

  constructor: function(element) {
    element && (this.element = element);
    this.combos = this.combos.map(function(c) {
      return c.split(',')
    });
    this.compliment();
  },

  compliment: function(e) {
    e && e.preventDefault();
    var compliment = this.get();

    this.element && (this.element.innerHTML = compliment);

    return compliment;
  },

  get: function() {
    var c = this.combos,
      self = this;

    return c[Math.random() * c.length >> 0].map(function(k) {
      return self[k][Math.random() * self[k].length >> 0]
    }).join(' ');
  }
});

(function() {
  var complimenter = new Complimenter(document.getElementById('compliment'));
  document.querySelector('.heading').addEventListener('click', complimenter.compliment.bind(complimenter));
}());

I got as far as changing the Twitter share link from the original fiddle, then adding this new var to the JS:

var link = "https://twitter.com/intent/tweet?hashtags=compliment&related=complimenttime&text=" + complimenter;
document.getElementById('tweet').setAttribute("href", link); //assigns url above as href to twitter button
document.getElementById('compliment').innerHTML = "<span class='bold'>" + complimenter + "</span>" + "<br />";

The fiddle for that change is here http://jsfiddle.net/LosHantos/catx520n/ (My second attempt)

But, the problems I'm seeing are:

  • It displays the string [object object] instead of the compliment
  • If you click generate a new compliment, a compliment then replaces [object object] but the Twitter sharer still uses [object object]

Solution

  • That's because you concating the object complimenter instead of the its output - which you get by calling to complimenter.get().

    Another thing that you want to present and share the same compliment but each get() returns different compliments so you need to get once and use it to render the div's html and also pass it to the link's href.

    const compliment = complimenter.get();
    var link = "https://twitter.com/intent/tweet?hashtags=compliment&related=complimenttime&text=" + compliment;
    document.getElementById('tweet').setAttribute("href", link); //assigns url above as href to twitter button
    document.getElementById('compliment').innerHTML = "<span class='bold'>" + compliment + "</span>" + "<br />";
    

    Working code:

    // idea + dictionary by hnldesign from b3ta
    var Complimenter = primish({
        a:  'lovely,beautiful,gorgeous,kind,wonderful,nice,perfect'.split(','),
        b: 'good-looking,super-duper,awesome'.split(','), 
        c: 'pal,friend,person,human'.split(','),
        d: 'improver,supporter,juggler'.split(','),
        
        combos: ['a,b,c', 'a,b,d', 'b,c', 'b,d'],
    
        constructor: function(element){
            element && (this.element = element);
            this.combos = this.combos.map(function(c){return c.split(',')});
            this.compliment();
        },
    
        compliment: function(e){
            e && e.preventDefault();
            var compliment= this.get();
            
            this.element && (this.element.innerHTML = compliment);
      			reGenerateLink(compliment);      
            return compliment;
        },
        
        get: function(){
            var c = this.combos, 
                self = this;
            
            return c[Math.random()*c.length>>0].map(function(k){
                return self[k][Math.random()*self[k].length>>0]
            }).join(' ');    
        }        
    });
    
    (function(){
        var complimenter = new Complimenter(document.getElementById('compliment'));
        document.querySelector('.heading').addEventListener('click', complimenter.compliment.bind(complimenter));
        
        const compliment = complimenter.get();
    	reGenerateLink(compliment);
      //assigns url above as href to twitter button
    	document.getElementById('compliment').innerHTML = "<span class='bold'>" + compliment + "</span>" + "<br />";
    }());
    
    function reGenerateLink(compliment) {
        var link = "https://twitter.com/intent/tweet?hashtags=compliment&related=complimenttime&text=" + compliment;
    	document.getElementById('tweet').setAttribute("href", link); 
    }
    @import url(http://fonts.googleapis.com/css?family=Russo+One);
    * {
      font-family: arial;
      font-weight: bold;
    }
    
    body,
    html {
      height: 100%;
      margin: 0;
    }
    
    body {
      background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHhtbG5zOnhsaW5rPSdodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rJyB3aWR0aD0nMTAwJScgaGVpZ2h0PScxMDAlJz4KICA8ZGVmcz4KICAgIDxnIGlkPSdhJz4KICAgICAgPHBhdGggZD0nTTUgNmwtNiAtNiB2LTIgbDYgNicgZmlsbC1vcGFjaXR5PScwJyBzdHJva2U9JyMyYjNhNzUnIC8+CiAgICAgIDxwYXRoIGQ9J001IDVsNiAtNiB2LTIgbC02IDYnIGZpbGwtb3BhY2l0eT0nMCcgc3Ryb2tlPScjMzE0MTdkJyAvPgogICAgPC9nPgogICAgPHBhdHRlcm4gcGF0dGVyblVuaXRzPSd1c2VyU3BhY2VPblVzZScgeD0nMCcgeT0nMCcgaWQ9J3AnIHdpZHRoPScyMCcgaGVpZ2h0PScyMCcgdmlld0JveD0nMCAwIDEwIDEwJz4KICAgICAgPHVzZSB4bGluazpocmVmPScjYScvPiAgCiAgICAgIDx1c2UgeGxpbms6aHJlZj0nI2EnIHk9Jy00Jy8+CiAgICAgIDx1c2UgeGxpbms6aHJlZj0nI2EnIHk9JzQnLz4KICAgICAgPHVzZSB4bGluazpocmVmPScjYScgeT0nOCcvPgogICAgICA8dXNlIHhsaW5rOmhyZWY9JyNhJyB5PScxMicvPgogICAgPC9wYXR0ZXJuPgogICAgPHJhZGlhbEdyYWRpZW50IGdyYWRpZW50VW5pdHM9J3VzZXJTcGFjZU9uVXNlJyBpZD0nZycgY3g9JzUwJScgY3k9JzUwJScgZng9JzMwJScgZnk9JzMwJScgcj0nNjAlJz4KICAgICAgPHN0b3Agb2Zmc2V0PScwJScgc3RvcC1jb2xvcj0nI2FhYWFhYScgc3RvcC1vcGFjaXR5PScuNScgLz4KICAgICAgPHN0b3Agb2Zmc2V0PScxMDAlJyBzdG9wLWNvbG9yPScjMDAwMDAwJyBzdG9wLW9wYWNpdHk9Jy43JyAvPgogICAgICA8L3JhZGlhbEdyYWRpZW50PgogIDwvZGVmcz4KICA8cmVjdCB4PSctNSUnIHk9Jy01JScgd2lkdGg9JzExMCUnIGhlaWdodD0nMTEwJScgZmlsbD0nIzAwMDAyMicvPgogIDxyZWN0IHdpZHRoPScxMTAlJyBoZWlnaHQ9JzExMCUnIGZpbGw9J3VybCgjcCknLz4KICA8cmVjdCB4PSctNSUnIHk9Jy01JScgd2lkdGg9JzExMCUnIGhlaWdodD0nMTEwJScgZmlsbD0ndXJsKCNnKScvPgo8L3N2Zz4=');
    }
    
    .box {
      text-align: center;
      width: 600px;
      height: 276px;
      color: rgba(255, 255, 255, .7);
      text-shadow: 1px 1px 5px rgba(0, 0, 0, .7);
    }
    
    #compliment {
      font-family: "Russo One";
      text-transform: uppercase;
      font-size: 4em;
    }
    
    button.heading {
      outline: none;
      -moz-box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
      -webkit-box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
      box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
      padding: 5px;
      border: 1px solid #808080;
      background-color: #f5f5f5;
      background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6);
      background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));
      background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6);
      background-image: linear-gradient(to bottom, #ffffff, #e6e6e6);
      background-repeat: repeat-x;
      filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0);
      font-size: 14px;
      font-family: "Russo One";
      text-transform: uppercase;
      margin: 15px auto 50px;
    }
    
    .ac {
      margin: auto;
      position: absolute;
      top: 0;
      left: 0;
      bottom: 0;
      right: 0;
    }
    
    .twitter-share a,
    .twitter-share a:visited {
      color: #fff;
    }
    <script src="https://rawgit.com/DimitarChristoff/primish/master/primish-min.js"></script>
    <div class="ac box">
      Random compliment generator. <br/>Generate compliments until you get one you like.<br/>
      <button class="heading">
            generate new compliment
        </button>
    
      <div id="compliment"></div>
    
      <div>
        <a target="_blank" role="button" class="btn btn-info my-btn" id="tweet"><i class="fa fa-twitter"></i> Tweet this</a>
      </div>
    </div>

    http://jsfiddle.net/moshfeu/n71L9skg/6/