I have some code that works perfectly for grabbing and clicking a custom upload file button. The thing is I want it to duplicate this form 2 more times to have the user use 3 upload buttons in my overall form. So the user will be able to upload three files. My question is, how do I change my vanilla JavaScript so that instead of grabbing the one element, it grabs multiple elements? Do I use getElementsByClassName? And if I do how do I iterate through each form element individually to upload the file?
Upload form 1:
<input type="file" id="real-file" hidden="hidden" />
<button type="button" id="custom-button">CHOOSE A FILE</button>
<span id="custom-text">No file chosen, yet.</span>
Upload form 2:
<input type="file" id="real-file" hidden="hidden" />
<button type="button" id="custom-button">CHOOSE A FILE</button>
<span id="custom-text">No file chosen, yet.</span>
upload form 3:
<input type="file" id="real-file" hidden="hidden" />
<button type="button" id="custom-button">CHOOSE A FILE</button>
<span id="custom-text">No file chosen, yet.</span>
const realFileBtn = document.getElementById("real-file");
const customBtn = document.getElementById("custom-button");
const customTxt = document.getElementById("custom-text");
customBtn.addEventListener("click", function() {
realFileBtn.click();
});
realFileBtn.addEventListener("change", function() {
if (realFileBtn.value) {
customTxt.innerHTML = realFileBtn.value.match(
/[\/\\]([\w\d\s\.\-\(\)]+)$/
)[1];
} else {
customTxt.innerHTML = "No file chosen, yet.";
}
});
CSS
#custom-button {
padding: 10px;
color: white;
background-color: #009578;
border: 1px solid #000;
border-radius: 5px;
cursor: pointer;
}
#custom-button:hover {
background-color: #00b28f;
}
#custom-text {
margin-left: 10px;
font-family: sans-serif;
color: #aaa;
}
As suggested by #Taplar, you'll need to change IDs to classes and then somehow link the elements (I used data-file-input-id).
One of the possible solutions could be:
HTML:
<input type="file" class="real-file" id="first" hidden="hidden" />
<button type="button" class="custom-button" data-file-input-id="first" >CHOOSE A FILE</button>
<span class="custom-text" data-file-input-id="first">No file chosen, yet.</span>
<input type="file" class="real-file" id="second" hidden="hidden" />
<button type="button" class="custom-button" data-file-input-id="second">CHOOSE A FILE</button>
<span class="custom-text" data-file-input-id="second">No file chosen, yet.</span>
<input type="file" class="real-file" id="third" hidden="hidden" />
<button type="button" class="custom-button" data-file-input-id="third">CHOOSE A FILE</button>
<span class="custom-text" data-file-input-id="third">No file chosen, yet.</span>
JS:
// Grab only buttons with data-file-input-id attribute
const buttons = document.querySelectorAll("button[data-file-input-id]");
const fileInputs = document.querySelectorAll("input[type=file]");
Array.from(buttons).forEach(function (button) {
button.addEventListener("click", function () {
const correspondingInputId = button.getAttribute("data-file-input-id");
document.getElementById(correspondingInputId).click();
});
});
Array.from(fileInputs).forEach(function (fileInput) {
fileInput.addEventListener("change", function () {
const fileInputId = fileInput.id;
const correspondingTextField = document.querySelector(
'span[data-file-input-id="' + fileInputId + '"]'
);
if (fileInput.value) {
correspondingTextField.innerHTML = fileInput.value.match(
/[\/\\]([\w\d\s\.\-\(\)]+)$/
)[1];
} else {
correspondingTextField.innerHTML = "No file chosen, yet.";
}
});
});
CSS:
.custom-button {
padding: 10px;
color: white;
background-color: #009578;
border: 1px solid #000;
border-radius: 5px;
cursor: pointer;
}
.custom-button:hover {
background-color: #00b28f;
}
.custom-text {
margin-left: 10px;
font-family: sans-serif;
color: #aaa;
}
Related
I'm using the clone method to duplicate a form. I'm adding and removing the active
class on the buttons but, once I clone the form, the duplicate buttons no longer
function because they share the same class as the original. I want the buttons to still
function regardless how many times I clone it. I used jQuery and JavaScript, and I'm
still new to programming. Can you please give me some ideas as to how to solve this.
Thanks in advance fellow developers.
Here is my HTML Code:
<div class="column-bottom phone">
<p class="para_txt">Phone</p>
<div id="main-wrapper">
<div id="wrapper_1" class="parentClass">
<div class="basic_infor">
<p>Select the nature of phone:</p>
<div class="parent_btns">
<button class="func_btns btn_first_4 " >Private</button>
<button class="func_btns btn_second_4" >Work</button>
</div>
</div>
<div class="basic_infor">
<p>Select the type of phone:</p>
<div class="parent_btns">
<button class="func_btns btn_5">Mobile</button>
<button class="func_btns btn_6 ">Telephone</button>
<button class="func_btns btn_7 ">Fax</button>
<button class="func_btns btn_8">Extension</button>
</div>
</div>
<div class="txt_area">
<input type="textarea" placeholder="+27 85 223 5258">
<span onclick="delete_el();">x</span>
</div>
</div>
</div>
<div class="btn_add">
<button class="repl_btns phone_repl" onclick="duplicate();">Add additional</button>
<p>Display on foreman contact list?</p>
<input type="checkbox" id="input_field" name="Phone_contact">
</div>
</div>
Here is my jQuery and JavaScript Code. I selected the class for the first button and
added a active class to it while removing the active class for the second button. I did
the same for the rest of the buttons.
//private btn
$(".btn_first_4").click(function () {
$(this).addClass("is_active");
$(".btn_second_4").removeClass("is_active");
});
//work btn
$(".btn_second_4").click(function () {
$(this).addClass("is_active");
$(".btn_first_4").removeClass("is_active");
});
//Bottom 5 btns
$(".btn_5").click(function () {
$(this).addClass("is_active");
$(".btn_6,.btn_7,.btn_8").removeClass("is_active");
})
$(".btn_6").click(function () {
$(this).addClass("is_active");
$(".btn_5,.btn_7,.btn_8").removeClass("is_active");
})
$(".btn_7").click(function () {
$(this).addClass("is_active");
$(".btn_5,.btn_6,.btn_8").removeClass("is_active");
})
$(".btn_8").click(function () {
$(this).addClass("is_active");
$(".btn_5,.btn_6,.btn_7").removeClass("is_active");
})
/*
Cloning Functions....
I tried to set the id of my new clone to "wrapper_2", but it only works when i clone it
once. I wanted to change the class attribute this way but I realize it wont work as
well. Please advise. Thanks
*/
function duplicate(){
const wrapper = document.getElementById("wrapper_1");
const clone = wrapper.cloneNode(true);
clone.id = "wrapper_2";
const main_wrapper = document.getElementById("main-wrapper");
main_wrapper.appendChild(clone)
}
function delete_el() {
const del_el = document.getElementById("wrapper_2");
del_el.remove();
}
Problems
If you use .cloneNode() any event handlers bound to the original will not carry over to the clone. Fortunately you are using jQuery which has it's own method .clone(). It has the ability to clone and keep event handlers, $(selector).clone(true) to copy with events and $(selector).clone(true, true) for a deep copy with events.
Note: Using .clone() has the side-effect of producing elements with duplicate id attributes, which are supposed to be unique. Where possible, it is recommended to avoid cloning elements with this attribute or using class attributes as identifiers instead.
.clone()|jQuery API Documentation
Do not clone anything with an id, in fact you are using jQuery so don't use id at all. Convert every id to a class, it might feel like a lot of work but in the long run you'll be thankful you did.
Do not use inline event handlers
<button onclick="lame(this)">DON'T DO THIS</button>
This is especially important if you use jQuery which makes event handling incredibly easy to write and very versatile.
let count = 0;
$('output').val(++count);
$('.remove').hide();
$('.select button').on('click', function() {
const $old = $(this).parent().find('.active');
if (!$old.is(this)) {
$old.removeClass('active');
}
$(this).toggleClass('active');
});
$('.clear').on('click', function() {
$(this).parent().find('input').val('');
});
$('.remove').on('click', function() {
$(this).closest('.fields').remove();
let out = $.makeArray($('output'));
count = out.reduce((sum, cur, idx) => {
cur.value = idx + 1;
sum = idx + 1;
return sum;
}, 0);
});
$('.add').on('click', function() {
const $first = $('.fields').first();
const $copy = $first.clone(true, true);
$copy.insertAfter($('.fields').last());
$copy.find('output').val(++count);
$copy.find('.remove').show();
$copy.find('input').val('');
});
html {
font: 300 2ch/1.2 'Segoe UI'
}
fieldset {
min-width: fit-content
}
.fields {
margin-top: 1rem;
}
output {
font-weight: 900;
}
menu {
display: flex;
align-items: center;
margin: 0.5rem 0 0.25rem;
}
button,
input {
display: inline-block;
font: inherit;
font-size: 100%;
}
button {
cursor: pointer;
border: 1.5px ridge lightgrey;
}
.numbers {
display: flex;
align-items: center;
margin: 1rem 0 0.5rem -40px;
}
.clear {
border: 0;
font-size: 1.25rem;
line-height: 1.25;
}
.right {
justify-content: flex-end;
}
.left {
padding-left: 0;
}
.number-3 {
width: 9rem;
}
.number-1 {
width: 3rem;
}
[class^="number-"] {
font-family: Consolas
}
.clear {
border: 0;
background: transparent;
}
label+label {
margin-left: 6px;
}
button:first-of-type {
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
button:nth-of-type(2) {
border-radius: 0;
}
button:last-of-type {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
}
.active {
outline: 2px lightblue solid;
outline-offset: -2px;
}
#foreman {
transform: translate(0, 1.5px)
}
.btn.remove {
display: block;
border-radius: 4px;
float: right;
}
<form id='phone'>
<fieldset class='main'>
<legend>Add Phone Numbers</legend>
<section class='fields'>
<fieldset>
<legend>Phone Number <output value='1'></output></legend>
<button class='btn remove' type='button'>Remove</button>
<label>Phone number is used for:</label>
<menu class='purpose select'>
<button class="btn priv" type='button'>Private</button>
<button class="btn work" type='button'>Work</button>
</menu>
<label>Select the type of phone:</label>
<menu class='type select'>
<button class="btn mob" type='button'>Mobile</button>
<button class="btn tel" type='button'>Telephone</button>
<button class="btn fax" type='button'>Fax</button>
</menu>
<menu class='numbers'>
<form name='numbers'>
<label>Number:  </label>
<input name='phone' class='number-3' type="tel" placeholder="+27 85 223 5258" required>
<label>  Ext.  </label>
<input name='ext' class='number-1' type='number' placeholder='327'>
<button class='btn clear' type='button'>X</button>
</form>
</menu>
</fieldset>
</section>
<fieldset>
<menu class='right'>
<button class='btn cancel' type='button'>Cancel</button>
<button class='btn done'>Done</button>
<button class='btn add' type='button'>Add</button>
</menu>
</fieldset>
<footer>
<menu>
<input id='foreman' name="contact" type="checkbox">
<label for='foreman'>Display on foreman contact list?</label>
</menu>
</footer>
</fieldset>
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
When load page , JS add event click for elements ( elements were created)
When you clone new elements ( those do not add event click) and event click of you not working on those elements
You are using Jquery then i suggest you code same as below :
$(document).on('click', ".btn_first_4", function () {
$(this).addClass("is_active");
$(".btn_second_4").removeClass("is_active");
});
//work btn
$(document).on('click', ".btn_second_4", function () {
$(this).addClass("is_active");
$(".btn_first_4").removeClass("is_active");
});
//Bottom 5 btns
$(document).on('click', ".btn_5", function () {
$(this).addClass("is_active");
$(".btn_6,.btn_7,.btn_8").removeClass("is_active");
})
$(document).on('click', ".btn_6", function () {
$(this).addClass("is_active");
$(".btn_5,.btn_7,.btn_8").removeClass("is_active");
})
$(document).on('click', ".btn_7", function () {
$(this).addClass("is_active");
$(".btn_5,.btn_6,.btn_8").removeClass("is_active");
})
$(document).on('click', ".btn_8", function () {
$(this).addClass("is_active");
$(".btn_5,.btn_6,.btn_7").removeClass("is_active");
})
function duplicate(){
const wrapper = document.getElementById("wrapper_1");
const clone = wrapper.cloneNode(true);
clone.id = "wrapper_2";
const main_wrapper = document.getElementById("main-wrapper");
main_wrapper.appendChild(clone)
}
function delete_el() {
const del_el = document.getElementById("wrapper_2");
del_el.remove();
}
.is_active {
background-color: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="column-bottom phone">
<p class="para_txt">Phone</p>
<div id="main-wrapper">
<div id="wrapper_1" class="parentClass">
<div class="basic_infor">
<p>Select the nature of phone:</p>
<div class="parent_btns">
<button class="func_btns btn_first_4 " >Private</button>
<button class="func_btns btn_second_4" >Work</button>
</div>
</div>
<div class="basic_infor">
<p>Select the type of phone:</p>
<div class="parent_btns">
<button class="func_btns btn_5">Mobile</button>
<button class="func_btns btn_6 ">Telephone</button>
<button class="func_btns btn_7 ">Fax</button>
<button class="func_btns btn_8">Extension</button>
</div>
</div>
<div class="txt_area">
<input type="textarea" placeholder="+27 85 223 5258">
<span onclick="delete_el();">x</span>
</div>
</div>
</div>
<div class="btn_add">
<button class="repl_btns phone_repl" onclick="duplicate();">Add additional</button>
<p>Display on foreman contact list?</p>
<input type="checkbox" id="input_field" name="Phone_contact">
</div>
</div>
I have the following program (using skulpt) which generates python output in the browser on hitting "run". The output code is in the "pre" tags. I have tried various different things to apply the CSS to the executed output, but it isn't working.
This is my css
<style>
.running {
border: 20px outset black ;
background-color: black;
text-align: center;
p: color:white;
pre
{
white-space: pre-wrap !important;
}
}
</style>
This is the HTML part of the code.
<h3>Heading here</h3>
<form>
<textarea id="yourcode" cols="40" rows="10">
print("Hello World")
</textarea><br />
<button type="button" onclick="runit()">Run</button>
<button type="button" onclick="clearit()">Clear</button>
<button type="button" onclick="clearit()">--X--</button>
<button type="button" onclick="clearit()">--Y--</button>
<button type="button" onclick="clearit()">--Z--</button>
</form>
<br>
<br>
<br>
<div class="running">
<pre id="output" ></pre>
<!-- If you want turtle graphics include a canvas -->
<div id="mycanvas">
</div>
I assume it is this that is responsible for generating the output code:
<pre id="output" ></pre>
This is the javascript functionality (for reference) that produces the output code
<body>
<center>
<script type="text/javascript">
// output functions are configurable. This one just appends some text
// to a pre element.
function outf(text) {
var mypre = document.getElementById("output");
mypre.innerHTML = mypre.innerHTML + text;
}
function builtinRead(x) {
if (Sk.builtinFiles === undefined || Sk.builtinFiles["files"][x] === undefined)
throw "File not found: '" + x + "'";
return Sk.builtinFiles["files"][x];
}
// Here's everything you need to run a python program in skulpt
// grab the code from your textarea
// get a reference to your pre element for output
// configure the output function
// call Sk.importMainWithBody()
function runit() {
var prog = document.getElementById("yourcode").value;
var mypre = document.getElementById("output");
mypre.innerHTML = '';
Sk.pre = "output";
Sk.configure({output:outf, read:builtinRead});
(Sk.TurtleGraphics || (Sk.TurtleGraphics = {})).target = 'mycanvas';
var myPromise = Sk.misceval.asyncToPromise(function() {
return Sk.importMainWithBody("<stdin>", false, prog, true);
});
myPromise.then(function(mod) {
console.log('success');
},
function(err) {
console.log(err.toString());
});
}
function clearit(){
document.getElementById('yourcode').value = 'Your awesome code here';
document.getElementById('output').innerHTML = '';
}
</script>
Question: How do I format the code such that the background is black (this works) but the output code on pressing "run" is WHITE.
I don't know if it is due to missing out an ID - I notice the pre tags in the HTML have an id or incorrect use of the tags in the css. An explanation along with a solution (code) would be appreciated.
Other things I have tried in the CSS: (doesn't work either)
<style>
.running {
border: 20px outset black ;
background-color: black;
text-align: center;
p: color:white;
pre {
color:white;
display: block;
font-family: monospace;
white-space: pre;
margin: 1em 0;
}
}
</style>
It seems p: color: white; is invalid css, since p is an element not a style property. Instead, this line should be just color: white;.
Example snippet below:
.running {
border: 20px outset black;
background-color: black;
text-align: center;
color:white;
pre {
white-space: pre-wrap !important;
}
}
<h3>Heading here</h3>
<form>
<textarea id="yourcode" cols="40" rows="10">
print("Hello World")
</textarea><br />
<button type="button" onclick="runit()">Run</button>
<button type="button" onclick="clearit()">Clear</button>
<button type="button" onclick="clearit()">--X--</button>
<button type="button" onclick="clearit()">--Y--</button>
<button type="button" onclick="clearit()">--Z--</button>
</form>
<br>
<br>
<br>
<div class="running">
<pre id="output">Test output should be white!</pre>
<!-- If you want turtle graphics include a canvas -->
<div id="mycanvas">
</div>
I have a program for a makeshift task list that I am working on that should allow a user to enter more than one task by separating the tasks with a comma. I am not sure how I would write a portion of code to allow this function. I am trying to also make the lists themselves separate so if a user needed to delete a task, all the tasks would not be deleted too.
"use strict";
var $ = function(id) { return document.getElementById(id); };
var tasks = [];
var displayTaskList = function() {
var list = "";
// if there are no tasks in tasks array, check storage
if (tasks.length === 0) {
// get tasks from storage or empty string if nothing in storage
var storage = localStorage.getItem("tasks") || "";
// if not empty, convert to array and store in global tasks variable
if (storage.length > 0) { tasks = storage.split("|"); }
}
// if there are tasks in array, sort and create tasks string
if (tasks.length > 0) {
tasks.sort();
list = tasks.join("\n");
}
// display tasks string and set focus on task text box
$("task_list").value = list;
$("task").focus();
};
var addToTaskList = function() {
var task = $("task");
if (task.value === "") {
alert("Please enter a task.");
} else {
// add task to array and local storage
tasks.push(task.value);
localStorage.tasks = tasks.join("|");
// clear task text box and re-display tasks
task.value = "";
displayTaskList();
}
};
var clearTaskList = function() {
tasks.length = 0;
localStorage.tasks = "";
$("task_list").value = "";
$("task").focus();
};
window.onload = function() {
$("add_task").onclick = addToTaskList;
$("clear_tasks").onclick = clearTaskList;
displayTaskList();
};
body {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 100%;
background-color: white;
width: 700px;
margin: 0 auto;
border: 3px solid blue;
padding: 0 2em 1em;
}
h1 {
font-size: 150%;
color: blue;
margin-bottom: .5em;
}
label {
float: left;
width: 8em;
}
input {
width: 22em;
margin-right: 1em;
margin-bottom: 1em;
}
#tasks {
margin-top: 0;
float: right;
}
<!DOCTYPE html>
<html>
<head>
<title>Ch09 Task Manager</title>
<link type="text/css" rel="stylesheet" href="task_list.css">
<script type="text/javascript" src="task_list.js"></script>
</head>
<body>
<main>
<h1>Task Manager</h1>
<div id="tasks">
<span id="name"> </span>Tasks<br>
<textarea id="task_list" rows="8" cols="50"></textarea>
</div>
<label for="task">Task</label><br>
<input type="text" name="task" id="task"><br>
<input type="button" name="add_task" id="add_task" value="Add Task">
<input type="button" name="clear_tasks" id="clear_tasks" value="Clear Tasks"><br>
<input type="button" name="delete_task" id="delete_task" value="Delete Task">
<input type="button" name="toggle_sort" id="toggle_sort" value="Toggle Sort"><br>
<input type="button" name="set_name" id="set_name" value="Set Name">
<input type="button" name="filter_tasks" id="filter_tasks" value="Filter Tasks"><br>
</main>
</body>
</html>
I found a lot of other stuff that needed fixing, so I did (mostly having to do with how you use jQuery). Works for me locally. Snippet runner doesn't want to do some of this stuff - sorry! Don't know about that.
var tasks = [];
var displayTaskList = function() {
var list = "";
if (tasks.length === 0) { // if there are no tasks in tasks array, check storage
var storage = localStorage.getItem("tasks") || ""; // get tasks from storage or empty string if nothing in storage
if (storage.length > 0) {
tasks = storage.split("|");
} // if not empty, convert to array and store in global tasks variable
}
if (tasks.length > 0) { // if there are tasks in array, sort and create tasks string
tasks.sort();
list = tasks.join("\n");
}
$("#task_list").val(list); // display tasks string and set focus on task text box
$("#task").focus();
};
var addToTaskList = function() {
var task = $("#task").val();
console.log(`entering addtotask list with task value = ${task}`);
if (task === "") {
alert("Please enter a task.");
} else {
if (task.indexOf(',') === -1) {
tasks.push(task); // add task to array and local storage
} else {
const split = task.split(','); // 2 lines for readability
split.forEach(atask => {
tasks.push(atask);
});
}
localStorage.tasks = tasks.join("|");
$("#task").val(""); // clear task text box and re-display tasks
displayTaskList();
}
};
var clearTaskList = function() {
tasks.length = 0;
localStorage.tasks = "";
$("#task_list").val("");
$("#task").focus();
};
window.onload = function() {
$("#add_task").on('click', function() {
addToTaskList();
});
$("#clear_tasks").on('click', function() {
clearTaskList();
});
displayTaskList();
};
body {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 100%;
background-color: white;
width: 800px;
margin: 0 auto;
border: 3px solid blue;
padding: 0 2em 1em;
}
h1 {
font-size: 150%;
color: blue;
margin-bottom: .5em;
}
label {
float: left;
width: 8em;
}
input {
width: 22em;
margin-right: 1em;
margin-bottom: 1em;
}
#tasks {
margin-top: 0;
float: right;
}
<body>
<main>
<h1>Task Manager</h1>
<div id="tasks">
<span id="name"> </span>Tasks<br>
<textarea id="task_list" rows="8" cols="50"></textarea>
</div>
<label for="task">Task</label><br>
<input type="text" name="task" id="task"><br>
<input type="button" name="add_task" id="add_task" value="Add Task">
<input type="button" name="clear_tasks" id="clear_tasks" value="Clear Tasks"><br>
<input type="button" name="delete_task" id="delete_task" value="Delete Task">
<input type="button" name="toggle_sort" id="toggle_sort" value="Toggle Sort"><br>
<input type="button" name="set_name" id="set_name" value="Set Name">
<input type="button" name="filter_tasks" id="filter_tasks" value="Filter Tasks"><br>
</main>
<script src="//code.jquery.com/jquery-3.4.1.min.js"></script>
</body>
I have created a form with an add and delete button :
<p-growl [(value)]="msgs"></p-growl>
<div class="center" appMcard>
<form [formGroup]="GroupRMPM_FG">
<div formArrayName="GroupId_Name" *ngFor="let control of GroupRMPM_FG.controls.GroupId_Name.controls; let i= index">
<input type="text" pInputText [formControl]="control.controls.Group_Id_Name"/>
<button pButton type="button" class="delete-btn " *ngIf="GroupRMPM_FG.controls.GroupId_Name.controls.length > 1" (click)="deleteGroup(i)" icon="fa-minus" >
</button>
<button *ngIf="GroupRMPM_FG.controls.GroupId_Name.controls.length == i+1" pButton type="button" (click)="addNewGroup()" icon="fa-plus formcontainer" class="add-btn formcontainer"></button>
</div>
</form>
</div>
CSS
.center {
width: 40%;
height : 100%;
min-height: 40vh;
margin:auto;
text-align: center;
vertical-align: center;
background-color: #F3F3F3;
padding: 20px;
}
input {
font-family: 'bnppSans';
}
.delete-btn {
background-color: #E61D00;
border-color: #E61D00;
}
.add-btn {
background-color: #24b3c7;
border-color: #24b3c7;
}
.delete-btn:hover {
background-color: #c61a01 !important;
border-color: #c61a01 !important;
}
Actually here's what I get
The problem is when I add new fields to the text-align: center in center class, it is not working as expected. I would want the input to be centered like the first field and the buttons get shifted to the right
Your CSS work perfect as it has to, you have to add dummy html element like button/div when there is no second button at right side.
<form [formGroup]="GroupRMPM_FG">
<div formArrayName="GroupId_Name" *ngFor="let control of GroupRMPM_FG.controls.GroupId_Name.controls; let i= index">
<input type="text" pInputText [formControl]="control.controls.Group_Id_Name"/>
<button pButton type="button" class="delete-btn " *ngIf="GroupRMPM_FG.controls.GroupId_Name.controls.length > 1" (click)="deleteGroup(i)" icon="fa-minus" >
</button>
<button *ngIf="GroupRMPM_FG.controls.GroupId_Name.controls.length == i+1" pButton type="button" (click)="addNewGroup()" icon="fa-plus formcontainer" class="add-btn formcontainer"></button>
<----add dummy element here---->
<button *ngIf="GroupRMPM_FG.controls.GroupId_Name.controls.length != i+1" pButton type="button" class="dummyElement"></button>
</div>
</form>
CSS:
.dummyElement,.dummyElement:hover{
background-color:transparent;
color:transparent;
border-color:transparent;
pointer-events: none;
}
Note: Anyway you have to hide new dummy element and set to default cursor.
Here is working DEMO of my above answer.
.center{
text-align:center;
width:100%;
}
.dummyButton{
background-color:transparent;
color:transparent;
border-color:transparent;
pointer-events: none;
}
<div class='center'>
<div>
<input type='text'><input type="button" value="click"><input type="button" value="click" class="dummyButton">
<br>
<input type='text'><input type="button" value="click"><input type="button" value="click" class="dummyButton">
<br>
<input type='text'><input type="button" value="click"><input type="button" value="click">
<br>
</div>
</div>
I'm trying to code a custom upload button. I've hidden the regular one and then put a div with image background over the top.
It works great but I want to fill the (disabled) input field below with the file name once the user selects a file but it's not working.
JavaScript:
document.getElementById("upload_button").onchange = function () {
document.getElementById("upload_file").value = this.value;
};
HTML:
<div id="Form_FileInput_Container"><input type="file" id="upload_button" /></div>
<input class="Form_Input" id="upload_file" placeholder="Choose File" disabled="disabled" />
CSS:
#Form_FileInput_Container { position: relative; width: 100px; height: 100px; background: #e5e5e5 url('path/to/upload/image/forms_upload.png') no-repeat; border: 1px solid #cccccc; }
#Form_FileInput_Container input { filter: alpha(opacity=0); opacity: 0; width: 100px; height: 100px; }
Any help is most appreciated :)
Make sure you attach your JavaScript after the elements exist.
<input id="foo" type="file" />
<input id="bar" type="text" placeholder="Choose File" disabled />
// after elements exist
var foo = document.getElementById('foo'),
bar = document.getElementById('bar');
foo.addEventListener('change', function () {
var slash = this.value.lastIndexOf('\\');
bar.value = this.value.slice(slash + 1);
});
DEMO
HTML:
<input type="file" id="upload_button" onchange="cutomButton()" />
JS:
function customButton() {
var z=document.getElementById("upload_button").value;
document.getElementById("upload_file").value = z;
alert(document.getElementById("upload_file").value);
}