How to link to specific row in google sheets from sidebar - html

I have a very large google sheet document that I am creating for work. I have written a short script to create a sidebar from a separate HTML file. The script is as follows:
function onOpen() {
SpreadsheetApp.getUi()
.createMenu('MaintainRegistry')
.addItem('GenerateContractTemplate', 'generateContractTemplate')
.addToUi();
SpreadsheetApp.getUi()
.createMenu('Sidebar').addItem('Open', 'openSidebar').addToUi();
SpreadsheetApp.getUi()
.createMenu('Sidebar').addItem('Open', 'openSidebar').addToUi();
}
The function is :
function openSidebar() {
var html = HtmlService.createHtmlOutputFromFile('index');
SpreadsheetApp.getUi().showSidebar(html);
}
And the simple HTML is:
<!DOCTYPE html>
<head>
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-
alpha.6/css/bootstrap.min.css" integrity="sha384-
rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ"
crossorigin="anonymous">
<style type = "text/css">
button {
width: 150px;
margin: 0 auto;
}
#header {
background-color: rgb(47,129,183);
margin-bottom: 20px;
padding: 5px;
color: white;
text-align: center;
}
</style>
</head>
<body>
<div id="header">
<h1> Index </h1>
</div>
<div class="text-center">
<p>
<button type="button" class="btn btn-primary">Hotel name</button>
</p>
<p>
<button type="button" class="btn btn-primary">Periods</button>
</p>
<p>
<button type="button" class="btn btn-primary">Contract template</button>
</p>
<p>
<button type="button" class="btn btn-primary">Non renewals</button>
</p>
</div>
</body>
</html>
Essentially this is just a simple sidebar and I want the buttons to take the user to a specific place in the spreadsheet. There are over 60 columns so if the user clicks on 'hotel name' I want it to lead them to for example, column AE etc...
How can this be done? I have no idea what to reference in the link and obviously don't want this to open a new page either - just skip straight to the right column...

Add these to your gs file. Change the sheet name and row and column of each yo where you want to position to.
function hotel(){
var ss=SpreadsheetApp.getActiveSpreadsheet()
var s=ss.getSheetByName("Sheet1")
var row=s.getActiveCell().getRow()
var column=12
s.getRange(row, column).activate()
}
function periods(){
var ss=SpreadsheetApp.getActiveSpreadsheet()
var s=ss.getSheetByName("Sheet1")
var row=s.getActiveCell().getRow()
var column=13
s.getRange(row, column).activate()
}
function contracttemplate(){
var ss=SpreadsheetApp.getActiveSpreadsheet()
var s=ss.getSheetByName("Sheet1")
var row=s.getActiveCell().getRow()
var column=14
s.getRange(row, column).activate()
}
function nonrenewals(){
var ss=SpreadsheetApp.getActiveSpreadsheet()
var s=ss.getSheetByName("Sheet1")
var row=s.getActiveCell().getRow()
var column=15
s.getRange(row, column).activate()
}
In the HTML file, I added a reference to jquery. I changed the buttons to have unique ids and added script yo handle the button clicks and call the new functions.
<!DOCTYPE html>
<html>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js">
</script>
<head>
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-
alpha.6/css/bootstrap.min.css" integrity="sha384-
rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ"
crossorigin="anonymous">
<style type = "text/css">
button {
width: 150px;
margin: 0 auto;
}
#header {
background-color: rgb(47,129,183);
margin-bottom: 20px;
padding: 5px;
color: white;
text-align: center;
}
</style>
</head>
<body>
<div id="header">
<h1> Index </h1>
</div>
<div class="text-center">
<p>
<input id="Button1" button type="button" class="btn btn-primary"
value="Hotel name">
</p>
<p>
<input id="Button2" button type="button" class="btn btn-primary"
value="Periods">
</p>
<p>
<input id="Button3" button type="button" class="btn btn-primary"
value="Contract template">
</p>
<p>
<input id="Button4" button type="button" class="btn btn-primary" value="Non
renewals">
</p>
</div>
</body>
<script>
$("#Button1").on('click',function(){
google.script.run.hotel()
google.script.host.editor.focus()
});
$("#Button2").on('click',function(){
google.script.run.periods()
google.script.host.editor.focus()
});
$("#Button3").on('click',function(){
google.script.run.contracttemplate()
google.script.host.editor.focus()
});
$("#Button4").on('click',function(){
google.script.run. nonrenewals()
google.script.host.editor.focus()
});
</script>
</html>

Related

Creating a list of items, assign them id and than make a option button with overlay with multiple options

