I have a form with some tabs. This form creates a new user, or edits an existing user. If the user is new, I want to have in the main tab some fields that in a edit form is in other tabs, but keeping the fields in the original tab. I have done this by monitoring the selected tab, and adding or removing fields. But if a form field has associated some events, when I remove it and add to other tab, the events are lost. For example:
Fiddle: http://jsfiddle.net/p3tkL/
<div id="tabs" class="tabbable">
<ul class="nav nav-tabs">
<li> Personal</li>
<li class="active"> Mail</li>
</ul>
</div>
<div class="tab-content">
<div class="tab-pane" id="tab_personal">
<p>Personal info tab</p>
<div id="personal_mail_div">
</div>
</div>
<div class="tab-pane active" id="tab_mail">
<p>Mail Tab</p>
<div id="mail_container">
<div id="mail_address_div">
Mail address: <input id="mail_address" type="text" />
</div>
</div>
</div>
</div>
<script type='text/javascript'>//<![CDATA[
$(window).load(function(){
$(document).ready(function() {
$("#mail_address").keyup( function() {
console.log("text changed, new value: " + $(this).val() );
});
$("#tabs").on('shown', function (e) {
var previousDiv = $(e.relatedTarget).attr('href');
var newDiv = $(e.target).attr('href');
// OUs / Servicios
if ( ( newDiv == "#tab_personal" ) || ( newDiv == "#tab_mail" ) ) {
var divaddremove = $("#mail_address_div");
if ( newDiv == "#tab_personal" ) {
$("#mail_container").empty();
$("#mail_container").hide();
$("#personal_mail_div").append(divaddremove);
$("#personal_mail_div").show();
}
else if ( newDiv == "#tab_mail" ) {
$("#personal_mail_div").empty();
$("#personal_mail_div").hide();
$("#mail_container").append(divaddremove);
$("#mail_container").show();
}
}
});
});
});//]]>
</script>
So, when the page loads initially, the text changed event in the mail fields has its event fired, but when i change the tab, the field is removed from the mail tab and added to the personal tab correctly, but the events are no more fired. How can I solve this?
Regards and thanks in advance.
Update:
Well, the initial solutions using delegates don't work for me, as the example I did is not exactly what I am doing. I am using select2 to make select inputs search by ajax. When I remove and then add the selects, it stops working. Here is another fiddle showing the effect.
http://jsfiddle.net/p3tkL/2/
You can use delegated events:
$('.tab-content').on('keyup', '#mail_address', function(){
console.log("text changed, new value: " + this.value);
});
Or have a look at detatch
Use jQuery event delegation
Demo -- > http://jsfiddle.net/p3tkL/1/
$('.tab-content').on('keyup', '#mail_address', function(){
console.log("text changed, new value: " + this.value);
});
change your keyup binding code to this
$(".tab-content").on("keyup", "#mail_address", function() {
console.log("text changed, new value: " + $(this).val() );
});
Related
I found this fiddle from other questions, and its good to use. The problem is the added class(.active) in button remove when refresh. How can I make it remain even I reload it.
FIDDLE
HTML
<div class="flr-wrap">
<ul>
<li><a class="button active" data-rel="#content-a" href="#">a button</a></li>
<li><a class="button" data-rel="#content-b" href="#">b button</a></li>
</ul>
<div class="flr-inner">
<div class="container" id="content-a">
AAA
</div>
<div class="container" id="content-b">
BBB
</div>
</div>
JS
// set content on click
$('.button').click(function(e) {
e.preventDefault();
setContent($(this));
});
// set content on load
$('.button.active').length && setContent($('.button.active'));
function setContent($el) {
$('.button').removeClass('active');
$('.container').hide();
$el.addClass('active');
$($el.data('rel')).show();
}
Thanks in advance..
You need to store the active state either in the server(if there is a way to do this) or in the client side(you can use web storage)
To store it in client side
// set content on click
$('.button').click(function(e) {
e.preventDefault();
setContent($(this));
localStorage.setItem('active-container', $(this).data('rel'));
});
// set content on load
localStorage.getItem('active-container') && setContent($('.button[data-rel="' + localStorage.getItem('active-container') + '"]'));
function setContent($el) {
$('.button').removeClass('active');
$('.container').hide();
$el.addClass('active');
$($el.data('rel')).show();
}
Added more details to Arun's answer.
Store menu item in local storage after click.
$('.menu-item').click(function (e) {
localStorage.setItem('active-menu-item', $(this).attr('href'));
});
Set active menu item style by adding class 'active' and click the item to go to the active page. It is inside $(document).ready() so that it runs after refresh.
$(document).ready(function () {
const activeMenuItem = $('.menu-item[href="' + localStorage.getItem('active-menu-item') + '"]').first();
activeMenuItem && setActiveLink(activeMenuItem);
});
function setActiveLink($el) {
$el.addClass('active');
$el.click();
}
I have problem in hide and show the div element.
In this scenario when user click on the year the respect content is shown.
Problem I want to inactive hyperlinking on respective year when it is opened.
The script and html is below;
for this I have tried .preventDefault(). but not got any success:
<script type="text/javascript" >
$(document).ready(function() {
$("div.new:gt(0)").hide();// to hide all div except for the first one
$("div[name=arrow]:eq(0)").hide();
// $("div.nhide:gt(0)").hide();
// $("a[name=new]").hide();
$("a[name=new]").hide();
$('#content a').click(function(selected) {
var getID = $(this).attr("id");
var value= $(this).html();
if( value == '<< Hide')
{
// $("#" + getID + "arrow").hide();
$("a[name=new]").hide();
$("#" + getID + "_info" ).slideUp('slow');
$("div[name=arrow]").show();
$("div.new").hide();
$(this).hide();
// var getOldId=getID;
// $("#" + getID ).html('<< Hide').hide();
}
if($("a[name=show]"))
{
// $("div.new:eq(0)").slideUp()
$("div.new").hide();
$("div[name=arrow]").show();
$("a[name=new]").hide();
$("#news" + getID + "arrow").hide();
$("#news" + getID + "_info" ).slideDown();
$("#news" + getID ).html('<< Hide').slideDown();
}
});
});
</script>
The html code is below:
<div id="content">
<div class="news_year">
<a href="#" name="show" id="2012">
<div style="float:left;" name="year" id="news2012year">**2012** </div>
<div style="float:left;" name="arrow" id="news2012arrow">>></div>
</a>
</div>
<div class="new" id="news2012_info">
<div class="news">
<div class="news_left">News for 2012</div>
</div>
<div class="nhide" ><< Hide </div>
</div>
<div id="content">
<div class="news_year">
<a href="#" name="show" id="2011">
<div style="float:left;" name="year" id="news2012year">2012 </div>
<div style="float:left;" name="arrow" id="news2012arrow">>></div>
</a>
</div>
<div class="new" id="news2011_info">
<div class="news">
<div class="news_left">News for 2011</div>
</div>
<div class="nhide" ><< Hide </div>
</div>
Fiddle
if i am understanding your problem,
event.preventDefault(); not works with all browser so if you are using other browser like IE
then use event.returnValue = false; instead of that.so you can detect your browser using javascript as
var appname = window.navigator.appName;
This is what I'm currently using in my projects to "disable" an anchor tag
Disabling the anchor:
Remove href attribute
Change the opacity for added effect
<script>
$(document).ready(function(){
$("a").click(function () {
$(this).fadeTo("fast", .5).removeAttr("href");
});
});
</script>
Enabling the anchor:
$(document).ready(function(){
$("a").click(function () {
$(this).fadeIn("fast").attr("href", "http://whatever.com/wherever.html");
});
});
Original code can be found here
Add a class called 'shown' to your wrapper element when expanding your element and remove it when hiding it. Use .hasClass('shown') to ensure the inappropriate conditional is never executed.
Surround the code inside of the click function with an if statement checking to see if a variable is true or false. If it is false, it won't run the code, meaning the link is effectively inactive. Try this..
var isActive = true;
if (isActive) {
// Your code here
}
// The place where you want to de-activate the link
isActive = false;
You could also consider changing the link colour to a grey to signify that it is inactive.
Edit
Just realised that you want to have multiple links being disabled.. the code above will disable all of them. Try the code below (put the if around the code in the click function)
if(!$(this).hasClass("disabled")) {
// Your code here
}
// The place where you want to de-activate the link
$("#linkid").addClass("disabled");
// To re-enable a link
$("#linkid").removeClass("disabled");
// You can even toggle the link from disabled and non-disabled!
$("#linkid").toggleClass("disabled");
Then in your CSS you could have a declaration like this:
.disabled:link {
color:#999;
}
I have 2 images (.field-img) , wrapped in a container (.group-container),
each of the images are in a unique field id, so my tpl is broken down into
<div class=group-container>
<div id=field1>
<div class=field-img>
</div></div>
<div id=field2>
<div class=field-img>
</div></div>
</div>
my js is
$(".group-container .field-img").click(function() {
alert(".group-container .field-img");
what I would like is to detect automatically if the image belongs to field1 or field2.
So I could alert (".group-container .field1/2 .field-img");
How would I do this?
Thanks for any help
$(".group-container .field-img").click(function() {
var field=$(this).parent().attr('id');
});
An alternative to Izzey's solution is to use .closest with an attribute starts with selector (or classname because it would be more appropriate for those divs to have a common class)
$(".group-container .field-img").click(function() {
var field = $(this).closest("[id^=field]")[0].id;
});
or, with a common classname,
html
<div class=group-container>
<div class="field" id=field1>
<div class=field-img>
</div></div>
<div class="field" id=field2>
<div class=field-img>
</div></div>
</div>
js
$(".group-container .field-img").click(function() {
var field = $(this).closest(".field")[0].id;
});
$(".group-container .field-img").click(function() {
var field = this.parentNode.id;
alert (".group-container ." + field + " .field-img");
});
$(".group-container .field-img").each(function() {
$(this).click(function(){
var fieldid=$(this).parent().attr('id');
});
});
Since one element is inside the other, the click will propagate up anyway, so you could always just bind the click to the parent element and do :
$('div[id^="field"]').on('click', function() {
alert(".group-container "+this.id+" .field-img");
});
FIDDLE
or even get them all dynamically:
$('div[id^="field"]').on('click', function(e) {
alert('.'+this.parentNode.className+" "+this.id+" ."+e.target.className);
});
FIDDLE
I have a tabed screen and want to trigger a click on the selected tab once the form is submitted and the return is valid. Here a part of the html:
<ul id="tabUL" class="tabs js-tabs same-height">
<li class="current">
<a class="tabLink" href="#tabProducts" data-url="/bla/bla">Products</a>
</li>
</ul>
My success command is :
success: function(data, textStatus, XMLHttpRequest) {
$('#tabUL').find('li.current a').trigger('click');
}
This seems not working... Any help is appreciated :) Regards Andrea
Try using the a[href=""] selector:
$('#tabUL a[href="#tabProducts"]').trigger('click');
I put together a jsfiddle demo to show it in action, and how to optionally hide the other tabs since often when I'm programmatically forcing tabs its to require missing mandatory information be entered on the initial tab before unlocking the other tabs...
Edit
Here is the contents of the jsfiddle:
HTML
<div id="tabs">
<ul>
<li>Address</li>
<li>Shipping</li>
<li>Parts</li>
<li>Datasheets</li>
</ul>
<div id="tab0">
<h1>This is the first tab (0)</h1>
</div>
<div id="tab1">
<h1>This is the second tab (1)</h1>
</div>
<div id="tab2">
<h1>This is the third tab (2)</h1>
</div>
<div id="tab3">
<h1>This is the fourth tab (3)</h1>
</div>
</div>
<br/>
Select the
<select id="tabSelect">
<option value="0">1st</option>
<option value="1">2nd</option>
<option value="2">3rd</option>
<option value="3">4th</option>
</select>Tab and
<input type="checkbox" id="tabHide" checked="checked" /> Lock the Others
jQuery
$(document).ready(function () {
$('#tabs').tabs();
$('#tabSelect').change(function () {
//pass empty array to unlock any locked tabs
$('#tabs').tabs({disabled: []}).find('a[href="#tab' + $(this).val() + '"]').trigger('click');
if ($('#tabHide').prop('checked')) {
//hide will be an array like [0,2,3]
var hide = Array();
$('#tabs li').not('.ui-tabs-active').each(function () {
hide.push($(this).index());
});
$('#tabs').tabs({disabled: hide});
}
});
});
If you want to reload the tab programmatically then i recommend use Jquery Tab API utility like below:
This makes first tab active and then activates second tab, quite simple and also raises the events that would be normally raised when you click directly.
$( "#myTabs" ).tabs( "option", "active", 0 );
$( "#myTabss" ).tabs( "option", "active", 1 );
Also you can catch tabs active event like below for performing any operations
$( "#myTabs" ).on( "tabsactivate", function( event, ui ) {
// your custom code on tab click
});
rather than trying to trigger the click event itself (which I believe is not possible to invoke a user event programatically in this context), I suggest that you trigger the function that has to be called on click event, you might want to look into triggerHandler
I have one form located on several Twitter's Bootstrap tabs:
<form id="personal-data" class="form-horizontal">
<div class="tabbable">
<ul id="tab" class="nav nav-tabs">
<li class="active">Home</li>
<li class="">Profile</li>
<!-- ... -->
</ul>
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade active in" id="home">
<fieldset>
<div class="control-group">
<div class="controls">
<input type="text" id="field1">
</div>
</div>
</fieldset>
</div>
<div class="tab-pane fade" id="profile">
<fieldset>
<div class="control-group">
<div class="controls">
<input type="text" id="field2">
</div>
</div>
</fieldset>
</div>
When I validate the form with jQuery validate on active tab and field with invalid value is on the same tab, then validation fails (which is correct). But when I am on one tab and invalid value is on another tab, then validation returns true, which is incorrect. How can I fix it? How can I highlight that field on another tab?
Please see this demo (just press button next - it will show error message, then go to last tab and press finish there).
I think your problem lies in the fact that validation occurs in visible elements only.
Reading this issue we see that on version 1.9
Fixed #189 - :hidden elements are now ignored by default
and a solution a few comments down
$.validator.setDefaults({
ignore: ""
});
My solution to enable tabs
...
highlight: function(label) {
$(label).closest('.control-group').addClass('error');
$(".tab-content").find("div.tab-pane:hidden:has(div.error)").each( function(){
var id = $(this).attr("id");
$('#tabs a[href="#'+id+'"]').tab('show');
});
},
...
Is necessary that you add this code to allow change tab by js
$('a[data-toggle="tab"]').on('shown', function (e) {
e.target // activated tab
e.relatedTarget // previous tab
});
thanks for your code it solved most of my problem, except the part to navigate to first tab with error. I got around as follows:
var IsValid = true;
// Validate Each Bootstrap tab
$(".tab-content").find("div.tab-pane").each(function (index, tab) {
var id = $(tab).attr("id");
$('a[href="#' + id + '"]').tab('show');
var IsTabValid = $("#SomeForm").valid();
if (!IsTabValid) {
IsValid = false;
}
});
// Show first tab with error
$(".tab-content").find("div.tab-pane").each(function (index, tab) {
var id = $(tab).attr("id");
$('a[href="#' + id + '"]').tab('show');
var IsTabValid = $("#SomeForm").valid();
if (!IsTabValid) {
return false; // Break each loop
}
});
Are these jQuery tabs you're using? You can deactivate all other tabs and gradually activate them while the submitted data on each form pass the validation. Disable them all but the first in your constructor and after each validation enable the next.
.tabs( "enable" , index )
Read more here.
You could also put one final validation method in the end and put all your content visible depending on the tabs so you can escape the reloading of the links.
Building upon #juanmanuele's answer, this is how I managed to get it working with Bootstrap 3 tabs:
if($(".tab-content").find("div.tab-pane.active:has(div.has-error)").length == 0)
{
$(".tab-content").find("div.tab-pane:hidden:has(div.has-error)").each(function(index, tab)
{
var id = $(tab).attr("id");
$('a[href="#' + id + '"]').tab('show');
});
}
To place focus on the 1st input with error:
$('a[data-toggle="tab"]').on('shown.bs.tab', function(e)
{
e.target // activated tab
$($(e.target).attr('href')).find("div.has-error :input:first").focus();
//e.relatedTarget // previous tab
});
Not exactly the solution for jQuery Validate, but you could use the "invalid" event on form elements, to catch HTML5 validation errors, and get the focused element, find the respectively tab-pane, and show it.
I have done this.
$("form").find("input, select").on("invalid", function() {
var id = $(this).parents(".tab-pane").attr("id");
$("#tabs-selector ul").find("li a[href='#" + id + "']").tab("show");
});
Hope this helps you. Again, this is for HTML5 or if jQuery Validate fires an invalid event.