Motsie Motsie - 3 months ago 11
jQuery Question

Disable options when other options are selected

What I am trying to build is a dynamic selection process. To elaborate, the end-user is only allowed to select a total of 4 lines (across both unlimited and basic).

So, if they select 2 unlimited phone lines, then boxes 3 and 4 under basic phone should be given the class

.mb-disabled
which prevents selection of those two options (since they can only have 4 total).

If in another scenario they were to choose 1 unlimited phone line and 3 basic phone lines, then boxes 2, 3, and 4 under unlimited would be disabled, and box 4 under basic would be disabled.

Here is a diagram to illustrate what I mean further:

phone selection diagram

I tried earlier using
.each()
to assign a
data-unl-number='x'
to the unlimited miniboxes, and a
data-basic-number='x'
to the basic miniboxes, but I was unable to produce anything that a) functioned properly and b) was relatively clean code. It quickly became a mess of if/else statements and I am hoping to avoid that.

Any help/suggestions would be greatly appreciated!

Thanks,

-M



var $unlminibox = $('.unl-selection-container > .minibox');
var $basicminibox = $('.basic-selection-container > .minibox');

$(function() {
$unlminibox.on('click', toggleBox);
$basicminibox.on('click', toggleBox);
})

function toggleBox(e) {
if($(this).hasClass('mb-disabled')) {
e.preventDefault();
} else {
$(this).toggleClass('mb-selected').siblings().removeClass('mb-selected');
}
if($(this).hasClass('mb-selected')) {
racePhone = true;
} else {
racePhone = false;
}
}

h2 {
color:#787878;
font-weight:700;
}

.divider {
background-color:#e8e8e8;
height:2px;
}

.prime-aux {
position:relative;
display:block;
padding:15px;
margin-bottom:50px;
overflow:hidden;
-webkit-box-shadow: 3px 3px 2px 0px rgba(0,0,0,0.13);
-moz-box-shadow: 3px 3px 2px 0px rgba(0,0,0,0.13);
box-shadow: 3px 3px 2px 0px rgba(0,0,0,0.13);
}

.aux-phn-subtext {
color:#787878;
font-size:18px;
font-weight:600;
font-style:italic;
}

.itembox-container {
display:flex;
}

.boxes-2 {
width:calc((100% - 25px)/2);
margin:10px;
padding: 10px;
}

.itembox {
position:relative;
display:inline-block;
border:5px solid #e8e8e8;
border-radius:10px;
}

.user-selected {
border:5px solid #E16E5B;
}

.itembox > h4 {
color:#22ddc0;
font-weight:700;
}

span.price {
display:inline-block;
font-weight:700;
float:right;
color:#22ddc0;
}

.itembox > ul {
list-style: none;
}

.itembox > ul > li {
line-height:3;
}

.radial {
position:absolute;
float:right;
height:35px;
width:35px;
padding:2px;
border:5px solid #e8e8e8;
border-radius:50%;
top:43%;
right:10px;
}

.itembox .center-dot {
display:none;
position:relative;
height:21px;
width:21px;
background-color:#E16E5B;
border-radius:50%;
}

.itembox.user-selected .center-dot{
display: block;
}

/* === (Int/Phn/TV) Thumbnails === */

/* UL Padding Adjustment for itembox */
.itembox > ul {
padding-left:0;
}

.itembox > ul > li {
margin:10px 0;
padding-left:35px;
line-height: 2;
}


/* === Price Bar === */


.price-bar:before {
content:'';
display:block;
background:#e8e8e8;
height:1px;
margin:10px;
}

.price-bar p {
position:relative;
margin:0;
top:5px;
left:10px;
float:left;
font-weight:700;
font-size:18px;
color:#787878;
}

/* === Continue Button === */

.continue {
display:inline-block;
font-size: 18px;
color:#fff;
background-color:#E16E5B;
border:0;
border-radius:0;
float:right;
margin-right:10px;
}

.continue:hover {
color:#fff;
background-color:#E16E5B;
}

/* === Phone Aux Specific === */

.phn-subtext {
font-size:18px;
color:#787878;
}

.unl-selection-container {
display:flex;
flex-wrap:wrap;
position:relative;
}

.minibox {
display:inline-block;
position:relative;
text-align:center;
color:#787878;
cursor:pointer;
flex-grow:1;
width:calc((100% * (1/4)) - 25px);
margin:5px 0 0 25px;
padding:5px;
border:3px solid #e8e8e8;
border-radius:10px;
}

.minibox.mb-selected > p {
color:#22ddc0;
}

.minibox:nth-child(4n+1) {
margin:5px 0 0 0;
}

.minibox > h4 {
font-size:18px;
font-weight:700;
}

/* Selection and Disabled Classes */

.mb-selected {
border:3px solid #E16E5B;
}

.mb-disabled {
background-color:#e8e8e8;
color:#fff;
cursor: not-allowed;
}

