We help IT Professionals succeed at work.

Could you point a way to avoid an user to vote more than one time at each picture on this Laravel view?

Eduardo Fuerte
Eduardo Fuerte asked
Hi Experts


Could you point a way to avoid an user to vote more than one time at each picture on this Laravel view?

    <input type="hidden" id="hdnCurtiu" value="{{$curtiu}}">

        <div class="col-md-12 col-sm-12">

                <section class="row">
               
                        @foreach($vitrinesX->chunk(3) as $row)
                        
                            @foreach($row as $vitrine)
          
                          
                               <div class="col-sm-12 col-md-4">
                               
                                    @php 
                                        $currentUserId = auth()->user()->id;
                                        $hasUserVoted = $vitrine->liked_by->contains($currentUserId); 
                                    @endphp
                               
                                    <div class="box-noticias">
                                       	<a href="javascript:void(0);" onclick='hotsite.vitrine.abrirVitrine({{$vitrine->id}});' >
                	    				{{$vitrine->titulo}}
                	    			    </a>                    
                                    </div> 
                                    
                                    <p id="like" class="likes" @if (!$hasUserVoted ) onclick="hotsite.vitrine.salvarEscolha({{ $vitrine->id }}, 1)" @endif>
                                        <i class="fa fa-thumbs-up"></i> <span id="qtdeCurtiu_{{ $vitrine->id }}">{{ $vitrine->qtdeCurtiu }}</span>
                                    </p> 
          
                     
                               </div>     
                              
                            @endforeach
                            
                        @endforeach
                          
                                                  
                </section>
			</div>

	</div>

Open in new window


The Javascript to manage it:

Vitrine.prototype.salvarEscolha = function(vitrine_id, curtiu) {

  $.ajax({
    url: "/vitrine/salvarescolha",
    data: {
      _token: $('input[name="_token"]').val(),
      vitrine_id: vitrine_id,
      curtiu: curtiu
    },
    method: "POST",
    dataType: "json",
    error: function() {
      hotsite.openModalCustom(
        "Erro",
        "Erro ao salvar a escolha.",
        "Entendi",
        "error"
      );
    },
    success: function(data) {
      
      var qtdeCurtiu = parseInt($("#qtdeCurtiu_" + vitrine_id).html());

      if (curtiu == 1) {
        $("#qtdeCurtiu_"+ vitrine_id).html(qtdeCurtiu + 1);

        $("#like").addClass("like");

      } else {
         if (qtdeCurtiu > 0) $("#qtdeCurtiu_" + vitrine_id).html(qtdeCurtiu - 1);

        $("#like").removeClass("like");
        $("#dislike").addClass("like");
      }
    }
  });
};

Open in new window



Thanks in advance!
Comment
Watch Question

Most Valuable Expert 2018
Distinguished Expert 2018
Hey Eduardo,

There are a few ways you could do this. The most secure way would be to do it at the server side. You are posting your data to /vitrine/salvarescolha. In that method, just update the DB using the sync() method we've previously discussed, and then return the likes count from there. This way, when your AJAX call has completed, you will always get an accurate count back from your server. It won't matter how many times a user clicks on the the Like button - the count won't keep increasing.

You could also do it with Javascript. A simple way would be to just remove the onclick attribute once your AJAX call has completed.

On a side note, be careful of adding IDs to elements within a loop. As you currently have it, you will end up with several <p> elements - all with the same ID - #like. This means that you script will probably not work the way you expect it to. This line for example:

$("#like").addClass("like");

Will only ever add the like class to the first element with an ID of #like in your page. IDs need to be unique.
Eduardo FuerteDeveloper and Analyst

Author

Commented:
Hi Chris

The parts  $("#like").addClass("like");   could be eliminated with no effects - since it remains from old code.

What I tryed (but it's wrong) is:
$(".like".prop( "onclick", null ));

Could you clear how to remove the onclick just from the "Like" clicked ?
Most Valuable Expert 2018
Distinguished Expert 2018
Hi Eduardo,

In your code, the onclick property belongs to the <p> tag, so you'll need to tell you r script which <p> tag you have clicked. Easiest way to do that is to pass this into your function. Change your function signature to:

Vitrine.prototype.salvarEscolha = function(vitrine_id, curtiu, elem) {

Open in new window

And then in your success handler, add this:

success: function(data) {
    ...
    $(elem).prop("onclick", null);

Open in new window

And finally, edit your blade template to pass in the extra data:

onclick="hotsite.vitrine.salvarEscolha({{ $vitrine->id }}, 1, this)"

Open in new window

Eduardo FuerteDeveloper and Analyst

Author

Commented:
Chris

Perfect !

And I'm learning....

Thank you very much!
Most Valuable Expert 2018
Distinguished Expert 2018
No worries