BO
450 9
Asked
Updated
Viewed
2.6k times

I'm using laravel to run my application and in it, I'm using the unisharp/filemanager to upload files and choose for blog post submittions and avatar changes and all that sort of thing. It works perfectly in my summernote implementation but now I've being struggling to implement it to update the user's profile avatar.

The Javascript I use to open the filemanager window is:

(function( $ ){

    $.fn.filemanager = function(type) {
        this.on('click', function(e) {
            var route_prefix = '/filemanager';
            window.open(route_prefix + '?type=' + type, 'FileManager', 'width=900,height=600');
            window.SetUrl = function (items) {
                var file_path = items.map(function (item) {
                    const image = item.url;
                    return item.url;
                });
        
                $("#preview-container").css("background-image", "url(" + file_path + ")");
                $('#avatar-path').value = file_path;
                $('#file-input').value = file_path;
            };
            return false;
        });
    }
    
})(jQuery);

$('#file-input').filemanager('image');

/* I've also tried the following way to use the filemanager and it had the same results as the previous method
$('#invoke-file-input').filemanager('image'); */

The corresponding HTML for that javascript is:

<div id="preview-container">
</div>
<!-- Custom Styled File Input Button -->
<label for="file-input" id="invoke-file-input" class="btn btn-primary" data-input="file-input" data-preview="preview-container">
    Choose File
</label>
<!-- File Input -->
<input type="file" name="avatar" id="file-input" class="form-control visually-hidden">

<!-- Hidden input fields to store background path a second time -->
<input type="hidden" name="avatar-path" id="avatar-path">

and the css for those aren't relevant

I'm hiding the input field since I want just the preview box and a button underneath it to upload the image and that part works.

I click on that label disguised as a button and it opens the file manager and uploads the image and selects the image and inserts it into the preview container just like I want it to... but I can't manage to get the input field populated as hard as I try. I'm not very good at javascript so there might be issues here that I'm not noticing, but to be fair, chatGPT has being helping me for the past few hours on this thing and we didn't get anywhere.

I've tried clearing my cache and restarting the artisan server. I literally don't know what to do. I just need that url path so I can update the database as everything else is done, but it isn't working.

The console doesn't show anything and inspecting the element I see that when I select an image it doesn't add the value to either 'file-input' or 'avatar-path' (I tried a second hidden field in case it might work, but it doesn't).

I've got other hidden fields in there and they get updated VIA javascript just fine.

I'm not using react or any of those javascript front-end frameworks.

  • 0
    What value are you expecting the input field to have? Secondly, you have more than one input field here, what input field are you specifically referring to? — Brian Wozeniak
  • 0
    The value I'm expecting is a url address which exists. I've done the console.log() and it prints out just the url. I'm referring to both of the input field. I need only #file-input but put in #avatar-path to check if the problem might be with type="file" but neither of them are updating. The php file returns a json response. — Bogey
  • 0
    As far as I recall, the file input field would only locally reference a file on your computer, it would not reference any sort of remote address such as a URL. Additionally, due to security, I don't think it would provide any path information either, all you would get is the local file name that was selected. Also the value of the file input is purely set by what the user chooses, you cannot set this value remotely with a script, see this reference. The URL path would not be set by the user, that would be set by the server, and something you should be able to figure out via PHP without depending on Javascript since it's up to your server programming to determine the final URL for where that image or resource would be located. Thus, the only purpose of a file input is to allow a user to get their local image (or other file) uploaded to your server. Everything else is up to the server, the user does not choose where this image will be located, thus there would be no way for the user to even know where the file is located on the server to create a URL. Now, however, the server could return a JSON response after submitting which could reference to where the asset is now located, such as the URL. — Brian Wozeniak
  • 0
    The URL is 127.0.0.1:8000, everything is local. This is why I put a second field to see if it'll work. — Bogey
  • 0
    Yes that is local, but you aren't going to get anything related to the HTTP protocol there in the form of a URL when it comes to the file input field. It is only a local file reference to be able to get access to the data referenced for uploading. — Brian Wozeniak
  • 0
    But the other input field that is type="hidden" and not type="file" ? It should work — Bogey
add a comment
0

2 Answers

  • Votes
  • Oldest
  • Latest
JO
184 4
Answered
Updated

Look at how you're setting your values in both pieces of javascript. In the second one you're using

.val(value)

Given you're using the $() wrapper to retrieve the element, that val() setter is likely correct.

In the first snippet, you're trying to set the .value attribute of the HTML element directly, which I'm not sure gets exposed by the $() wrapper.

  • 0
    That may have being the issue why the hidden field was not getting updated. I don't javascript much, so I didn't know that fact about Javascript. — Bogey
  • 0
    But that brings me to my other question, why didn't the console give an error that I was trying to access a function that wasn't accessible in the context of my implementation? — Bogey
  • 0
    I think Joebert may be on to something with this. There is a difference between an object's properties vs an object's attributes. I believe when setting value you are only modifying the actual attribute on the object. When you use val you are setting the property. The issue here is that an object's properties are initially read from the attributes when the page first loads up, but after that, it uses its own internal map and may no longer match up if changed. — Brian Wozeniak
  • 0
    I think one of the toughest parts about javascript is keeping track of what's native to the language, and what's library or implementation specific. It gets more confusing when you venture out of browser land, and into APIs exposed by software such as AutoCAD or Excel. — joebert
add a comment
2
BO
450 9
Answered
Updated

I finally got it to work by simply changing that field from type="file" to type="text" and moving all the setting actions into the map function and having it run consecutively after submitting rather than calling on that as a lambda function (if I understand correctly what a lambda function is).

(function( $ ){

    $.fn.filemanager = function() {
        this.on('click', function(e) {
            window.open('/filemanager?type=image', 'FileManager', 'width=900,height=600');
            window.SetUrl = function (items) {
                items.map(function (item) {
                    $("#preview-container").css("background-image", "url(" + item.url + ")");
                    $('#file-input').val(item.url);
                });
            };
            return false;
        });
    }
    
})(jQuery);

$('#invoke-file-input').filemanager();

And the HTML input field is:

<input type="text" name="avatar" id="file-input" class="form-control visually-hidden">

On top of that, I tried to run the following javascript function to strip the domain and port out of the url and just have a relative path and that didn't work.

function removeDomainAndPort(url) {
    var parsedUrl = new URL(url);
    return parsedUrl.pathname;
}

I understand why this didn't work with a type="file" input field but I didn't understand why it didn't work with type="hidden".

  • 0
    Now it stopped working all of a sudden. I want to scream!!! (Edit: Fixed it) — Bogey
add a comment
0