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
});
Related
Hi I'm using this script to prevent users from submitting specific blank form text input fields. Does a great job but I have 2 submit buttons within 1 form and I need this to work for only 1. Is there any way to make this code below apply to 1 specific button using the button id or name?
<script type="text/javascript">
$('form').on('submit', function () {
var thisForm = $(this);
var thisAlert = thisForm.data('alert');
var canSubmit = true;
thisForm.find('[data-alert]').each(function(i) {
var thisInput = $(this);
if ( !$.trim(thisInput.val()) ) {
thisAlert += '\n' + thisInput.data('alert');
canSubmit = false;
};
});
if( !canSubmit ) {
alert( thisAlert );
return false;
}
});
</script>
Your first line:
$('form').on('submit', function () {
will take all form elements in the document. You can change the 'form' part of that to the ID of the form element i.e.
$('#form1').on('submit', function () {
You have one form and two submit buttons which, by default, will both submit the form. To prevent one button from submitting, add a click handler that both prevents the default submit action and does whatever else you want that button to do.
HTML
<form id="form1">
<input type="text" value="something" />
<input id="submit1" type="submit" value="send" />
<input id="submit2" type="submit" value="ignore" />
</form>
JavaScript
$('#submit2').on('click', function (event) {
event.preventDefault();
// Form will not be submitted
// Do whatever you need to do when this button is clicked
});
$('form ').on('submit ', function () {
var thisForm = $(this);
var thisAlert = thisForm.data('alert');
var canSubmit = true;
thisForm.find(' [data - alert]').each(function (i) {
var thisInput = $(this);
if (!$.trim(thisInput.val())) {
thisAlert += '\n ' + thisInput.data('alert ');
canSubmit = false;
};
});
if (!canSubmit) {
alert(thisAlert);
return false;
}
});
Demo https://jsfiddle.net/BenjaminRay/ccuem4yy/
<input id="input1" type="text" />
<br />
<input id="input2" type="text" />
I have followed this simple script that stores the focus on the input text.
$(document).ready(function() {
changeFocus();
$("#input1").click(function(){
localStorage.setItem('txtObjectid', "input1");
changeFocus();
return false;
});
$("#input2").click(function(){
localStorage.setItem('txtObjectid', "input2");
changeFocus();
return false;
});
});
function changeFocus(){
if(localStorage.getItem('txtObjectid')==null)
id="input1"
else
id=localStorage.getItem('txtObjectid');
var v = "#" + id;
$(v).focus();
}
What I want to learn/know about is how to make the script flexible? How could I make this so that it won't search of the id = "input1" instead it will search for input[type=text]?
Something like this should do it
$(document).ready(function () {
var id = 'input1';
if (localStorage.getItem('txtObjectid')) {
id = localStorage.getItem('txtObjectid');
}
$('#' + id).focus();
$('input[type="text"]').on('focus', function () {
localStorage.setItem('txtObjectid', this.id);
});
});
FIDDLE
I am creating a system where a user can preview the title and steps of a recipe, i have created a dynamic form so the user can add more steps, the preview works with the title and first step however it seems that i can't get it to work on the second, third, fourth step. Can anyone help me? Any help would be greatly appreciated!
http://jsfiddle.net/uKgG2/
Jquery
var commentNode = $('#lp-step'),
nameNode = $('#lp-name');
$('input, textarea').bind('blur keyup', function () {
commentNode.html($('textarea[name="step_detail[]"]').val().replace(/\n/g, '<br />'));
nameNode.text('Title: ' + $('input[name="name"]').val());
});
var addDiv1 = $('#addStep');
var i = $('#addStep p').size() + 1;
$('#addNewStep').on('click', function () {
$('<p> <textarea id="step_' + i + '" name="step_detail[]"> </textarea>Remove </p>').appendTo(addDiv1);
i++;
return false;
});
$(document).on('click', '.remNew1', function () {
if (i > 2) {
$(this).parents('p').remove();
i--;
}
return false;
});
HTML
<label for="name">Enter recipe name:</label>
<input type="text" name="name">
<br />
<h1>Method</h1>
<div id="addStep">
<p>
<textarea id="step_1" name="step_detail[]"></textarea>
Add
</p>
</div>
<br />
<button type="submit">
Save on xml
</button>
</form>
<div id="live-preview-display">
<div id="lp-name"> </div>
<div id="lp-step"> </div>
</div>
You should bind the keyup or blur event to all the new textareas which are created with add button or link whatever.
Improved
try this :
$('#addStep').on('keyup', 'textarea', function () {
step_id = $(this).attr('id');
step_text = $('#' + step_id).val();
if($('.'+step_id).length > 0) {
$('.'+step_id).text(step_text);
return;
}
p = document.createElement('p');
p.className = step_id;
$(p).appendTo(commentNode);
$(p).text(step_text);
});
it worked! I saved it to fiddle too. you should just update the recipe name and clean this as I said i't very hacky just have to improve it.good luck. http://jsfiddle.net/uKgG2/3/
Sorry - still a beginner - How do I dynamically create action url using the input text from the user?
<form name="myInstitution" action="" method="GET">
<div>
<label for="names" class="bold">Institution Name</label>
<input id="names" name="schoolName" type="text"></input>
</div>
<div class="bold"></div>
<div>
<input type="submit" value="Submit" id="sbutton" name="submit" />
<input type="reset" value="Reset" />
</div>
</form>
Since you don't seem to be using a javascript library, I'll copy the bind code in pure javascript from this answer.
var on = (function(){
if ("addEventListener" in window) {
return function(target, type, listener){
target.addEventListener(type, listener, false);
};
}
else {
return function(object, sEvent, fpNotify){
object.attachEvent("on" + sEvent, function(){
fpNotify(window.event);
});
};
}
}());
on(document.getElementById("sbutton"), "click", function(){
this.action = document.getElementById( "names" ).val() + ".ext";
});
If you were using a javascript library like jQuery, you could bind to the event handler like this:
$( "form[name=\"myInstitution\"]" ).on( "submit", function( e ){
var $this = $(this),
text = $this.find( "input#names" ).val();
$this.prop( "action", text + ".ext" );
});
$('#myForm').submit(function ()
{
var action = '';
// compute action here...
$(this).attr('action', action);
});
Hope it will help you..
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/