Clone a file input element in Javascript - javascript

I have a file input element that needs to be cloned after the user has browsed and selected a file to upload. I started by using obj.cloneNode() and everything worked fine, that is until I tried using it in IE.
I've since tried using jQuery's clone method as follows:
var tmp = jQuery('#categoryImageFileInput_'+id).clone();
var clone = tmp[0];
Works as expected in FireFox, but again not in IE.
I'm stuck. Anyone have some suggestions?

Guessing that you need this functionality so you can clone the input element and put it into a hidden form which then gets POSTed to a hidden iframe...
IE's element.clone() implementation doesn't carry over the value for input type="file", so you have to go the other way around:
// Clone the "real" input element
var real = $("#categoryImageFileInput_" + id);
var cloned = real.clone(true);
// Put the cloned element directly after the real element
// (the cloned element will take the real input element's place in your UI
// after you move the real element in the next step)
real.hide();
cloned.insertAfter(real);
// Move the real element to the hidden form - you can then submit it
real.appendTo("#some-hidden-form");

Editing the file form field is a security risk and thus is disabled on most browsers and should be disabled on firefox. It is not a good idea to rely on this feature. Imagine if somebody was able, using javascript, to change a hidden file upload field to, lets say,
c:\Users\Person\Documents\Finances
Or
C:\Users\Person\AppData\Microsoft\Outlook.pst
:)

In jQuery fileupload widget there is a file input replace method to get around the change event listener only firing once.
https://github.com/blueimp/jQuery-File-Upload/blob/master/js/jquery.fileupload.js#L769
(_replaceFileInput method in jquery.fileupload.js)

You can apply other method. You have to send real element to an iframe and cloned elements insert to form. For example:
$("INPUT[type='file']").each
(
function(index, element)
{
$(this).wrap("<div></div>");
var Div = $(this).parent();
$(this).appendTo("FORM[name='forIframe']"); // This form for iframe
Div.append($(this).clone());
}
);
If you use this method your form will send file to a server, but only one note, in Chrome an IE inputs with files is reseted.

Related

Getting the Underlying Input Element of a Selectize.js element from one of its event handlers

This turned out to be a far more difficult task to determine on my own than I originally expected, but hopefully I'm just missing something.
I'm using Selectize.js for population of some fields within a form. The field sets are always the same (one text element initialized with .selectize(), and two other text elements with similar Ids. The selectize drop-down is populated via remote API calls and when an item is selected I have other fields auto-populated via selectize's onChange event.
The problem is that I want to retrieve a data attribute from the original textboxes that each selectize is initialized from inside the onChange handler to determine what additional fields should be populated. I cannot determine where to get the original element from because there is nothing in the API discussing this, and when debugging I cannot locate the actual element either.
Does anyone know how to get access to the underlying input element?
After some more digging using developer tools it turns out you can get the underlying input element with this from inside an event handler:
this.$input
Where $input is a jQuery object of the underlying element. Unfortunately, this is not in the documentation.
Usage:
$('.lookup').selectize({
onChange: function(value) {
var data = this.$input.data('stuff');
}
});

Sitecore - Field not detected as modified. How to force the save prompt to show?

We are using the Taxonomy module for Sitecore: https://marketplace.sitecore.net/Modules/T/Taxonomy.aspx?sc_lang=en
The module works fine 90% of the time. The only catch is that when in a taxonomy field you select a value from the auto-complete options, the field doesn't seem to be marked as changed. This creates the occasional confusion with editors as when they publish the "Do you want to save?" prompt doesn't show and the content is published without tags.
If instead of selecting from the auto-complete we use the dialog box, everything works fine.
I looked at the markup, JavaScript and C# code and couldn't find a solution.
I even tried to set Sitecore.Context.ClientPage.Modified = true but it doesn't seem to do anything.
How can I force the save prompt to show?
I had a similar issue, I was updating a field using js and the experience editor wasnt detecting the change.
I got this working by doing the following using js:-
There is a save button state object saved in a view state field. You can grab by doing window.parent.document.getElementById("__SAVEBUTTONSTATE"). I then did the following:-
var saveButtonState = window.parent.document.getElementById("__SAVEBUTTONSTATE");
saveButtonState.value = 1;
saveButtonState.onchange();
This will make the save button enabled
In the experience editor, Sitecore wraps your sitecore item fields in an span element, which contain a unique id. (These are the fields you interact with in the experience editor). However, its not these values which Sitecore receives when you hit Save button. Sitecore actually stores values of your item fields in hidden inputs, so when you interact with the span element, in the background, these hidden inputs are being updated. So in order for Sitecore to receive your changes, you must update the corresponding hidden input. If you open Inspect element in the experience editor and search "scFieldValues", you will see these hidden inputs. I updated the field by using jquery:-
$('#scFieldValues').children('input').each(function () {
if (id.indexOf($(this).attr('id')) >= 0) {
$(this).val(value);
}
});
The id object is the id of the span element. The contents of that id is used in the id of the hidden input. This is why I use "id.IndexOf" to find correct input element. So when I update the span element value, I grab that value and update the corresponding input.
Hope this helps

