Blazor Input File Component (File Upload) - asp.net-core

I am facing one small issue related to Blazor Input File component used for file upload.
Source - https://github.com/SteveSandersonMS/BlazorInputFile
Component Call -
<div class="form-control">
<InputFile OnChange="HandleFileSelected" />
</div>
I am successfully able to upload and delete files with this component. When I am uploading the file, the file name is shown beside component as shown in the screenshot below.
When I am deleting the file, the file gets deleted successfully but the file name is still shown beside component.
I want the file name should be removed once I delete the file. I tried few option but no luck example StateHasChanged();
Is it possible to just refresh the specific component ?? How ?
Could anyone please help to solve this issue. (I don't want to use javascript to achieve the solution)

An easy way to achieve this is simply using some Bootstrap 4.
<div class="custom-file" style="overflow: hidden; white-space: nowrap;" id="customFile">
<InputFile OnChange="OnInputFileChange" class="custom-file-input" id="exampleInputFile" aria-describedby="fileHelp" multiple></InputFile>
<label class="custom-file-label" for="exampleInputFile">
#InputFileMessage
</label>
</div>
and then in the code behind you'll have something like this
IBrowserFile File;
public string InputFileMessage = "Select a file...";
public void OnInputFileChange(InputFileChangeEventArgs e)
{
File=e.File;
InputFileMessage=e.File.Name;
}
And then whenever you want to reset the InputFile's label to its default value, you can just
InputFileMessage = "Select a file...";
Easy, isn't it? :)

I can show you what I did to hide the standard file input, and show a custom image and use custom labels for the file names, so you can hide it, change the text, etc.
I have a wrapper component to BlazorInputFile with an option to hide the standard input, and show a button or another image, and bind a variable to show the file name:
<FileUpload CustomSuccessMessage="Your file uploaded successfully." OnChange="OnFileUploaded"
OnReset="OnReset" ResetButtonClassName="localbutton"
ShowStatus="false" PartialGuidLength="10" MaxFileSize=#UploadLimit FilterByExtension="true"
ShowCustomButton="true" ButtonText="Start" CustomButtonClassName="startbutton"
AllowedExtensions=".jpg;.png;" ShowResetButton="false"
CustomExtensionMessage="Only .jpg and .png files are allowed."
AppendPartialGuid="true" InputFileClassName="customfileupload"
FileTooLargeMessage=#FileTooLargeMessage>
</FileUpload>
[Parameter] public EventCallback<string> OnReset { get; set; }
In my CSS I hide the input file like this, which doesn't work on Edge, working on that:
Here is the CustomButtonClassName, this uses my Start image:
CustomButtonClassName="startbutton"
.startbutton
{
position: fixed;
background-color: transparent;
border: 0px;
outline: none;
background-image: url('../images/StartButton.png');
background-repeat: no-repeat;
top: 36vh;
left: 50%;
width: 28%;
height: 28%;
background-size: 100%;
margin-left: -14%;
cursor: pointer;
}
.customfileupload
{
display: inline-block;
cursor: pointer;
height:48px;
min-height: 48px;
visibility: hidden;
display: none;
position: fixed;
left: 0px;
top: 0px;
}
input[type=file], /* FF, IE7+, chrome (except button) */
input[type=file]::-webkit-file-upload-button
{
cursor: pointer;
display: none;
visibility: hidden;
}
And the end result is my Upload button looks like this:
The full source code and a sample project is here if it might help anyone:
https://github.com/DataJuggler/BlazorFileUpload
Nuget: DataJuggler.Blazor.FileUpload

Thanks Chris Pratt & Data Juggler for you response..
I wrote small logic to toggle the upload file control..it will appear only when file needs to be uploaded and will disappear when upload is done successfully.
Simple function did the trick.
public void ToggleFileUpload()
{
if (showUploadFileComponent == true)
showUploadFileComponent = false;
else
showUploadFileComponent = true;
}
Thanks. Hope this helps if anyone facing same issue.

Related

Can I replace the button displayed by Blazor's InputFile component with another element?

I am using the element to upload image files to my hosted Blazor WASM site. The component renders a button with the words "Choose Files" on it.
I would like to replace this button with an image (or my own text, or anything else). I have tried using CSS to set a background image to the URL of an image I would want to use, and set the background-color of the button to "transparent", but this does not seem to change anything.
The source code for this component can be found here:
https://github.com/SteveSandersonMS/BlazorInputFile
I studied the code and found that this component is built using the standard Blazor input type.
<input type=file>
Steve shows a way to override the default functionality and style of the button using CSS.
Here is an example I created based on what I found:
<style>
.file-input-zone {
display: flex;
align-items: center;
justify-content: center;
background-color: blue;
color: white;
cursor: pointer;
position: relative;
width: 120px;
height: 30px;
}
.file-input-zone:hover {
background-color: lightblue;
}
.file-input-zone input[type=file] {
position: absolute;
width: 100%;
height: 100%;
opacity: 0;
cursor: pointer;
}
</style>
<div class="file-input-zone">
<InputFile />
Get me a file!
</div>
It will give you a button that looks like this:
You might pick up more tips by studying his source code further.

Customize iViewUI <Tag> component

I'm using iViewUI for my Tag component, but I wanted to customize its size and where the "X" close button is.
I was able to change the width by simply adding a class to the Tag, but for some reason, even i'm trying to override also its children icon, is not responding to the change at all, is not applying it. Checked on browser, not adding it there either.
This is what I've done so far:
<Tag class="Badge-tag" color="warning" closable #on-close="removeTag">{{ badge }}</Tag>
Then on the less file I added the following:
.Badge-tag {
width: 60px;
position: relative;
.ivu-icon.ivu-icon-ios-close {
position: absolute;
right: 2px;
top: 4px;
}
}
I had no luck at all. I don't know why is not setting it.
If you put above css as global css, I think it should work.
I create a demo on jsfiddle here, please check
If you use scoped css, you can try using deep selector
.Badge-tag {
width: 60px;
position: relative;
/deep/ .ivu-icon.ivu-icon-ios-close {
position: absolute;
right: 2px;
top: 4px;
}
}

I can't figure out why the header is not "responsive" in this "responsive" Wordpress theme

Here is the site-to-be (work in progress still)
http://www.fairhavenstorage.com/DRAFT
On a desktop screen it's fine, but on a mobile device, the site title and description do not budge. I added some custom CSS to allow the logo to display beside the site title - here is what I entered:
#logo .site-title, #logo .site-description {
display: block !important;
}
.site-title {margin-top: 26px;}
#logo img {
float: left;
margin-right: 20px;
}
#logo {
float: left;
width: 800px;
}
And for the image on the right side of header, I entered this:
.header-widget {
float: right;
width: 200px;
margin-top: 10px;
}
It's not looking good on my iPhone and I'm unsure what to do. If anyone can suggest a fix, that would be greatly appreciated!
try and deactvate or override existing css . There are #media queries in your existing css

