MVC PartialViews and JQuery, JS being applied to all PartialViews - javascript

I have my main page which contains a number of PartialViews
Here is my Index.cshtml
<div class="container">
#{
foreach (var summary in Model.Summaries)
{
<div class="partialViewWrapper">
#Html.Partial("_Summary", summary)
</div>
}
}
</div>
Here is my Javascript:
$(document).ready(function() {
$(".toggle").on("click",
function() {
var btn = $(this);
var state = btn.html();
if (state === 'Show Down Times') {
btn.html('Hide Down Times');
$('.foo').show();
} else {
btn.html('Show Down Times');
$('.foo').hide();
}
My partial View (relevant bits):
<div class="row">
<div class="col-md-12">
<button class="toggle btn btn-default" >Show Down Times</button>
</div>
<div class="foo col-md-12" style="display: none">
<table class="table table-striped table-bordered table-responsive">
...
</table>
</div>
</div>
My issue is, when I click the button on the first partial view, it changes its text to Hide from Show, but both Partial Views show their respective table.
So, the JS to change the button text is being applied to the correct partial view buttons but the showing / hiding the table is being applied to all partial views.
I think I need to do something with $(this) rather than just referencing it by class but I have no idea how to achieve this with JQuery.
Thanks,

Use relative selectors to get the .closest() ancestor containing both elements and then .find() the other element inside that ancestor.
var btn = $(this);
var foo = btn.closest('.row').find('.foo');
if (state === 'Show Down Times') {
btn.html('Hide Down Times');
foo.show();
} else {
btn.html('Show Down Times');
foo.hide();
}

The reason is $('.foo'). Since you are not pointing out the table in a specific partial. The selector selects all classes with the class foo.
The solution to this problem is to
Either
Select the sibling of the parent using the parent and next functions with btn and then use hide or show.
Or
Add an additional attribute to the button say data-target and add the name of the class or id. Access it using btn.data('target') and then use hide or show.

Related

hide/show div using id property with index in javascript

Here Iam facing issue with toggling the div containers. if I click on video button, other divs should close, only if open. because of toggling, if it close already, its opening on click of particular btn.can you help me?
html:
<div class="row" *ngFor="let doctor of doctordata;let i=index">
<button appointmentToggle(doctor,'video',i)">video</button>
<button appointmentToggle(doctor,'clinic',i)">In-clinic</button>
<div class="row" id="clinicShow{{i}}">
<button (click)="clinicdetails(i)">clinicName</button>
</div>
<div class="col-lg-12 col-sm-12" id="videoappointmentShow{{i}}">
videocalendertimeslot
<div>
<div class="col-lg-12 col-sm-12" id="inclinicappointmentShow{{i}}">
Incliniccalendertimeslot
<div>
</div>
component.ts
index: any;
appointmentToggle(doctor,type,index){
if(type == 'video'){
$("#appointmentShow"+index).toggle();
//here i need to check condition whether its already opened or not, if open, then it should toggle.
$("#clinicShow"+index).toggle();
}
if(type == 'clinic'){
if(this.index==undefined){
$("#clinicShow"+index).toggle();
$("#appointmentShow"+index).toggle();
this.index=index;
}else if(this.index == index){
$("#clinicShow"+index).toggle();
$("#appointmentShow"+index).toggle();
index = undefined;
}else{
$("#clinicShow"+this.index).toggle();
$("#clinicShow"+index).toggle();
$("#appointmentShow"+index).toggle();
this.index= index;
}
}
clinicdetails(index){
$("#clinicShow"+index).toggle();
$("#appointmentShow"+index).toggle();
}
There are going to be a lot of ways to do this. I'd probably create an array of boolean values to show/hide stuff.
<div class="row" *ngFor="let doctor of doctordata;let i=index">
<button appointmentToggle(doctor,'video',i)">video</button>
<button appointmentToggle(doctor,'clinic',i)">In-clinic</button>
<div class="row" *ngIf="hideVideo[i]">
<button (click)="clinicdetails(i)">clinicName</button>
</div>
<div class="col-lg-12 col-sm-12" *ngIf="hideVideo[i]">
videocalendertimeslot
<div>
<div class="col-lg-12 col-sm-12" *ngIf="hideClinic[i]">
Incliniccalendertimeslot
<div>
</div>
Then you're Component file can have a boolean array:
hideVideo: boolean[] = [];
hideClinic: boolean[] = []
Whenever doctordata is initialized also initialize the array:
doctordata.forEach(() => { this.hideVideo.push(false);this.hideClinic.push(false); });
You're appointment toggle can be something like this:
appointmentToggle(doctor,type,index){
if(type == 'video'){
this.hideVideo[index] = !this.hideVideo[index];
this.hideClinic[index] = !this.hideClinic[index];
}
}
clinicdetails(index){
this.hideVideo[index] = !this.hideVideo[index];
this.hideClinic[index] = !this.hideClinic[index];
}
This is incredibly rough and untested.
Edit: Here is working code. This version is less rough and untested:
https://stackblitz.com/edit/angular-ivy-xtz8xv?file=src%2Fapp%2Fapp.component.ts
I used the same concept that I used above. However, I think the code would be more ideal if you could introspect your doctordata objects to determine if it should be displayed or not instead of keeping a second array. However, there is also a good argument about not letting display specific logic clutter up your data model objects.
It looks like your logic would be simpler if you use show() and hide() instead.
Especially because hiding a hidden element is okay and has no effect...
Look at: jQuery Effects - Hide and Show
If the first thing you do is hiding the old index (if any) you only need to show the new...
In the jquery when showing a div and hiding it. I think you don't need an if ... Else condition
Try this code:
$(".btn).click(function(){
$("div").toggle();
});
Once that .btn is click div will show and if u want to hide it just click the button again
I also try to combine javascript and jquery before but it didn't work out well.
<script src = "https://code.jquery.com/jquery-3.6.0.min.js"></script>
Just add this to your header and you are good to go and it's much easy? Hope this works for you

JS toggle for multiple div elements

What should I do if I have multiple elements in HTML foreach and I need to make them all a toggle slider what opens div block with specific information about the element and I need to add close button too if a user wants to close the div. Sorry, I don't have any code to show because I did not find anything that suits my needs. The main idea is to have a product page with products that are displayed on a page using foreach... Then when you click on a product toggle div block is opened with information about a product. What should I search and what to use, I can't find anything because I am limited with my knowledge. Sorry for terrible English.
You can easily control the visibility of an element either within the div you're clicking or after it using a class you toggle. Here's an example controlling the div after one of the divs that controls the toggle:
document.getElementById("container").addEventListener("click", function(e) {
var toggleDiv = e.target.closest(".toggle");
if (toggleDiv && this.contains(toggleDiv)) {
toggleDiv.classList.toggle("closed");
}
});
.closed + .detail {
display: none;
}
<div id="container">
<div class="toggle closed">Product A</div>
<div class="detail">Details about Product A</div>
<div class="toggle closed">Product B</div>
<div class="detail">Details about Product B</div>
<div class="toggle closed">Product C</div>
<div class="detail">Details about Product C</div>
</div>
The key bits there are:
Hiding the details via CSS with the adjacent sibling combinator (+)
Toggling the class on the toggling div
I used event delegation to hook up the handler, but you could instead hook it up to each individual div if you preferred. Note that the Element#closest method I used is relatively new, you may need a polyfill or a loop on parentNode instead.
From what i have understood.
You need to toggle div elements using button tag and the button u click will show that particular div element.
<div id="container1" class={container1 ? "show" : "hide"}>
container1
</div>
<div id="container2"class={container2 ? "show" : "hide"}>
container2
</div>
<div id="container3"class={container3 ? "show" : "hide"}>
container3
</div>
and three button tags to call toggle function to show the three div element.
<div class="container">
<button name="container1" onclick=(toggle())>Container1</button>
<button name="container2" onclick=(toggle())>Container2</button>
<button name="container3" onclick=(toggle())>Container3</button>
</div>
toggle function
function toggle(e) {
if(e.target.name === 'container1'){
container1 = true;
}
else if(e.target.name === 'container2'){
container2 = true;
}
else if(e.target.name === 'container3'){
container3 = true;
}
}
css part
.show{
display: block;
}
.hide{
display: none;
}

hide all but one element of certain class in Jquery

I am trying to create an effect whereby clicking on a title toggles the corresponding content div. Clicking on another title while some content is showing should hide that content div and show the content div corresponding to the title just clicked.
However the code is not doing anything, as you can see on the following jquery: http://jsfiddle.net/dPsrL/
Any ideas?
HTML:
<div class="row title">
<div class="title" industry_id="education">Ed</div>
<div class="title" industry_id="tech">Tech</div>
<div class="title" industry_id="finance">Fin</div>
</div>
<br>
<br>
<div class="row content">
<div class="content" id="education">Education is great</div>
<div class="content" id="tech">Technology is awesome</div>
<div class="content" id="finance">Finance is super</div>
</div>
JAVASCRIPT:
$(document).ready(function () {
$('.content').hide();
});
('.title').on('click', function () {
var clicked = $(this).attr('industry_id');
alert(clicked);
$("#"+clicked).toggle(400);
$("#"+clicked).siblings().hide();
});
Instead of toggling the clicked element first and then hiding the others, why don't you just hide everything first and then show the clicked one? Saves you a check, and all you have to do is switch the order
$('.title').on('click', function () {
var clicked = $(this).attr('industry_id');
alert(clicked);
$('.content').hide();
$('#' + clicked).show(400);
});
Your attribute doesn't have the id selector in it. You need to do a string concatenation :
$('.title').on('click', function () {
var clicked = $(this).attr('industry_id');
alert(clicked);
$('#' + clicked).toggle(400);
$('#' + clicked).siblings().hide();
//The two last lines could be :
//$('#' + clicked).toggle(400).siblings().hide();
});
Also you have to remove the class content and title on the row since it trigger the click event and the hide part.
Here's a working fiddle : http://jsfiddle.net/dPsrL/3/
Typo on ('.title'). Should be $('.title'). Also, you should probably not give the container divs the same class as the child divs and then use that same class in your CSS and jQuery. It just makes selection more difficult.
jsFiddle example

jQuery toggle 3 Div

I wanna toggle 3 div.
In the start situation I have the first div that is not trigger able for the clic because its ID.
When I click the second or third div (triggered), the DIV clicked have to become unclickable and the others 2 clickable.
I attach my live example:
http://jsfiddle.net/YV3V5/
HTML:
<div id = "not-selectable" class = "btn1">Div 1</div>
<div id = "selectable" class = "btn2">Div 2</div>
<div id = "selectable" class = "btn3">Div 3</div>
JAVASCRIPT:
$( "#selectable" ).click(function(e) {
var className = $(this).attr('class');
alert(className);
if (className == "btn1") {
$("btn1").attr("selectable","not-selectable");
$("btn2").attr("not-selectable","selectable");
$("btn3").attr("not-selectable","selectable");
} else if (className == "btn2") {
$("btn2").attr("selectable","not-selectable");
$("btn1").attr("not-selectable","selectable");
$("btn3").attr("not-selectable","selectable");
} else if (className == "btn3") {
$("btn3").attr("selectable","not-selectable");
$("btn1").attr("not-selectable","selectable");
$("btn2").attr("not-selectable","selectable");
}
});
In this situation when I click the second DIV, it should became unclickable....but nothing happens.
Thanks for you're help!
You have several errors in your code. The most important being that IDs should be unique. Secondly you are trying to assign values to attributes "selectable" and "not-selectable". These attributes do not exist.
If you lay out your markup correctly, you could do this pretty simple. I would suggest something like this:
HTML
<div class="buttons">
<div class="button">Div 1</div>
<div class="button selectable">Div 2</div>
<div class="button selectable">Div 3</div>
</div>
jQuery
$( ".buttons" ).on("click",".selectable",function(e) {
$('.button').addClass('selectable');
$(this).removeClass('selectable');
});
Can be tested here
(I've added a parent element to simplify event delegation in jQuery.)
there is no attribute called selectable for html tags.
when you write $("btn3").attr("selectable","not-selectable"); it means set the selectable attribute of btn3 to value 'not-selectable'.
also as btn3 is a class you should have written $('.btn3') instead of $('btn3')
WORKING DEMO http://jsfiddle.net/YV3V5/23/
There was a lot wrong with your code :
1) using duplicate id's : Id's must be unique , one per page. Classes do not have to be unique. So I changed around your id's and classes.
2) you should change classes with addClass/removeClass/or toggleClass
3) you shouldn't use a class your removing as the trigger of the click function, so I gave them all a same class of btn.
html :
<div id="btn1" class="not-selectable btn">Div 1</div>
<div id="btn2" class="selectable btn">Div 2</div>
<div id="btn3" class="selectable btn">Div 3</div>
css I added background of blue for selectable and red for not-selectable so easier to visualize what's happening:
.selectable {
background: blue;
}
.not-selectable {
background: red;
}
jquery :
$(document).ready(function () {
$(".btn").click(function (e) {
var id = $(this).attr('id');
if (id == "btn1") {
$("#btn1").removeClass("selectable").addClass("not-selectable");
$("#btn2").addClass("selectable").removeClass("not-selectable");
$("#btn3").addClass("selectable").removeClass("not-selectable");
} else if (id == "btn2") {
$("#btn2").removeClass("selectable").addClass("not-selectable");
$("#btn1").addClass("selectable").removeClass("not-selectable");
$("#btn3").addClass("selectable").removeClass("not-selectable");
} else if (id == "btn3") {
$("#btn3").removeClass("selectable").addClass("not-selectable");
$("#btn1").addClass("selectable").removeClass("not-selectable");
$("#btn2").addClass("selectable").removeClass("not-selectable");
}
});
});
.attr() sets the attribute to the tags. So like you would get <div non-selectable='selectable'> for that code. Here is the documentation. I would use .removeClass() and .addClass() though there might be a more efficient way.

How to append the root element of partial view

In my main view of ASP.NET MVC project, I am rendering a partial view once and then on click of add button I want to append the partial view to the form. But when I click add, only the child element ... is added to the MainView. How can I append the root element of my partial view (_roll.cshtml)?
MainView.cshtml
<div id="rolls">
#Html.Partial("_roll")
</div>
<br />
<div class="row">
<button id="addRoll" class="btn"></button>
</div>
_roll.cshtml
<div class="roll">
<div class="row">
...
</div>
</div>
.js
$(function () {
$('#addRoll').click(function (e) {
e.preventDefault();
$('#rolls').append($('.roll').html());
});
});
Try to just use the element itself and not its innerHTML (.html()):
$(function () {
var $rolls = $('#rolls'), $role = $('.roll:first');
$('#addRoll').click(function (e) {
e.preventDefault();
//$rolls.append($('.roll')); // wont work since you want to append the same element to the same parent
$rolls.append($role.clone());
});
});
Or you can simply use the OuterHTML of the element if you want.

Categories

Resources