In Javascript DOM, is it ok to set focus to an item and later render the item in the document?

For example:
// build the form
var form = document.createElement('form');
var item = document.createElement('item');
form.appendChild(item);
// item is where we want our future focus
item.focus();
....
// render the form
document.getElementById('id').appendChild( form );
Is this legal? Will focus be on item once rendered?
This is important because I am dealing with a library that expects me to pass a built form that it will then place on the page. I would like to ensure proper focus when the form has been rendered.
No, you can only focus on an element that exists in the page.
You can however keep the reference to the object, and use it to set focus once it has been added to the page.

Javascript - get the form if of current control location

I have a form and it has 4 input elements. if the user enters just two entries and clicks anywhere on the screen (out the form)...i would like to save the details..it is like auto-save.
I have id of my form..i want to compare with form id of the current control on the screen..so that i can ssave the data if both form ids are different..
could you please tell me how can i get the form id of current control location on screen (some times the control could be outside the forms..in that case form id of current cotrol location would null)... but how can i determine that in javascript.
please suggest...
Many Thanks in advance,
Jack.
That's an interesting question.
Well, if you didn't think a second (as I admittedly did), you would just hook on the blur event of the HTML <form> element in question.
<form onblur="autosave(this)">
However, the HTML <form> element doesn't support that event. Too bad.
I then thought about jQuery's new 1.4 focusout() event.
$('form').focusout(function() { autosave(this); });
Unfortunately that event get fired as well when you just jump (tab, click) to the next input field inside the same form. Not so nice, it'll probably be too expensive to autosave on every fieldjump. The same effect as with an $(':input').blur(function() { autosave(this.form); });.
I then tried the other way round using focusin():
$('form').focusin(function() {
$(this).addClass('focused');
});
$(':not(form)').focusin(function(e) {
if (!$(e.target).parents('form.focused').length) {
var form = $('form.focused').removeClass('focused');
autosave(form);
}
});
Strangely enough this works in IE only and not in the other browsers. It'll be another IE bug/quirk that focus is supported by all elements other than input elements.
Your best bet will probably be hooking on the click() event instead.
$('form').focusin(function() {
$(this).addClass('focused');
});
$(':not(form)').click(function(e) {
if (!$(e.target).parents('form.focused').length) {
var form = $('form.focused').removeClass('focused');
autosave(form);
}
});
This works fine. You can find here a live demo.
Note that I don't mean to push you jQuery (a JS library which insanely eases HTML DOM traversion and manipulation) through your throat or so, but I don't see nice ways in plain JavaScript to achieve this without writing 10 times as much as code here.

How to simulate click on <input type="image" />?

when we submit a form using this type of input, the coordinates (x,y) are appended to the result.
it works if I dynamically create 2 hidden inputs, but I wanted something different.
Event or MouseEvent would be great, but I couldn't make it work
here's my current code: (it works fine)
var input = document.createElement("input");
input.type = "hidden";
input.name = "x";
input.value = posx;
my_form.appendChild(input);
input = input.cloneNode(false);
input.name = "y";
input.value = posy;
my_form.appendChild(input);
I'll give you an example of situation
Let's imagine that near to the image form element there is a plain text that says: Click in the image below in any position greater than 20 and lesser than 60
A normal person would read this and click normally.
But I need to, as a robot without hands, simulate the same click event
Without fully understanding what you are trying to do here (your question is a little vague, IMO), I have to ask this: Have you ever considered using jQuery or another javascript library/framework? I understand sometimes, for very simple sites, it's overkill. But, it might be worth it to relieve the headache of figuring this stuff out on your own.
From what I can understand, you are using an "image" form element to submit a form and you want to simulate a click on the image element to retrieve the x/y coordinates of something. I could be wrong. Could you be more explicit in your details?
I'll see if I can show you how to do it in jQuery when I know more about your problem.
I can't tell what you're trying to append the result to. The values in the form? This is automatic and requires no code (they come across and x and y, or elementname.x and elementname.y).
edited after comment:
You can avoid the node insert event by not making the elements at that time; ie add x and y to the form. Then on the event you can simply set their value. There are certainly different events you could bind this too, and I don't know your situation, but I made an example that uses an onClick event attached to the body of the page itself. You may want, instead, to bind specific onClick events to different clickable items and insert your own locations for them but in my case I submitted the location of the mouse on the page. If that's not helpful, make a comment about why and I'll see if I can mod it again.

Categories