Link to home
Start Free TrialLog in
Avatar of Eduardo Fuerte
Eduardo FuerteFlag for Brazil

asked on

Could you point why this Laravel view code doesn't correctly actualize the icons like/ dislike on the correct position after click?

Hi Experts

Could you point why this Laravel view code doesn't correctly actualize the icons like/ dislike on the correct position after click?

Accordingly with:
 User generated image
Even clicking on the 2nd or 3rd like/ dislike icons only the count at the icon side of the 1st picture are (incorrectly) actualized.

The views code:
@extends('layouts.appinterno')

@section('content')

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


  	  	<!--div class="col-xs-12 col-sm-4 col-md-4"-->
        <div class="col-md-10 col-sm-12">
		    <p class="titResumoNoticia">Arquivo de Fotos</p>
		   
   
            @foreach($vitrinesX as $vitrine)

                <section class="row">
        
        
                        <div class="col-sm-12 col-md-4">
                            <div class="box-noticias">
                               	<a href="javascript:void(0);" onclick='hotsite.vitrine.abrirNoticia({{$vitrine->id}});' >
        	    				{{$vitrine->titulo}}
        	    			    </a>                    
                            </div>
                            
                            	<p id="like" class="likes" onclick="hotsite.vitrine.salvarEscolha({{ $vitrine->id }}, 1)">
				                    <i class="fa fa-thumbs-up"></i> <span id="qtdeCurtiu">{{ $qtdeCurtiu }}</span>
				               	</p>   
                                    
           						<p id="dislike" class="likes" onclick="hotsite.vitrine.salvarEscolha({{ $vitrine->id }}, 0)">
				                    <i class="fa fa-thumbs-down"></i> <span id="qtdeNaoCurtiu">{{ $qtdeNaoCurtiu }}</span>
						       </p>       
                        </div>    
                               
                        @if($loop->last)
                            @break
                        @else
                            @continue 
                        @endif       
                               
                               
                               

                        <div class="col-sm-12 col-md-4">
                            <div class="box-noticias">
                               	<a href="javascript:void(0);" onclick='hotsite.vitrine.abrirNoticia({{$vitrine->id}});' >
        	    				{{$vitrine->titulo}}
        	    			    </a>                    
                            </div>
                            	
                                <p id="like" class="likes" onclick="hotsite.vitrine.salvarEscolha({{ $vitrine->id }}, 1)">
				                    <i class="fa fa-thumbs-up"></i> <span id="qtdeCurtiu">{{ $qtdeCurtiu }}</span>
				               	</p>    
           						
                                <p id="dislike" class="likes" onclick="hotsite.vitrine.salvarEscolha({{ $vitrine->id }}, 0)">
				                    <i class="fa fa-thumbs-down"></i> <span id="qtdeNaoCurtiu">{{ $qtdeNaoCurtiu }}</span>
						       </p>
                                
                        </div>    
                     
                     
                        @if($loop->last)
                            @break
                        @else
                            @continue 
                        @endif       
                               
                     
                        <div class="col-sm-12 col-md-4">
                            <div class="box-noticias">
                               	<a href="javascript:void(0);" onclick='hotsite.vitrine.abrirNoticia({{$vitrine->id}});' >
        	    				{{$vitrine->titulo}}
        	    			    </a>                    
                            </div>
                            	
                                <p id="like" class="likes" onclick="hotsite.vitrine.salvarEscolha({{ $vitrine->id }}, 1)">
				                    <i class="fa fa-thumbs-up"></i> <span id="qtdeCurtiu">{{ $qtdeCurtiu }}</span>
				               	</p>    
                                
               					<p id="dislike" class="likes" onclick="hotsite.vitrine.salvarEscolha({{ $vitrine->id }}, 0)">
				                    <i class="fa fa-thumbs-down"></i> <span id="qtdeNaoCurtiu">{{ $qtdeNaoCurtiu }}</span>
						       </p>                
      
                        </div>    
     

                </section>
            
  
            @endforeach
			</div>

	</div>
@endsection

@section('scripts')
	<script src="{{ asset('js/hotsite/Hotsite.Formatadores.js').'?v='.md5(uniqid()) }}" ></script>
	<script src="{{ asset('js/hotsite/hotsite.Vitrine.js').'?v='.md5(uniqid()) }}" ></script>

	<script>
		$(document).ready(function() {
			if($('#hdnCurtiu').val() == "1")
				$('#like').addClass('like');
			else if($('#hdnCurtiu').val() == "0")
				$('#dislike').addClass('like');
		})
	</script>
@endsection

Open in new window


The table is correctly actualized after the likes / dislikes, just not to correctly appear.

Thanks in advance.
Avatar of Chris Stanyon
Chris Stanyon
Flag of United Kingdom of Great Britain and Northern Ireland image

Hey Eduardo,

Not sure why, but it's probably got something to do with your ID. In HTML, and ID has to be unique - you can't have 2 elements with the same ID. All of your Like buttons have the same ID - 'like'.

You're also passing exactly the same value to each of your Javascript functions:

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

$vitrine->id is the same across all of your calls.
Avatar of Eduardo Fuerte

ASKER

Hi Chris

That's my doubt.
Since the code is inside a Laravel's loop - doesn't the $vitrine->id  is been automatically actualized?

If not, could you suggest how to deals with?
One evidence that the loop is taking effect is that
{{$vitrine->titulo}}

It's correspondently the same as {{ $vitrine->id }} are

And the tituulo (titles) are changing, accordingly with the picture
Hi Eduardo

In your code, you're looping through $vitrines. Inside the loop, you have code for 3 columns, but you also have code that either calls break or continue. This means that the last 2 columns of your code are never executed, so there's no need for them. You just need one, so remove the other 2.

Also, in your jQuery, you have this:

$(document).ready(function() {
    if($('#hdnCurtiu').val() == "1")
        $('#like').addClass('like');
    else if($('#hdnCurtiu').val() == "0")
        $('#dislike').addClass('like');
});

Open in new window

In that code, you're checking the value of an element with an ID of #hdnCurtiu and adding a class to elements with IDs of #like or #dislike.

Like I said above, IDs in HTML need to be unique. You're creating elements with those IDs inside your loop, so you have several elements with the same ID (like / dislike). That jQuery code will only ever find the first element that matches the ID which is why you're only getting the first like/dislike buttons to work.

It might be easier to set you classes directly in code instead of with jQuery. Something like this:

// For the like link
<p class="likes {{ $curtiu == '1' ? 'like' : '' }}" onclick...

// For the dislike link
<p class="likes {{ $curtiu == '0' ? 'like' : '' }}" onclick...

Open in new window

Hi Chris


Adjusting the way you suggested I don't know if correctly, I get:


@extends('layouts.appinterno')

@section('content')

	<header>
		<br/>
		Vitrines XXX
		<br/><br/>
	</header>
	

	<div class='row'>
	<!--style>
		.noticias-body {
			margin-left: 45px;
		}

		.noticias-body img {
			width: 100%;
		}

		.noticias-visualizacao{
			position: relative;
			display: inline-block;
		}
		.noticias-image{
			/* position: absolute; */
			/* display: inline-block; */
			float: left;
			clear: left;
			margin: 2rem;
		}
	</style-->

	{{ csrf_field() }}
	
	
	
<!--input type="hidden" id="hdnCurtiu" value="{{ $curtiu }}"-->


        <div class="col-md-10 col-sm-12">
		    <p class="titResumoNoticia">Arquivo de Fotos</p>
		   
     
            
            @foreach($vitrinesX as $vitrine)


                <section class="row">
        
        
                        <div class="col-sm-12 col-md-4">
                            <div class="box-noticias">
                               	<a href="javascript:void(0);" onclick='hotsite.vitrine.abrirNoticia({{$vitrine->id}});' >
        	    				{{$vitrine->titulo}}
        	    			    </a>                    
                            </div>
                            
                            	<!--p id="like" class="likes" onclick="hotsite.vitrine.salvarEscolha({{ $vitrine->id }}, 1)"-->
                                <p class="likes {{ $curtiu == 1 ? 'like' : '' }}" onclick="hotsite.vitrine.salvarEscolha({{ $vitrine->id }}, 1)">
				                    <i class="fa fa-thumbs-up"></i> <span id="qtdeCurtiu">{{ $qtdeCurtiu }}</span>
				               	</p>   
                                    
           						
								<!--p id="dislike" class="likes" onclick="hotsite.vitrine.salvarEscolha({{ $vitrine->id }}, 0)"-->
                                <p class="likes {{ $curtiu == 0 ? 'like' : '' }}" onclick="hotsite.vitrine.salvarEscolha({{ $vitrine->id }}, 0)">
				                    <i class="fa fa-thumbs-down"></i> <span id="qtdeNaoCurtiu">{{ $qtdeNaoCurtiu }}</span>
						       </p>       
                        </div>    
                               
                      
                       
                        @if($loop->last)
                            @break
                        @else
                            @continue 
                        @endif      
 

                </section>
            
  
            @endforeach
			</div>

	</div>
@endsection

<!--
@section('scripts')
	<script src="{{ asset('js/hotsite/Hotsite.Formatadores.js').'?v='.md5(uniqid()) }}" ></script>
	<script src="{{ asset('js/hotsite/hotsite.Vitrine.js').'?v='.md5(uniqid()) }}" ></script>

	<script>
		$(document).ready(function() {
			if($('#hdnCurtiu').val() == "1")
				$('#like').addClass('like');
			else if($('#hdnCurtiu').val() == "0")
				$('#dislike').addClass('like');
		})
	</script>
@endsection
-->

Open in new window


The id(s) are correctly captured but still not actualizing the likes/ dislikes of 2nd/3rd/... pictures.
 User generated image
Hey Eduardo,

You've still got duplicate IDs in your code. Take a look at the <span> that wraps the number of likes and dislikes:

<i class="fa fa-thumbs-up"></i> <span id="qtdeCurtiu">{{ $qtdeCurtiu }}</span>
<i class="fa fa-thumbs-down"></i> <span id="qtdeNaoCurtiu">{{ $qtdeNaoCurtiu }}</span>

They both have an ID, so when you loop through your data, you will have several <span> elements with the same ID. If the code that updates that number looks for that ID, it will only ever find the first one. IDs HAVE to be unique for this to work properly.

I suspect you'll need to change or remove those IDs and then edit your Javascript code to make sure the correct number is being updated.
You means dinamically changes the id?

Remove the  id="qtdeCurtiu" ?


If you see the console at the picture the values received on JS code is correctly assigned to the picture. Just the counting is done just for the first.

JS code:

