I currently have the below for uploading images, but I also want to add a restriction that prevents users from uploading any file less than 50px in height. Is this possible?
file_field "form", "image", accept: 'image/png,image/gif,image/jpeg'
Try this one, Maybe this will help you: Reference
validate :validate_image_size
def validate_image_size
image = MiniMagick::Image.open(picture.path)
unless image[:height] < 50
errors.add :image, "should be 50px minimum!"
end
end
This will work for you if you use MiniMagick.
Is this possible?
Yes it's possible, but you need some javascript to do it on the client side, here is am example. Change that html input to the rails helper.
html
<input id="image" name="img" type="file" />
/* */
<img src="#" alt="This image is going to load" id="image_on_load" />
<p id='image_info_width'> </p>
<p id='image_info_heigth'> </p>
the js code:
// The upload listner function
$('#image').on('change', function() {
var img = document.getElementById('image_on_load');
var reader = new FileReader();
// add uploaded image to the img element
reader.onloadend = function() {
$('#image_on_load').prop('src', reader.result)
}
reader.readAsDataURL(this.files[0]);
// listen onload event and get dimension
img.onload = function(image) {
$('#image_info_width').text('Width: ' + image.target.width)
$('#image_info_heigth').text('Height: ' + image.target.height)
// here you able to upload or reject
// file accourding to dimension
}
});
In this example image was uploaded and the you able to get the width and the height.
JSFIDDLE
Read how the works with JS in Rails
7 Must-Reads about JavaScript with Ruby on Rails
Related
I have two js functions for the one same input (type="file"). They work by onclick attribute however when i click just for the second function, first one still works.. (Maybe beacuse of input changes..) I tried "return" or "break" to terminate but they didnt help. How can i terminate the function if it has finished its job.
■ HTML tags;
<input id="File1" type="file" name="galeri[]" accept="image/*" hidden="">
<label id="Label1" class="uploadProductPic" data-no="1" for="File1" onclick="myFunction(this)"><i class="fas fa-plus"></i></label>
and if i added a new picture codes below will be creating by myFunction
<div id="Picture1" onmouseover="mouseOnPic(this)" onmouseout="mouseOutPic(this)" class="ilanPreview d-flex justify-content-center">
<img src="img/pgiysi/pgiysi-44-2761428725-1.png" class="d-block" id="imgPicture1">
<div class="ilanPreviewEdit" hidden="true" data-edit="1" onclick="myEdit(this)"><i class="fas fa-edit"></i><div class="ilanPreviewEEText">Düzenle</div></div>
<div class="ilanPreviewErase" hidden="false" onclick="myErase(this)"><i class="fa fa-trash-o"></i><div class="ilanPreviewEEText">Sil</div></div>
</div>
■ First function is; (Creates a preview of image for the selected file from input and creates a new add input type="file")
var i = 1;
function myFunction(identifier) {
i++
no = $(identifier).data('no');
var loader = function(e) {
//content goes here
//create a preview of image
//add a new input file
}
var fileInput = document.querySelector("#File"+editNo);
fileInput.addEventListener("change", loader);
};
■ Second function is; (Jjust for the changing picture. If user clicks on the change button - that created on preview image before, so this function changes the preview of image.
function myEdit(identifier) {
var editNo = $(identifier).data('edit');
document.getElementById('File'+editNo).click();
var editor = function(e) {
//content goes here
//change the preview of image
return false; //After changing picture stop here and dont step to the first function again...
}
var fileInput = document.querySelector("#File"+editNo);
fileInput.addEventListener("change", editor);
};
When I click to change the picture, yes it changes but at the same time function add a new preview (same with selected one for the change and adds a new input file so i have 2 previews and 2 add buttons)
I am building a application where user can write something inside input and it will be converted to a image they can download.
I use html2canvas.js for converting text to a downloadable image (this part works fine)
Currently it take the text inside <div id="talltweets"></div> and converts it to a image, but what I want is to be able to change the text/image when writing text inside input.
I tried to make a function called edValueKeyPress and it takes whats inside the input and adds it into <div id="talltweets"></div>, Now how can I take the text inside #talltweets and add it to <img id="textScreenshot"/> in realtime/when writing?
This is my code:
html2canvas(document.getElementById("talltweets"), {
onrendered: function(canvas) {
var screenshot = canvas.toDataURL("image/png");
document.getElementById("textScreenshot").setAttribute("src", screenshot);
}
});
function edValueKeyPress() {
var edValue = document.getElementById("body");
var s = edValue.value;
var lblValue = document.getElementById("talltweets");
lblValue.innerText = s;
}
<script src="http://files.codepedia.info/uploads/iScripts/html2canvas.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js" type="text/javascript"></script>
<input type="text" onKeyPress="edValueKeyPress()" onKeyUp="edValueKeyPress()" id="body">
<div id="talltweets"></div>
<!-- The PNG image will be added here-->
<div>
<img id="textScreenshot" />
</div>
Basically, you need to wrap that whole rendering step of the process into a function that can then be called with the keypress event. You're already on the right track - here's one way you could implement this (plus a few miscellaneous code improvements; also, I had to change the URL for html2canvas to pull from a different cdn, as the original one wasn't loading correctly from SO):
// If we store these, we only need to query the dom once, not on every update
var tallTweets = document.getElementById('talltweets');
var screenshotImg = document.getElementById('textScreenshot');
var textInput = document.getElementById('body');
// Note - it wouldn't surprise me if html2canvas has a specific API
// for doing this kind of update. Worth checking their documentation for.
function updateImage() {
html2canvas(tallTweets, {
onrendered: function(canvas) {
var screenshot = canvas.toDataURL("image/png");
screenshotImg.setAttribute("src", screenshot);
}
});
};
function edValueKeyPress() {
tallTweets.innerText = textInput.value || '';
updateImage();
}
updateImage();
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js" type="text/javascript"></script>
<input type="text" onKeyPress="edValueKeyPress()" onKeyUp="edValueKeyPress()" id="body" placeholder="Type something!">
<div id="talltweets"></div>
<!-- The PNG image will be added here-->
<div>
<img id="textScreenshot" alt="Generated screenshot" />
</div>
You could also make it even simpler by combining the two functions into one - IE, moving tallTweets.innerText = textInput.value into updateImage, and then binding the event listener to updateImage instead. But keeping them separated has its advantages, especially if you might want to reuse updateImage elsewhere.
I know there are other questions like this and I've tried following them I'm just not aware of what exactly I'm doing wrong. I've declared the pic variable as being linked to the image with the corresponding id of 'pic' and I've tried many different examples and trying to follow other questions like this but to no avail.
--- THE REAL QUESTION ----
I would like the image to change its src to another one that I have in my workspace with the click of a button.
HTML:
<img class="trans" id="pic" src="images/link_rouge.png" alt="" width="1000" height="333" />
JavaScript:
var pic = document.getElementById('pic');
function rouge() {
pic.src = "images/link_rouge.png";
}
function blue() {
pic.src = "images/link_blue.png";
}
I know the functions already work with the buttons because they are affecting some divs on the page that change color the only things not changing are the images.
The EventTarget.addEventListener() method registers the specified listener on the EventTarget it's called on.
Use addEventListener over button elements to attach click events and bind your handler functions to those events.
var pic = document.getElementById('pic');
function rouge() {
pic.src = "http://www.projectvictorycosplay.com/images/zelda/Links/3198_render_link.png";
}
function blue() {
pic.src = "http://bin.smwcentral.net/u/1944/Link%2BBlue%2BTP%2Bshrunk.png";
}
document.getElementById('btn1').addEventListener('click', rouge);
document.getElementById('btn2').addEventListener('click', blue);
img {
width: 200px;
}
<button id='btn1'>rouge</button>
<button id='btn2'>blue</button>
<br/>
<img class="trans" id="pic" src="http://www.projectvictorycosplay.com/images/zelda/Links/3198_render_link.png" alt="" width="1000" height="333" />
There's a chance your page has not loaded before pic is set equal to document.getElementById('pic');.
You can use something like jQuery's $(document).ready() function (or document.addEventListener("DOMContentLoaded", handler);) to ensure your page is fully loaded before assigning the pic variable.
$( document ).ready(function() {
var pic = document.getElementById('pic');
function rouge() {
pic.src = "images/link_rouge.png";
}
function blue() {
pic.src = "images/link_blue.png";
}
});
Note: You will need to pull the JQuery library into your project to use this method. See here.
Also, you can read this post to learn a little more about HTML/JavaScript and page loading.
I want to add a simple progress bar to this html with jquery, what is the most minimalistic way to do so? I just need a percent value and a progress bar.
<!DOCTYPE html>
<html>
<body>
<form action="basic.php" method="post" enctype="multipart/form-data">
Select file to upload:
<input type="file" name="file" id="file">
<input type="submit" value="Upload Image" name="submit">
</form>
</body>
</html>
I recently had a project which I was supposed to do the samething. As you probably did, I went through lots of plugins and I found dmUploader plugin particularly useful. It allows you fetching the image by drag and drop as well as input tag. The plugin is available HERE.
I have created a working example in CODEPEN, which I think is the best way to learn how to use this plugin. As you might notice, lines of jQuery code from 1 through 290 are just the plugin itself. I had to paste it there since the plugin does not have CDN link. Let's go through the codes:
HTML
<div class="SciSecPic">
<i class="fa fa-fw fa-picture-o"></i>
<label>
<span>Click to browse your picture</span>
<input type="file" title='Click to add Files' style="display:none;">
</label>
<div class="progress" style=" display:none;">
<div class="progress-bar progress-bar-striped active" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%;">
0%
</div>
</div>
</div>
You need a container div, called SciSecPic in this example, a label which contains span and input tags inside. Remember the input is hidden and your button is your span tag. This is just how this plugin works. Then you can have your progress bar, div with progress class, which in this case is a Bootstrap progress bar. It primarily is not displayed and only will be shown when uploading is in progress.
There is no special setting required for CSS so I will skip that part and refer you to the working example.
jQuery - Setting dmUploader
var readPic;
$(".SciSecPic").each(function () {
var self = $(this);
self.dmUploader({
//url: "/Something/ImageSaver",
url: "http://posttestserver.com/post.php?dir=ali",
dataType: "json",
allowedTypes: "image/*",
//extraData: {
//Name: self.data("name"),
//Id: ~~self.data("id")
//},
onInit: function () {
},
onNewFile: function (id, file) {
// showing progressbar
$(this).find(".progress").show(200);
/* preparing image for preview */
if (typeof FileReader !== "undefined") {
var reader = new FileReader();
reader.onload = function (e) {
readPic = e.target.result;
}
reader.readAsDataURL(file);
};
},
onUploadProgress: function (id, percent) {
$(this).find(".progress-bar").width(percent + "%").attr("aria-valuenow", percent).text(percent + "%");
},
onComplete: function () {
var thisEl = $(this);
addPic(thisEl, readPic);
// to fadeout and reset the progress bar at the end
setTimeout(function () {
thisEl.find(".progress").hide(200, function () {
thisEl.find(".progress-bar").width("0%").attr("aria-valuenow", 0).text("0%");
})
}, 300);
}
});
});
The variable is just a placeholder to store dataURL of the image to show later, when uploading is completed. What necessarily is happening that you have to change url to the .php file in PHP or controller if you use MVC. You also can add extra data using extraData method. dmUploader provides you with different callback functions. They are very much self explanatory. For instance, onUploadProgress is where you can get the upload percentage and show it in the progress bar, onNewFile is where you can show your progress bar and to read the image in dataURL format to show it on the go in your HTML markup, and most importantly onComplete where you can do whatever you want after upload is finished. This is where I called addPic function that I wrote to show the uploaded picture on top of the input box.
To keep this answer short, I will not explain or copy addPic function here. IT is very simple to understand by the way. That's pretty much it. Now you can have your dmUploader.
I know this question is a bit lengthy, but all of it is related so I am putting them here.I am trying this since past 2 days and i am very close of getting a solution.But something is wrong in css or scripting code can't understand where.
Following is the fiddle link I received as a response to my question click here to view
You can view my question here .
In order to test it I simply copied and pasted the code as given in the link and saved as demo.html. The contents are exactly this:
<body>
<header>
<h1>File API - FileReader (Text)</h1>
</header>
<article>
<label for="files">Select a file: </label>
<input id="files" type="file" onchange="readURL(this);" /><br>
div<div id="result"></div><br>
img<img src='' id="img"><br>
</article>
<script>
var readURL;
window.onload = function() {
//Check File API support
readURL = function(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = (function (tFile) {
return function (evt) {
//$('#img').attr('src', evt.target.result);
$('#result').css({'background-image': 'url('+evt.target.result+')','background-size': '200px 200px', 'background-repeat': 'no-repeat', 'background-position':'center'})
};
}(input.files[0]));
reader.readAsDataURL(input.files[0]);
}
}
}
</script>
</body>
Problem-1 is that image is not showing up.I simply can't understand why?
Problem-2:
Next with code posted in my previous question you can view here. I am at least able to set the background. But not resize the background image even if I use background-size after background or irrespective of the property-value pair in quotes or not.I have accepted the answer because fiddle was working,but problem is still unresolved. Is it that .css() function of jQuery is not taking multiple values well in that case this fiddle
must also not work. But its working.
Problem-3:
Another point of interest is switching the background image on-click multiple times like for eg. onclick of button for red background changes to red but onclick of upload image is uploaded and background becomes image. Now I have implemented both in single page.I can show you the code on request.Problem is once I set image as background I cannot simply change it back to color. Note the script of color change in the background is before image change script.
You can choose to answer any of the problem according to your expertise. Any help or links or research will be appreciated.
You need this style for it to work:
#result {
height: 300px;
width: 100%;
}
You also need to add query:
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
For your first problem..
I didn't dig why exactly your fiddle had an error of 'readURL' is undefined
but since you used jquery, I attached the event and called it with jquery
and now it works:
$(function () {
$("#files").on('change', readURL);
});
//Check File API support
function readURL() {
var input = this;
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = (function (tFile) {
return function (evt) {
//$('#img').attr('src', evt.target.result);
$('#result').css({ 'background-image': 'url(' + evt.target.result + ')', 'background-size': '200px 200px', 'background-repeat': 'no-repeat', 'background-position': 'center' })
};
}(input.files[0]));
reader.readAsDataURL(input.files[0]);
}
}
working demo