I'm working on a list of items for my website.
I have a list of 5 items with a 'id'. When you click the button, an overlay must be shown with 2 buttons 'change to background to red' and than 'cancel'.
If you click the cancel, the specific 'div class="item"' with the specific id his background must become red.
But, the problem is I don't know how using jquery/javascript to know which button of the div what pressed (button of item id 1 or 2 or 3..)
And also when you click outside the buttons, the overlay must be removed.
Here's the code
$(document).ready(() => {
$('.options-btn').click(function ()
{
var id = $(this).parent().attr('id'); /* find <div class="item"> */
$('body').append('<div class="overlay"></div>');
var append = `
<div class="item-options-active">
<button class="feed-option-btn-number background-btn" tabindex="0">Background set to RED</button>
<button class="feed-option-btn-number cancel-btn" tabindex="0">Cancel</button>
</div>
`;
$(append).appendTo('.overlay');
});
$(document).click(function (e)
{
if (document.getElementsByClassName("overlay").length == 1)
{
if(document.getElementsByClassName("item-options-active").length == 1)
{
// this condition is not working when you click the specific button
if($(".background-btn").data('clicked'))
{
// how to get <div> of the button which was press to change the background??
$('.item').css('background', 'red');
}
}
}
});
})
body {
background: grey;
}
.item {
background: green;
border: 5px solid purple;
margin: 20px;
}
.item button {
margin-left: 10px;
}
.overlay {
position: fixed;
width: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0,0,0,.85);
z-index: 10000;
}
<body>
<div class="show-items">
<div class="item" id="1">
<button type="button" class="options-btn">check options</button>
</div>
<div class="item" id="2">
<button type="button" class="options-btn">check options</button>
</div>
<div class="item" id="3">
<button type="button" class="options-btn">check options</button>
</div>
<div class="item" id="4">
<button type="button" class="options-btn">check options</button>
</div>
<div class="item" id="5">
<button type="button" class="options-btn">check options</button>
</div>
</div>
</body>
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
If you rewrite the .option-btn click event to something like this and delete the document click event it should work:
$('.options-btn').click(function ()
{
var id = $(this).parent().attr('id'); /* find <div class="item"> */
var button = $(this);
$('body').append('<div class="overlay"></div>');
var append = `
<div class="item-options-active">
<button class="feed-option-btn-number background-btn" tabindex="0">Background set to RED</button>
<button class="feed-option-btn-number cancel-btn" tabindex="0">Cancel</button>
</div>
`;
$(append).appendTo('.overlay');
$('.overlay').on('click', function(){
$(this).remove();
}).find('.cancel-btn').on('click', function(){
$(this).closest('.overlay').remove();
});
$('.overlay').find('.background-btn').on('click', function(){
button.closest('.item').css('background', 'red');
$(this).closest('.overlay').remove();
});
});
Working fiddle: https://jsfiddle.net/qntupzj6/

How i can create a jquery script with var btn1 onclick change css

Hi I want to create several buttons that change the css how i can do this
and click it again to undo it
var btn = document.getElementById("btn");
var btn2 = document.getElementById("btn2");
var btn3 = document.getElementById("btn3");
<button id="btn">bold</button>
<button id="btn2">italic</button>
<button id="btn3">underline</button>
<div class="item-1"></div>
If you want to do it in a proper way then you need to use jquery toggleClass() method like below
$(document).ready(function(){
$("#btn").click(function(){
$(".item-1").toggleClass("red");
});
$("#btn2").click(function(){
$(".item-1").toggleClass("blue");
});
$("#btn3").click(function(){
$(".item-1").toggleClass("green");
});
});
.red
{
color:red;
}
.blue
{
color:blue;
}
.green
{
color:green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="btn">red</button>
<button id="btn2">blue</button>
<button id="btn3">Green</button>
<br>
<div class="item-1">color</div>
You can use classes for toggle(do-undo) properties.
Css:
.boldText{
font-weight:Bold;
}
var btn = document.getElementById("btn");
var btn2 = document.getElementById("btn2");
var btn3 = document.getElementById("btn3");
var txt = $('.item-1');
btn.onclick = function(){
txt.toggleClass('boldText')
}
.boldText{
font-weight:Bold;
}
<script src="https://code.jquery.com/jquery-3.5.0.min.js"></script>
<button id="btn">bold</button>
<button id="btn2">italic</button>
<button id="btn3">underline</button>
<div class="item-1">test Text</div>
You can also add italic and underline options.

How to get textbox value in Code.GS file from HTML page

I have a spreadsheet and am writing code to integrate with Twitter API. In my sheet, I have two files:
Code.gs
settingpage.html
I have some global variables on code.gs i.e CONSUMER_KEY,CONSUMER_SECRET. I want to set these two variables when the user enters a value into textbox and hits the save button.
Textboxes are placed under sidebar. Sidebar is generated from settingpage.html using (HtmlService.SandboxMode.IFRAME)
Let me know if am doing it wrong, or of any other way to set global variable value entered by user.
Code.gs
CONSUMER_KEY = "Your key value";
CONSUMER_SECRET = "Your key value";
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('BOT')
.addItem('Setting-config','fnShowSidebar')
.addItem('Start', 'StartCP')
.addSeparator()
.addItem('Stop', 'StopCP')
.addToUi();
}
function fnShowSidebar() {
var html = HtmlService.createHtmlOutputFromFile('settingpage')
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setTitle('Welcome to TwitterBot-RWT!')
.setWidth(300);
SpreadsheetApp.getUi() // Or DocumentApp or FormApp.
.showSidebar(html);
}
settingpage.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">
<style>
.centerAlign {
vertical-align: middle;
width:80%;
margin-top:10px;
}
.branding-below {
bottom: 56px;
top: 0;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
$("#btn_save").click(function(){
google.script.run.withSuccessHandler(onSuccess).fn_setCustomValue();
});
function onSuccess(){
// Logger.log("Success!");
}
</script>
</head>
<body>
<div class="block form-group">
<label for="city">CONSUMER_KEY</label>
<input id="txt_CONSUMER_KEY" type="text" value="" style="width: 150px;" />
</div>
<div class="block form-group">
<label for="city">CONSUMER_SECRET</label>
<input id="txt_CONSUMER_SECRET" type="text" value="" style="width: 150px;">
</div>
<div class="block">
<button id="btn_save" class="create">Save</button> <button>Cancel</button>
</div>
</body>
</html>
Edited:
HTML
<button id="btn_save" class="create">Save</button>
<button>Cancel</button>
</div>
JS:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
$(function() {
var buttonEl=document.getElementById("btn_save");
buttonEl.addEventListener("click", myFunction);
function myFunction() {
alert ("Hello World!");
var keyValue=document.getElementById("txt_CONSUMER_KEY").value;
var secretValue=document.getElementById("txt_CONSUMER_SECRET").value;
google.script.run.withSuccessHandler(onSuccess).fn_setCustomValue(keyValue,secretValue);
}
function onSuccess(){
Logger.log("Success!");
}
});
</script>
On button click i get this screen
When you run fn_setCustomValue you need to pass the values as an argument, you can do that with document.getItemById().
Something along the lines of:
google.script.run.withSuccessHandler(onSuccess).fn_setCustomValue(document.getElementById("txt_CONSUMER_KEY").value, document.getElementById("txt_CONSUMER_SECRET").value);
With fn_setCustomValue() within Code.gs being something along the lines of
function fn_setCustomValue(key, secret){
CONSUMER_KEY = key;
CONSUMER_SECRET = secret;
}

Links are not clickable?

As I'm designing my node.js application, I'm having trouble figuring out why my anchor links are not working/not clickable. The code itself was working fine before I designed the app. Is there a CSS property I need to configure to fix this? This is for the .player ul li links.
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<link href='http://fonts.googleapis.com/css?family=Bree+Serif' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="/style.css">
<link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Indie+Flower' rel='stylesheet' type='text/css'>
<script src="http://connect.soundcloud.com/sdk.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script src="https://cdn.socket.io/socket.io-1.2.0.js"></script>
<!-- <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css"> -->
<meta charset="UTF-8">
<title>Open Mic Chatroom</title>
</head>
<header>
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<!-- <a class="navbar-brand" href="#">
<img alt="Brand" src="...">
</a> -->
<h1>OpenMic</h1>
</div>
</div>
</nav>
</header>
<body>
<div class="container">
<div class="row">
<div class="musicians col-sm-3 col-md-3">
<!-- <div class="musicians col-sm-6 col-md-4"> -->
<!-- <div class="col-sm-6 col-md-4"> -->
<!-- <div class="thumbnail musicians-box"> -->
<!-- <img src="..." alt="..."> -->
<div class="caption">
<h2>Musicians Online</h2>
<p>
<div id="chatters">
</div>
</p>
<!-- <p>Button Button</p> -->
<!-- </div> -->
</div>
</div>
<div class="chatroom col-sm-8 col-md-8">
<!-- <div class="chatroom col-sm-6 col-md-4">
--><!-- <div class="col-sm-6 col-md-4">-->
<!-- <div class="thumbnail chatroom-box"> -->
<!-- <img src="..." alt="..."> -->
<div class="caption">
<h2>Messages</h2>
<div id="messagesContainer"></div>
<!-- </div> -->
</div>
<form action="" id="chat_form">
<input id="info" autocomplete="off" />
<input type="submit" value="Submit">
</form>
</div>
</div>
</div>
<!-- <h3>Messages</h3>
<div id="messagesContainer"></div>
<form action="" id="chat_form">
<input id="info" autocomplete="off" />
<input type="submit" value="Submit">
</form> -->
<!-- SoundCloud Recording Feature -->
<div class="row player">
<div class="soundcloud-player">
<ul>
<div id="player">
<!-- <button type="button" id="startRecording" class="btn btn-default btn-lg">
<span class="glyphicon glyphicon-record" aria-hidden="true"></span>
</button> -->
<li id="startRecording">Start Recording</li>
</div>
<!-- <button type="button" id="stopRecording" class="btn btn-default btn-lg">
<span class="glyphicon glyphicon-stop" aria-hidden="true"></span>
</button> -->
<li id="stopRecording">Stop Recording</li>
<!-- <button type="button" id="playBack" class="btn btn-default btn-lg">
<span class="glyphicon glyphicon-play" aria-hidden="true"></span>
</button> -->
<li id="playBack">Play Recorded Sound</li>
<!-- <button type="button" id="upload" class="btn btn-default btn-lg">
<span class="glyphicon glyphicon-open" aria-hidden="true"></span>
</button> -->
<li id="upload">Upload</li>
</ul>
<p class="status"></p>
<div class="audioplayer">
</div>
</div>
</div>
<!-- <script src="/socket.io/socket.io.js"></script> -->
</div>
<script>
$(document).ready(function() {
var trackUrl;
//establish connection
var socket = io.connect('http://localhost:3000');
$('#chat_form').on('submit', function (e) {
e.preventDefault();
var message = $('#info').val();
socket.emit('messages', message);
$('#info').val('');
});
socket.on('messages', function (data) {
console.log("new message received");
$('#messagesContainer').append(data);
$('#messagesContainer').append('<br>');
// insertMessage(data);
});
socket.on('add_chatter', function (name) {
var chatter = $('<li>' + name + '</li>').data('name', name);
$('#chatters').append(chatter);
});
// //Embed SoundCloud player in the chat
// socket.on('track', function (track) {
// console.log("new track", track);
// SC.oEmbed(track, {auto_play: true}, function (oEmbed) {
// console.log('oEmbed response: ' + oEmbed);
// });
// SC.stream(track, function (sound) {
// console.log("streaming", sound);
// sound.play();
// });
// // socket.on('remove chatter', function (name) {
// // $('#chatters li[data-name=]' + name + ']').remove();
// });
//SOUNDCLOUD RECORDING FEATURE
function updateTimer(ms) {
// update the timer text. Used when user is recording
$('.status').text(SC.Helper.millisecondsToHMS(ms));
}
//Connecting with SoundCloud
console.log("calling SoundCloud initialize");
SC.initialize({
client_id: "976d99c7318c9b11fdbb3f9968d79430",
redirect_uri: "http://localhost:3000/auth/soundcloud/callback"
});
SC.connect(function() {
SC.record({
start: function() {
window.setTimeout(function() {
SC.recordStop();
SC.recordUpload({
track: { title: 'This is my sound' }
});
}, 5000);
}
});
//Adds SoundCloud username to chat app
console.log("connected to SoundCloud");
SC.get('/me', function(me) {
console.log("me", me);
socket.emit('join', me.username);
});
// SC.get('/me/tracks', {}, function(tracks) {
// var myTracks = $("<div>");
// var heading = $("<h1>").text("Your tracks");
// var list = $("<ul>");
// tracks.forEach(function (single) {
// var listItem = $("<li>").text(single.permalink);
// listItem.on("click", function () {
// SC.oEmbed(single.permalink_url, {
// auto_play: true
// }, function(oEmbed) {
// console.log("oEmbed", oEmbed);
// $('.status').html(oEmbed.html);
// });
// });
// list.append(listItem);
// });
// $("body").append(myTracks.append(heading, list));
// });
// username = prompt("What is your username?");
// socket.emit('join', username);
// });
//Start recording link
$('#startRecording a').click(function (e) {
$('#startRecording').hide();
$('#stopRecording').show();
e.preventDefault();
SC.record({
progress: function(ms, avgPeak) {
updateTimer(ms);
}
});
});
//Stop Recording link
$('#stopRecording a').click(function (e) {
e.preventDefault();
$('#stopRecording').hide();
$('#playBack').show();
$('upload').show();
SC.recordStop();
});
//Playback recording link
$('#playBack a').click(function (e) {
e.preventDefault();
updateTimer(0);
SC.recordPlay({
progress: function (ms) {
updateTimer(ms);
}
});
});
//Uploaded SoundCloud Track after recorded
$('#upload').click(function (e) {
e.preventDefault();
SC.connect({
connected: function() {
console.log("CONNECTED");
$('.status').html("Uploading...");
SC.recordUpload({
track: {
title: 'My Recording',
sharing: 'public'
}
},
//When uploaded track, provides link user, but not everyone
function (track) {
// console.log("TRACK", track);
setTimeout(function () {
SC.oEmbed(track.permalink_url, {auto_play: true}, function(oEmbed) {
console.log("THIS IS oEMBED", oEmbed);
// console.log(oEmbed.html);
socket.emit('messages', oEmbed.html );
$('.status').html(oEmbed.html);
});
}, 8000);
// $('.status').html("Uploaded: <a href='" + track.permalink_url + "'>" + track.permalink_url + "</a>");
});
}
});
});
});
});
</script>
</body>
</html>
CSS:
body {
background: url('microphone.svg') no-repeat center center fixed;
background-position: 4% 100%;
}
h1, h2, h3 {
font-family: 'Bree Serif', serif;
}
body {
font-family: 'Open Sans', sans-serif;
}
h1 {
color: white;
padding-left: 5%;
padding-bottom: 5%;
letter-spacing: 4px;
}
.navbar-default {
background-color: #000000;
/* background-image: url('SoundWave.jpg');
background-position: center;
opacity: 0.8;*/
}
input, button, select, textarea {
line-height: 3;
}
.chatroom, .musicians {
border-style: solid;
border-radius: 6%;
border-color: black;
margin-left: 20px;
height: 500px;
background-color: #F2F2F2;
opacity: 0.8;
}
.musicians {
height: fixed;
}
input#info {
margin: 47% 1%;
width: 656px;
border-radius: 10%;
}
.visualSoundContainer__teaser {
height: 100px;
}
.row {
padding-top: 2%;
}
.player {
text-align: center;
}
.player ul li {
z-index: 30;
}
Comment the margin property. It is cover the section. you can check it on firebug while selecting the anchor element.
input#info {
/*margin: 47% 1%;*/
width: 656px;
border-radius: 10%;
}
Working link: http://jsfiddle.net/95yz0h63/
add css
a{
cursor:pointer;
}

