For selectize.js with ajax search inserting text by mouse not cause search
It's can be simle reproduced on http://brianreavis.github.io/selectize.js page.
On Remote Source — Github example:
focus on field
delete selected
insert text any text by mouse (not
by ctrl+v)
no result
How to fix it?
Update
For catching event by jquery bind method. Selectize on method can't catch it (bug?).
$('.selectize').bind('input', function(){
// force selectize to make ajax call and show result
});
// following code catch nothing
$('.selectize')[0].selectize.on('input', function(){
// force selectize to make ajax call
});
But can't find solution for forcing selectize ajax call
You can find fix on the issue page https://github.com/selectize/selectize.js/issues/882
the code
onPaste: function(e) {
var self = this;
if (self.isFull() || self.isInputHidden || self.isLocked) {
e.preventDefault();
} else {
// If a regex or string is included, this will split the pasted
// input and create Items for each separate value
setTimeout(function() {
if (self.settings.splitOn) {
var splitInput = $.trim(self.$control_input.val() || '').split(self.settings.splitOn);
for (var i = 0, n = splitInput.length; i < n; i++) {
self.createItem(splitInput[i]);
}
}
self.onKeyUp(e);
}, 0);
}
},
Related
I am trying to set values on an angular page through a chrome extension I create so I can easily complete some repetitive angular forms I have to fill it up many times a day. (Change the angular page's code is not an option, the new values have to be injected or "typed" somehow)
On my tests, I can see the values been updated on the DOM and displaying on the page, however when I press the submit button the bound angular variables have no values.
Bellow is the code inject on the DOM by the extension, It has a little added complexity as it has everything I tried many different things such as to simulate typing using a timer, setting focus, selecting the field using select, etc.
// listen for checkForWord request, call getTags which includes callback to sendResponse
chrome.runtime.onMessage.addListener(
function (request, sender, sendResponse) {
if (request.action === "checkForWord") {
TypeIntoInput("inputFieldPasswordRegister", "Password123!")
TypeIntoInput("inputFieldConfirm", "Password123!")
var inputs = document.getElementsByTagName('input');
for(var i=0; i<inputs.length; i++){
if(inputs[i].getAttribute('type')=='button'){
inputs[i].disabled = false
}
}
return true;
}
}
);
function TypeIntoInput(inputBox, valueText) {
var input = document.getElementById(inputBox);
input.select();
input.focus();
input.value="";
var text = valueText;
var l=text.length;
var current = 0;
var time = 100;
var write_text = function() {
input.value+=text[current];
if(current < l-1) {
current++;
setTimeout(function(){write_text()},time);
} else {
input.setAttribute('value',input.value);
var e = document.createEvent('KeyboardEvent');
e.initKeyEvent('ENTER', true, true, window, false, false, false, false, 13, 0);
// Dispatch event into document
document.body.dispatchEvent(e);
}
}
setTimeout(function(){write_text()},time);
}
Following js code is for html5 multiple files selected [duplicate] that doesn't work for chrome browser, after selecting a file homonymous several times.
For EX: selecting file admin.png for 2 or up times tandem. It only alert for first times.
DEMO (This doesn't work only in chrome browser ): http://jsfiddle.net/s9mt4/
function doClick() {
var el = document.getElementById("fileElem");
if (el) {
el.click();
}
}
function handleFiles(files) {
var d = document.getElementById("fileList");
var elementArray = document.getElementsByClassName("ImgNameUp");
var ReValue = true;
for (var i = 0; i < elementArray.length; ++i){
if(elementArray[i].innerHTML == files[0].name){
ReValue = false;
}
}
$('.ImgNameUp2').append('<div class="ImgNameUp">'+files[0].name+'</div>')
if (ReValue) {
alert('true');
} else {
alert('false');
}
}
what do i do,change in code that it working right?
Your input fields are listening to the onchange event to fire the javascript.
According to W3C's document:
onchange event occurs when a control loses the input focus and its
value has been modified since gaining focus
if you try to upload the same file, the value of file input does not change so does not fire the function. I think Chrome is the only browser to implement this "correctly".
If you want to upload twice, clear file input value:
function doClick() {
var el = document.getElementById("fileElem");
$(el).val(null); // <-- this line
if (el) {
el.click();
}
}
http://jsfiddle.net/s9mt4/2/
I am building a django site and have implemented the redips.drag library in one of my pages to allow dragging of table rows. I want a very simple functionality in my code- add a listener, so when the row is dropped, it send the row data to the server. jQuery-speaking, something like this:
$(function() {
$(someDomElement).on('DropEvent', function() {
// send data to server
};
});
The problem though, is that redips.drag is not a jQuery plugin but a javascript one, so my knowledge is a little (more than a little) lacking. I can probably find some other library, but it's performing really well and I prefer understanding how to work with it than look for a different one.
I can probably handle the "sending the data to the server" part by myself, what I can't understand at all is how to "catch" the drop event, what part of the dom do I listen to? I tried adding monitorEvents to different selectors but failed completely.
I also tried to manipulate the script.js file (the one that initializes the row handling), but also failed. here's the one I'm using (example 20 in the redips package):
"use strict";
// define redips object container
var redips = {};
redips.init = function () {
// reference to the REDIPS.drag library and message line
var rd = REDIPS.drag,
msg = document.getElementById('msg');
// initialization
rd.init();
//
// ... more irrelevent code ...
//
// row event handlers
//
// row clicked (display message and set hover color for "row" mode)
rd.event.rowClicked = function () {
msg.innerHTML = 'Clicked';
};
// row row_dropped
rd.event.rowDropped = function () {
msg.innerHTML = 'Dropped';
};
// and so on...
};
// function sets drop_option parameter defined at the top
redips.setRowMode = function (radioButton) {
REDIPS.drag.rowDropMode = radioButton.value;
};
// add onload event listener
if (window.addEventListener) {
window.addEventListener('load', redips.init, false);
}
else if (window.attachEvent) {
window.attachEvent('onload', redips.init);
}
Now I tried adding a console.log('hello') to the rd.event.rowDropped function (right above the msg.innerHTML line), but that doesn't work, I drop the row and nothing shows in the log. Doing a console.log outside the init function works so I know the script can pass stuff to the console.
Please, can anyone help me? I'm at a complete loss...
I know this may be a little lateto answer your question but I found the answer. You need to use the event dropped and the attribute rd.obj (REDIPS.drag.obj) to get the id use it with simple javascript like getAttribute('id')
redips.init = function () {
// reference to the REDIPS.drag library and message line
var rd = REDIPS.drag,
msg = document.getElementById('msg');
// initialization
rd.init();
// row clicked (display message and set hover color for "row" mode)
rd.event.clicked = function () {
msg.innerHTML = 'Clicked' + rd.obj.getAttribute('id');
};
// row row_dropped
rd.event.dropped = function () {
msg.innerHTML = 'Dropped' + rd.obj.getAttribute('id');
};
};
I have a jQuery script that searches in the DOM and shows the results in a list.
There is a simplified version of the script here: http://jsfiddle.net/FuJta/1/
There is usually a large number of results, so the script can take a while to execute. (In the example above, this is simulated with a function that delays the script). So if you type too fast in the searchbox, the script prevents you from typing, and it feels bad.
How could I change my script so that you can type freely, and the results show up when they are ready. I want something like the facebook search : if you type too fast, the results are just delayed, but you can still type.
Html
<p>Type in foo, bar or baz for searching. It works, but it is quite slow.</p><br/>
<input type="text" id="search"/>
<div id="container" style="display:none">
<div class="element">foo</div>
<div class="element">bar</div>
<div class="element">baz</div>
</div>
<div id="results">
</div>
Javascript
$(function() {
function refreshResults() {
var search = $('#search').val();
var $filtered = $('#container .element').clone().filter(function() {
var info = $(this).text();
return info.toLowerCase().indexOf(search) >= 0;
});
$('#results').empty();
$filtered.each(function() {
$('#results').append($(this));
});
}
// simulating script delay
function pausecomp(millis) {
var date = new Date();
var curDate = null;
do {
curDate = new Date();
}
while (curDate - date < millis);
}
$('#search').keyup(function() {
pausecomp(700);
refreshResults();
});
});
One solution could to refresh the results only when pressing enter. This way, the delay for searching the results feels ok. But I would prefer if I just delay the results and let the user freely type.
You should perform a search like this using asynchronous techniques. No doubt Facebook uses some sort of AJAX to request search results - which means getting the results from the server. This will help prevent the UI 'freeze' that you are currently experiencing.
Here is a very simple example of what you can try (it uses JQuery for the AJAX requests):
var searchInProgress = false;//used to work out if a search is in progress
var searchInQueue = false;//used to flag if the input data has changed
function getSearchResults(searchText){
if (searchInProgress ) {
searchInQueue = true;
return;
}
searchInProgress = true;
searchInQueue = false;
$.getJSON("URL",//URL to handle AJAX query
{ searchText: searchText},//URL parameters can go here
function (data) {
//handle your returned data here
searchInProgress = false;
if (searchInQueue){//text has changed, so search again
getSearchResults();
}
});
}
$('#search').keyup(function() {
getSearchResults($(this).val());
});
A few things to note: It is probably a good idea to handle failed AJAX requests to ensure you can reset the searchInProgress flag as needed. Also, you can add delays after the keyup as desired, but this all depends on how you want it too work.
From How to delay KeyPress function when user is typing, so it doesn't fire a request for each keystroke? :
var timeoutId = 0;
$('#search').keyup(function () {
clearTimeout(timeoutId); // doesn't matter if it's 0
timeoutId = setTimeout(refreshResults, 100);
});
It does what I want indeed.
Here's a solution that divides the search process into steps, returning flow to the browser during the process to allow the UI to respond.
$(function() {
function searchFunc($element,search) {
var info = $element.text();
return info.toLowerCase().indexOf(search) >= 0;
}
var searchProcessor = null;
function restartSearch() {
console.log('Restarting...');
// Clear previous
if (searchProcessor != null) {
clearInterval(searchProcessor);
}
$('#results').empty();
// Values for the processor
var search = $('#search').val();
var elements = $('#container .element').get();
console.log('l:',elements,elements.length);
// Start processing
searchProcessor = setInterval(function() {
if (elements.length == 0) {
// Finished searching all elements
clearInterval(searchProcessor);
searchProcessor = null;
console.log('Finished.');
} else {
console.log('Checking element...');
var $checkElement = $(elements.shift());
if (searchFunc($checkElement, search)) {
$('#results').append($checkElement.clone());
}
}
}, 10);
}
$('#search').keyup(function() {
restartSearch()
});
});
It only processes one element each time. That should probably be increased so it handles perhaps 10 or 100 each time around, but the important point is that the work is divided into chunks.
This solution should also be faster than the original because it doesn't clone() everything, only the elements that were matched.
I'd like to learn how to bind a CNRTL-S or COMMAND-S to call a function that I have on my page which AJAX saves the textarea content's
How can I bind those two commands? I used to use the following when it was just a textarea, but since adding TinyMCE it no longer works. Suggestions?
// Keybind the Control-Save
jQuery('#text_area_content').bind('keydown', 'ctrl+s',function (evt){
saveTextArea();
return false;
});
// Keybind the Meta-Save Mac
jQuery('#text_area_content').bind('keydown', 'meta+s',function (evt){
saveTextArea();
return false;
});
Thanks
To use a custom method for saving, i declare my saving function in the tinymce.init method
tinyMCE.init({
// General options
mode: "none",
/* some standard init params, plugins, ui, custom styles, etc */
save_onsavecallback: saveActiveEditor,
save_oncancelcallback: cancelActiveEditor
});
Then i define the function itself
function saveActiveEditor() {
var activeEditor = tinyMCE.activeEditor;
var saveUrl = "http://my.ajax.path/saveStuff";
var idEditor = activeEditor.id;
var contentEditor = activeEditor.getContent();
/* the next line is for a custom language listbox to edit different locales */
var localeEditor = activeEditor.controlManager.get('lbLanguages').selectedValue;
$.post(saveUrl ,
{ id: idEditor, content: contentEditor, locale: localeEditor },
function(results) {
if (results.Success) {
// switch back to display instead of edit
return false;
}
else {
activeEditor.windowManager.alert('Error saving data');
return false;
}
},
'json'
);
return false;
}
Don't forget to return false to override the default save action that posts back your data to the server.
edit to add: i only let the user change one tinymce instance at a time. You may want to change the locating the current instance to something else :)
edit #2: TinyMce already catches the Ctrl+s binding to process the data. Since it also cleans up html and is able to handle specific rules it's given when saving, the solution i propose is to plug your way of saving in tinyMce instead of fully overriding the Ctrl+s binding
The problem here is that the tinymce iframe does not delegate the events to the parent window. You can define custom_shortcuts in tinymce and/or use the following syntax:
// to delegate it to the parent window i use
var create_keydown_event = function(combo){
var e = { type : 'keydown' }, m = combo.split(/\+/);
for (var i=0, l=m.length; i<l; i++){
switch(m[i]){
case 'ctrl': e.metaKey = true;
case 'alt': case 'shift': e[m[i] + 'Key'] = true; break;
default : e.charCode = e.keyCode = e.which = m[i].toUpperCase().charCodeAt(0);
}
}
return e;
}
var handler = function(){
setTimeout(function(){
var e = create_keydown_event(combo);
window.parent.receiveShortCutEvent(e);
}, 1);
}
//ed.addShortcut(combo, description, handler);
ed.addShortcut('ctrl+s', 'save_shortcut', handler);
in the parent window you need a function receiveShortCutEvent which will sort out what to do with it