B4J Tutorial [ABMaterial] Facebook-like timeline in less 200 lines!

Discussion in 'B4J Tutorials' started by alwaysbusy, Mar 23, 2017.

  1. alwaysbusy

    alwaysbusy Expert Licensed User

    Note: This example will be included in the upcoming 3.02 Maintenance Update.

    I had a question if it was possible to create a Facebook-like WebApp with ABMaterial so I had some time to spare :rolleyes: and wrote a basic one.

    Using ABMContainers and the next CloseContent/OpenContent feature introduced in 3.02, and the existing NextContent to create an infinite page, this was written in less than 200 lines of code!

    It also needed a ABMCustomComponent for the 'Like' feature, of which you can find the source code under the video.

    Video:


    Source code for the 'Like' custom component.

    You'll need also the attached zip file for the images and js/css files. Put the images and css in the /css/custom folder, the js file in the /js/custom/ folder.

    Class LikeComponent
    Code:
    'Class module
    Sub Class_Globals
       
    Public ABMComp As ABMCustomComponent   
       
    Public Counter As Int
    End Sub

    'Initializes the object. Countries and data are Json Strings
    Public Sub Initialize(InternalPage As ABMPage, ID As String, AlreadyLiked As Int)
       ABMComp.Initialize(
    "ABMComp", Me, InternalPage, ID)   
       Counter = AlreadyLiked
    End Sub

    Sub ABMComp_Build(internalID As StringAs String
       
    Return $"<div id="${internalID} class="facebook-reaction"><!-- container div for reaction system -->
            <span class="like-btn"> <!-- Default like button -->
              <span class="like-btn-emo like-btn-default"></span> <!-- Default like button emotion-->
               <span class="like-btn-text">Like</span> <!-- Default like button text,(Like, wow, sad..) default:Like  -->
               <ul class="reactions-box"> <!-- Reaction buttons container-->
                 <li class="reaction reaction-like" data-reaction="Like"></li>
                 <li class="reaction reaction-love" data-reaction="Love"></li>
                 <li class="reaction reaction-haha" data-reaction="HaHa"></li>
                 <li class="reaction reaction-wow" data-reaction="Wow"></li>
                 <li class="reaction reaction-sad" data-reaction="Sad"></li>
                 <li class="reaction reaction-angry" data-reaction="Angry"></li>
               </ul>
             </span>
             <div class="like-stat"> <!-- Like statistic container-->
               <span class="like-emo"> <!-- like emotions container -->
                 <span class="like-btn-like"></span> <!-- given emotions like, wow, sad (default:Like) -->
               </span>
               <span class="like-details">${
    Counter} others</span>
             </div>
           </div>"$

    End Sub

    Sub ABMComp_FirstRun(InternalPage As ABMPage, internalID As String)
       
    Dim script As String = $"$("#${internalID} .reaction").on("click",function(){  // like click
         var data_reaction = $(this).attr("data-reaction");
         $("#${
    internalID} .like-details").html("You and ${Counter} others");
         $("#${
    internalID} .like-btn-emo").removeClass().addClass('like-btn-emo').addClass('like-btn-'+data_reaction.toLowerCase());
         $("#${
    internalID} .like-btn-text").text(data_reaction).removeClass().addClass('like-btn-text').addClass('like-btn-text-'+data_reaction.toLowerCase()).addClass("active");;

         if(data_reaction == "Like") {
             $("#${
    internalID} .like-emo").html('<span class="like-btn-like"></span>');
         } else {
             $("#${
    internalID} .like-emo").html('<span class="like-btn-like"></span><span class="like-btn-'+data_reaction.toLowerCase()+'"></span>');
         }
         var json = {'target': '${
    internalID}', 'like': data_reaction};
         b4j_raiseEvent('likecomponent_liked', json);
         });     
     
         $("#${
    internalID} .like-btn-text").on("click",function(){ // undo like click
         if($(this).hasClass("active")){
           $("#${
    internalID} .like-btn-text").text("Like").removeClass().addClass('like-btn-text');
           $("#${
    internalID} .like-btn-emo").removeClass().addClass('like-btn-emo').addClass("like-btn-default");
           $("#${
    internalID} .like-emo").html('<span class="like-btn-like"></span>');
           $("#${
    internalID} .like-details").html("${Counter} others");
           var json = {'target':'${
    internalID}'};
             b4j_raiseEvent('likecomponent_unliked', json);
           }     
         })"$


       InternalPage.ws.Eval(script, 
    Array As Object(ABMComp.ID))
       
    ' flush not needed, it's done in the refresh method in the lib
    End Sub

    Sub ABMComp_Refresh(InternalPage As ABMPage, internalID As String)
       
    Dim script As String = $""$
       InternalPage.ws.Eval(script, 
    Null)
    End Sub

    ' do the stuff needed when the object is removed
    Sub ABMComp_CleanUp(InternalPage As ABMPage, internalID As String)

    End Sub

    Usage:

    Code:
    Sub Class_Globals
       ...
       
    Dim myLike As LikeComponent
       ...
    End Sub

    ' adding the component
    myLike.initialize(pageID & "Like"Rnd(20500))
    myContainer.Cell(
    4,1).AddComponent(myLike.ABMComp)
    Events (the name LikeComponent is programmed fixed in the LikeComponent class:
    Code:
    public Sub LikeComponent_Liked(value As Map)   
       
    Log(value.Get("like") & " ----> " & value.Get("target"))
    End Sub

    public Sub LikeComponent_UnLiked(value As Map)
       
    Log("Unliked ----> " & value.Get("target"))
    End Sub


    Alain
     

    Attached Files:

  2. Martin Fernandez

    Martin Fernandez Member Licensed User

    Great!!!
     
    joulongleu likes this.
  3. Erel

    Erel Administrator Staff Member Licensed User

    Amazing!

    BTW, this code is a good example of the power of smart strings. The ability to embed html or JS in the code was the main reason behind this feature.
     
  4. alwaysbusy

    alwaysbusy Expert Licensed User

    Indeed, a powerful feature that has proven to be very useful!
     
    joulongleu and Martin Fernandez like this.
  5. Hanz

    Hanz Member

    What if you want to add a comment through some input and with a button to send the comment, should you use "AddArrayComponent" to insert a new comment?
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice