Gammer
Gammer

Reputation: 5608

PHP foreach shows last record in first iteration

I have the following code in my view :

@foreach($totalUsers as $user)
    <tr>
        <td class="v-a-m ">
            <input type="checkbox" class="user" name="user" value="{{$user->id}}">
            <input type="hidden" name="city" value="{{$user->city}}">
        </td>
        <td class="v-a-m text-white">
            <span>{{$user->name}}</span>
        </td>
        <td class="v-a-m">
            <span>{{$user->cnic}}</span>
        </td>
   </tr>
@endforeach

Some Jquery :

$('input.user').on('change', function() {
    $('input.user').not(this).prop('checked', false);
});

The hidden field is not returning its iteration result, Instead it returns the result of the last row in the database table.

dd($request->all()); return the requests, but city have the value of last row of the table, Which is well tested.

What i want is that the hidden field should return the current iteration city.

What am I doing wrong here ?

Upvotes: 1

Views: 743

Answers (4)

Gammer
Gammer

Reputation: 5608

Simply you can't have multiple input fields with the same name.

If you are passing an user id to the controller, Or anything where you can query the users table with, There you can get the city of the exact same user, Whom you checked the checkbox.

Like :

public function findUser(Request $request){
    //You can pass anything here with `where()`, E.g name,username
    $user = \App\User::find($request->get('id'));

    //Do the rest...
}

You should use first() with eloquent where()

Upvotes: 1

Zakaria Acharki
Zakaria Acharki

Reputation: 67505

You could "disable/enable" the city you want to send with the user input to "allow/prevent" the hidden field from submitting to the server, in your change event like :

$('input.user').on('change', function() {
   $('input.user').not(this).attr('selected', false);
   $('input.city').attr('disabled','disabled');

   $(this).siblings('input.city').removeAttr('disabled');
});

You could see that just the related city with selected user will be send in the submit action.

Hope this helps.

$('input.user').on('change', function() {
   $('input.user').not(this).attr('selected', false);
   $('input.city').attr('disabled','disabled');

   $(this).siblings('input.city').removeAttr('disabled');
});

$(document).on('submit','form.remember',function(e){
   console.log($(this).serialize());
   return false;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form class="remember">
  <table>
    <tr>
      <td class="v-a-m ">
        <input type="radio" name="user" class="user" value="1" />
        <input type="hidden" name="city" class="city" value="city_1" disabled />
      </td>
      <td class="v-a-m text-white"><span>name 1</span></td>
      <td class="v-a-m"><span>cnic 1</span></td>
    </tr>
    <tr>
      <td class="v-a-m ">
        <input type="radio" name="user" class="user" value="2" />
        <input type="hidden" name="city" class="city" value="city_2" disabled />
      </td>
      <td class="v-a-m text-white"><span>name 2</span></td>
      <td class="v-a-m"><span>cnic 2</span></td>
    </tr>
    <tr>
      <td class="v-a-m ">
        <input type="radio" name="user" class="user" value="3" />
        <input type="hidden" name="city" class="city" value="city_3" disabled />
      </td>
      <td class="v-a-m text-white"><span>name 3</span></td>
      <td class="v-a-m"><span>cnic 3</span></td>
    </tr>
    <tr>
      <td class="v-a-m ">
        <input type="radio" name="user" class="user" value="4"/>
        <input type="hidden" name="city" class="city" value="city_4" disabled />
      </td>
      <td class="v-a-m text-white"><span>name 4</span></td>
      <td class="v-a-m"><span>cnic 4</span></td>
    </tr>
  </table> 
  
  <input type="submit" value="Submit values"/>
</form>

Upvotes: 0

Hamoud
Hamoud

Reputation: 1929

Your form can't have multiple input fields with the same name. It works with the checkbox because it's stores the value in an array with the same name. But input type hidden will return the value of the last input of the form with the same name, which is the last row of your table. In other word, the value is overwritten by the last input field.

when you use city[], it will return an array of all cities, which is not what you want.

I'dont understand your purpose of including hidden field with the user's city. Couldn't you just retrieve this data from your controller?

foreach($request->user as $user) {
    $user->city // and do your login here. 
}

Upvotes: 0

Idob
Idob

Reputation: 1650

If you need your user to select one of the options, you need to replace your checkbox with radio button. With that, only one option will be allowed to be selected.

CSS and JS can help you hiding the city radio and making it synced with the user radio:

@foreach($totalUsers as $user)
    <tr>
        <td class="v-a-m">
            <label class="user-label">
                <input type="radio" class="user-radio" name="user" value="{{ $user->id }}"/>
                {{ $user->id }}
            </label>
            <input type="radio" class="city-radio" name="city" value="{{ $user->city }}"/>
        </td>
        <td class="v-a-m text-white">
            <span>{{ $user->name }}</span>
        </td>
        <td class="v-a-m">
            <span>{{ $user->cnic }}</span>
        </td>
    </tr>
@endforeach

<style>
    .city-radio {
        display: none;
    }
</style>

<script>
    $(document).ready(function() {
        $('.user-label').change(function () {
            $(this).parent().find('.city-radio').prop("checked", true);
        });
    });
</script>

Upvotes: 0

Related Questions