so I have got my form successfully adding a new input on the click of a button. However now I want to be able to remove that last addition on the click of a new button and then also feature a reset button.
this was the code I had in place, which I realise now just removes the submit button first, which obviously I dont want.
here is my javascript snippet: (note ive included the appendTo() to demonstrate the div I am successfully appending to)
$(function() {
var i = $('input').size('#temp') + 1;
$('a#add').click(function() {
$('<input type="text" value="user' + i + '" />').appendTo('#temp');
i++;
});
$('a#remove').click(function() {
if(i > 3) {
$('input:last').remove();
i--;
}
});
many thanks,
Your script will remove the last input from the page, not the last one from the div with id temp. Maybe you are removing another input from your page.
Try this:
$('a#remove').click(function() {
if(i > 3) {
$('#temp input:last').remove();
i--;
}
});
Edit:
You only close the $('a#remove').click() event handler, not the anonymous function. That may be a copy/paste error here, but may also be a problem in your code.
Edit 2:
To remove all but the original, I would recommend keeping a reference to all added inputs, as this reduces the need to traverse the DOM for each remove. So do something like this (This code is neither tested nor verified):
$(function() {
var addedInputs = [];
$('a#add').click(function() {
var newInput = $('<input type="text" value="user' + i + '" ">').appendTo('#temp');
addedInputs.push(newInput);
});
$('a#remove').click(function() {
var inputToRemove = addedInputs.pop();
inputToRemove.remove();
});
$('a#clear').click(function() {
var i,
inputToRemove;
for(i = addedInputs.length - 1;i >= 0; i -=1) {
inputToRemove = addedInputs[i];
inputToRemove.remove();
}
addedInputs = [];
});
});
Have you tried :
$("a#remove").click(function() {
if(i > 3) {
$("input[type='text']").last().remove();
i--;
}
});
This will select the inputs having type="text", take the last one and remove it.
Related
I can't figure out why $('label.error') is showing up on every bootstrap tab when that particular element should only show on 1 tab. I have a field that's not passing validation on a bootstrap tab and thus a label with class error is being appended the DOM on the violating field. But, I can't seem to get my code to land on the specific tab that has the violating field. What am I doing wrong in the code below? isErrorPresent should only be true on 1 particular tab but EVERY tab is showing it to be true...
$("#" + formId).validate({ignore:""}).form(); // ignore:"" allows for hidden fields to be validated as well
$(".tab-content").find("div.tab-pane").each(function (index, tab) {
var id = $(tab).attr("id");
$('a[href="#' + id + '"]').click();
alert('processing tab ' + id);
var isErrorPresent = $('div.tab-pane, div.active').find('label.error').length > 0;
alert(isErrorPresent);
// if (isErrorPresent) {
// alert("label.error detected...");
// hasError = true;
// return false; // Break .each loop and return to page
// }
});
Without seeing more markup, this is what I am thinking:
You are doing this:
var isErrorPresent = $('div.tab-pane, div.active').find('label.error').length > 0;
The selector has a comma in it, meaning you want to checking on div.tab-pane && div.active
Is that what you wanted? Maybe you meant to do this (no comma and no space):
var isErrorPresent = $('div.tab-pane.active').find('label.error').length > 0;
Figured it out with #Red2678's help (thanks)...here's what's working for me now...
// Check all tabs for errors & show first tab that has errors
$(".tab-content").find("div.tab-pane").each(function (index, tab) {
var id = $(tab).attr("id");
$('a[href="#' + id + '"]').click();
$("#" + formId).validate().form();
var activeTab = $('div.tab-pane.active');
var isErrorPresent = false;
if ($(activeTab).find('label.error').length > 0) {
isErrorPresent = $(activeTab).find('label.error').css('display') !== 'none';
}
if (isErrorPresent) {
hasError = true;
return false; // Break .each loop and return to page
}
});
I have a form (demo link below).
I've tried about 8 different methods of storing the data but it won't work.
(link retracted)
The goal is, the user visits the site and fills out the form (partially or complete). They can then login if they wish.
The next time they visit the site the form should be complete (excluding password) and the avatar should display with the one stored in local storage.
I can't figure out why nothing will display, whether it's a compatibility issue or syntax issue etc.
Problem Solved
another js script has been interfering with it causing it to fail. Resolved.
I'm not going to check your website for errors since you didn't provide any code. Instead I show you a quick and working way to save and read values from localStorage.
The values will be stored in key/value pairs while the key is the name of the input field.
HTML:
<input type="text" name="username" id="user" />
<input type="text" name="email" id="email" />
JS:
$('input').each(function() {
$(this).on('blur', function() {
localStorage.setItem($(this).attr('name'), $(this).val());
});
});
for (var i = 0; i < localStorage.length; i++){
var storageKey = localStorage.key(i),
storageValue = localStorage.getItem(storageKey);
$('input[name='+storageKey+']').val(storageValue);
}
Remeber that the for loop has to be inside of your domready function. Check the working fiddle below. Like this you have a dynamic approach for input fields - you can also do this for selects if you like to.
If you want some faster selectors you can also save the ID as key and select the input via id. Is even more dynamic.
Fiddle
Edit: As requested here is an example for checkboxes/selects. It might not be the best approach but its working.
JS:
$('.autofill').each(function () {
$(this).on('change', function () {
if ($(this).is('input')) {
if ($(this).attr('type') == 'checkbox') {
if ($(this).is(':checked')) {
localStorage.setItem($(this).attr('id'), 'checked');
} else {
localStorage.setItem($(this).attr('id'), '');
}
} else {
localStorage.setItem($(this).attr('id'), $(this).val());
}
} else if ($(this).is('select')) {
localStorage.setItem($(this).attr('id'), $(this).find('option:selected').val());
}
});
});
for (var i = 0; i < localStorage.length; i++) {
var storageKeyElement = $('#' + localStorage.key(i)),
storageKey = localStorage.key(i),
storageValue = localStorage.getItem(storageKey);
if (storageValue == 'checked') {
storageKeyElement.attr('checked', 'checked');
} else if (storageKey.indexOf('Select') > 0) {
storageKeyElement.find('option[value=' + storageValue + ']').attr('selected', 'selected');
} else {
storageKeyElement.val(storageValue);
}
}
Fiddle with Selects and Checkboxes
The problem is, you have syntax error.
Change all the mb-* variables to mb_*
For example:
var mb-username
should be
var mb_username
But you have another problems in your source code too:
<meta name="author" content="Michael Clarke"
has a missing /> closing tag.
And you have another error:
ReferenceError: applySetting is not defined
Fix these errors, and use your console to see errors.
i m trying to make an anchor toggle function which appends data to textarea on click and removes on reclick. here is the jsfiddle.
`
function btnsInit()
{
var i, a = document.getElementById('btns').getElementsByTagName('a');
for (i = 0; i < a.length; ++i)
{
var str=document.getElementById('ta').value;
var index= str.indexOf(a[i]);
if(index!=-1)
{
a[i].onclick = btnClick;
}
else
{
str.replace(a[i],"_");
}
}
}
function btnClick(e)
{
document.getElementById('ta').value += this.firstChild.nodeValue + ',';
xPreventDefault(e);
return false;
}
`Please reply ASAP
Here is new js code, you can use it -
<div id='btns'>
<p>
<!-- adding id to element, helps to maintain the list
of element which have been clicked, and also helps in
distinguishing between two elements have same text.
Dont forget to add href="#' or href="javascript:void(0)"
else your page may refresh and form data will be lost -->
<a id="a1" href='#'>category</a>
</p>
<p>
<a id="a2" href='#'>url</a>
</p>
</div>
<textarea id='ta' rows='10' cols='20'></textarea></body>
Javascript -
window.onload = btnsInit;
var selected = {};//keeps list of selected links
function btnsInit() {
var i, a = document.getElementById('btns').getElementsByTagName('a');
for (i = 0; i < a.length; ++i) {
a[i].onclick = btnClick;
}
}
function btnClick(e) {
if (selected[this.id]) {
delete selected[this.id];//deleting if already been clicked
} else {
selected[this.id] = this.innerHTML;//adding to the selected list
}
updateTextArea();
xPreventDefault(e);
return false;
}
function updateTextArea() {
var ta = document.getElementById('ta');
var val = "";
for ( var id in selected) {
val += selected[id] + ",";
}
ta.value = val;//updating from selected list
}
function xPreventDefault(e) {
if (e && e.preventDefault)
e.preventDefault();
else if (window.event)
window.event.returnValue = false;
}
Problems with your code -
btnsInit was not actually assigning onclick listeners to <a> elements.
Re click on a link was not handled or not handled properly(if handled).
Use attribute/value href=' ' for a tag which is refreshing the page.
Update - questions asked in comments
Was my code not working as it was refreshing the page?
No, It was not. It was missing reclick handling and btnsInit was not working properly.
Is delete a predefined function?
delete is a JavaScript keyword, which delete an object property.
About delete keyword
What is the use of 'this'?
this is another keyword which holds the reference of the object in context, in this case it holds the element clicked.
More about this keyword
I have the following snippets of code. Basically what I'm trying to do is in the 1st click function I loop through my cached JSON data and display any values that exist for that id. In the 2nd change function I capturing whenever one of the elements changes values (i.e. yes to no and vice versa).
These elements are all generated dynamically though the JSON data I'm receiving from a webservice. From my understanding that is why I have to use the .live functionality.
In Firefox everything works as expected (of course). However, in IE7 it does not. In IE7, if I select a radio button that displays an alert from the click function then it also adds to the array for the changed function. However, if the radio button does not do anything from the click function then the array is not added to for the change.
As I look at this code I'm thinking that I might be able to combine these 2 functions together however, right now I just want it to work in IE7.
$(document).ready(function () {
//This function is run whenever a 'radio button' is selected.
//It then goes into the CPItemMetaInfoList in the cached JSON data
//($.myglobals) and checks to see if there are currently any
//scripts to display.
$("input:radio").live("click", function () {
var index = parseInt(this.name.split(':')[0]);
for (i = 0; i <= $.myglobals.result.length - 1; i++) {
if ($.myglobals.result[i].CPItemMetaInfoList.length > 0) {
for (j = 0; j <= $.myglobals.result[i].CPItemMetaInfoList.length - 1; j++) {
if (index == $.myglobals.result[i].QuestionId) {
alert($.myglobals.result[i].CPItemMetaInfoList[j].KeyStringValue);
return;
}
}
}
}
});
});
$(document).ready(function () {
var blnCheck = false;
//Checks to see if values have changed.
//If a value has been changed then the isDirty array gets populated.
//This array is used when the questionSubmit button is clickeds
$('input').live('change', function () {
blnCheck = false;
for (i = 0; i <= isDirty.length - 1; i++) {
if (isDirty[i] == $(this).attr("name")) {
blnCheck = true;
break
}
}
if (blnCheck == false) {
isDirty[arrayCount] = $(this).attr("name");
arrayCount += 1;
alert($(this).attr("name"));
}
});
$('textarea').live('change', function () {
blnCheck = false;
for (i = 0; i <= isDirty.length - 1; i++) {
if (isDirty[i] == $(this).attr("id")) {
blnCheck = true;
break
}
}
if (blnCheck == false) {
isDirty[arrayCount] = $(this).attr("id");
arrayCount += 1;
//alert($(this).attr("name"));
}
});
});
UPDATE:
I had to move this chunk of code into the click function:
blnCheck = false;
for (i = 0; i <= isDirty.length - 1; i++) {
if (isDirty[i] == $(this).attr("name")) {
blnCheck = true;
break
}
}
if (blnCheck == false) {
isDirty[arrayCount] = $(this).attr("name");
arrayCount += 1;
alert($(this).attr("name"));
}
Like this:
$(document).ready(function () {
//This function is run whenever a 'radio button' is selected.
//It then goes into the CPItemMetaInfoList in the cached JSON data
//($.myglobals) and checks to see if there are currently any
//scripts to display.
$("input:radio").live("click", function () {
var index = parseInt(this.name.split(':')[0]);
for (i = 0; i <= $.myglobals.result.length - 1; i++) {
if ($.myglobals.result[i].CPItemMetaInfoList.length > 0) {
for (j = 0; j <= $.myglobals.result[i].CPItemMetaInfoList.length - 1; j++) {
if (index == $.myglobals.result[i].QuestionId) {
alert($.myglobals.result[i].CPItemMetaInfoList[j].KeyStringValue);
return;
}
}
}
}
blnCheck = false;
for (i = 0; i <= isDirty.length - 1; i++) {
if (isDirty[i] == $(this).attr("name")) {
blnCheck = true;
break
}
}
if (blnCheck == false) {
isDirty[arrayCount] = $(this).attr("name");
arrayCount += 1;
}
});
});
But...
I had to leave the change function the same. From my testing I found that the .click function worked for IE7 for the radio buttons and checkbox elements, but the .change functionality worked for the textboxes and textareas in IE7 and FF as well as the original functionality of the radio buttons and checkbox elements.
This one got real messy. Thanks to #Patricia for looking at it. Here suggestions did lead me to this solution. I'm going to leave the question unanswered as I wonder if there isn't a cleaner solution to this.
Fact: change event on radio buttons and checkboxes only get fired when the focus is lost (i.e. when the blur event is about to occur). To achieve the "expected" behaviour, you really want to hook on the click event instead.
You basically want to change
$('input').live('change', function() {
// Code.
});
to
$('input:radio').live('click', functionName);
$('input:not(:radio)').live('change', functionName);
function functionName() {
// Code.
}
(I'd however also take checkboxes into account using :checkbox selector for the case that you have any in your form, you'd like to treat them equally as radiobuttons)
I think this is because IE fires the change when focus is lost on checks and radios. so if the alert is popping up, focus is being lost and therefor the change event is firing.
EDIT:
try changing the $('input') selector to $('input:not(:radio)')
so the click will fire for your radios and the change for all your others.
Edit #2:
How bout putting the stuff that happens on change into a separate function. with the index as a parameter. then you can call that function from the change() and the click(). put the call to that function after your done with the click stuff.
You're declaring your blnCheck variable inside one of your document.ready() functions. You don't need two of these either, it could all be in one.
This means that the variable that you're declaring there won't be the one used when your change function is actually called, instead you're going to get some kind of implicit global. Don't know if this is part of it, but might be worth looking at. You should declare this at the top of your JS file instead.
I have listview with two checkboxes in itemtemplate.
I want to validate that user can only select only one checkbox in each row.
The behaviour you're describing is accomplished using standard HTML radiobuttons. If you change your design to use these you'll get the benefit that
The user can only select a single item, no extra javascript needed
Users expect to be able to choose multiple checkboxes but only a single radiobutton IE you're working with their expectations
If you're still sure you want to use jQuery then something like this should do it.
$(':checkbox').change(function(){
if($(this).attr('checked')) {
$(this).siblings(':checkbox').attr('checked',false);
}
});
#vinit,
just a little change, you forgot the else part,
$('input:checkbox[id*=EmailCheckBox]').click(uncheckOthercheckbox);
$('input:checkbox[id*=SMSCheckBox]').click(uncheckOthercheckbox);
function uncheckOthercheckbox() {
if (this.id.indexOf("EmailCheckBox") != -1) {
var otherCheckBoxId = this.id.substring(0, this.id.indexOf("EmailCheckBox")) + "SMSCheckBox";
}
else {
var otherCheckBoxId = this.id.substring(0, this.id.indexOf("SMSCheckBox")) + "EmailCheckBox";
}
var i = "#" + otherCheckBoxId;
if (this.checked) {
$(i).removeAttr('checked');
}
else {
if ($(i).attr('checked') === false) {
$(i).attr('checked', 'checked');
}
}
}
Thanks for the reply. had also asked one of my friend and he gave me the following solution which is working fine. Posting it, if anybody needs it.-
say ur checkboxes in the 2 clumns are named EmailCheckBox and SMSCheckBox
then use this code to toggle the checkboxes in each single row:
$('input:checkbox[id*=EmailCheckBox]').click(uncheckOthercheckbox);
$('input:checkbox[id*=SMSCheckBox]').click(uncheckOthercheckbox);
function uncheckOthercheckbox() {
if (this.id.indexOf("EmailCheckBox") != -1) {
var otherCheckBoxId = this.id.substring(0, this.id.indexOf("EmailCheckBox")) + "SMSCheckBox";
}
else {
var otherCheckBoxId = this.id.substring(0, this.id.indexOf("SMSCheckBox")) + "EmailCheckBox";
}
var i = "#" + otherCheckBoxId;
if (this.checked) {
$(i).removeAttr('checked');
}
}