Latest

Thursday, July 6, 2017

Laravel jQuery remove, hide or disable dynamically-generated select options dynamically based on previous select

Asked by: Jeffrey Ollendorf


Relevant section of edit.blade.php in users:

<div id='skill-list'>
   @foreach(range(1, $skillCount) as $skillNumber)
       <div class="form-group row skill">
           <label for="skill_{{ $skillNumber }}" class="col-md-2 inline skill-name">Skill {{ $skillNumber }}</label>
           <div class="col-md-4">
               <select class="col-md-4 form-control skill-choice" name="skill_{{ $skillNumber }}">
                   <option value=""></option>
                   @php
                   $usersCurrentSkill = $user->skills->get($skillNumber - 1)
                   $usersCurrentSkillLevel = !is_null($usersCurrentSkill) ? $usersCurrentSkill->pivot->skill_level : false;
                   @endphp
                   @foreach ($skills as $skill)
                       <option value="{{ $skill->id }}" {{ $usersCurrentSkill && $usersCurrentSkill->id === $skill->id ? 'selected' : ''}}>
                           {{ $skill->name }}
                       </option>
                    @endforeach
               </select>
           </div>
           <div class="col-md-4">
               <select class="col-md-4 form-control skill-choice" name="level_{{ $skillNumber }}">
                   <option value=""></option>
                   <option value="Expert" {{ $usersCurrentSkillLevel && $usersCurrentSkillLevel === "Expert" ? 'selected' : ''}}>Expert</option>
                   <option value="Intermediate" {{ $usersCurrentSkillLevel && $usersCurrentSkillLevel === "Intermediate" ? 'selected' : ''}}>Intermediate</option>
                    <option value="Novice" {{ $usersCurrentSkillLevel && $usersCurrentSkillLevel === "Novice" ? 'selected' : ''}}>Novice</option>
                    <option value="Want To Learn" {{ $usersCurrentSkillLevel && $usersCurrentSkillLevel === 'Want To Learn' ? 'selected' : ''}}>Want To Learn</option>
                </select>
            </div>
            <div class="col-md-2">
                <span class="input-group-btn"><button class='skill-remove btn btn-warning glyphicon glyphicon-remove' href='#'></button></span>
            </div>
     </div>
     @endforeach
  </div>
     <button id='add' class='btn btn-primary'>Add Skill</button>
     <button type="submit" class="btn btn-primary">Update</button>

And skill-add.js:

$(document).ready(function() {
document.getElementById('add').addEventListener( 'click', function ( event ) {

event.preventDefault();
var getSkill = document.getElementsByClassName("skill");
var numOfSkills = document.querySelectorAll('#skill-list .skill').length;
var newSkill = $(getSkill[numOfSkills-1]).clone(true);
$(".skill-name", newSkill).eq(0).html("Skill " + (numOfSkills+1));
$(".skill-name", newSkill).eq(0).attr("for", "skill_" + (numOfSkills+1));
$(".skill-choice", newSkill).eq(0).val("");
$(".skill-choice", newSkill).eq(0).attr("name", "skill_" + (numOfSkills+1));
$(".skill-choice", newSkill).eq(1).val("");
$(".skill-choice", newSkill).eq(1).attr("name", "level_" + (numOfSkills+1));
$("#skill-list").append(newSkill);


}, false );

$(".skill-remove").each(function() {
    $(this).on("click", function(event) {
        event.preventDefault();
        var numOfSkills = document.querySelectorAll('#skill-list .skill').length;
        if (numOfSkills <= 1){
            alert("Sorry, can't remove any more boxes.");
        }
        else{
        $(this).closest('.row').remove(); 
    };
    false
});

});

}); 

Relevant section of UserController.php:

public function edit(User $user)
{
        $skills = Skill::orderBy('name', 'ASC')->get();
        $statuses = Status::all();
        $usersCurrentStatus = $user->status_id;
        $usersCurrentRole = $user->role_id;
        $skillCount = $user->skills->count() >= 1 ? $user->skills->count() : 1;
        return view ('users.edit', compact('skills', 'usersCurrentStatus', 'usersCurrentRole', 'statuses', 'user', 'skillCount'));
}

Now, my question:

I want to, using jQuery, be able to do the following:

  • When a user selects a given skill from one of the dropdowns, remove/hide/disable that choice from all the other dropdowns, even ones that are generated after. This will also be applied for any skills the user already has, as when the page loads, their skills (and skill levels) will be pre-selected in the dropdowns.
  • If the user changes their choice for that specific dropdown, I want the changes undone to the old choice and applied to the new choice.

Something sort of like this, if options 1 and 2 is selected:

1st :

<select>
    <option selected="selected">Option 1</option>
    <option>Option 2</option>
    <option>Option 3</option>
    <option>etc.</option>
</select>

2nd:

<select>
    <option disabled="disabled">Option 1</option>
    <option selected="selected">Option 2</option>
    <option>Option 3</option>
    <option>etc.</option>
</select>

3rd:

<select>
    <option disabled="disabled">Option 1</option>
    <option disabled="disabled">Option 2</option>
    <option selected="selected">Option 3</option>
    <option>etc.</option>
</select>

Or, if the user has 4 sets of dropdowns, but leaves the 2nd one blank for some reason:

1st :

<select>
    <option>Option 1</option>
    <option selected="selected">Option 2</option>
    <option>Option 3</option>
    <option>etc.</option>
</select>

2nd:

<select>
    <option>Option 1</option>
    <option disabled="disabled">Option 2</option>
    <option>Option 3</option>
    <option>etc.</option>
</select>

3rd:

<select>
    <option selected="selected">Option 1</option>
    <option disabled="disabled">Option 2</option>
    <option>Option 3</option>
    <option>etc.</option>
</select>

4th:

<select>
    <option disabled="disabled">Option 1</option>
    <option disabled="disabled">Option 2</option>
    <option>Option 3</option>
    <option selected="selected">etc.</option>
</select>

Sorry about the wall of text, but it seemed really complicated to explain. Also, this needs to be scaleable. Thanks!



Source

No comments:

Post a Comment

Adbox