1

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]
Mosh Feu
  • 28,354
  • 16
  • 88
  • 135
LosHantos
  • 23
  • 4

1 Answers1

0

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/

Mosh Feu
  • 28,354
  • 16
  • 88
  • 135
  • Wow! Thank you so much for this. Do you know if it's possible for the "Tweet this" link to grab whatever compliment is generated? Right now, the "Tweet this" button is only using whatever compliment was generated first (rather than any new compliments that get generated after clicking the "Generate New Compliment" button). – LosHantos Jul 08 '19 at 15:15
  • Just updated my answer. To be honest, the code looks like complicated for no reason unless if it's meaning to learning. Anyway, there is code duplication because basically you want to do generate compliment in page ready and also when user clicks on the button. It should encapsulate in a function and both of the cases will call that function. – Mosh Feu Jul 08 '19 at 15:44
  • Thank you. That's amazing. Yes - this is for learning. It's, frankly, all very much beyond me. But, for me, trying to get small projects like this working - and then seeing how they work - is a way for me to learn the language of JavaScript. I know that you're busy - so thank you very much for your time & talent! – LosHantos Jul 09 '19 at 15:28