Toggle class in closest parent - javascript

So I have this jquery that i need to make it work. But through all the parents() and children(), I can't get to where I want.
My objective is when I click in the button, the class icon-cross, toggle to icon-tick.
(In this snippet bellow, I made an example to explain better. In this case I want to change the color of the rectangle)
$(function() {
$(".addOpt").click(function(e) {
$(this).text(function(i, text) {
return text === "Add" ? "Remove" : "Add";
});
$(this).toggleClass("btn-primary btn-remove");
//the problem is the following line:
$(this).closest(".quoteCompare").children(".quoteCompareInside").p.toggleClass("icon-tick icon-cross");
e.preventDefault();
});
})
.icon-cross {
width: 50px;
height: 10px;
background-color: green;
}
.icon-tick {
width: 50px;
height: 10px;
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row ">
<div class="medium-6 xsmall-12 small-12 column quoteCompare ">
<div class="quoteCompareInside quoteStandard sameHeight2">
<p class="icon-cross"></p>
<p class="title noMarginBottom">10€</p>
</div>
</div>
<div class="medium-6 xsmall-12 small-12 column quoteCompare ">
<div class="quoteCompareInside quoteStandard sameHeight2">
<div class="form-row valign">
<button type="button" class="btn btn-primary buttonOpt addOpt">Add</button>
</div>
</div>
</div>
</div>

You should take p as selector, not as property:
$(this).closest(".quoteCompare").children(".quoteCompareInside").find('p').toggleClass("icon-tick icon-cross");
If you want to get only 1st p element you can use eq method:
$(this).closest(".quoteCompare").children(".quoteCompareInside").find('p').eq(0).toggleClass("icon-tick icon-cross");
Edit:
Note that closest quoteCompare will return second div with classes medium-6 xsmall-12 small-12 column quoteCompare, so you probably also should use prev() in your code:
$(this).closest(".quoteCompare").prev().children(".quoteCompareInside").find('p').eq(0).toggleClass("icon-tick icon-cross");
$(function() {
$(".addOpt").click(function(e) {
$(this).text(function(i, text) {
return text === "Add" ? "Remove" : "Add";
});
$(this).toggleClass("btn-primary btn-remove");
//the problem is the following line:
$(this).closest(".quoteCompare").prev().children(".quoteCompareInside").find('p').eq(0).toggleClass("icon-tick icon-cross");
e.preventDefault();
});
})
.icon-cross {
width: 50px;
height: 10px;
background-color: green;
}
.icon-tick {
width: 50px;
height: 10px;
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row ">
<div class="medium-6 xsmall-12 small-12 column quoteCompare ">
<div class="quoteCompareInside quoteStandard sameHeight2">
<p class="icon-cross"></p>
<p class="title noMarginBottom">10€</p>
</div>
</div>
<div class="medium-6 xsmall-12 small-12 column quoteCompare ">
<div class="quoteCompareInside quoteStandard sameHeight2">
<div class="form-row valign">
<button type="button" class="btn btn-primary buttonOpt addOpt">Add</button>
</div>
</div>
</div>
</div>

You can include the p in the children() selector:
$(function() {
$(".addOpt").click(function(e) {
$(this).text(function(i, text) {
return text === "Add" ? "Remove" : "Add";
});
$(this).toggleClass("btn-primary btn-remove");
//the problem is the following line:
$(this).closest(".quoteCompare").children(".quoteCompareInside p").toggleClass("icon-tick icon-cross");
e.preventDefault();
});
})
.icon-cross {
width: 50px;
height: 10px;
background-color: green;
}
.icon-tick {
width: 50px;
height: 10px;
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row ">
<div class="medium-6 xsmall-12 small-12 column quoteCompare ">
<div class="quoteCompareInside quoteStandard sameHeight2">
<p class="icon-cross"></p>
<p class="title noMarginBottom">10€</p>
</div>
</div>
<div class="medium-6 xsmall-12 small-12 column quoteCompare ">
<div class="quoteCompareInside quoteStandard sameHeight2">
<div class="form-row valign">
<button type="button" class="btn btn-primary buttonOpt addOpt">Add</button>
</div>
</div>
</div>
</div>

We need to traverse to <div class="row"> to grab the associated <p> tag. Please have a look at below snippet:
$(function() {
$(".addOpt").click(function(e) {
$(this).text(function(i, text) {
return text === "Add" ? "Remove" : "Add";
});
$(this).toggleClass("btn-primary btn-remove");
//the problem is the following line:
if($(this).text() === "Remove")
$(this).closest(".row").find("p.icon-cross").toggleClass("icon-tick icon-cross");
else
$(this).closest(".row").find("p.icon-tick").toggleClass("icon-tick icon-cross");
e.preventDefault();
});
})
.icon-cross {
width: 50px;
height: 10px;
background-color: blue;
}
.icon-tick {
width: 50px;
height: 10px;
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row ">
<div class="medium-6 xsmall-12 small-12 column quoteCompare ">
<div class="quoteCompareInside quoteStandard sameHeight2">
<p class="icon-cross"></p>
<p class="title noMarginBottom">10€</p>
</div>
</div>
<div class="medium-6 xsmall-12 small-12 column quoteCompare ">
<div class="quoteCompareInside quoteStandard sameHeight2">
<div class="form-row valign">
<button type="button" class="btn btn-primary buttonOpt addOpt">Add</button>
</div>
</div>
</div>
</div>

Related

Image slider using css and javascript

I'm new to JavaScript/JQuery. I'm trying to implement a image slider using only CSS and Jquery. When clicked on one slider's navigation, elements of other slider also starts moving. If i use separate Id for each slider then it works fine, but I don't want to use separate Id for each slider. How I will detect which slider's navigation is clicked and move elements accordingly.
Thanks in advance!!
Here is Demo
<div class="container">
<div class="row">
<div class="col-sm-12">
<div class="outer_pro_layer">
<div class="presentation">
<button class="prev" aria-describedby="prevdesc" aria-controls="live">Previous</button>
<div class="live">
<div class="ul">
<div class="col-sm-3 li">
<div>1</div>
</div>
<div class="col-sm-3 li">
<div>2</div>
</div>
<div class="col-sm-3 li">
<div>3</div>
</div>
<div class="col-sm-3 li">
<div>4</div>
</div>
<div class="col-sm-3 li">
<div>5</div>
</div>
<div class="col-sm-3 li">
<div>6</div>
</div>
</div>
</div>
<button class="next" aria-describedby="nextdesc" aria-controls="live">Next</button>
</div>
</div>
<div class="outer_pro_layer">
<div class="presentation">
<button class="prev" aria-describedby="prevdesc" aria-controls="live">Previous</button>
<div class="live">
<div class="ul">
<div class="col-sm-3 li">
<div>A</div>
</div>
<div class="col-sm-3 li">
<div>B</div>
</div>
<div class="col-sm-3 li">
<div>C</div>
</div>
<div class="col-sm-3 li">
<div>D</div>
</div>
<div class="col-sm-3 li">
<div>E</div>
</div>
<div class="col-sm-3 li">
<div>F</div>
</div>
</div>
</div>
<button class="next" aria-describedby="nextdesc" aria-controls="live">Next</button>
</div>
</div>
</div>
</div>
</div>
CSS
.sr {
position: absolute;
clip: rect(1px 1px 1px 1px);
clip: rect(1px, 1px, 1px, 1px);
padding: 0;
border: 0;
height: 1px;
width: 1px;
overflow: hidden;
}
.ul {
overflow:hidden;
height:100px;
}
.li {
display: inline-block;
text-align:center;
height:100px;
background:#ccc;
}
.js #live {
display:none;
}
Jquery
$(document).ready(function() {
var slidestash;
var lastindex = $(".live .ul .li").length - 1;
var numstashed = 2;
function setup() {
$(".live")
.attr('aria-label', "Rotating list of statistics")
.attr('aria-live', 'polite')
.attr('aria-relevant', 'additions')
.attr('aria-atomic', 'false');
slidestash = $(".live .ul .li:nth-child(-n+" + numstashed + ")").detach();
}
setup();
$("html").removeClass("js");
$(".prev").click(function() {
$(".live .ul").prepend(slidestash);
slidestash = $(".live .ul .li:nth-child(n+" + lastindex + ")").detach();
if (!$(this).is(":focus")) $(this).focus(); //iOS hack
});
$(".next").click(function() {
$(".live .ul").append(slidestash);
slidestash = $(".live .ul .li:nth-child(-n+" + numstashed + ")").detach();
if (!$(this).is(":focus")) $(this).focus(); //iOS hack
})
});
What you want to do here is
place all the code for running a slider in a single function
run that function on each of your slider instances
limit the code from one instance to apply inside that element only.
First two points are easy:
1.
function initSlider(e) {
..code here...
}
2.
$('presentation').each(function(i,e) {
initSlider(e);
})
For 3, you need to pass the instance - $(e) - to all jQuery selectors in your function, as the second param (delimiter), to tell jQuery: "only select inside this element".
For example, $(".live") will become $(".live", $(e)).
Here it is, working:
$(window).on('load', function() {
$("html").removeClass("js");
$('.presentation').each(function(i, e) {
initSlider(e);
});
function initSlider(e) {
var slidestash,
lastindex = $(".live .ul .li", $(e)).length - 1,
numstashed = 2;
function setup() {
$(".live", $(e))
.attr('aria-label', "Rotating list of statistics")
.attr('aria-live', 'polite')
.attr('aria-relevant', 'additions')
.attr('aria-atomic', 'false');
slidestash = $(".live .ul .li:nth-child(-n+" + numstashed + ")", $(e)).detach();
}
setup();
$(".prev", $(e)).click(function() {
$(".live .ul", $(e)).prepend(slidestash);
slidestash = $(".live .ul .li:nth-child(n+" + lastindex + ")", $(e)).detach();
if (!$(this).is(":focus")) $(this).focus(); //iOS hack
});
$(".next", $(e)).click(function() {
$(".live .ul", $(e)).append(slidestash);
slidestash = $(".live .ul .li:nth-child(-n+" + numstashed + ")", $(e)).detach();
if (!$(this).is(":focus")) $(this).focus(); //iOS hack
})
}
})
.sr {
position: absolute;
clip: rect(1px 1px 1px 1px);
clip: rect(1px, 1px, 1px, 1px);
padding: 0;
border: 0;
height: 1px;
width: 1px;
overflow: hidden;
}
.ul {
overflow:hidden;
height:100px;
}
.li {
display: inline-block;
text-align:center;
height:100px;
background:#ccc;
}
.js #live {
display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<div class="container">
<div class="row">
<div class="col-sm-12">
<div class="outer_pro_layer">
<div class="presentation">
<button class="prev" aria-describedby="prevdesc" aria-controls="live">Previous</button>
<div class="live">
<div class="ul">
<div class="col-sm-3 li">
<div>1</div>
</div>
<div class="col-sm-3 li">
<div>2</div>
</div>
<div class="col-sm-3 li">
<div>3</div>
</div>
<div class="col-sm-3 li">
<div>4</div>
</div>
<div class="col-sm-3 li">
<div>5</div>
</div>
<div class="col-sm-3 li">
<div>6</div>
</div>
</div>
</div>
<button class="next" aria-describedby="nextdesc" aria-controls="live">Next</button>
</div>
</div>
<div class="outer_pro_layer">
<div class="presentation">
<button class="prev" aria-describedby="prevdesc" aria-controls="live">Previous</button>
<div class="live">
<div class="ul">
<div class="col-sm-3 li">
<div>A</div>
</div>
<div class="col-sm-3 li">
<div>B</div>
</div>
<div class="col-sm-3 li">
<div>C</div>
</div>
<div class="col-sm-3 li">
<div>D</div>
</div>
<div class="col-sm-3 li">
<div>E</div>
</div>
<div class="col-sm-3 li">
<div>F</div>
</div>
</div>
</div>
<button class="next" aria-describedby="nextdesc" aria-controls="live">Next</button>
</div>
</div>
</div>
</div>
</div>
As you can see, the JavaScript now works correctly. If you need more help with it, please turn your code into a live snippet, so I can see what I'm doing and how it's supposed to look.
You are on the right track, but you need to limit the context of the elements. for example, prev button should only affect the slider that the button is contained within.
For this, you can use the .container element as the root of a slider, and search for the elements inside it.
For example:
$(".prev").click(function() {
var container = $(this).parents(".outer_pro_layer").first();
// or $(this).closest(".outer_pro_layer") or $(this).parent(".outer_pro_layer")
container.find(".live .ul").prepend(slidestash);
slidestash = container.find(".live .ul .li:nth-child(n+"+lastindex+")").detach();
if (!$(this).is(":focus")) $(this).focus(); //iOS hack
});

Add / remove div for each button on click

I'm trying use append to give each button it's own div (.modal-item) that can be created and removed inside of the .modal container when the button is clicked. Each .item has it's own button and different content nested inside.
What I need as an example: If I click the button labelled Btn 1, I want a .modal-item div created inside of .modal that has the content from the Btn 1 .item. If I click Btn 1 again, it is removed. The same goes for each of the buttons.
The buttons should act as a checkbox for creating and removing the .modal-items. So in other words, the adding/removing of each .modal-item is handled by it's button.
$(function() {
$('#btn').click(function() {
var newDiv = $('<div class="modal-item"><h4><a>Dynamic Title</a></h4> </div>');
$('.modal').append(newDiv);
});
});
.container {
display: flex;
border: 1px solid blue;
}
.item,
.modal-item {
width: 100px;
border: 1px solid;
}
.modal {
display: flex;
border: 1px solid green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="item">
<button id="btn">Btn 1</button>
<h4> Test 1 </h4>
<div class="subtitle"> Title 1 </div>
<div class="info"> This is Info / Description 1. </div>
</div>
<div class="item">
<button id="btn">Btn 2</button>
<h4> Test 2 </h4>
<div class="subtitle"> Title 2 </div>
<div class="info"> This is Info / Description 2. </div>
</div>
<div class="item">
<button id="btn">Btn 3</button>
<h4> Test 3 </h4>
<div class="subtitle"> Title 3 </div>
<div class="info"> This is Info / Description 3. </div>
</div>
</div>
<div class="modal"></div>
1st: id must be unique so you need to change id="btn" to class="btn"
2nd: by using data attribute for each btn and pass it to the modal-item div it can be done
$(function() {
$('.btn').click(function() {
var newDiv = $('<div data-btn="'+$(this).attr("data-btn")+'" class="modal-item"><h4><a>Dynamic Title'+ ($(this).closest('.item').index() + 1) +'</a></h4> </div>');
if($('.modal .modal-item[data-btn="'+$(this).attr("data-btn")+'"]').length < 1 ){
$('.modal').append(newDiv);
}else{
$('.modal .modal-item[data-btn="'+$(this).attr("data-btn")+'"]').remove();
}
});
});
.container {
display: flex;
border: 1px solid blue;
}
.item,
.modal-item {
width: 100px;
border: 1px solid;
}
.modal {
display: flex;
border: 1px solid green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="item">
<button class="btn" data-btn="btn1">Btn 1</button>
<h4> Test 1 </h4>
<div class="subtitle"> Title 1 </div>
<div class="info"> This is Info / Description 1. </div>
</div>
<div class="item">
<button class="btn" data-btn="btn2">Btn 2</button>
<h4> Test 2 </h4>
<div class="subtitle"> Title 2 </div>
<div class="info"> This is Info / Description 2. </div>
</div>
<div class="item">
<button class="btn" data-btn="btn3">Btn 3</button>
<h4> Test 3 </h4>
<div class="subtitle"> Title 3 </div>
<div class="info"> This is Info / Description 3. </div>
</div>
</div>
<div class="modal"></div>

positioning div classes next to another div using jquery

below is my current html layout, inside my .container class I have two <span> tags with classes of .download-btn and .save-btn. I want, whenever page load, remove those <span> from there and postioning near <div class="share"></div>
tag.
current layout
<div class="container">
<div class="col-md-6 col-center">
<span class="download-btn">download</span>
<span class="save-btn">save</span>
</div>
<div id="options">
<div class="share"></div>
</div>
expected layout when page load
<div class="container">
<div class="col-md-6 col-center">
</div>
<div id="options">
<span class="download-btn">download</span>
<span class="save-btn">save</span>
<div class="share"></div>
</div>
</div>
pls advice how to proceed using js ?
Using jQuery,
It can be done in a one line of code.
$("#options").prepend($(".save-btn")).prepend($(".download-btn"));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="col-md-6 col-center">
<span class="download-btn">download</span>
<span class="save-btn">save</span>
</div>
<div id="options">
<div class="share"></div>
</div>
</div>
Use prepend() to move the buttons to the beginning of the element with ID options:
$('#options').prepend($('.download-btn, .save-btn'));
In this example I'm removing this two buttons from their places, and append them before <div class="share"></div> (and I have added content "share" to this div to see the difference):
var downloadBtn = $('.download-btn');
var saveBtn = $('.save-btn');
$('.share').before(saveBtn).before(downloadBtn);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="col-md-6 col-center">
<span class="download-btn">download</span>
<span class="save-btn">save</span>
</div>
<div id="options">
<div class="share">share</div>
</div>
Use button for for the buttons. It's semantically correct and accessible.
$(window).on('load', function() {
var download = $('.download-btn'),
save = $('.save-btn'),
options = $('#options');
download.remove();
save.remove();
options.prepend(download, save);
});
.container {
border: .1rem solid red;
min-height: 5rem;
margin-bottom: 1rem;
}
#options {
border: .1rem solid blue;
min-height: 100px;
}
button {
padding: 1rem;
background-color: #ddd;
display: inline-block;
margin: .5rem;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="col-md-6 col-center">
<button class="download-btn">download</button>
<button class="save-btn">save</button>
</div>
</div>
<div id="options">
<div class="share"></div>
</div>

How to use $(this) selector to animate divs with the same class?

I have two divs, with the same class name of .pageSlide. When I click on the button with class name .moveup or .movedown, I specifically want that button's respective div to slide up or down. At the moment, if I click on the button associated with say, div A, then div B also animates. I'm guessing I need a $(this) selector in the JS somewhere. I'm not sure.
Here's a jsfiddle of working code
https://jsfiddle.net/hpe459ok/
Essentially I have this:
$('.moveup').click(function() {
if ($('.pageSlide').css('top') == '-420px') {
$('.pageSlide').animate({
top: '0'
}, 700);
} else {
$('.pageSlide').animate({
top: '0'
}, 700);
}
});
$('.movedown').click(function() {
if ($('.pageSlide').css('top') == '0') {
$('.pageSlide').animate({
top: '420'
}, 500);
} else {
$('.pageSlide').animate({
top: '420'
}, 500);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container1">
<div class="page1">
content
<button class="moveup">Next page</button>
</div>
<div class="page2 pageSlide">
content
<button class="movedown">Previous page</button>
</div>
</div>
<div class="container2">
<div class="page1">
content
<button class="moveup">Next page</button>
</div>
<div class="page2 pageSlide">
content
<button class="movedown">Previous page</button>
</div>
</div>
Try using the below code:
$('.moveup').click(function() {
$(this).closest(".page1").siblings('.pageSlide').animate({
top: '0'
}, 700);
});
$('.movedown').click(function() {
$(this).closest(".page2").animate({
top: '420'
}, 500);
});
I would use data attributes on your .moveup and .movedown buttons. By setting an attribute data-parent to be the id of the top level parent <div> it becomes trivial to modify your existing functions to handle the proper animations.
$('.moveup').click(function() {
var parent = $(this).data('parent');
if ($('#'+parent).find('.pageSlide').css('top') == '-420px') {
$('#'+parent).find('.pageSlide').animate({
top: '0'
}, 700);
} else {
$('#'+parent).find('.pageSlide').animate({
top: '0'
}, 700);
}
});
$('.movedown').click(function() {
var parent = $(this).data('parent');
if ($('#'+parent).find('.pageSlide').css('top') == '0') {
$('#'+parent).find('.pageSlide').animate({
top: '420'
}, 500);
} else {
$('#'+parent).find('.pageSlide').animate({
top: '420'
}, 500);
}
});
.pageSlide {
position: absolute;
left: 0;
right: 0;
top: 0;
height: 400px;
background: ghostwhite;
z-index: 0;
}
.page2 {
z-index: 1;
top: 420px;
}
.image-wrapper {
height: 400px;
overflow: hidden;
position: relative;
text-align: center;
border: black 1px solid;
}
.overlay-left {
background-color: white;
}
.overlay-right {
background-color: white;
}
.image-overlay-content-left {
background-color: white;
}
.image-overlay-content-right {
background-color: white
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="small-12 columns" id="nominate">
<div class="image-wrapper overlay overlay-left">
<div class="image-overlay-content image-overlay-content-left" id="formslide">
<form id="foo" method="post" name="nomForm" action="nominate-test.html#thankyou">
<div class="page1">
<label class="row">
<h2 class="headline">Your name</h2>
<input placeholder="e.g. John Smith" type="text" name="name" id="name" tabindex="1" autofocus>
<span id="nameError" class="error headline"></span>
</label>
<label class="row email">
<h2 class="headline">Your email address</h2>
<input placeholder="example#rofordaward.co.uk" type="text" name="email" id="email" tabindex="2">
<span id="emailError" class="error headline"></span>
</label>
<label class="row">
<h2 class="headline">Company name</h2>
<input placeholder="e.g. Roford" type="text" name="company" id="company" tabindex="3">
<span id="companyError" class="error headline"></span>
</label>
<div class="next">
<button type="button" class="moveup" data-parent="nominate">Next page</button><i class="icon-down-open"></i></div>
</div>
<div class="pageSlide page2">
<label class="row reason">
<h2 class="headline">Reason for nomination</h2>
<textarea id="textarea" rows="6" cols="25" maxlength="1000" name="message" id="message" placeholder="A brief evidence based summary"></textarea>
<span id="messageError" class="error headline"></span>
<div id="text-area-wrap">
<div id="textarea_feedback"></div>
</div>
</label>
<div class="row button-wrap">
<div class="column small-12">
<input class="button" name="submit" type="submit" id="contact-submit" value="Submit">
</div>
</div>
<div class="prev">
<button type="button" class="movedown" data-parent="nominate">Previous page</button><i class="icon-up-open"></i></div>
</div>
</form>
</div>
</div>
</div>
<div class="small-12 columns" id="apply">
<div class="image-wrapper overlay overlay-right">
<div class="overlay-option-headline overlay-option-headline-right">
<h5>Tell us why you're a great business</h5>
<h1 class="headline">Apply</h1>
</div>
<div class="image-overlay-content image-overlay-content-right">
<div class="page1">
<h2 class="headline">Application Form</h2>
<div class="row apply-points">
<div class="column small-12">
<h5>Please make sure you have read our Criteria page and terms and conditions in full before applying.</h5></div>
<div class="column small-12">
<h5>Ensure you have gathered evidence to support your application.</h5></div>
<div class="column small-12">
<h5>Shortlisted companies will be contacted with further instructions.</h5></div>
</div>
<div class="next">
<button type="button" class="moveup" data-parent="apply">Next page</button><i class="icon-down-open"></i></div>
</div>
<div class="page2 pageSlide">
<h2 class="headline">Contact name</h2>
<div class="row apply-points">
<div class="column small-12">
<h5>aduhwijdaduhwijdaduhwijd aduhwijd aduhwijd aduhwijd aduhwijd aduhwijd aduhwijd aduhwijd aduhwijdaduhwijdaduhwijdaduhwijdaduhwijdad aduhwijd aduhwijd aduhwijdaduhwijd aduhwijd ijdaduhwijdaduhwijdaduhwijdaduhwijdad aduhwijd aduhwijd aduhwijdaduhwijd aduhwijd</h5></div>
</div>
<div class="prev">
<button type="button" class="movedown" data-parent="apply">Previous page</button><i class="icon-up-open"></i></div>
</div>
</div>
</div>
</div>

Backbone view rendering through multiple templates

So I am creating a project on backbone and I have two drugtype categories and each drugtype shows a div with different field form when they are being clicked. I have created two different templates in my HTML. But unable to figure out how to render them on the basis of drugtype in my view. here are few code snippets:
Router.js
app = {
models: {},
views: {},
collections: {},
routers: {},
init: function() {
directory = new app.views.medicine(directoryData);
appRouter = new app.routers.Router();
Backbone.history.start();
}}
app.routers.Router = Backbone.Router.extend({
routes: {
'filter/:type': 'urlFilter'
},
urlFilter: function(type) {
directory.filterType = type;
directory.trigger('change:filterType');
}});
drug-model.js
app = app || {};
app.models.drug = Backbone.Model.extend({
defaults: {
'drugId': '',
'drugName': '',
'drugType': '',
'pharmaCompName': '',
'compound': '',
'drugInteractions': ''
},
initialize: function() {
var self = this;
}});
app.collections.medicine = Backbone.Collection.extend({
model: app.models.drug,
comparator: function(drug) {
return drug.get('drugName');
}});
drug-view
app = app || {};
app.views.drug = Backbone.View.extend({
tagName: 'li',
attributes: function() {
return {
class: 'drug ' + this.model.get('type')
};
},
events: {
'click .list-header': 'showDetails'
},
template1: _.template1($('#TABLET_TEMPLATE').html()),
template2:_.template2($('#SYRUP_TEMPLATE').html())
render: function() {
if (this.model.get('drugType') == 'Tablet') {
this.$el.html(_.template1(this.model.toJSON()));
else if (this.model.get('drugType') == 'Syrup') {
this.$el.html(_.template2(this.model.toJSON()));
return this;
},
showDetails: function(e) {
$(e.target).toggleClass('active');
$(e.target).siblings('.details').slideToggle('fast');
}});
app.views.medicine = Backbone.View.extend({
el: '#wrapper',
initialize: function(data) {
this.collection = new app.collections.medicine(data);
this.render();
this.$el.find('#filters').append(this.createFilters());
this.on('change:searchFilter', this.filterBySearch, this);
this.on('change:filterType', this.filterByType, this);
this.collection.on('reset', this.render, this);
},
events: {
'keyup #searchBox': 'searchFilter',
'click a.filter': 'setFilter'
},
render: function() {
var self = this;
$('#listing').empty();
_.each(this.collection.models, function(drug) {
self.renderdrug(drug);
}, this);
},
renderdrug: function(drug) {
var newdrug = new app.views.drug({
model: drug
});
$('#listing').append(newdrug.render().el);
},
getTypes: function() {
return _.uniq(this.collection.pluck('type'));
},
setListLength: function(l) {
$('#count').html(l);
},
createFilters: function() {
var filters = '<a class="filter" href="#all">all</a>';
_.each(this.getTypes(), function(item) {
filters += '<a class="filter" href="#' + item + '">' + item + '</a>';
});
return filters;
},
searchFilter: function(e) {
this.searchFilter = e.target.value;
this.trigger('change:searchFilter');
},
setFilter: function(e) {
e.preventDefault();
this.filterType = e.currentTarget.innerHTML;
this.trigger('change:filterType');
},
filterBySearch: function() {
this.collection.reset(directoryData, {
silent: true
});
var filterString = this.searchFilter,
filtered = _.filter(this.collection.models, function(item) {
return item.get('drugName').toLowerCase().indexOf(filterString.toLowerCase()) !== -1;
});
this.setListLength(filtered.length);
this.collection.reset(filtered);
},
filterByType: function() {
if (this.filterType === 'all') {
this.collection.reset(directoryData);
this.setListLength(this.collection.length);
appRouter.navigate('filter/all');
} else {
this.collection.reset(directoryData, {
silent: true
});
var filterType = this.filterType,
filtered = _.filter(this.collection.models, function(item) {
return item.get('type') === filterType;
});
this.setListLength(filtered.length);
this.collection.reset(filtered);
appRouter.navigate('filter/' + filterType);
}
}});
data.json
directoryData = [
{
"drugId": 44332,
"drugName": "Nimkul Para 100,500mg",
"drugType": "Tablet",
"pharmaCompName": "Finecure",
"compound": "Nimesulide + Paracetamol",
"drugInteractions": "",
"drugIndications": "",
"drugContraIndications": ""
},
{
"drugId": 44331,
"drugName": "Nimkul Para 50,125mg/5ml",
"drugType": "Syrup",
"pharmaCompName": "Finecure",
"compound": "Nimesulide + Paracetamol",
"drugInteractions": "",
"drugIndications": "",
"drugContraIndications": ""
}]
index.html
<head>
<title>App</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<link href="css/style.css" rel="stylesheet" />
</head>
<style>
ul#listing li .list-header.active .part2 {
display: none;
}
ul#listing li .list-header.active .icon {
display: block;
}
.icon {
display: none;
}
</style>
<body>
<div class="col-xs-12 container-fluid" id="wrapper">
<div class="col-xs-12 parentdiv" style=" ">
<div class="col-xs-12 part1">
<div class="col-xs-1 spacer1"></div>
<div class="col-xs-10 searchsection">
<div class="col-xs-12 header" style="">
Prescription For Hrittika Bhowmick
</div>
<div class="col-xs-12 nextsec">
<div class="col-xs-1 spacer2"></div>
<div class="col-xs-10 tooldiv">
<div class="col-xs-12 tools">
<form class="navbar-form" role="search" >
<div class="col-xs-12 input-groupaddon">
<div class="col-xs-11 searchbar">
<div class="col-xs-12 gh" style="padding-left:0px; padding-right: 0px;">
<input class="form-control" type="text" id="searchBox" placeholder="Search For Latest drugs" name="srch-term" style="
width: 100%;
height: 52px;
border-bottom-left-radius: 22px;
" />
</div>
</div>
<div class="col-xs-1 input-group-btn" style="
padding-right: 0px;
padding-left: 0px;
">
<button class="btn btn-default" type="submit" style="
height: 52.3px;
border-top-right-radius: 22px;
"><i class="glyphicon glyphicon-search"></i></button>
</div>
</div>
</form>
</div>
</div>
<div class="col-xs-1 spacer1"></div>
</div>
<div class="col-xs-12 showdiv">
<div class="col-xs-6 col-md-2 text" style="">We are showing</div>
<div class="col-xs-1 mid" style="" id="count">20</div>
<div class="col-xs-4 next" style="">results </div>
</div>
</div>
<div class="col-xs-12 section2" style="height: 464px;">
<div class="col-xs-2 spacer2"></div>
<div class="col-xs-12 col-md-8 listdiv" style="padding-left: 0px;
padding-right: 0px;
border-radius: 10px">
<ul id="listing" style="
background: linear-gradient(to right,rgb(203, 111, 21) , rgb(205, 186, 88));
overflow-x: hidden;
border-radius: 24px;
overflow-y: scroll;
height:411px;" class="list"></ul>
</div>
<div class="col-xs-2"></div>
</div>
</div>
<script type="text/template" id="TABLET_TEMPLATE">
<div class="col-xs-12 list-header">
<div class="col-xs-6 part1">
<%= drugName %>
</div>
<div class="col-xs-6 part2" style="text-align: right;">
<%= drugType %>
</div>
<div class="col-xs-12 icon" style="margin-top: -20px;
text-align: right;">
<div class="col-xs-10 glyphicon glyphicon-trash" style="text-align: right;"></div>
<div class="col-xs-2 glyphicon glyphicon-info-sign" id="add-button" data-toggle="modal" data-target="#myModal" style="text-align: left;"></div>
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Modal Header</h4>
</div>
<div class="modal-body">
<p>Some text in the modal.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="details" style="border-bottom-left radius: 24px;height: 263px;display:none;background-color: rgba(220, 151, 25, 0.45);border-bottom-right-radius: 24px;padding-left: 0px; padding-right: 0px;">
<form class="form-inline" role="form">
<div class="col-xs-12 leftform" style="
padding-left: 0px;
height: 189px;
">
<div class="col-xs-12 semidiv">
<div class="col-xs-12 form-inline" style="padding-left:0px;">
<div class="col-xs-9 col-sm-11 div1" style="padding-left: 0px;">
<label for="name" class="labelclass" style="">Tablets (per dosage)</label>
</div>
<div class="col-xs-3 col-sm-1 div2">
<input type="number" class="form-control" id="name" placeholder="1" style="
color: white;
background-color: rgba(128, 128, 128, 0.44);
border: 1px solid rgba(0, 0, 255, 0);
font-weight: bold;
width:100px;
">
</div>
</div>
</div>
</div>
</form>
</div>
</script>
<script type="text/template" id="SYRUP_TEMPLATE">
<div class="col-xs-12 list-header">
<div class="col-xs-6 part1">
<%= drugName %>
</div>
<div class="col-xs-6 part2" style="text-align: right;">
<%= drugType %>
</div>
<div class="col-xs-12 icon" style="margin-top: -20px;
text-align: right;">
<div class="col-xs-10 glyphicon glyphicon-trash" style="text-align: right;"></div>
<div class="col-xs-2 glyphicon glyphicon-info-sign" id="add-button" data-toggle="modal" data-target="#myModal" style="text-align: left;"></div>
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Modal Header</h4>
</div>
<div class="modal-body">
<p>Some text in the modal.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="details" style=" border-bottom-left-radius: 24px;
height: 263px;
display:none;
background-color: rgba(220, 151, 25, 0.45);
border-bottom-right-radius: 24px;padding-left: 0px; padding-right: 0px;">
<form class="form-inline" role="form">
<div class="col-xs-12 leftform" style="
padding-left: 0px;
height: 189px;
">
<div class="col-xs-12 semidiv">
<div class="col-xs-12 form-inline" style="padding-left:0px;">
<div class="col-xs-9 col-sm-11 div1" style="padding-left: 0px;">
<label for="name" class="labelclass" style="">Tablets (per dosage)</label>
</div>
<div class="col-xs-3 col-sm-1 div2">
<input type="number" class="form-control" id="name" placeholder="1" style="
color: white;
background-color: rgba(128, 128, 128, 0.44);
border: 1px solid rgba(0, 0, 255, 0);
font-weight: bold;
width:100px;
">
</div>
</div>
</div>
</div>
<a href="#" <div="" class="col-xs-12 footer" style="
padding-left: 0px;
height: 53px;
background-color: #33D281;
border-bottom-left-radius: 18px;
padding-right: 0px;
text-align: center;
font-size: 26px;
border-bottom-right-radius: 21px;
">
Create Prescription
</a>
</form>
</div>
</script>
<script src="js/libs/jquery-1.10.2.min.js" type="text/javascript"></script>
<script src="js/libs/underscore-min.js" type="text/javascript"></script>
<script src="js/libs/backbone-min.js" type="text/javascript"></script>
<script src="js/libs/curl.js" type="text/javascript"></script>
<script src="js/libs/lodash.js" type="text/javascript"></script>
<script src="js/routers/router.js" type="text/javascript"></script>
<script src="js/models/drug-model.js" type="text/javascript"></script>
<script src="js/views/drug-views.js" type="text/javascript"></script>
<script src="js/data.json" type="text/javascript"></script>
<script src="js/app.js" type="text/javascript"></script>
</div>
One of these two suggestions should help. These assume you recall render() when switching between types:
Switch based on drugType in render():
render: function() {
if (this.model.get('drugType') == 'Tablet') {
this.$el.html(_.template(TABLET_TEMPLATE));
else if (this.model.get('drugType') == 'Syrup') {
this.$el.html(_.template(SYRUP_TEMPLATE));
return this;
},
Use a single template that behaves according to the drugType from the model you pass into it:
<% if (drugType == 'Tablet') { %>
<!-- Render things here -->
<% } else if (drugType == 'Syrup') { %>
<!-- Render other things -->
<% } %>

Categories