Changing size of Dojo Filtering Select via CSS in XPages

I just want to change the size of Dojo Filtering Select design element via CSS.
I tried manual or CSS File. It did not work.
<xe:djFilteringSelect id="djselect1" value="#{document1.Language}" style="min-height: 8px;height:8.px;"></xe:djFilteringSelect>
Any suggestion is important
Cumhur Ata
You just need to override the dijitTextBox CSS class.
You might need to use CSS specificity to make sure that the CSS is picked up (instead of using !important).
Here's a simple example:
.dijitTextBox {
width: 40px;
height: 8px;
}
As you are using Bootstrap theme you need to adjust the arrow button too.
This works for me:
.dbootstrap .dijitTextBox {
height: 24px;
}
.dbootstrap .dijitComboBox .dijitButtonNode.dijitArrowButton {
height: 22px;
}
.xsp.dbootstrap .dijitInputContainer {
padding-top: 0px;
}
.dbootstrap .dijitComboBox input.dijitArrowButtonInner {
margin-top: -3px;
margin-left: -5px;
}
.dbootstrap .dijitMenuItem {
padding: 0px 10px;
}

Populate a input[type=file] with drag and drop without ajax [duplicate]

I have a web site with a regular <input type="file"> file upload, POSTing the data to the backend when the form is submitted.
I would like to progressively enhance the form so that you can drop a file from outside the browser anywhere in the viewport (not just on the file input field, as built into some browsers) to upload it.
Whether or not the form autosubmits isn't important. So if the drag-and-drop only selects the file in the file field, without starting an upload, that's fine. I don't need support for multiple files. I don't need to show upload progress, thumbnails or anything fancy.
I know there are JS libs that support drag-and-drop uploads, but they all seem to upload via AJAX. I could do that, but then I would need to modify the backend and frontend to handle upload errors, redirect and show the right messages on success and so on.
I want a progressive enhancement that doesn't require any backend changes. It should happen synchronously using the form in the page. JS is fine, as long as the upload happens "in the foreground". Synchronous AJAX would not work, of course.
Although not really "synchronous" (JavaScript execution won't actually halt), you can set the files selected by <input type="file"> programatically. In fact, such elements and dragging share their file backend implementation (File and FileList instances), so it's really straight-forward. What's more, due to both frontends using FileLists, dragging multiple files work just as seamlessly.
This works in Chrome (using jQuery): http://jsfiddle.net/qMmPr/.
$(document).on("dragover drop", function(e) {
e.preventDefault(); // allow dropping and don't navigate to file on drop
}).on("drop", function(e) {
$("input[type='file']")
.prop("files", e.originalEvent.dataTransfer.files) // put files into element
.closest("form")
.submit(); // autosubmit as well
});
Thanks to #pimvdb comment, I came up with a pretty elegant solution.
Since drag and dropping on the <input type="file" /> works, why not making it full-screen on dragstart to make sure the user can't miss it? Anyway he is dragging so his intentions are clear at this moment.
Here's a demo: https://jsfiddle.net/08wbo4um
NB: unfortunately this doesn't seem to work in an iframe, but it does work on an actual page. You can still apprehend the behavior.
Here's the snippet:
$('input[type="file"]').on('change', function(e){
var fileName = e.target.files[0].name;
if (fileName) {
$(e.target).parent().attr('data-message', fileName);
}
});
$(document).on('drag dragstart dragend dragover dragenter dragleave drop', function(e) {
if ($('input[type="file"]').length) {
if (['dragover', 'dragenter'].indexOf(e.type) > -1) {
if (window.dragTimeout)
clearTimeout(window.dragTimeout);
$('body').addClass('dragged');
} else if (['dragleave', 'drop'].indexOf(e.type) > -1) {
// Without the timeout, some dragleave events are triggered
// when the :after appears, making it blink...
window.dragTimeout = setTimeout(function() {
$('body').removeClass('dragged');
}, 100);
}
}
});
h3, p {
text-align: center;
}
.form-group {
margin: 30px;
}
.file-upload .form-control {
height: 150px;
outline: 1px dashed #ccc;
outline-offset: -15px;
background-color: #eee;
}
.file-upload .form-control:before {
content: "\f093";
font: normal normal normal 14px/1 FontAwesome;
font-size: 3em;
left: 0;
right: 0;
display: block;
margin: 20px auto;
text-align: center;
}
.file-upload .form-control:after {
content: attr(data-message);
left: 0;
right: 0;
bottom: 0;
text-align: center;
display: block;
}
.file-upload .form-control input[type="file"] {
cursor: pointer;
opacity: 0;
width: 100%;
height: 100%;
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
}
body.dragged .file-upload .form-control input[type="file"] {
/* Make sure it is full screen, whatever the position absolute container */
position: fixed;
top: -50vh;
bottom: -50vh;
left: -50vw;
right: -50vw;
height: 200vh;
width: 200vw;
z-index: 10002;
}
body:after {
content: 'You can drop the file. :-)';
font-size: 2em;
text-align: center;
line-height: 100vh;
position: absolute;
top: 10px;
bottom: 10px;
left: 10px;
right: 10px;
background-color: #eee;
z-index: 10000;
border-radius: 4px;
border: thin solid #ccc;
visibility: hidden;
opacity: 0;
transition: visibility 0s, opacity 0.5s ease;
}
body.dragged:after {
opacity: 1;
visibility: visible;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<h3>Drag N Drop file upload without AJAX Demo</h3>
<p>Try drag and dropping a file. :-)</p>
<div class="form-group file-upload" required="required">
<label class="cols-sm-2 control-label" for="document_file">File Upload</label><br>
<div class="cols-sm-10">
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-file" aria-hidden="true"></i></span>
<div class="form-control" data-message="Click to select file or drag n drop it here">
<input required="required" title="Click to select file or drag n drop it here" type="file" name="document[file]" id="document_file">
</div>
</div>
</div>
</div>
It can be done by turning autoUpload to false, collecting the files in an array, then on form submit do a single ajax call with all the files together with the form data, as described here.