<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<div class="prime-aux"> <!-- Phone -->
<h2>Phone</h2>
<p class="aux-phn-subtext">Mix and match (up to 4 lines total)</p>
<hr class="divider"/>
<div id="race-phone" class="itembox-container">
<div class="itembox boxes-2" data-price="20"> <!-- Unlimited -->
<h4>Unlimited Phone <span class="price">$20/mo</span></h4>
<h5 class="phn-subtext">+ $20/mo per additional line</h5>
<ul>
<li class="unl-icon icon-thumb">Unlimited nationwide calling</li>
<li class="intl-icon icon-thumb">Low International Rates</li>
</ul>
<div class="unl-selection-container noselect"> <!-- Minibox Containers UNL -->
<div class="minibox">
<h4>1</h4>
<p>+ $20/mo</p>
</div>
<div class="minibox">
<h4>2</h4>
<p>+ $40/mo</p>
</div>
<div class="minibox">
<h4>3</h4>
<p>+ $60/mo</p>
</div>
<div class="minibox">
<h4>4</h4>
<p>+ $80/mo</p>
</div>
</div>
</div>
<div class="itembox boxes-2" data-price="10"> <!-- Basic -->
<h4>Basic Phone <span class="price">$10/mo</span></h4>
<h5 class="phn-subtext">+ $10/mo per additional line</h5>
<ul>
<li class="unl-icon icon-thumb">Unlimited incoming calls</li>
<li class="nation-icon icon-thumb">$0.05 cents/min outgoing, domestic calls</li>
</ul>
<div class="basic-selection-container noselect"> <!-- Minibox Containers Basic -->
<div class="minibox">
<h4>1</h4>
<p>+ $10/mo</p>
</div>
<div class="minibox">
<h4>2</h4>
<p>+ $15/mo</p>
</div>
<div class="minibox">
<h4>3</h4>
<p>+ $20/mo</p>
</div>
<div class="minibox">
<h4>4</h4>
<p>+ $25/mo</p>
</div>
</div>
</div>
</div>
<div class="price-bar">
<p>Total: <span class="phn-price">$0/mo</span></p>
<div id="phn-continue" class="continue btn">Continue without Phone</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>




Answer

I added some logic. Hope this is what you want

var $unlminibox = $('.unl-selection-container > .minibox');
var $basicminibox = $('.basic-selection-container > .minibox');

$(function() {
  $unlminibox.on('click', toggleBox);
  $basicminibox.on('click', toggleBox);
})

function toggleBox(e) {
  if($(this).hasClass('mb-disabled')) {
    e.preventDefault();
  } else {
    $(this).toggleClass('mb-selected').siblings().removeClass('mb-selected');
  }
  if($(this).hasClass('mb-selected')) {
    racePhone = true;
  } else {
    racePhone = false;
  }
  var toDisable = $unlminibox.index($(this)) == -1 ? $unlminibox : $basicminibox;
    var curr = $unlminibox.index($(this)) != -1 ? $unlminibox : $basicminibox;

    var val = parseInt($('h4', $(this)).text());
    if(!$(this).hasClass('mb-disabled')) {
        var dec = false;
        for(var j = 0; j<curr.length; j++) {
            if($(curr[j]).hasClass('mb-selected')){
                dec=true;
                break;
            }
        }
        if(!dec){
            for(var k = 0; k<toDisable.length; k++) {
                $(toDisable[k]).removeClass('mb-disabled');
            }
        }
        for (var i = 0; i < toDisable.length; i++) {
            if ($(this).hasClass('mb-selected') && (val + parseInt($(toDisable[i]).text()) > 4)) {
                $(toDisable[i]).addClass('mb-disabled')
            } else {
                $(toDisable[i]).removeClass('mb-disabled')
            }
        }
    }
}
h2 {
	color:#787878;
	font-weight:700;
}

.divider {
	background-color:#e8e8e8;
	height:2px;
}

.prime-aux {
	position:relative;
	display:block;
	padding:15px;
	margin-bottom:50px;
	overflow:hidden;
	-webkit-box-shadow: 3px 3px 2px 0px rgba(0,0,0,0.13);
		-moz-box-shadow: 3px 3px 2px 0px rgba(0,0,0,0.13);
			box-shadow: 3px 3px 2px 0px rgba(0,0,0,0.13);
}

.aux-phn-subtext {
	color:#787878;
	font-size:18px;
	font-weight:600;
	font-style:italic;
}

.itembox-container {
	display:flex;
}

.boxes-2 {
	width:calc((100% - 25px)/2);
	margin:10px;
	padding: 10px;
}

.itembox {
	position:relative;
	display:inline-block;
	border:5px solid #e8e8e8;
	border-radius:10px;
}

.user-selected {
	border:5px solid #E16E5B;
}

.itembox > h4 {
	color:#22ddc0;
	font-weight:700;
}

