Forum Discussion

Gursimrat's avatar
Gursimrat
Leader
11 years ago

Add kudos button Via REST

We want to add the kudos button on the post on home page which we have fetched via REST calls, is this possible that I have a kudo link in my custom component in front of each post which when clicked, gives the kudos to that post.

7 Replies

  • Quick answer is yes - but you need to manage all the states yourself - such as already kudo'd, can't kudo your own post etc. This while not impossible tends to be a lot of work. The lads at Lithium might have a confiuration way to add kudo buttons at the list view level - not 100% on this though. HTH

  • Henrik's avatar
    Henrik
    Advisor
    11 years ago

    Hi Gursimrat,

     

    Yes you can!

     

    First, as Chris said, you need to manage all the states yourself. In our case, we are managing 4 states:

    1. The user is anonymous (when he clicks on the button, we invite him to log in)
    2. The kudos button is disabled (end of a contest, user rights, etc.)
    3. The user already gave a kudo
    4. The user can give a kudo

     We use freemarker to get the kudo's status:

    <#assign kudo_status = "anonymous" />
    <#if !user.anonymous>
    	<#assign kudo_status = "disabled" />
    	<#if rest("/messages/id/${topic_id}/kudos/give/allowed").value == "true" >
    		<#assign kudo_status = "kudoed" />
    		<#if rest("/messages/id/${topic_id}/kudos/for/users/self/count").value?number == 0 >
    			<#assign kudo_status = "enabled" />
    		</#if>
    	</#if>
    </#if>

     

    Regarding the last state, you can use AJAX and the Lithium API to allow a user to give a kudo. Here is a quick example where the "Topic" object contains all the information about the topic (id, kudos count, etc.):

     

    	Topic.prototype.like = function() {
    		var topic = this;
    		var url = '/restapi/vc/messages/id/' + topic.id + '/kudos/give';
    		var xhr;
    		if (window.XMLHttpRequest) { xhr = new XMLHttpRequest(); } else { xhr = new ActiveXObject("Microsoft.xhr"); }
    		xhr.onreadystatechange = function() {
    			if (xhr.readyState == 4 && xhr.status == 200) {
    				topic.kudo.count += 1;
    				topic.kudo.status = "kudoed";
    				topic.kudo.refreshButton();
    			}
    		};
    		xhr.open("POST",url,true);
    		xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    		xhr.send();
    	};

    Henrik

     

  • Gursimrat's avatar
    Gursimrat
    Leader
    11 years ago

    Hi Henrik 

     

    Thanks for your reply, I am trying to implement this, but when I am hitting the following call in browser, it gives 504 error.

     

    /restapi/vc/messages/id/thread.id/kudos/give

     

    <response status="error">
    <error code="504">
    <message>
    Method 'get' is not supported off of node 'message.kudos.give'.
    </message>
    </error>
    </response>

     

     
    Also, a question on the implementation, after I placed your FTL code in my file, the states are being shown fine based on the checks you have, but I am not able to get the likes using the ajax, do I need to get something enabled from lithium?
  • Henrik's avatar
    Henrik
    Advisor
    11 years ago

    Hi Gursimrat ,

     

    When you hit the API request in the browser URL bar, you are using the GET method.

    It seems that the API "kudos give" does not support the GET method. Here is the documentation of the function.

     

    So you need to use the AJAX function to give a kudo with the POST method.

    I usually use the POST method when I need to update the database (give a kudo, post a comment, etc.) and the GET method to load a message, or any data.

     

    Try this javascript code in your browser's console:

    function giveAKudo (messageId) {
    	// The API url, with '?xslt=json.xsl' parameter to get the result in JSON
    	var url = '/restapi/vc/messages/id/' + messageId + '/kudos/give?xslt=json.xsl';
    	// The XMLHttpRequest object for AJAX
    	var xhr;
    	if (window.XMLHttpRequest) { xhr = new XMLHttpRequest(); } else { xhr = new ActiveXObject("Microsoft.xhr"); }
    	// What you want to do when the API call succeeded (or not)
    	xhr.onreadystatechange = function() {
    		if (xhr.readyState == 4 && xhr.status == 200) {
    			// Parse the response to check if everything is fine. Note that I use jQuery ($) for older browsers.
    			var responseJSON = JSON && JSON.parse(xhr.responseText) || $.parseJSON(xhr.responseText);
    			if (responseJSON.response.status == 'success') {
    				alert('You successfully gave a kudo !');
    			} else {
    				alert('It didn\'t work :(');
    			}
    		}
    	};
    	xhr.open("POST",url,true);
    	xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    	xhr.send();
    };

    Then, for a  message whose Id is 3241, just call giveAKudo(3241). Check eventually on the Lithium message page if the kudo was given.

     

    Regarding the user rights and Lithium API, you have to allow users to use them (it is in french but it should be the same lines for you).

    Here is a screenshot of what I mean:

    API rights.bmp

     

    I hope it will help!

    Henrik

     

  • Gursimrat's avatar
    Gursimrat
    Leader
    11 years ago

    Hi Henrik - I tried this, states are coming fine, and this might look rusty, but where is the Topics object defined?

     

    Regarding the last state, you can use AJAX and the Lithium API to allow a user to give a kudo. Here is a quick example where the "Topic" object contains all the information about the topic (id, kudos count, etc.):

     

    Getting an error in firebug, ReferenceError: Topic is not defined

     

    Posting a snippet of my code below:

     

    <div id="recent_threads_feed_view">
    
    <#assign recent_threads = rest("/categories/id/community-id/topics/recent?restapi.response_style=view&page_size=5").messages>
    <#list recent_threads.message as threads>
    					
    <div class="thread-feeds-widget">
    					
    	<div id="thread-feeds">
    
    	<ul class="th-feeds" id="feeds-list">
    		
    	
    <#assign kudo_status = "anonymous" />
    <#if !user.anonymous>
    
    	<#assign kudo_status = "disabled" />
    	<#if rest("/messages/id/${threads.id}/kudos/give/allowed").value == "true" >
    
    		<#assign kudo_status = "kudoed" />
    		<#if rest("/messages/id/${threads.id}/kudos/for/users/self/count").value?number == 0 >
    
    		<!-- <div style="background-color:orange; color:#fff;">kudo given</div> -->
    <script>
    alert("0");
    Topic.prototype.like = function () {
        alert("1");
        var topic = this;
        var url = '/restapi/vc/messages/id/' + ${threads.id} + '/kudos/give';
        var xhr;
        if (window.XMLHttpRequest) {
            xhr = new XMLHttpRequest();
            alert("2");
        } else {
            alert("3");
            xhr = new ActiveXObject("Microsoft.xhr");
        }
        xhr.onreadystatechange = function () {
            alert("4");
            if (xhr.readyState == 4 && xhr.status == 200) {
                alert("5");
                topic.kudo.count += 1;
                topic.kudo.status = "kudoed";
                topic.kudo.refreshButton();
            }
            alert("6");
        };
        alert("7");
        xhr.open("POST", url, true);
        xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        xhr.send();
    };
    </script>
    
    			<#assign kudo_status = "enabled" />
    		</#if>
    	</#if>
    </#if>

     

     

  • Henrik's avatar
    Henrik
    Advisor
    11 years ago

    Hi Gursimrat ,

     

    The topic object is a custom object I have defined in my community. It is an example so you don't need this object to give a kudo.

    Please check my second sample of code. All you will need is the ID of the message you want to give a kudo.

     

    In your custom component, just add buttons that call "giveAKudo(message ID)". The "message ID" must be given by your custom component.

     

    Henrik

  • Gursimrat's avatar
    Gursimrat
    Leader
    11 years ago
    Thanks Henrik, I will check and get back if I have any concerns.