I inherited an application and trying to figure out way scripts on the tabs are loading more than once.
It is an basic bootstrap tab feature that loads partial views.
<ul class="nav nav-tabs" id="myTab">
<li class="active"><a data-target="#home" data-toggle="tab">Home</a></li>
<li><a data-target="#reputation" data-toggle="tab">Reputation</a></li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="home">
#Html.Action("SocialConfig", "Admin", new {area = "Admin", accountID = ViewBag.AccountID})
</div>
<div class="tab-pane" id="reputation">
#Html.Action("ReputationConfig", "Admin", new { area = "Admin", accountID = ViewBag.AccountID })
</div>
</div>
There is an JavaScript file included on each partial view. Each script will get loaded as many times there are #Html.Action
So for instance I have 2 #Html.Action so the script on the SocialConfig view will load twice and the script on the ReputationConfig will also load twice.
How can i stop this silly behavior.
If you are using jQuery to add some event handlers then check if the selectors are filtering elements of both partials views. If so you should change your selector in way that it is contextualized to your partial view.
Ex:
Partial view 1
<div>
<button class="button" type="button">Click me</button>
</div>
<script>
$(".button").click(function () { alert("click on button") });
</script>
Partial view 2
<div>
<a class="button">Click me</a>
</div>
<script>
$(".button").click(function () { alert("click on link") });
</script>
A example of contextualized events:
Partial view 1
<div id="my-partial-view-1-container">
<button class="button" type="button">Click me</button>
</div>
<script>
$("#my-partial-view-1-container").find(".button").click(function () { alert("click on button") });
</script>
Partial view 2
<div id="my-partial-view-2-container">
<a class="button">Click me</a>
</div>
<script>
$("#my-partial-view-2-container").find(".button").click(function () { alert("click on link") });
</script>
When working with partialview try to avoid loading script, add it instead in the main view. Why not just add it in the current view?
Related
I am using JQUERY 3.4.1 in .NET MVC project. When I took partial page then on click is not working. Here I have put my tried code's. when I am using $(document).on('click') then it is creating another issue that it is opening tab data also. So I avoid it.
$(document).on('click', '.dummy_current_card_header_dropDownBtn', function () {
$(this).next('.dummy_current_card_header_dropDownBtn_item').toggle();
});
// project_lesting_current_card_header_dropDownBtn
$('.dummy_current_card_header_dropDownBtn').on('click', function () {
$(this).next('.dummy_current_card_header_dropDownBtn_item').toggle();
});
$('.dummy_current_card_header_dropDownBtn').click(function () {
$(this).next('.dummy_current_card_header_dropDownBtn_item').toggle();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="current_card_header_btn">
<span class="current_card_header_dropDownBtn dummy_current_card_header_dropDownBtn" type="button" role="button"><img src="~/images/project/icon/action_icon.png" style="width: 14px;"></span>
<div class="current_card_header_dropDownBtn_item dummy_current_card_header_dropDownBtn_item">
<ul>
<li>Review</li>
<li>Duplicate</li>
<li>Archive</li>
<li>Delete</li>
</ul>
</div>
</div>
It is solved. I used onclick in HTML.
here is the code.
function CurrentTabDropDown(status) {
$(status).next('.dummy_current_card_header_dropDownBtn_item').toggle();
}
I am really new to javascript and jquery, but I am trying to create a page that will allow the user to click on a Country name and information for that country will load in a div from a separate html file.
Else where I found this code which works nicely for this, using the .click(function) on the <a> tag:
var $j = jQuery.noConflict();
$j(document).ready(function(){
$j("a").click(function(){
$j.ajax({
url: $j(this).attr("href"),
success: function(response) {
$j("#partnerContent").html(response);
}
});
return false;
});
});
Here is the basic html:
<div id="contentcontain">
<div class="partnercol1">
<div class="container">
<div id="menu" class="btn-group">
<button type="button" class="btn btn-default dropdown-toggle" data- toggle="dropdown">International Sales <span class="caret"></span></button>
<ul class="dropdown-menu scrollable-menu" role="menu">
<li>Belgium</li>
<li>Brunei</li>
<li>Bulgaria</li>
</ul>
</div>
</div>
</div>
<div class="partnercol2">
<div id="partnerContent"></div>
</div>
However, now every <a> tag on the page (including top and bottom menus) loads their href into the div when clicked. How can I target just the div containing the state menu to work with this function?
Make the selector for the elements you're attaching the events to more restrictive:
// this selects all the anchors below the items with ID menu
$j("#menu a").click(function () {
...
});
in your html, put:
<ul class="dropdown-menu scrollable-menu" role="menu">
<li><a class="menu-item" href="partners/belgium.html">Belgium</a></li>
<li><a class="menu-item" href="partners/brunei.html">Brunei</a></li>
<li><a class="menu-item" href="partners/bulgaria.html">Bulgaria</a></li>
</ul>
And in your javascript
var $j = jQuery.noConflict();
$j(document).ready(function(){
$j(".menu-item").click(function(){
$j.ajax({
url: $j(this).attr("href"),
success: function(response) {
$j("#partnerContent").html(response);
}
});
return false;
});
});
You're loading an entire html page, which means you're loading
<html>...</html>
and then stuffing that in its entirety into your page, that means you'll eventually have
<html>
....
<html>...</html>
...
</html>
which is NOT valid. If you're trying to replace the contents of a single <div> in your page, then either you fetch that entire page into a var and slice out the chunk you want, or have jquery fetch/insert ONLY the part you want, e.g.
$('#div_to_replace').load('source_of_new.html #id_of_element_to_use_for_replacement');
Note the second #... argument in the .load() call. That tells jquery to ignore everything in the page EXCEPT for the specified element/ID. Only that ID's contents will be stuffed into #div_to_replace.
Here I need to click on a thumbnail, so that it will show the details on other page, it should show the details of that particular thumb only. I used xml file here to fetch the data and display thumbnail. I am unable to pass the values to other page and open it at the same time onclick event. pls help
<div class="container-page">
<div class="row" id="portfolio">
<div class="col-md-2">
<nav>
<ul class="nav nav-pills nav-stacked" id="test">
<li role="presentation" class="active">Services</li>
<li role="presentation">Desktop</li>
<li role="presentation">Web</li>
<li role="presentation">Mobile</li>
<li role="presentation">Design</li>
</ul>
</nav>
</div>
<div class="col-md-10">
<div class="row" id="thumb">
</div>
</div>
</div>
</div>
<!-- js -->
$.ajax({
type:"GET",
url:"portfolio.xml",
dataType:"xml",
success:function(xml)
{
$(xml).find('thumbnail').each(function()
{
var $thumbnail=$(this);
var type=$thumbnail.find('type').text();
var descr=$thumbnail.find('description').text();
var title=$thumbnail.attr('title');
var imageurl=$thumbnail.attr('imageurl');
var thum='<div class="col-xs-6 col-md-3"> </div>';
thum=$(thum).appendTo("#thumb");
thum = $('').appendTo(thum);
var thumName = $('<div class="thumTitle"></div>').appendTo(thum);
$('<h2>'+title+'</h2>').appendTo(thumName);
$('<p>'+type+'</p>').appendTo(thumName)
thum = $('<img src="'+imageurl+'" alt="image" class="thumbImgSize imgSlide">').appendTo(thum);
$(".forHove").mouseup(function()
{
//here is the redirection code, and want to pass $thumbnail to testxml.html page
window.location="http://www.bookmane.in/skillworks/testxml.html";
$(thum).appendTo(".s");
});
});
}
});
Well, one of the alternative is using Web Storage API.
Just store img html and use it.
// use 'click' instead of 'mouseup'
$(".forHove").click(function()
{
// store image html to sessionStorage
window.sessionStorage.image_data = $thumbnail.clone().wrapAll("<div>").parent().html();
window.location="http://www.bookmane.in/skillworks/testxml.html";
$(thum).appendTo(".s");
});
// in http://www.bookmane.in/skillworks/testxml.html
// You have data sotred and insert it somewhere
$(document.body).append(window.sessionStorage.image_data);
You can achieve this thing using the following steps:
Add a form tag like
<form action="YOUR_PATH" method="GET">
<a class="thubnailClick" href="#" >
<html_of_your_thumbnail>
<input type="text" name="NAME_OF_PARAMETER" />
</a>
</form>
Now override the click event of <a> tag with
$(document).ready(function() {
$(".thubnailClick").on('click', function(event) {
// to override the default behavior of <a> tag.
preventDefault();
// Find the form element using closest() of jQuery.
// Call submit event of that form using $(form_element).submit();
});
})
Now on the other page you can get parameter from URL using location.search or follow:
Getting Query params using JavaScript
Now use these Params according to your needs.
I'm creating a prototype application. I wanted to template my header and footer over html files. I'm loading these in using jQuery load.
In my index file I have this in the first part of my body:
<!--COMMON HEADER ------------- -->
<header id="common-include-header" class="blade child ns">
</header>
I'm including via a document called includes.js which is listed before header.js in my head/script tags. Here is the includes.js like so:
$(document).ready(function () {
$("#common-include-header").load("includes/header.html");
$("#common-include-footer").load("includes/footer.html");
});
Here is my header.html:
<div class="blade-content flexr xc sb">
<img src="img/logo100.svg"></img>
<div class="child g">
<form class="search-form flexr jc">
<input class="location" value="Auckland" />
<input class="context" placeholder="Find something" />
<button class="child ns"><i class="fa fa-search"></i></button>
</form>
</div>
<button class="search-toggle"><i class="fa fa-search"></i></button>
<div class="child ns">
<button class="sign-in-button pill outline pink">Sign in</button>
<button class="user-signed-in flexr xc hide">
<p>test#gmail.com</p>
<img src="img/av.png"></img>
<i class="fa fa-chevron-down"></i>
</button>
</div>
<nav class="signed-in-nav flexc">
<button type="button" class="dropdown-menu child ns">Favourites</button>
<button type="button" class="dropdown-menu child ns">Reviews</button>
<button type="button" class="dropdown-menu child ns">Businesses</button>
<button type="button" class="dropdown-menu sign-out child ns">Sign out</button>
</nav>
</div>
And my header.js
$(document).ready(function () {
//hide/show mobile search
$(".search-toggle").on("click", function () {
if ($(".toggle-search").hasClass('open')) {
$(".toggle-search").removeClass("open");
} else {
$(".toggle-search").addClass("open");
};
});
//hide/show sign in
$(".sign-in-button").on("click", function () {
$(".sign-in-button").addClass("hide");
$(".user-signed-in").removeClass("hide");
});
//hide/show user menu
$(".user-signed-in").on("click", function () {
if ($(".signed-in-nav").hasClass("open")) {
$(".signed-in-nav").removeClass("open");
$(".user-signed-in").removeClass("open");
} else {
$(".signed-in-nav").addClass("open");
$(".user-signed-in").addClass("open");
};
});
//sign out
$("button.sign-out").on("click", function () {
$(".signed-in-nav").removeClass("open");
$(".user-signed-in").removeClass("open");
$(".user-signed-in").addClass("hide");
$(".sign-in-button").removeClass("hide");
});
});
My problem is that the event handlers aren't binding to .sign-in-button. I would have thought since I used jQuery .on this would work. I can't figure it out. Where am I going wrong?
jQuery's load has a callback function...
Try this:
$("#common-include-header").load("includes/header.html", function(){
// bind to header code here
});
$("#common-include-footer").load("includes/footer.html", function(){
// bind to any footer code here
});
You can also use .toggleClass() instead of having separate lines to add or remove class names.
//hide/show mobile search
$(".search-toggle").on("click", function () {
var isOpen = $(".toggle-search").hasClass('open');
$(".toggle-search").toggleClass("open", !isOpen);
});
//hide/show sign in
$(".sign-in-button").on("click", function () {
$(".sign-in-button").addClass("hide");
$(".user-signed-in").removeClass("hide");
});
//hide/show user menu
$(".user-signed-in").on("click", function () {
var isOpen = $(".signed-in-nav").hasClass("open");
$(".signed-in-nav").toggleClass("open", !isOpen);
$(".user-signed-in").toggleClass("open", !isOpen);
});
//sign out
$("button.sign-out").on("click", function () {
$(".signed-in-nav, .user-signed-in").removeClass("open");
$(".user-signed-in").addClass("hide");
$(".sign-in-button").removeClass("hide");
});
As you are loading your html on DOM ready, all your javascript files are already loaded and your header.html is being loaded after that. So your header.js can not locate the element using $(".search-toggle").on("click", function () { . Here you have to use $(document).on("click",".search-toggle", function () {
I'm using jScroll (jscroll.com) in my Laravel 5.1 application for infinite scrolling. I'm further using some jquery which I want to be triggered on clicking the 'Like' button for each post. Jquery is working perfectly on the first page's posts i.e localhost/myproject/index but it is not triggered for the posts which are appended by jScroll from the next page(s) i.e localhost/myproject/index?page=2 etc.
Here is my code for displaying the posts:
#foreach($posts as $post)
<div class="panel panel-default">
<div class="panel-body post">
<h3>{{ $post->title }}</h3>
<hr>
<p>{{ $post->discripion }}</p>
</div>
<div class="panel-footer">
<div class="btn-group">
<button type="button" data-id="{{$post->id}}" class="btn btn-default like-btn">Like</button>
</div>
</div>
</div>
#endforeach
and the simple jquery that I want to be triggered for each posts is:
<script type="text/javascript">
$('button.like-btn').on('click',function(){
var post_id = $(this).data('id');
alert('Liked post with id = ' + post_id);
});
</script>
It's because jquery doesn't bind to those elements (they are not in the DOM initially). Bind it to document instead, like this:
$(document).on("click", 'button.like-btn', function(event) {
alert("new link clicked!");
});
Look here for a little more