.trigger() not triggering autosize event - javascript

Hi I have a project using autosize text fields, these field need to be updated using an 'autosize:update' trigger if the field is edited by a script, but I'm having some trouble getting this to work. If I try entering:
$('.auto-size').trigger('autosize:update')
Into the console when the update needs to happen, nothing happens and I'm not sure why?
I'm pretty new to javascript/jquery so any help would be greatly appreciated.

As reported in the documentation you can use:
autosize.update($('.auto-size'));
or you can use:
var evt = document.createEvent('Event');
evt.initEvent('autosize:update', true, false);
$('.auto-size').get(0).dispatchEvent(evt);
An example:
// initialiaze the field
autosize($('.auto-size'));
// add new text to textarea and update!
$('#myBtn').on('click', function(e) {
var ele = $('.auto-size');
ele.text(ele.text() + 'This is a new line.\n');
autosize.update(ele);
// Dispatch a 'autosize:update' event to trigger a resize:
//var evt = document.createEvent('Event');
//evt.initEvent('autosize:update', true, false);
//$('.auto-size').get(0).dispatchEvent(evt);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/jackmoore/autosize/master/dist/autosize.min.js"></script>
<textarea class="auto-size"></textarea>
<button id="myBtn">Click Me</button>

if autosize:update is a css property, it probably is but i can't find it online. But if it IS,
$(".auto-size").trigger(function(){
$(".auto-size").css("autosize","update");
});

Related

cannot find non-jQuery equivalent for "trigger"

Tigran Saluev suggested the following answer to manually triggering a prompt to select a file, but the code used jQuery. His code was a follows:
var input = $(document.createElement("input"));
input.attr("type", "file");
input.trigger("click");
In my project, I wanted the equivalent effect but without jQuery. I thought I had it here:
var input = document.createElement("input");
input.setAttribute("type", "file");
input.dispatchEvent(new Event("click"));
But nothing happens. What am I doing incorrectly?
In your case a simple click() call is all that is needed to trigger the event. Or if you want to use dispatch event, you want to create a Mouse Event and trigger that.
var fi = document.querySelector("#f");
// simple call to click()
document.querySelector("button.test1").addEventListener("click", function() {
f.click()
});
// Or with dispatch event
document.querySelector("button.test2").addEventListener("click", function() {
var event = new MouseEvent('click', {
view: window,
bubbles: true,
cancelable: true
});
fi.dispatchEvent(event);
});
<input id="f" type="file" />
<button class="test1" type="button"> CLICK ME 1</button>
<button class="test2" type="button"> CLICK ME 2</button>
you can use initMouseEvent as an alternative to trigger
here's link to it to the api, for more details
function clickSimulation(id) {
var theEvent;
var theElement = document.getElementById(id);
if (document.createEvent) {
theEvent = document.createEvent("MouseEvents");
theEvent.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
}
(theEvent) ? theElement.dispatchEvent(theEvent) : (theElement.click && theElement.click());
}
var input = $(document.createElement("input"));
input.attr("type", "file");
input.attr("id", "TheFileCatcher");
clickSimulation("TheFileCatcher");
I think you were just missing an event listener. Try the following construction:
// Create an input object
var input = $(document.createElement("input"));
input.attr("type", "file");
// Add an event listener
input.addEventListener("click", function(e) {
console.log(e.detail);
});
// Create the event
var event = new CustomEvent("click", { "detail": "My click event" });
// Dispatch/Trigger/Fire the event
input.dispatchEvent(event);
You can also try "playing" with an event types, so instead of CustomEvent you can try the same you did in your code, because click is not a custom one. I assume that the problem is because you are missing an event listener
Ref to the original answer
EDIT Found an info about security restriction for triggering file input programmatically
Most browsers prevent submitting files when the input field didn't receive a direct click (or keyboard) event as a security precaution. Some browsers (e.g. Google Chrome) simply prevent the click event, while e.g. Internet Explorer doesn't submit any files that have been selected by a programmatically triggered file input field. Firefox 4 (and later) is so far the only browser with full support for invoking "click"-Events on a completely hidden (display: none) file input field.

Get the html element of the selected event in kendo scheduler

I was wondering how can I get in the html element with ".k-event" class, contains selected event in function binded to edit event of the Scheduler?
$("#src-ap-01-scheduler").kendoScheduler({
date: new Date(),
allDaySlot: false,
editable: {
template: $("#scr-ap-01-editor").html()
},
edit: function(e){
// i have tried these
// e.currentTarget
// e.container.closest("k-event")
}
})
I've logged the (e) on the function but I have no idea how to get the .k-event element from inside of the function. I hope you guys have some idea to get this element, any advice would be appreciated, thanks.
To get selected event element put this code in function triggered on edit:
edit: function(e){
var uid = e.container.attr('data-uid');
var element = e.sender.element.find('div.k-event[data-uid="' + uid + '"]');
}
Greetings.
The above answer doesn't work in Kendo UI v2015.1.318, and here's my quick solution for this issue.
edit: function(e) {
if (e.event.YOUR_EVENT_CONDITION) {
// Allow the user to edit this event!
} else {
e.preventDefault();
var element = e.sender.element.find('div.k-event[data-uid="'+e.event.uid+'"]');
if (element)
$(element).notify("You can't modify a completed event.", {className: "error", placement: "top", autoHideDelay: 3000});
else
$.notify("You can't modify a completed event.", "error");
}
}
I'm using notify.js to display a popup message right on the selected event UI only if it exists. Please visit the following link for notify.js.
http://notifyjs.com/

Change-Event for div [duplicate]

I want to run a function when a user edits the content of a div with contenteditable attribute. What's the equivalent of an onchange event?
I'm using jQuery so any solutions that uses jQuery is preferred. Thanks!
2022 update
As pointed out in the comments, this doesn't answer the question asked, which wanted the equivalent of the change event rather than the input event. However, I'll leave it here as is.
Original answer
I'd suggest attaching listeners to key events fired by the editable element, though you need to be aware that keydown and keypress events are fired before the content itself is changed. This won't cover every possible means of changing the content: the user can also use cut, copy and paste from the Edit or context browser menus, so you may want to handle the cut copy and paste events too. Also, the user can drop text or other content, so there are more events there (mouseup, for example). You may want to poll the element's contents as a fallback.
UPDATE 29 October 2014
The HTML5 input event is the answer in the long term. At the time of writing, it is supported for contenteditable elements in current Mozilla (from Firefox 14) and WebKit/Blink browsers, but not IE.
Demo:
document.getElementById("editor").addEventListener("input", function() {
console.log("input event fired");
}, false);
<div contenteditable="true" id="editor">Please type something in here</div>
Demo: http://jsfiddle.net/ch6yn/2691/
Here is a more efficient version which uses on for all contenteditables. It's based off the top answers here.
$('body').on('focus', '[contenteditable]', function() {
const $this = $(this);
$this.data('before', $this.html());
}).on('blur keyup paste input', '[contenteditable]', function() {
const $this = $(this);
if ($this.data('before') !== $this.html()) {
$this.data('before', $this.html());
$this.trigger('change');
}
});
The project is here: https://github.com/balupton/html5edit
Consider using MutationObserver. These observers are designed to react to changes in the DOM, and as a performant replacement to Mutation Events.
Pros:
Fires when any change occurs, which is difficult to achieve by listening to key events as suggested by other answers. For example, all of these work well: drag & drop, italicizing, copy/cut/paste through context menu.
Designed with performance in mind.
Simple, straightforward code. It's a lot easier to understand and debug code that listens to one event rather than code that listens to 10 events.
Google has an excellent mutation summary library which makes using MutationObservers very easy.
Cons:
Requires a very recent version of Firefox (14.0+), Chrome (18+), or IE (11+).
New API to understand
Not a lot of information available yet on best practices or case studies
Learn more:
I wrote a little snippet to compare using MutationObserers to handling a variety of events. I used balupton's code since his answer has the most upvotes.
Mozilla has an excellent page on the API
Take a look at the MutationSummary library
non jQuery quick and dirty answer:
function setChangeListener (div, listener) {
div.addEventListener("blur", listener);
div.addEventListener("keyup", listener);
div.addEventListener("paste", listener);
div.addEventListener("copy", listener);
div.addEventListener("cut", listener);
div.addEventListener("delete", listener);
div.addEventListener("mouseup", listener);
}
var div = document.querySelector("someDiv");
setChangeListener(div, function(event){
console.log(event);
});
I have modified lawwantsin 's answer like so and this works for me. I use the keyup event instead of keypress which works great.
$('#editor').on('focus', function() {
before = $(this).html();
}).on('blur keyup paste', function() {
if (before != $(this).html()) { $(this).trigger('change'); }
});
$('#editor').on('change', function() {alert('changed')});
Two options:
1) For modern (evergreen) browsers:
The "input" event would act as an alternative "change" event.
https://developer.mozilla.org/en-US/docs/Web/Events/input
document.querySelector('div').addEventListener('input', (e) => {
// Do something with the "change"-like event
});
or
<div oninput="someFunc(event)"></div>
or (with jQuery)
$('div').on('click', function(e) {
// Do something with the "change"-like event
});
2) To account for IE11 and modern (evergreen) browsers:
This watches for element changes and their contents inside the div.
https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
var div = document.querySelector('div');
var divMO = new window.MutationObserver(function(e) {
// Do something on change
});
divMO.observe(div, { childList: true, subtree: true, characterData: true });
const p = document.querySelector('p')
const result = document.querySelector('div')
const observer = new MutationObserver((mutationRecords) => {
result.textContent = mutationRecords[0].target.data
// result.textContent = p.textContent
})
observer.observe(p, {
characterData: true,
subtree: true,
})
<p contenteditable>abc</p>
<div />
Here's what worked for me:
var clicked = {}
$("[contenteditable='true']").each(function(){
var id = $(this).attr("id");
$(this).bind('focus', function() {
// store the original value of element first time it gets focus
if(!(id in clicked)){
clicked[id] = $(this).html()
}
});
});
// then once the user clicks on save
$("#save").click(function(){
for(var id in clicked){
var original = clicked[id];
var current = $("#"+id).html();
// check if value changed
if(original != current) save(id,current);
}
});
This thread was very helpful while I was investigating the subject.
I've modified some of the code available here into a jQuery plugin so it is in a re-usable form, primarily to satisfy my needs but others may appreciate a simpler interface to jumpstart using contenteditable tags.
https://gist.github.com/3410122
Update:
Due to its increasing popularity the plugin has been adopted by Makesites.org
Development will continue from here:
https://github.com/makesites/jquery-contenteditable
Non JQuery answer...
function makeEditable(elem){
elem.setAttribute('contenteditable', 'true');
elem.addEventListener('blur', function (evt) {
elem.removeAttribute('contenteditable');
elem.removeEventListener('blur', evt.target);
});
elem.focus();
}
To use it, call on (say) a header element with id="myHeader"
makeEditable(document.getElementById('myHeader'))
That element will now be editable by the user until it loses focus.
In Angular 2+
<div contentEditable (input)="type($event)">
Value
</div>
#Component({
...
})
export class ContentEditableComponent {
...
type(event) {
console.log(event.data) // <-- The pressed key
console.log(event.path[0].innerHTML) // <-- The content of the div
}
}
To avoid timers and "save" buttons, you may use blur event wich fires when the element loses focus. but to be sure that the element was actually changed (not just focused and defocused), its content should be compared against its last version. or use keydown event to set some "dirty" flag on this element.
Here is the solution I ended up using and works fabulously. I use $(this).text() instead because I am just using a one line div that is content editable. But you may also use .html() this way you dont have to worry about the scope of a global/non-global variable and the before is actually attached to the editor div.
$('body').delegate('#editor', 'focus', function(){
$(this).data('before', $(this).html());
});
$('#client_tasks').delegate('.task_text', 'blur', function(){
if($(this).data('before') != $(this).html()){
/* do your stuff here - like ajax save */
alert('I promise, I have changed!');
}
});
You need to use input event type
Demo
HTML
<div id="editor" contenteditable="true" >Some text here</div>
JS
const input = document.getElementById('editor');
input.addEventListener('input', updateValue);
function updateValue(e) {
console.log(e.target);
}
know more
The onchange event doesn't fires when an element with the contentEditable attribute is changed, a suggested approach could be to add a button, to "save" the edition.
Check this plugin which handles the issue in that way:
Creating a quick and dirty jQuery contentEditable Plugin
Using DOMCharacterDataModified under MutationEvents will lead to the same. The timeout is setup to prevent sending incorrect values (e.g. in Chrome I had some issues with space key)
var timeoutID;
$('[contenteditable]').bind('DOMCharacterDataModified', function() {
clearTimeout(timeoutID);
$that = $(this);
timeoutID = setTimeout(function() {
$that.trigger('change')
}, 50)
});
$('[contentEditable]').bind('change', function() {
console.log($(this).text());
})
JSFIDDLE example
I built a jQuery plugin to do this.
(function ($) {
$.fn.wysiwygEvt = function () {
return this.each(function () {
var $this = $(this);
var htmlold = $this.html();
$this.bind('blur keyup paste copy cut mouseup', function () {
var htmlnew = $this.html();
if (htmlold !== htmlnew) {
$this.trigger('change')
}
})
})
}
})(jQuery);
You can simply call $('.wysiwyg').wysiwygEvt();
You can also remove / add events if you wish
A simple answer in JQuery, I just created this code and thought it will be helpful for others too
var cont;
$("div [contenteditable=true]").focus(function() {
cont=$(this).html();
});
$("div [contenteditable=true]").blur(function() {
if ($(this).html()!=cont) {
//Here you can write the code to run when the content change
}
});
For me, I want to check the input is valid or not.
If valid, then update, Otherwise show an error message and keep the value as same as before.
Skill: When you edit done, usually, it will trigger the blur event.
Example
<span contenteditable="true">try input somethings.</span>
<script>
const elem = document.querySelector(`span`)
let oldValue = elem.innerText
elem.onkeydown = (keyboardEvent) => {
if (keyboardEvent.key === "Enter") {
elem.blur() // set focusout
}
}
elem.onblur = (e) => {
const curValue = elem.innerText
if (curValue === oldValue) {
return
}
if (curValue.length <= 50) { // 👈 Input your conditions.
// 👇 fail
elem.innerText = oldValue
// (Optional) Add error message
elem.insertAdjacentHTML("beforeend", `<span style="margin-left:5px;color:red">error length=${curValue.length}. Must greater than 50. undo to the previous value.</span>`)
const errMsg = elem.querySelector(`span`)
setTimeout(() => errMsg.remove(), 3500) // wait 3.5 second, and then remove it.
return
}
// 👇 OK, update
oldValue = curValue
}
</script>
Check this idea out.
http://pastie.org/1096892
I think it's close. HTML 5 really needs to add the change event to the spec. The only problem is that the callback function evaluates if (before == $(this).html()) before the content is actually updated in $(this).html(). setTimeout don't work, and it's sad. Let me know what you think.
Based on #balupton's answer:
$(document).on('focus', '[contenteditable]', e => {
const self = $(e.target)
self.data('before', self.html())
})
$(document).on('blur', '[contenteditable]', e => {
const self = $(e.target)
if (self.data('before') !== self.html()) {
self.trigger('change')
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

jQuery custom event not firing or triggering

Can anyone tell me what am I doing wrong in the given below code?
<script type="text/javascript">
$('#sp7').on("test", processData);
function processData(e){
recievedData=null;
recievedData[e.message[id]] = e.message;
return recievedData;
}
function testData(id,a){
temp = {id:id, a:a};
$.event.trigger({
type : "test",
message : temp,
time : new Date()
});
}
</script>
I am calling the testData on a button click:
<input type = "button" onclick="testData(1,'a1');" value="test1"/>
I don't know if you specifically need to resort to custom events. However, the event should be triggered on the dom element that is supposed to listen to it. Like
$('#sp7').trigger('test',[parameters]);

Select all contents of textbox when it receives focus (Vanilla JS or jQuery)

What is a Vanilla JS or jQuery solution that will select all of the contents of a textbox when the textbox receives focus?
$(document).ready(function() {
$("input:text").focus(function() { $(this).select(); } );
});
<input type="text" onfocus="this.select();" onmouseup="return false;" value="test" />
$(document).ready(function() {
$("input[type=text]").focus().select();
});
$(document).ready(function() {
$("input:text")
.focus(function () { $(this).select(); } )
.mouseup(function (e) {e.preventDefault(); });
});
jQuery is not JavaScript which is more easy to use in some cases.
Look at this example:
<textarea rows="10" cols="50" onclick="this.focus();this.select()">Text is here</textarea>
Source: CSS Tricks, MDN
This is not just a Chrome/Safari issue, I experienced a quite similar behavior with Firefox 18.0.1. The funny part is that this does not happen on MSIE! The problem here is the first mouseup event that forces to unselect the input content, so just ignore the first occurence.
$(':text').focus(function(){
$(this).one('mouseup', function(event){
event.preventDefault();
}).select();
});
The timeOut approach causes a strange behavior, and blocking every mouseup event you can not remove the selection clicking again on the input element.
HTML :
var textFiled = document.getElementById("text-filed");
textFiled.addEventListener("focus", function() { this.select(); });
Enter Your Text : <input type="text" id="text-filed" value="test with filed text">
Using JQuery :
$("#text-filed").focus(function() { $(this).select(); } );
Using React JS :
In the respective component -
<input
type="text"
value="test"
onFocus={e => e.target.select()}
/>
my solution is to use a timeout. Seems to work ok
$('input[type=text]').focus(function() {
var _this = this;
setTimeout(function() {
_this.select();
}, 10);
});
This will also work on iOS:
<input type="text" onclick="this.focus(); this.setSelectionRange(0, 9999);" />
https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/select
I know inline code is bad style, but I didn't want to put this into a .js file.
Works without jQuery!
<input type="text" value="blah blah" onfocus="this.select(); this.selAll=1;" onmouseup="if(this.selAll==0) return true; this.selAll=0; return false;"></input>
The answers here helped me up to a point, but I had a problem on HTML5 Number input fields when clicking the up/down buttons in Chrome.
If you click one of the buttons, and left the mouse over the button the number would keep changing as if you were holding the mouse button because the mouseup was being thrown away.
I solved this by removing the mouseup handler as soon as it had been triggered as below:
$("input:number").focus(function () {
var $elem = $(this);
$elem.select().mouseup(function (e) {
e.preventDefault();
$elem.unbind(e.type);
});
});
Hope this helps people in the future...
This will work, Try this -
<input id="textField1" onfocus="this.select()" onmouseup="return false" />
Works in Safari/IE 9 and Chrome, I did not get a chance to test in Firefox though.
I know there are already a lot of answers here - but this one is missing so far; a solution which also works with ajax generated content:
$(function (){
$(document).on("focus", "input:text", function() {
$(this).select();
});
});
Like #Travis and #Mari, I wanted to autoselect when the user clicked in, which means preventing the default behaviour of a mouseup event, but not prevent the user from clicking around. The solution I came up with, which works in IE11, Chrome 45, Opera 32 and Firefox 29 (these are the browsers I currently have installed), is based on the sequence of events involved in a mouse click.
When you click on a text input that does not have focus, you get these events (among others):
mousedown: In response to your click. Default handling raises focus if necessary and sets selection start.
focus: As part of the default handling of mousedown.
mouseup: The completion of your click, whose default handling will set the selection end.
When you click on a text input that already has focus, the focus event is skipped. As #Travis and #Mari both astutely noticed, the default handling of mouseup needs to be prevented only if the focus event occurs. However, as there is no "focus didn't happen" event, we need to infer this, which we can do within the mousedown handler.
#Mari's solution requires that jQuery be imported, which I want to avoid. #Travis's solution does this by inspecting document.activeElement. I don't know why exactly his solution doesn't work across browsers, but there is another way to track whether the text input has focus: simply follow its focus and blur events.
Here is the code that works for me:
function MakeTextBoxAutoSelect(input)
{
var blockMouseUp = false;
var inputFocused = false;
input.onfocus =
function ()
{
try
{
input.selectionStart = 0;
input.selectionEnd = input.value.length;
}
catch (error)
{
input.select();
}
inputFocused = true;
};
input.onblur =
function ()
{
inputFocused = false;
};
input.onmousedown =
function ()
{
blockMouseUp = !inputFocused;
};
input.onmouseup =
function ()
{
if (blockMouseUp)
return false;
};
}
I hope this is of help to someone. :-)
I was able to slightly improve Zach's answer by incorporating a few function calls. The problem with that answer is that it disables onMouseUp completely, thereby preventing you from clicking around in the textbox once it has focus.
Here is my code:
<input type="text" onfocus="this.select()" onMouseUp="javascript:TextBoxMouseUp();" onMouseDown="javascript:TextBoxMouseDown();" />
<script type="text/javascript">
var doMouseUp = true;
function TextBoxMouseDown() {
doMouseUp = this == document.activeElement;
return doMouseUp;
}
function TextBoxMouseUp() {
if (doMouseUp)
{ return true; }
else {
doMouseUp = true;
return false;
}
}
</script>
This is a slight improvement over Zach's answer. It works perfectly in IE, doesn't work at all in Chrome, and works with alternating success in FireFox (literally every other time). If someone has an idea of how to make it work reliably in FF or Chrome, please share.
Anyway, I figured I'd share what I could to make this a little nicer.
What is a JavaScript or jQuery solution that will select all of the contents of a textbox when the textbox receives focus?
You only need to add the following attribute:
onfocus="this.select()"
For example:
<input type="text" value="sometext" onfocus="this.select()">
(Honestly I have no clue why you would need anything else.)
This worked for me (posting since it is not in answers but in a comment)
$("#textBox").focus().select();
onclick="this.focus();this.select()"
$('input').focus(function () {
var self = $(this);
setTimeout(function () {
self.select();
}, 1);
});
Edit: Per #DavidG's request, I can't provide details because I'm not sure why this works, but I believe it has something to do with the focus event propagating up or down or whatever it does and the input element getting the notification it's received focus. Setting the timeout gives the element a moment to realize it's done so.
If you chain the events together I believe it eliminates the need to use .one as suggested elsewhere in this thread.
Example:
$('input.your_element').focus( function () {
$(this).select().mouseup( function (e) {
e.preventDefault();
});
});
Note: If you are programming in ASP.NET, you can run the script using ScriptManager.RegisterStartupScript in C#:
ScriptManager.RegisterStartupScript(txtField, txtField.GetType(), txtField.AccessKey, "$('#MainContent_txtField').focus(function() { $(this).select(); });", true );
Or just type the script in the HTML page suggested in the other answers.
I sow this one some where , work perfectly !
$('input').on('focus', function (e) {
$(this)
$(element).one('mouseup', function () {
$(this).select();
return false;
}) .select();
});
I'm kind of late to the party, but this works perfectly in IE11, Chrome, Firefox, without messing up mouseup (and without JQuery).
inputElement.addEventListener("focus", function (e) {
var target = e.currentTarget;
if (target) {
target.select();
target.addEventListener("mouseup", function _tempoMouseUp(event) {
event.preventDefault();
target.removeEventListener("mouseup", _tempoMouseUp);
});
}
});
My solution is next:
var mouseUp;
$(document).ready(function() {
$(inputSelector).focus(function() {
this.select();
})
.mousedown(function () {
if ($(this).is(":focus")) {
mouseUp = true;
}
else {
mouseUp = false;
}
})
.mouseup(function () {
return mouseUp;
});
});
So mouseup will work usually, but will not make unselect after getting focus by input

Categories

Resources