I have 2 input fields with the same name - that is because business logic of the project.
They look like that:
<input type="file" name="director_front_passport[]" class="app-file" id="director_front_passport" />
<input type="file" name="director_front_passport[]" class="app-file" />
I need to append image name after input field on change event.But in this way, how to make difference between these 2 inputs?
I thought to try to differ them by id attr, but I have clone button to add more fields and I don't think this will work on change event.
Updated: My code for on change event is the following:
var inputs = document.querySelectorAll( '.app-file' );
Array.prototype.forEach.call( inputs, function( input )
{
input.addEventListener( 'change', function( e )
{
//my code for displaying image
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
I updated my code using $(this) to find changed input and my code looks:
var inputs = document.querySelectorAll( '.app-file' );
Array.prototype.forEach.call( inputs, function( input )
{
input.addEventListener( 'change', function( e )
{
var changed = $(this);
var label = changed.next(),
labelVal = label.innerHTML,
divName = label.next();
fileName = e.target.value.split('\\').pop();
divName.html(fileName);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="file" name="director_front_passport[]" class="app-file" id="director_front_passport" />
<input type="file" name="director_front_passport[]" class="app-file" />
You can use the this keyword within the event handler to identify the element which raised the event. Try this:
$('.app-file').change(function() {
$(this).after('<div>' + this.files[0].name + '</div>');
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="file" name="director_front_passport[]" class="app-file" id="director_front_passport" />
<input type="file" name="director_front_passport[]" class="app-file" />
With your second example it's a little odd to call forEach in the manner you are. You can just call forEach on the nodeList returned from querySelectorAll, like this:
document.querySelectorAll('.app-file').forEach(function(input) {
input.addEventListener('change', function(e) {
// my code for displaying image
})
}
Related
function getId(e){
var xid = e.target.id;
console.log(xid);
}
<form onclick="getId(event)">
<label for="name" id="I am an Span">Nombre</label><br>
<input type="text" name="name" id="tbx_nombre"> <br>
<span id="nombre"></span> <br>
</form>
<div id="result"></div>
When the user click on a texbox the function gets the id of the element, then the deleteSpan method is call with the splitted id of the textbox which is now the id of the span to be changed to an emply string.
I get this error Cannot set property 'onclick' of null at getId
<form onclick="getId(event)">
<input type="text" name="name" id="tbx_name"><br>
<span id="name"></span>
...MORE INPUTS AND SPAN TAGS...
</form>
JS
function getId(e){
var xid = e.target.id; // => tbx_name
var spanId = xid.split("_").pop(); // =>name
document.getElementById(xid).onclick = function(){deleteSpan(spanId)};
}
function deleteSpan(spanId){
document.getElementById(spanId).innerHTML = "";
}
You are getting that error because when you try to set the click handler on the span by ID, you don't currently have the correct ID. It's null, because the click target is currently the form (which doesn't have an ID) instead of the input.
As others mentioned, the click event listener should be attached to the input.
But you also don't need to set a separate click handler within getId--you can just call deleteSpan in the getId function. In fact, if you set it inside another handler like you have, it won't work the first time (unless that's your desired outcome).
function getId(e){
var xid = e.target.id; // => tbx_name
var spanId = xid.split("_").pop(); // =>name
deleteSpan(spanId);
}
function deleteSpan(spanId){
document.getElementById(spanId).innerHTML = "";
}
<form>
<input onclick="getId(event)" type="text" name="name" id="tbx_name"><br>
<span id="name">Span</span>
</form>
onclick attribute event handler should be at input instead of form
<form>
<input type="text" name="name" id="tbx_name" onclick="getId(event)"><br>
<span id="name"></span>
</form>
or even better, use addEventListener for the inputs which have id format as tbx_{{value}}
var allInputs = document.querySelectorAll("input[id^='tbx_']");
allInputs.forEach( s => s.addEventListener( "click", e => getId ));
You can invoke above code when the form has loaded (at document load or window load).
You have to set the attribute onclick in input instead of form to get the expected id. Otherwise you have to check if the target node is INPUT or not:
function getId(e){
if(e.target.nodeName == 'INPUT'){
var xid = e.target.id; // => tbx_name
var spanId = xid.split("_").pop(); // =>name
deleteSpan(spanId);
}
}
function deleteSpan(spanId){
document.getElementById(spanId).innerHTML = "";
}
<form onclick="getId(event)">
<input type="text" name="name" id="tbx_name"><br>
<span id="name">Span</span>
</form>
I have to copy the shipping name and zip in the billing name and zip if the checkbox is checked and keep billing name and zip empty if checkbox is unchecked.
Following is my JavaScript code:
function billingFunction(){
if(document.getElementById('same').checked==true){
document.getElementById("billingName").value = document.getElementById("shippingName").value;
document.getElementById("billingZip").value = document.getElementById("shippingZip").value;
}
else{
document.getElementById("billingZip").value = '';
document.getElementById("billingName").value = '';
}
}
same is the id of the checkbox.
What is wrong with this code? I can't use jQuery and I have to use the id attribute to access the HTML.
Your javascript looks good, so that leaves me to assume the problem lies with how you are triggering the billingFunction() function.
I recommend doing something like so:
//use your same billingFunction
function billingFunction(){
...
}
/*
Once the document is ready, attach an event listener to the checkbox
which fires the function when the checkbox is changed
*/
window.onload = function() {
document.getElementById('same').addEventListener('change', billingFunction);
}
This wiats for the page to be reday before attaching an eventListener to your checkbox. When the checkboxes value is changed (checked/unchecked), it triggers the billingFunction.
Your code is correct. Just call the billingFunction() on click of the checkbox.
function billingFunction(){
if(document.getElementById('same').checked==true){
document.getElementById("billingName").value = document.getElementById("shippingName").value;
document.getElementById("billingZip").value = document.getElementById("shippingZip").value;
}
else{
document.getElementById("billingZip").value = '';
document.getElementById("billingName").value = '';
}
}
shippingName: <input type='text' id='shippingName' /><br />
shippingZip: <input type='text' id='shippingZip' /><br />
<br />
Copy Same? <input type="checkbox" id='same' onclick='billingFunction()'/>I have a car
<br /><br />
billingName: <input type='text' id='billingName' /><br />
billingZip: <input type='text' id='billingZip' /><br />
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've got a page with a bunch of little forms. I want to dynamically assign a hotkey to submit each form. The code looks like:
HTML
<form:form id="formCtrlr" action="review.html">
<input name="id" type="hidden" value=""/>
</form:form>
<form:form id="formCtrls" action="save.html">
<input name="id" type="hidden" value=""/>
</form:form>
...lots of other little forms like this each with a unique id related to the hotkey...
jQuery
$('[id^="formCtrl"]').each(function() {
var me = $(this);
var myId = me.attr("id");
var keyBinding = myId.replace("form", "").replace(/(.{4})/g,"$1+");
$(document).bind('keydown', keyBinding, function (evt){
evt.stopPropagation();
evt.preventDefault();
$("#"+myId).submit();
return false;
});
});
Simple right? But there are also several text inputs on the page and if the user is typing in one of those fields and hits one of the hotkeys, the corresponding form is not submitted and in fact if the hotkey matches something for the browser like Ctrl-s the save dialog is shown. Any idea how I can stop this from happening?
I would guess that the hotkey event is being captured by the input and then blocked. Try adding the event to the inputs directly, instead of to the form.
To disable not only control-s but others, I found this:
function disableCtrlModifer(evt)
{
var disabled = {s:0};
var ctrlMod = (window.event)? window.event.ctrlKey : evt.ctrlKey;
var key = (window.event)? window.event.keyCode : evt.which;
key = String.fromCharCode(key).toLowerCase();
return (ctrlMod && (key in disabled))? false : true;
}
Taken from here:
http://www.arraystudio.com/as-workshop/disable-ctrl-n-and-other-ctrl-key-combinations-in-javascript.html
You can modify it to suit your needs. Although I don't know what "keyBinding" is, here's how I would plug it into your code:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="Charts/js/jquery-1.6.2.js"></script>
<script type="text/javascript">
function disableCtrlModifer( evt )
{
var disabled = { s:0 }; // You can add more keys here :)
var ctrlMod = ( window.event ) ? window.event.ctrlKey : evt.ctrlKey;
var key = ( window.event ) ? window.event.keyCode : evt.which;
key = String.fromCharCode( key ).toLowerCase();
return ( ctrlMod && (key in disabled) ) ? false : true;
}
$( document ).ready(function()
{
$( "[id^='formCtrl']" ).each(function()
{
var me = $( this );
var myId = me.attr( "id" );
var keyBinding = myId.replace("form", "").replace( /(.{4})/g,"$1+" );
//$(document).bind( "keydown keypress keyup", disableCtrlModifer );
me.find( "input" ).each( function()
{
$( this ).bind( "keydown keypress keyup", keyBinding, disableCtrlKeyCombination );
});
});
});
</script>
</head>
<body>
<form id="formCtrl-123" method="get">
<input type="text" name="test1" value="" />
</form>
</body>
</html>
I am trying to attach a calendar field to a dynamically added html code.
Initially, the code shows 3 input fields (as shown in the "p_scents" div).
When the "Add Another Employer" is clicked, it should generate another 3 inputs( as the ones above).
It is working fine for me to generate the first 2 fields (without the calendar field), but when I add the calendar field, it is not working.
<body>
<h2>Add Another Employer</h2>
<div id="p_scents">
<p>
<label>Employer Name</label><input class="dynamic" type="text" name="employern" id="employern" />
<label>Job Title</label><input class="dynamic" type="text" name="jtitle" id="jtitle" />
<label>Start Date </label>
<input type="text" name="startd" class="textfield" />
<script language="JavaScript">
new tcal ({
// form name
'formname': 'form',
// input name
'controlname': 'startd'
});
</script>
</p>
</div>
<script type="text/javascript">
$(function() {
var scntDiv = $('#p_scents');
var i = $('#p_scents p').size() + 1;
$('#addScnt').live('click', function() {
if( i <= 10 ) {
$('<p><label>Employer Name</label><input class="dynamic" type="text" name="employern' + i +'" id="employern" /><label>Job Title</label><input class="dynamic" type="text" name="jtitle' + i +'" id="jtitle" /><label>Start Date </label>
<input type="text" name="startd' + i +'" class="textfield" />
<script language="JavaScript">
new tcal ({'formname': 'form','controlname': 'startd' + i +''});</script>Remove</p>').appendTo(scntDiv);
i++;
return false;}
else{
alert('Maximum Reached!');
}
});
$('#remScnt').live('click', function() {
if( i > 2 ) {
$(this).parents('p').remove();
i--;
}
return false;
});
});
</script>
</body>
Sorry, but there is lot of stuff wrong/not good in your code. I'm trying to give some suggestions how to improve this, but first, what's wrong:
IDs have to be unique. In your code, you give multiple elements the same ID. Especially the remove link will not work.
Strings cannot span multiple lines in JavaScript.
Don't add such a bunch of HTML as string. You have a quotation error in this string.
Don't add <script> tags this way (at least here it is not necessary).
My suggestions:
Remove the script tag from the HTML, you don't need it and remove the IDs of the input elements
<h2>Add Another Employer</h2>
<div id="p_scents">
<p>
<label>Employer Name</label><input class="dynamic" type="text" name="employern" />
<label>Job Title</label><input class="dynamic" type="text" name="jtitle" />
<label>Start Date </label>
<input type="text" name="startd" class="textfield" />
</p>
</div>
You also don't need to use live [docs] for the click event handler on #addScnt. Just use click [docs]:
$('#addScnt').click(...
You only need live for elements you add dynamically.
Now the most important thing: How you add new fields.
You can do this very easily, by cloning the existing p element. The only thing you have to remember is to change the name of input fields (add the i) and call the tcal function:
$('#addScnt').click(function() {
if (i <= 10) {
$('#p_scents p:first').clone() // clone
.find('input').attr('name', function(index, value) { // change name
return value + i;
}).end()
.append('Remove') // add remove link
.appendTo(scntDiv);
// init calender
new tcal({
formname: 'form',
controlname: 'startd'+i
});
i++;
return false;
}
else {
alert('Maximum Reached!');
}
});
Reference: clone [docs], attr [docs]
Note that the remove link has a class, not an id. For this link it is better to use delegate [docs]:
$('#p_scents').delegate('.remScnt', 'click', function() {
if (i > 2) {
$(this).closest('p').remove();
i--;
}
return false;
});
Also note that I use closest [docs] here, which only gives the closest p element. If you use parents, you will remove all ancestor p elements and that might result in removing a lot more than you intended.
Last but not least, you also have to make a call to
new tcal ({
// form name
'formname': 'form',
// input name
'controlname': 'startd'
});
because we removed the script tag.
Here is a working demo of all that: http://jsfiddle.net/fkling/ygSn9/ (with empty tcal function).