Change default text in input type="file"?

I want to change default text on button that is "Choose File" when we use input="file".
How can I do this? Also as you can see in image button is on left side of text. How can I put it on right side of text?
Use the for attribute of label for input.
<div>
<label for="files" class="btn">Select Image</label>
<input id="files" style="visibility:hidden;" type="file">
</div>
Below is the code to fetch name of the uploaded file
$("#files").change(function() {
filename = this.files[0].name;
console.log(filename);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<label for="files" class="btn">Select Image</label>
<input id="files" style="visibility:hidden;" type="file">
</div>
I think this is what you want:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<button style="display:block;width:120px; height:30px;" onclick="document.getElementById('getFile').click()">Your text here</button>
<input type='file' id="getFile" style="display:none">
</body>
</html>
Each browser has it's own rendition of the control and as such you can't change either the text or the orientation of the control.
There are some "kind of" hacks you may want to try if you want an html/css solution rather than a Flash or silverlightsolution.
http://www.quirksmode.org/dom/inputfile.html
http://www.shauninman.com/archive/2007/09/10/styling_file_inputs_with_css_and_the_dom
Personally, because most users stick to their browser of choice, and therefore are probably used to seeing the control in the default rendition, they'd probably get confused if they saw something different (depending on the types of users you're dealing with).
This might help someone in the future, you can style the label for the input as you like and put anything you want inside it and hide the input with display none.
It works perfectly on cordova with iOS
<link href="https://cdnjs.cloudflare.com/ajax/libs/ratchet/2.0.2/css/ratchet.css" rel="stylesheet"/>
<label for="imageUpload" class="btn btn-primary btn-block btn-outlined">Seleccionar imagenes</label>
<input type="file" id="imageUpload" accept="image/*" style="display: none">
To achieve this, the default input button must be hidden using display:none CSS property and a new button element is added to replace it, so we can customize as we wish.
With Bootstrap
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
Optional text here
<label for="img" class="btn btn-info">Try me</label>
<input type="file" id="img" style="display:none">
With jQuery
In this case the onclick attribute added to the button element is indicating to JavaScript to click on the hidden default input button whenever the visible button is clicked.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Optional text here
<button style="cursor:pointer" onclick="$('#input').click()">Click me</button>
<input type="file" id="input" style="display:none">
Plain JavaScript with event listener
document.getElementById('btn').addEventListener('click', () => {
document.getElementById('input').click();
})
Optional text here
<button style="cursor:pointer" id="btn">Click me</button>
<input type="file" id="input" style="display:none">
It is not possible. Otherwise you may need to use Silverlight or Flash upload control.
$(document).ready(function () {
$('#choose-file').change(function () {
var i = $(this).prev('label').clone();
var file = $('#choose-file')[0].files[0].name;
$(this).prev('label').text(file);
});
});
.custom-file-upload{
background: #f7f7f7;
padding: 8px;
border: 1px solid #e3e3e3;
border-radius: 5px;
border: 1px solid #ccc;
display: inline-block;
padding: 6px 12px;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
can you try this
<label for="choose-file" class="custom-file-upload" id="choose-file-label">
Upload Document
</label>
<input name="uploadDocument" type="file" id="choose-file"
accept=".jpg,.jpeg,.pdf,doc,docx,application/msword,.png" style="display: none;" />
The trick is to trigger a click event on click of the file input and manage the visibility of the default input file via CSS. Here's how you can do it:
jQuery:
$(function() {
$("#labelfile").click(function() {
$("#imageupl").trigger('click');
});
})
css
.file {
position: absolute;
clip: rect(0px, 0px, 0px, 0px);
display: block;
}
.labelfile {
color: #333;
background-color: #fff;
display: inline-block;
margin-bottom: 0;
font-weight: 400;
text-align: center;
vertical-align: middle;
cursor: pointer;
background-image: none;
white-space: nowrap;
padding: 6px 8px;
font-size: 14px;
line-height: 1.42857143;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
HTML code:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div>
<input name="imageupl" type="file" id="imageupl" class="file" />
<label class="labelfile" id="labelfile"><i class="icon-download-alt"></i> Browse File</label>
</div>
I made a script and published it at GitHub: get selectFile.js
Easy to use, feel free to clone.
HTML
<input type=file hidden id=choose name=choose>
<input type=button onClick=getFile.simulate() value=getFile>
<label id=selected>Nothing selected</label>
JS
var getFile = new selectFile;
getFile.targets('choose','selected');
DEMO
jsfiddle.net/Thielicious/4oxmsy49/
Update 2017:
I have done research on how this could be achieved. And the best explanation/tutorial is here:
https://tympanus.net/codrops/2015/09/15/styling-customizing-file-inputs-smart-way/
I'll write summary here just in case it becomes unavailable. So you should have HTML:
<input type="file" name="file" id="file" class="inputfile" />
<label for="file">Choose a file</label>
Then hide the input with CSS:
.inputfile {
width: 0.1px;
height: 0.1px;
opacity: 0;
overflow: hidden;
position: absolute;
z-index: -1;}
Then style the label:
.inputfile + label {
font-size: 1.25em;
font-weight: 700;
color: white;
background-color: black;
display: inline-block;
}
Then optionally you can add JS to display the name of the file:
var inputs = document.querySelectorAll( '.inputfile' );
Array.prototype.forEach.call( inputs, function( input )
{
var label = input.nextElementSibling,
labelVal = label.innerHTML;
input.addEventListener( 'change', function( e )
{
var fileName = '';
if( this.files && this.files.length > 1 )
fileName = ( this.getAttribute( 'data-multiple-caption' ) || '' ).replace( '{count}', this.files.length );
else
fileName = e.target.value.split( '\\' ).pop();
if( fileName )
label.querySelector( 'span' ).innerHTML = fileName;
else
label.innerHTML = labelVal;
});
});
But really just read the tutorial and download the demo, it's really good.
This should work:
input.*className*::-webkit-file-upload-button {
*style content..*
}
Here is how its done with bootstrap, only u should put the original input somewhere...idk
in head and delete the < br > if you have it, because its only hidden and its taking space anyway :)
<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
</head>
<label for="file" button type="file" name="image" class="btn btn-secondary">Secondary</button> </label>
<input type="file" id="file" name="image" value="Prebrskaj" style="visibility:hidden;">
<footer>
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
</footer>
Using Bootstrap you can do this thing like the below code.
<!DOCTYPE html>
<html lang="en">
<head>
<style>
.btn-file {
position: relative;
overflow: hidden;
}
.btn-file input[type=file] {
position: absolute;
top: 0;
right: 0;
min-width: 100%;
min-height: 100%;
font-size: 100px;
text-align: right;
filter: alpha(opacity=0);
opacity: 0;
outline: none;
background: white;
cursor: inherit;
display: block;
}
</style>
<title>Bootstrap Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<span class="btn btn-file">Upload image from here<input type="file">
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<button style="display:block;width:120px; height:30px;" onclick="document.getElementById('getFile').click()">Your text here</button>
<input type='file' id="getFile" style="display:none">
</body>
</html>
I'd use a button to trigger the input:
<button onclick="document.getElementById('fileUpload').click()">Open from File...</button>
<input type="file" id="fileUpload" name="files" style="display:none" />
Quick and clean.
You can use this approach, it works even if a lot of files inputs.
const fileBlocks = document.querySelectorAll('.file-block')
const buttons = document.querySelectorAll('.btn-select-file')
;[...buttons].forEach(function (btn) {
btn.onclick = function () {
btn.parentElement.querySelector('input[type="file"]').click()
}
})
;[...fileBlocks].forEach(function (block) {
block.querySelector('input[type="file"]').onchange = function () {
const filename = this.files[0].name
block.querySelector('.btn-select-file').textContent = 'File selected: ' + filename
}
})
.btn-select-file {
border-radius: 20px;
}
input[type="file"] {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="file-block">
<button class="btn-select-file">Select Image 1</button>
<input type="file">
</div>
<br>
<div class="file-block">
<button class="btn-select-file">Select Image 2</button>
<input type="file">
</div>
My solution...
HTML :
<input type="file" id="uploadImages" style="display:none;" multiple>
<input type="button" id="callUploadImages" value="Select">
<input type="button" id="uploadImagesInfo" value="0 file(s)." disabled>
<input type="button" id="uploadProductImages" value="Upload">
Jquery:
$('#callUploadImages').click(function(){
$('#uploadImages').click();
});
$('#uploadImages').change(function(){
var uploadImages = $(this);
$('#uploadImagesInfo').val(uploadImages[0].files.length+" file(s).");
});
This is just evil :D
Ok so very simple pure css way of creating your custom input file.
Use labels, but as you know from previous answers, label doesn't invoke onclick
function in firefox, may be a bug but doesn't matter with the following.
<label for="file" class="custom-file-input"><input type="file" name="file" class="custom-file-input"></input></label>
What you do is style the label to look how you want it to
.custom-file-input {
color: transparent;/* This is to take away the browser text for file uploading*/
/* Carry on with the style you want */
background: url(../img/doc-o.png);
background-size: 100%;
position: absolute;
width: 200px;
height: 200px;
cursor: pointer;
top: 10%;
right: 15%;
}
now simply hide the actual input button, but you cant set it to to visability: hidden
So make in invisible by setting opacity: 0;
input.custom-file-input {
opacity: 0;
position: absolute;/*set position to be exactly over your input*/
left: 0;
top: 0;
}
now as you might have noticed i have the same class on my label as i do my input field, that is because i want the to both have the same styling, thus where ever you click on the label, you are actually clicking on the invisible input field.
I build a script that can be easier to do that.
For example:
<input data-com="fileBtn" placeholder="Select Image">
basically, my script is very similar to this link
Code
Pure javascript, no dependencies needed
<!-- bootstrap.min.css not necessary -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.0/css/bootstrap.min.css">
<input data-com="fileBtn" placeholder="Select Image"> <!-- com: components -->
<input data-com="fileBtn" placeholder="Select File">
<div class="mt-2">
<input id="build-by-myself" placeholder="Select Video" accept="video/mp4, video/webm">
<div>
<script>
// 👇 Test
(()=>{
window.onload = () =>{
// FileButton.className ="btn btn-danger"
FileButton.BuildAll() // auto build all data-com="fileBtn"
// or you can specify the target that you wanted.
new FileButton(document.getElementById("build-by-myself"), "btn btn-danger")
}
})()
// 👇 script begin
class FileButton {
static className = "btn btn-primary"
static BuildAll() {
document.querySelectorAll(`input[data-com="fileBtn"]`).forEach(input=>{
new FileButton(input, FileButton.className)
})
}
/**
* #param {HTMLInputElement} input
* #param {string} btnClsName
* */
constructor(input, btnClsName) {
input.style.display = "none" // [display is better than visibility](https://stackoverflow.com/a/48495293/9935654)
input.type = "file"
const frag = document.createRange().createContextualFragment(`<button class="${btnClsName}">${input.placeholder}</button>`)
const button = frag.querySelector(`button`)
input.parentNode.insertBefore(frag, input)
button.onclick = ()=>{
input.click()
}
input.addEventListener(`change`, (e)=>{
// create a textNode to show the file name.
const file = input.files[0]
if (file === undefined) {
return
}
const textNode = document.createTextNode(file.name)
if (button.textNode) { // create a new attribute to record previous data.
button.textNode.remove()
}
button.textNode = textNode
button.parentNode.insertBefore(textNode, input)
})
}
}
</script>
Reference
What is the difference between visibility:hidden and display:none?
data-*
Below is an example of a stylized upload button that will read an image, compress it, and download the resulting image. It works by hiding the actual input element, and then through some trickery we make it so that when you click on our fake file uploader it uses the actual input element to pop up the window for choosing a file. By using this method we get 100% control over how the file uploader looks since we are using our own element instead of styling the file upload menu. It also makes it easy to add drag and drop functionality in the future if we ever want to do that.
And then I actually created a series of blog posts about this file upload button.
'use strict'
var AMOUNT = 10
var WIDTH = 600
var HEIGHT = 400
var canvas = document.getElementById('canvas')
canvas.width = WIDTH
canvas.height = HEIGHT
//here's how I created the clickable area
//user clicks the clickable area > we send a click event
//to the file opener > the file opener clicks on the open
//file button > the open file dialogue pops up
function clickableAreaListener(e){
let clickEvent = new CustomEvent("click",{"from":"fileOpenerHandler"});
document.getElementById("fileOpener").dispatchEvent(clickEvent);
}
function fileOpenerListener(e) {
document.getElementById("file-btn").click();
e.preventDefault();
}
function fileSelectedListener(e){
readFiles(e.target.files);
}
document.getElementById('file-btn').addEventListener('change', fileSelectedListener);
document.getElementById("clickable-area").addEventListener('click', clickableAreaListener);
document.getElementById("fileOpener").addEventListener("click", fileOpenerListener);
function readFiles(files){
files = [].slice.call(files); //turning files into a normal array
for (var file of files){
var reader = new FileReader();
reader.onload = createOnLoadHandler(file);
reader.onerror = fileErrorHandler;
//there are also reader.onloadstart, reader.onprogress, and reader.onloadend handlers
reader.readAsDataURL(file);
}
}
function fileErrorHandler(e) {
switch(e.target.error.code) {
case e.target.error.NOT_FOUND_ERR:
throw 'Image not found';
break;
case e.target.error.NOT_READABLE_ERR:
throw 'Image is not readable';
break;
case e.target.error.ABORT_ERR:
break;
default:
throw 'An error occurred while reading the Image';
};
}
function createOnLoadHandler(file){
console.log('reading ' + file.name + ' of type ' + file.type) //file.type will be either image/jpeg or image/png
function onLoad(e){
var data = e.target.result
display(data);
var compressedData = compressCanvas(AMOUNT)
download(compressedData)
}
return onLoad
}
function display(data){
var img = document.createElement('img');
img.src = data;
var context = canvas.getContext('2d')
context.clearRect(0, 0, WIDTH, HEIGHT);
context.drawImage(img, 0, 0, WIDTH, HEIGHT);
}
function compressCanvas(){
return canvas.toDataURL('image/jpeg', AMOUNT / 100);
}
function download(data) {
function b64toBlob(b64Data, contentType, sliceSize) {
contentType = contentType || '';
sliceSize = sliceSize || 512;
var byteCharacters = atob(b64Data);
var byteArrays = [];
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
var slice = byteCharacters.slice(offset, offset + sliceSize);
var byteNumbers = new Array(slice.length);
for (var i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
var blob = new Blob(byteArrays, {type: contentType});
return blob;
}
var chromeApp = Boolean(chrome && chrome.permissions)
if (chromeApp){
chrome.fileSystem.chooseEntry({type:'openDirectory'}, function(entry) {
chrome.fileSystem.getWritableEntry(entry, function(entry) {
entry.getFile('example.jpg', {create:true}, function(entry) {
entry.createWriter(function(writer){
writer.write(b64toBlob(data.slice(23), 'image/jpg'))
})
})
})
})
} else {
let a = document.createElement("a");
a.href = data;
a.download = 'downloadExample.jpg'
document.body.appendChild(a)
a.click();
window.URL.revokeObjectURL(a.href);
a.remove()
}
}
.fileInput {
display: none;
position: absolute;
top: 0;
right: 0;
font-size: 100px;
}
#clickable-area{
background: #ccc;
width: 500px;
display: flex;
margin-bottom: 50px;
}
#clickable-area-text{
margin: auto;
}
.yellow-button {
cursor: pointer;
color: white;
background: #f1c40f;
height: 30px;
width: 120px;
padding: 30px;
font-size: 22px;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
}
<div id="clickable-area">
<a id='fileOpener'> </a>
<input type="file" class="fileInput" id="file-btn" accept="image/*" multiple/>
<div class="yellow-button"><span>Shrink Image</span>
</div><p id="clickable-area-text">( you can click anywhere in here ) </p>
</div>
<canvas id="canvas"></canvas>
Stack Overflow limitations seem to prevent the code snippet from actually compressing and downloading the file. The exact same code here shows that the full upload/compress/download process does actually work as intended.
With answers from this question, I fixed what many in coments said doesn¨t work for them which is that it's not showing how many files user chose.
<label for="uploadedFiles" class="btn btn-sm btn-outline-primary">Choose files</label>
<input type="file" name="postedFiles" id="uploadedFiles" multiple="multiple" hidden onchange="javascript:updateList()" />
<input class="btn btn-primary mt-2 btn-action" type="submit" value="Send" formmethod="post" formaction="#Url.Action("Create")" /><br />
<span id="selected-count">Selected files: 0</span>
<script>
updateList = function () {
var input = document.getElementById('uploadedFiles');//list of files user uploaded
var output = document.getElementById('selected-count');//element displaying count
output.innerHTML = 'Selected files: ' + input.files.length;
}
</script>
You can easily improve it by showing names of files instead or whatever you wish to do but all I wanted was to inform user that they have already picked files.
You can use a simple button and hide input file
using jquery and bootstrap :
HTML code
<button class="btn btn-white" id="btn-file" type="button"><i class="fa fa-file-pdf"></i> Anexar Documento</button>
<input name="shutdown" id="input-file" type="file" class="form-control hidden" accept="application/pdf, image/png, image/jpeg">
CSS :
.hidden{display:none}
JS :
$("#btn-file").click(function () {
$("#input-file").trigger('click');
});
$("#input-file").change(function () {
var file = $(this)[0].files[0].name;
$("#btn-file").html('<i class="fa fa-file-pdf"></i> ' + file);
});