So I have been messing around with dynamic input fields and everything is working great. The only issue I'm having is stopping the first input_line from being deleted.
So pretty much every input_line (refer to my fiddle for exmaple) should be able to be removed except the first one, that one should always stay.
Illustration:
Any suggestions how I can achieve this?
HTML:
<form action="javascript:void(0);" method="POST" autocomplete="off">
<button class="add">Add Field</button>
<div class='input_line'>
<input type="text" name="input_0" placeholder="Input1"><input type="button" class="duplicate" value="duplicate"><input type="button" class="remove" value="remove">
</div>
</form>
jQuery:
$(document).ready(function () {
'use strict';
var input = 1,
blank_line = $('.input_line');
$('.add').click(function () {
var newElement = blank_line.clone(true).hide();
$('form').append(newElement);
$(newElement).slideDown();
});
$('form').on('click', '.duplicate', function () {
$(this).parent().clone().hide().insertAfter($(this).parent().after()).slideDown();
$('.input_line').last().before($('.add'));
input = input + 1;
});
$('form').on('click', '.remove', function () {
$(this).parent().slideUp(function () {
$(this).remove();
});
$('.input_line').last().before($('.add'));
input = input - 1;
});
});
JSFiddle
Any help would be greatly appreciated!
Hide the remove when there's one row, else show it:
http://jsfiddle.net/gqgaswdy/23/
$(document).ready(function () {
'use strict';
var input = 1,
blank_line = $('.input_line');
var removing = false;
$('.remove').hide();
$('.add').click(function () {
var newElement = blank_line.clone(true).hide();
$('form').append(newElement);
$(newElement).slideDown();
$('.remove').show();
});
$('form').on('click', '.duplicate', function () {
$(this).parent().clone().hide().insertAfter($(this).parent().after()).slideDown();
$('.input_line').last().before($('.add'));
$('.remove').show();
input = input + 1;
});
$('form').on('click', '.remove', function () {
if (removing) {
return;
} else {
if ($('.input_line').length <= 2) $('.remove').hide();
$(this).parent().slideUp(function () {
$(this).remove();
removing = false;
});
$('.input_line').last().before($('.add'));
input = input - 1;
}
removing = true;
});
});
Just would like to show you how easy it is to create such behavior in frameworks actually intended for databinding (which jquery is not, so you have to write a lot of additional/unnecessary logic) with example of knockout.js
Demo
<div data-bind="foreach: rows">
<div>
<input type="text" data-bind="value: $data.name">
<button data-bind="click: $root.duplicate">Duplicate</button>
<button data-bind="click: $root.remove, enable: $root.rows().length > 1">Remove</button>
</div>
</div>
<button id="button" data-bind="click: addRow">add Row</button>
var row = function(name) {
this.name = ko.observable(name);
};
function TableModel() {
var self = this;
self.rows = ko.observableArray([]);
self.addRow = function() {
self.rows.push( new row('') );
};
self.duplicate = function(a) {
self.rows.push( new row(a.name()) );
};
self.remove = function(a) {
self.rows.remove(a);
};
}
ko.applyBindings(new TableModel());
Maybe add new function like this:
function HideRemoveButton(){
if($('.input_line').length <= 1){
$('.remove').hide()
}
else{
$('.remove').show()
}
}
Related
This was my code which it's not working. What I'm trying to accomplish is that if user doesn't type https://www. then automatically add it for them. If user does add https://www. then don't add it for them.
Javascript
var button = document.getElementById('button');
var search = document.getElementById("search");
button.addEventListener("click", function () {
if (search.value !== "https://www.") {
window.open("https://www." + search.value);
} else if (search.value == "https://www.") {
window.open(search.value);
}
})
HTML
<input id="search" type="text" placeholder="URL"
autocomplete="https://www.">
<button id="button">Search</button>
var button = document.getElementById('button');
var search = document.getElementById("search");
var protocol = /^(http(s)?(:\/\/))?(www\.)?/gi;
button.addEventListener("click", function() {
if (!search.value.match(protocol)[0]) {
window.open("https://www." + search.value);
} else if (search.value.match(protocol)[0]) {
window.open(search.value);
}
});
<input id="search" type="text" placeholder="URL" autocomplete="https://www.">
<button id="button">Search</button>
You could probably accomplish this with the indexOf() function.
var searchValue = 'example.com';
if (searchValue.indexOf('https://www') > -1) {
window.open("https://www." + searchValue);
} else {
window.open(searchValue);
}
I have an add tag form which includes input field and button. The user can enter multiple tags. Tags are separated by a comma.
Everything is working fine but I want to store added tags values in a variable using javascript, jquery.
Here is what I have done so far -
$("#tags input").on({
focusout: function () {
var txt = this.value.replace(/[^a-z0-9\+\-\.\#]/ig, ''); // allowed characters
if (txt) $("<span/>", {text: txt.toLowerCase(), insertBefore: this});
this.value = ""; // To remove entered value after inserting comma
},
keyup: function (ev) {
// if: comma|enter (delimit more keyCodes with | pipe)
if (/(188|13)/.test(ev.which)) $(this).focusout();
}
});
$('#tags').on('click', 'span', function () {
if (confirm("Remove " + $(this).text() + "?")) $(this).remove();
});
$(document).on('click', '#select_all', function () {
if (this.checked) {
$('.all').each(function () {
this.checked = true;
});
} else {
$('.all').each(function () {
this.checked = false;
});
}
});
$('#add_tag_btn').click(function () {
// Here I want to store added tags values in variable.
var added_tags=$('#tags span').html();
alert(added_tags);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<div id="tags">
<input type="text" value="" class="form-control" id="add_tag"placeholder="Add tag" />
</div>
<input type='button' class='btn btn-primary' id='add_tag_btn' value='Add'>
</form>
Here is the answer...
You just need to loop on button click for get each and every tag value in variable.
On button click create once array for get all the tag value in variable
HTML
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<div id="tags">
<input type="text" value="" class="form-control" id="add_tag"placeholder="Add tag" />
</div>
<input type='button' class='btn btn-primary' id='add_tag_btn' value='Add'>
</form>
JS
<script>
$("#tags input").on({
focusout: function () {
var txt = this.value.replace(/[^a-z0-9\+\-\.\#]/ig, ''); // allowed characters
if (txt)
$("<span/>", {text: txt.toLowerCase(), insertBefore: this});
this.value = ""; // To remove entered value after inserting comma
},
keyup: function (ev) {
// if: comma|enter (delimit more keyCodes with | pipe)
if (/(188|13)/.test(ev.which))
$(this).focusout();
}
});
$('#tags').on('click', 'span', function () {
if (confirm("Remove " + $(this).text() + "?"))
$(this).remove();
});
$(document).on('click', '#select_all', function () {
if (this.checked) {
$('.all').each(function () {
this.checked = true;
});
} else {
$('.all').each(function () {
this.checked = false;
});
}
});
</script>
Button click..
// Button Click
$('#add_tag_btn').click(function () {
var added_tags = [];
i = 0;
$('#tags span').each(function ()
{
added_tags[i++] = $(this).text();
});
alert(added_tags);
});
I hope its helpful for you..
You can save the tag inside an array in the focus out event of input.
When you click add button you can join the elements of this array by ,
// Here I want to store added tags values in variable.
var added_tags = [];
$("#tags input").on({
focusout: function() {
var txt = this.value.replace(/[^a-z0-9\+\-\.\#]/ig, ''); // allowed characters
if(txt != "")
added_tags.push(txt);
if (txt) $("<span/>", {
text: txt.toLowerCase(),
insertBefore: this
});
this.value = ""; // To remove entered value after inserting comma
},
keyup: function(ev) {
// if: comma|enter (delimit more keyCodes with | pipe)
if (/(188|13)/.test(ev.which)) $(this).focusout();
}
});
$('#tags').on('click', 'span', function() {
if (confirm("Remove " + $(this).text() + "?"))
{
var index = added_tags.indexOf($(this).text());
added_tags.splice(index, 1);
$(this).remove();
console.log(added_tags.join(","));
}
});
$(document).on('click', '#select_all', function() {
if (this.checked) {
$('.all').each(function() {
this.checked = true;
});
} else {
$('.all').each(function() {
this.checked = false;
});
}
});
$('#add_tag_btn').click(function() {
console.log(added_tags.join(","));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<div id="tags">
<input type="text" value="" class="form-control" id="add_tag" placeholder="Add tag" />
</div>
<input type='button' class='btn btn-primary' id='add_tag_btn' value='Add'>
</form>
You just need to declare it globally and then keep adding tags to it and do some changes in the span creation code. I hope the code explains itself:
var added_tags = "";
$("#tags input").on({
focusout: function() {
var txt = this.value.replace(/[^a-z0-9\+\-\.\#]/ig, ''); // allowed characters
if (txt) {
//$(this).prevAll('span').remove();
$("<span/>", {
text: txt.toLowerCase(),
insertBefore: this
});
}
this.value = ""; // To remove entered value after inserting comma
},
keyup: function(ev) {
// if: comma|enter (delimit more keyCodes with | pipe)
if (/(188|13)/.test(ev.which)) $(this).focusout();
}
});
$('#tags').on('click', 'span', function() {
if (confirm("Remove " + $(this).text() + "?")) $(this).remove();
});
$(document).on('click', '#select_all', function() {
if (this.checked) {
$('.all').each(function() {
this.checked = true;
});
} else {
$('.all').each(function() {
this.checked = false;
});
}
});
$('#add_tag_btn').click(function() {
// Here I want to store added tags values in variable.
added_tags = "";
$('#tags input').prevAll('span').each(function() {
added_tags += (added_tags == "" ? "" : ",") + $(this).html();
})
alert(added_tags);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<div id="tags">
<input type="text" value="" class="form-control" id="add_tag" placeholder="Add tag" />
</div>
<input type='button' class='btn btn-primary' id='add_tag_btn' value='Add'>
</form>
EDIT: Fill tags dynamically so that it accounts for removed tags too
I have a javascript function which is designed to add and remove additional input field to a div.
In a specific case, I could specify the div to which I would like the fields to be added when the function is called.
However, I want to have multiple buttons associated with multiple corresponding divs on one page which could call the function to add a field to that div.
The function:
$(function() {
var scntDiv = $('#DIV');
var i = $('#DIV p').size() + 1;
$('.addField').on('click', function() {
$('<p><input type="text" id="field_' + i +'" size="20" name="field_' + i +'" value="" /> Remove</p>').appendTo(scntDiv);
i++;
return false;
});
$('.remField').on('click', function() {
if( i > 2 ) {
$(this).parents('p').remove();
i--;
}
return false;
});
});
As you can see the add field button listens for a button with the class "addField" to be clicked.
I would like that click to pass the parameter for #DIV to be equal to the # of the parent div of that button, is that possible?
EDIT: Per request here is my markup (example of) with function (note ??? placeholders)
JsFiddle
Does this jsfiddle do the trick?
Html:
<div id="div">
<div>
<button type="button">
<span>Add Field</span>
</button>
</div>
<div>
<button type="button">
<span>Add Field</span>
</button>
</div>
<div>
<button type="button">
<span>Add Field</span>
</button>
</div>
</div>
JavaScript:
(function ($, undefined) {
'use strict';
var i;
i = 0;
function fieldMaker () {
i += 1;
return $('<p><input type="text" id="field_' + i +'" size="20" name="field_' + i +'" value="" /> Remove</p>');
}
$(function () {
$('#div').on({
click : function () {
$(this).closest('div').append(fieldMaker());
}
}, 'button');
$('#div').on({
click : function () {
$(this).closest('p').remove();
}
}, 'a');
});
}(jQuery));
You could store the information – where to add the input – at the button, for example using the HTML5 data-* attributes:
<p><button data-add-field-to=".fieldset-1">add field to .fieldset-1</button></p>
<fieldset class="fieldset-1"></fieldset>
JS:
jQuery( function() {
var i = 1; // your counter logic here
jQuery( '[data-add-field-to]').each( function() {
var $button = $( this );
$button.on( 'click', function( event ) {
var newFieldId = 'field_' + i,
target = jQuery( $button.attr( 'data-add-field-to' ) );
jQuery( '<input type="text" id="' + newFieldId +'" size="20" name="' + newFieldId +'" value="" />').appendTo( target );
i++;
return false;
} );
} );
} );
I will assume you have a mapping between the buttons (let's say button id) and the elements to add to:
var mapping = {
'#button1' : $('#receiver1'),
'#button2' : $('#receiver2'),
'#button3' : $('#receiver3')
}
One solution is to check which button the click event was triggered on:
$('.addField').on('click', function() {
$('<mycontent>').appendTo(mapping(this.id));
i++;
return false;
});
A more elegant solution is to create a function for each button:
Object.keys(mapping).forEach(function(key){
$(key).on('click', function() {
$('<mycontent>').appendTo(this);
i++;
return false;
}.bind(mapping[key])); // force this to be the receiver
});
I have decided to create a wizard form in HTML 5 (actually using ASP.NET MVC here). I have the following HTML form:
#using (Html.BeginForm())
{
<div class="wizard-step">
<input type="text" name="firstname" placeholder="first name" />
</div>
<div class="wizard-step">
<input type="text" name="lastname" placeholder="last name" />
</div>
<div class="wizard-step">
<input type="text" name="suffix" placeholder="suffix" />
</div>
<button class="back-button" type="button">
Back</button>
<button class="next-button" type="button">
Next</button>
}
Then I have this js script:
<script type="text/javascript">
$(document).ready(function () {
var $steps = $(".wizard-step");
var index = 0;
var count = $steps.length;
$steps.each(function () {
$(this).hide();
});
$(".back-button").attr("disabled", "disabled");
var $currentStep = $steps.first();
$currentStep.show();
$currentStep.addClass("current-step");
$(".back-button").click(function () {
$currentStep.hide();
$currentStep.removeClass("current-step");
$currentStep = $currentStep.prev();
$currentStep.addClass("current-step");
$currentStep.show();
index--;
$(".next-button").removeAttr("disabled");
if (index == 0) {
$(this).attr("disabled", "disabled");
}
else {
$(this).removeAttr("disabled");
}
});
$(".next-button").click(function () {
var $inputFields = $(".current-step :input");
var hasError = false;
$inputFields.each(function () {
if (!validator.element(this)) {
hasError = true;
}
});
if (hasError)
return false;
index++;
$(".back-button").removeAttr("disabled");
if (index == count - 1) {
$(this).attr("disabled", "disabled");
}
else {
$(this).removeAttr("disabled");
}
$currentStep.hide();
$currentStep.removeClass("current-step");
$currentStep = $currentStep.next();
$currentStep.addClass("current-step");
$currentStep.show();
});
});
</script>
Basically, what I want is upon clicking the Next button, it will validate the input elements found inside the current visible DIV, not the entire FORM. Is it possible to do this using HTML5? If not, maybe jQuery?
If you have others in mind, please do share it here. Many many thanks!
after some playing with the jquery i happened to find the solution despite of lack of samples and tutorials in validation. inside the $(".next-button").click() block, i made these changes:
old:
var hasError = false;
$inputFields.each(function () {
if (!validator.element(this)) {
hasError = true;
}
});
if (hasError)
return false;
new:
var isValid = false;
$inputFields.each(function () {
isValid = $(this).valid();
});
if (!isValid)
return false;
======================
i could also add this right under the $(document).ready() line to use/add jquery validation rules:
$("#myForm").validate({
rules: {
lastname: "required"
}
});
I am learning to write a plugin for myself, but I got something odd in the code. I have a reset button, and when I click it, it runs as times as the number of input elements I have.
My code: jsbin, jsfiddle
HTML:
<div id="container">
<div id="createCSVWrap">
<fieldset>
<legend> Create the CVS File </legend>
<div class="dateWrap">
<label> 开始时间: </label>
<div style="float:right">
<input id="startTime" name="startTime" type="text" value="13:37:06" />
</div>
</div>
</fieldset>
</div>
<input id="f" name="fck" value="18:27:56" />
<input class="tt" name="tt" value="02:07:56" />
<input name="ok" class="ok" value="08:07:56" />
</div>
Javascript
$(document).ready(function() {
$('#startTime').timePicker();
$('#f').timePicker();
$('.tt').timePicker();
$('.ok').timePicker();
});
(function($) {
$.fn.timePicker = function(options) {
var defaults = {
setTimeFocus: 'hour'
}; //,originalTime :''
var options = $.extend(defaults, options);
if ($('#timePicker').length === 0) {
var timePickerBody = '<div id="timePicker" style="display:none;">' + '<div id="setTimeOption">' + ' RESET' + '</div></div>';
$("body").append(timePickerBody);
}
return this.each(function() {
var o = options;
$(this).focus(function() {
_input = $(this); // ONLY put here can change value of each input field
originalTime = '';
//originalTime = {} ;
intial();
});
function intial() {
showSetTime();
setTimePickerPosition();
$('#timeReset ').click(resetTime);
}
function showSetTime() {
$('#timePicker').show();
}
function hiddenSetTime() {
$('#timePicker').hide();
}
function setTimePickerPosition() {
var _inputPosition = _input.offset();
var _timePickerPosition = [_inputPosition.left, _inputPosition.top + _input.height()];
var _timePickerPositionLeft = _timePickerPosition[0],
_timePickerPositionTop = _timePickerPosition[1];
$('#timePicker').css({
'left': _timePickerPositionLeft + 'px',
'top': _timePickerPositionTop + 'px'
});
}
time = 1;
function resetTime(event) {
event.preventDefault();
time++;
alert(time)
}
$(this).click(function(e) {
e.stopPropagation();
});
$('#timePicker').click(function(e) {
e.stopPropagation();
});
$(document).click(function() {
hiddenSetTime();
});
});
// ending return this
};
})(jQuery);
CSS:
#timePicker
{
position:absolute;
width:185px;
padding:10px;
margin-top:5px;
background:#F3F3F3;
border:1px solid #999;
}
I think I see the problem here. It's to do with this bit of code:
$(this).focus(function() {
_input = $(this);
originalTime = '';
intial();
});
function intial() {
showSetTime();
setTimePickerPosition();
$('#timeReset').click(resetTime);
}
This basically means that every time the user focuses onto the textbox another click handler will get attached to the "Reset" button, thus the same event firing multiple times.
What you need to do is the unbind the old event and reattach a new one, with the unbind event.
$('#timeReset').unbind('click').click(resetTime);
See it working here: http://www.jsfiddle.net/Sc6QB/1/