Vitrine.prototype.salvarEscolha = function(vitrine_id, curtiu) {
    
//---------------------------------------
    // Foto id
    console.log(vitrine_id);   

   // Like or dislike
    console.log(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").html());
      var qtdeNaoCurtiu = parseInt($("#qtdeNaoCurtiu").html());

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

        if (qtdeNaoCurtiu > 0) $("#qtdeNaoCurtiu").html(qtdeNaoCurtiu - 1);

        $("#like").addClass("like");
        $("#dislike").removeClass("like");
      } else {
        if (qtdeCurtiu > 0) $("#qtdeCurtiu").html(qtdeCurtiu - 1);

        $("#qtdeNaoCurtiu").html(qtdeNaoCurtiu + 1);

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

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Chris Stanyon
Chris Stanyon
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial

After adaptations:

 
 

Open in new window

Produced:

User generated image



The controller code:

public function salvarEscolha(Request $request){ 
 
 
      $vitrine_id = $request->input('vitrine_id'); 
      $curtiu = $request->input('curtiu'); 
 
      $mUserVitrine = new UserVitrine(); 
    
      $userVitrine = $mUserVitrine->obter(Auth::user()->id, $vitrine_id); 
 
 
      if(empty($userVitrine)){ 
        $userVitrine = new UserVitrine(); 
        $userVitrine->user_id = Auth::user()->id; 
        $userVitrine->vitrine_id = $vitrine_id; 
        $userVitrine->created_at = Carbon::now(); 
      } 
 
 
 
      $userVitrine->curtiu = $curtiu; 
      $userVitrine->updated_at = Carbon::now(); 
      $userVitrine->save(); 
 
      return response()->json(new Resultado(true, 'Sucesso', null), 200); 
    }

Open in new window

The first part of code above was not ok.


JS Code:

Vitrine.prototype.salvarEscolha = function(vitrine_id, curtiu) {
    
    // EF 2020
    
    console.log(vitrine_id);
    console.log(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").html());
      //var qtdeNaoCurtiu = parseInt($("#qtdeNaoCurtiu").html());
      
      var qtdeCurtiu = parseInt($("#qtdeCurtiu_" + vitrine_id).html());
      var qtdeNaoCurtiu = parseInt($("#qtdeNaoCurtiu_" + vitrine_id).html());
      
      console.log(qtdeCurtiu);
      console.log(qtdeNaoCurtiu);

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

        if (qtdeNaoCurtiu > 0) $("#qtdeNaoCurtiu").html(qtdeNaoCurtiu - 1);

        $("#like").addClass("like");
        $("#dislike").removeClass("like");
      } else {
        if (qtdeCurtiu > 0) $("#qtdeCurtiu").html(qtdeCurtiu - 1);

        $("#qtdeNaoCurtiu").html(qtdeNaoCurtiu + 1);

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

Open in new window


Page code::
 @foreach($vitrinesX as $vitrine)

	<section class="row">

				   
				   
			<div class="col-sm-12 col-md-4">
				<div class="box-noticias">
					<a href="javascript:void(0);" onclick='hotsite.vitrine.abrirNoticia({{$vitrine->id}});' >
					{{$vitrine->titulo}}
					</a>                    
				</div>
				
					<p id="like" class="likes" onclick="hotsite.vitrine.salvarEscolha({{ $vitrine->id }}, 1)">
					<!--p class="likes {{ $curtiu == 1 ? 'like' : '' }}" onclick="hotsite.vitrine.salvarEscolha({{ $vitrine->id }}, 1)"-->
						<i class="fa fa-thumbs-up"></i> <span id="qtdeCurtiu_{{ $vitrine->id }}">{{ $qtdeCurtiu }}</span>
					</p>   
						
					<p id="dislike" class="likes" onclick="hotsite.vitrine.salvarEscolha({{ $vitrine->id }}, 0)">
					<!--p class="likes {{ $curtiu == 0 ? 'like' : '' }}" onclick="hotsite.vitrine.salvarEscolha({{ $vitrine->id }}, 0)"-->
						<i class="fa fa-thumbs-down"></i> <span id="qtdeNaoCurtiu_{{ $vitrine->id }}">{{ $qtdeNaoCurtiu }}</span>
				   </p>       
			</div>           
				   
   
		   
			@if($loop->last)
				@break
			@else
				@continue 
			@endif      
				  

	</section>


@endforeach

Open in new window

You're still referring to the old IDs in your Javascript code:

if (qtdeNaoCurtiu > 0) $("#qtdeNaoCurtiu").html(qtdeNaoCurtiu - 1);
    $("#like").addClass("like");
    $("#dislike").removeClass("like");
} else {
    if (qtdeCurtiu > 0) $("#qtdeCurtiu").html(qtdeCurtiu - 1);
    $("#qtdeNaoCurtiu").html(qtdeNaoCurtiu + 1);

Anywhere these ID are used in your Javascript, you need to add the vitrine_id to them:

if (qtdeNaoCurtiu > 0) $("#qtdeNaoCurtiu_" + vitrine_id).html(qtdeNaoCurtiu - 1);
    $("#like").addClass("like");
    $("#dislike").removeClass("like");
} else {
    if (qtdeCurtiu > 0) $("#qtdeCurtiu_" + vitrine_id).html(qtdeCurtiu - 1);
    $("#qtdeNaoCurtiu_" + vitrine_id).html(qtdeNaoCurtiu + 1);
Yes....

Now it's working!!!
User generated image
Excellent news.

We got there in the end :)
Chris

Thank you very much for one more excelent help!!!
You're welcome Eduardo