span.price {
	display:inline-block;
	font-weight:700;
	float:right;
	color:#22ddc0;
}

.itembox > ul {
	list-style: none;
}

.itembox > ul > li {
	line-height:3;
}

.radial {
	position:absolute;
	float:right;
	height:35px;
	width:35px;
	padding:2px;
	border:5px solid #e8e8e8;
	border-radius:50%;
	top:43%;
	right:10px;
}

.itembox .center-dot {
	display:none;
	position:relative;
	height:21px;
	width:21px;
	background-color:#E16E5B;
	border-radius:50%;
}

.itembox.user-selected .center-dot{
  display: block;
}

/* === (Int/Phn/TV) Thumbnails === */

/* UL Padding Adjustment for itembox */
.itembox > ul {
	padding-left:0;
}

.itembox > ul > li {
	margin:10px 0;
	padding-left:35px;
	line-height: 2;
}


/* === Price Bar === */


.price-bar:before {
	content:'';
	display:block;
	background:#e8e8e8;
	height:1px;
	margin:10px;
}

.price-bar p {
	position:relative;
	margin:0;
	top:5px;
	left:10px;
	float:left;
	font-weight:700;
	font-size:18px;
	color:#787878;
}

/* === Continue Button === */

.continue {
	display:inline-block;
	font-size: 18px;
	color:#fff;
	background-color:#E16E5B;
	border:0;
	border-radius:0;
	float:right;
	margin-right:10px;
}

.continue:hover {
	color:#fff;
	background-color:#E16E5B;
}

/* === Phone Aux Specific === */

.phn-subtext {
	font-size:18px;
	color:#787878;
}

.unl-selection-container {
	display:flex;
	flex-wrap:wrap;
	position:relative;
}

.minibox {
	display:inline-block;
	position:relative;
	text-align:center;
	color:#787878;
	cursor:pointer;
	flex-grow:1;
	width:calc((100% * (1/4)) - 25px);
	margin:5px 0 0 25px;
	padding:5px;
	border:3px solid #e8e8e8;
	border-radius:10px;
}

.minibox.mb-selected > p {
	color:#22ddc0;
}

.minibox:nth-child(4n+1) {
	margin:5px 0 0 0;
}

.minibox > h4 {
	font-size:18px;
	font-weight:700;
}

/* Selection and Disabled Classes */

.mb-selected {
	border:3px solid #E16E5B;
}

.mb-disabled {
	background-color:#e8e8e8;
	color:#fff;
	cursor: not-allowed;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<div class="prime-aux"> <!-- Phone -->
        <h2>Phone</h2>
        <p class="aux-phn-subtext">Mix and match (up to 4 lines total)</p>
        <hr class="divider"/>
        <div id="race-phone" class="itembox-container">
          <div class="itembox boxes-2" data-price="20"> <!-- Unlimited -->
            <h4>Unlimited Phone <span class="price">$20/mo</span></h4>
            <h5 class="phn-subtext">+ $20/mo per additional line</h5>
            <ul>
              <li class="unl-icon icon-thumb">Unlimited nationwide calling</li>
              <li class="intl-icon icon-thumb">Low International Rates</li>
            </ul>
            <div class="unl-selection-container noselect"> <!-- Minibox Containers UNL -->
              <div class="minibox">
                <h4>1</h4>
                <p>+ $20/mo</p>
              </div>
              <div class="minibox">
                <h4>2</h4>
                <p>+ $40/mo</p>
              </div>
              <div class="minibox">
                <h4>3</h4>
                <p>+ $60/mo</p>
              </div>
              <div class="minibox">
                <h4>4</h4>
                <p>+ $80/mo</p>
              </div>
            </div>
          </div>
          <div class="itembox boxes-2" data-price="10"> <!-- Basic -->
            <h4>Basic Phone <span class="price">$10/mo</span></h4>
            <h5 class="phn-subtext">+ $10/mo per additional line</h5>
            <ul>
              <li class="unl-icon icon-thumb">Unlimited incoming calls</li>
              <li class="nation-icon icon-thumb">$0.05 cents/min outgoing, domestic calls</li>
            </ul>
            <div class="basic-selection-container noselect"> <!-- Minibox Containers Basic -->
              <div class="minibox">
                <h4>1</h4>
                <p>+ $10/mo</p>
              </div>
              <div class="minibox">
                <h4>2</h4>
                <p>+ $15/mo</p>
              </div>
              <div class="minibox">
                <h4>3</h4>
                <p>+ $20/mo</p>
              </div>
              <div class="minibox">
                <h4>4</h4>
                <p>+ $25/mo</p>
              </div>
            </div>
          </div>
        </div>
        <div class="price-bar">
          <p>Total: <span class="phn-price">$0/mo</span></p>
          <div id="phn-continue" class="continue btn">Continue without Phone</div>
        </div>
      </div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>