I have a textarea inside a form:
<textearea id="message"></textarea>
While typing, whenever a user types the character # inside the textarea, I want to trigger a function for every character typed afterwards and till the user hits enter or space bar.
How is this possible using jQuery or plain JS ?
You can use this :
var myCallback = function () {
//put your code here
}
(function (callback) {
var jMessage = $('#message'),
callbackCallable = false,
keycodeEnter = 13,
keycodeSpace = 32;
jMessage.keyup(function (e) {
var lastLetter = jMessage.val().slice(-1);
if (lastLetter === '#') {
callbackCallable = true;
} else if (e.keyCode === keycodeEnter || e.keyCode === keycodeSpace) {
callbackCallable = false;
} else if (callbackCallable) {
callback();
}
});
}(myCallback));
If you want to detect only typing you can listen for a key pressed event.
var anyHitYet = false;
jQuery('#massage').keydown(function (event) {
if (anyHitYet) return;
var key = event.keyCode;
if (key === 51) {
//call your function here
} else if (key === 13 || key === 32) {
anyHitYet = true;
}
});
Basically if it's 51 then # is hit so call your function if space or enter are hit your #-when-pressed-function won't be executed until you make anyHitYet=false again
Somebody might paste something though so then it is a different story
Not sure if the above answers do what the OP wants.
I think a second or third # should be monitored aswell, till a space or return ends monitoring.
// have a flag somewhere and initialize it to FALSE
var doMonitor = FALSE;
$('#message').keydown(function(event){
// trigger monitoring after # was tipped
// (only once till space or return reset)
if(event.keyCode == 51 && !doMonitor){
doMonitor = TRUE;
}
else if(event.keyCode == 32 || event.keyCode == 13)
doMonitor = FALSE;
else if(doMonitor){
// do whatever needs to be done
}
});
You may also add an attribute to your #message textarea and remove it (or change its value) instead of using a variable.
// for setting an attribute
.attr( attributeName, value )
// for removing it
.removeattr( attributeName )
look here http://api.jquery.com/removeAttr/ and here http://api.jquery.com/attr/
Related
i wrote this code for an information booth at a park, it works on html5 and javascript
function myFunction() {
var name = document.getElementById('name').value;
var nameFilter = /^(?!.*([A-Za-z0-9])\1{2})(?=.*[a-z])(?=.*\d)[A-Za-z0-9]+$/g;
if(nameFilter.test(name)) {
$('#name').keydown(function (e) {
if (e.keyCode == 8 || e.keyCode == 46) {
$(this).unbind(e).keypress();
}
else {
e.preventDefault();
//return false;
}
});
}
};
it is supposed to prevent more than one consecutive characters (the booth keyboard is kinda broken and on key press it puts like 3 to 5 times the pressed key)
so far i've accomplished to limit it to two characters, but then thanks to preventDefault() it does nothing, i used an unbind to restore it but still i've accomplished nothing and i need help with this, whether it be by this mean of any other
This version accounts for capitalizing letters with the shift key
var nameElement = $('#name');
var wasShiftKeyPressed;
var nameAfterFirstKeyDown;
nameElement.keydown(function(e) {
wasShiftKeyPressed = e.shiftKey;
setTimeout(function() {
nameAfterFirstKeyDown = nameAfterFirstKeyDown ? nameAfterFirstKeyDown : nameElement.val();
});
})
nameElement.keyup(function() {
if (wasShiftKeyPressed) {
wasShiftKeyPressed = false;
nameAfterFirstKeyDown = nameElement.val(); //Otherwise capitalization only works for first letter
}
else {
nameElement.val(nameAfterFirstKeyDown);
nameAfterFirstKeyDown = "";
}
});
I want to trigger the following function only if the character count in textfield is equal to 8 else I will do something else. Below is the code I am using, Payment.php has the code for querying data.
$(document).ready(function() {
$('#item').keypress(function (event) {
var key = event.which;
if (key == 13) {
var item = $(this).val().trim();
if(item.length == 8){
var item = $('input#item');
if (item != ''){
$.post('ajax/Payment.php',{user:item}, function(data){
$('div#test').append(""+data+"</br>");
});
};
};
else {
// my code
};
};
});
}):
The problem was solved by removing a line from the code.
var item = $('input#item');
Now I am getting the correct values.
So I've got a .js file that checks that the values of my form. I'm trying to check that the form values aren't empty, and that one of the values contains a specific piece of text (in this case, my name). If the form does hold my name, then run the rest of the script.
Where I have commented //etc etc, an AJAX script is ran that posts to a PHP file.
This is all functioning as expected, until I run the additional if statement checking the input value for my name.
$('#submit').click(function(e){
this.enabled=true;
if ($.trim($("#name").val()) === "" || $.trim($("#topic_title").val()) === ""){
$('#message').html('you did not fill out one of the fields').css("color", "#be4343")
return false;
if($('#name').val().indexOf("Rich") != -1){ // without this if statement, the code runs fine.
$('#message').html("You have entered the wrong name.");
return false;
}
} else {
if($('#name, #topic_title').length && $('#name, #topic_title').val().length){
var name = $("#name").val();
var topic_title = $("#topic_title").val();
}}
// etc etc
});
Question: How would I go about checking that the value of the id '#name' isn't empty, and that it contains a specific piece of text?
Thanks in advance,
Richie.
Solution:
I removed the additional if statement and included the following code.
var name = $('#name').val();
if ( name.indexOf("Rich") || $.trim($("#name").val()) === ""){
If you indent your code consistently, it's fairly clear why you have a problem:
$('#submit').click(function(e) {
this.enabled = true;
if ($.trim($("#name").val()) === "" || $.trim($("#topic_title").val()) === "") {
$('#message').html('you did not fill out one of the fields').css("color", "#be4343")
return false;
if ($('#name').val().indexOf("Rich") != -1) { // Note that this is WITHIN the `if ($.trim($("#name").val()) === "" || $.trim($("#topic_title").val()) === "")` condition
$('#message').html("You have entered the wrong name.");
return false;
}
} else {
if ($('#name, #topic_title').length && $('#name, #topic_title').val().length) {
var name = $("#name").val();
var topic_title = $("#topic_title").val();
}
}
// etc etc
});
If you want it to be handled, it needs to be an else if for that condition instead:
$('#submit').click(function(e) {
this.enabled = true;
if ($.trim($("#name").val()) === "" || $.trim($("#topic_title").val()) === "") {
$('#message').html('you did not fill out one of the fields').css("color", "#be4343")
return false;
} else if ($('#name').val().indexOf("Rich") != -1) { // without this if statement, the code runs fine.
$('#message').html("You have entered the wrong name.");
return false;
} else {
if ($('#name, #topic_title').length && $('#name, #topic_title').val().length) {
var name = $("#name").val();
var topic_title = $("#topic_title").val();
}
}
// etc etc
});
(Well, as you have return, those could both just be if rather than else if...)
There are other problems though, for instance this expression in your final block:
$('#name, #topic_title').length
...which checks to see if either #name or #topic_title elements exist in your DOM at all (it doesn't do anything to check their values, and it doesn't require that they both exist, just one of them), and this:
$('#name, #topic_title').val().length
...will only check the value in #name, it will completely ignore the value in #topic_title, because when used as a getter, val only gets the value of the first element in the jQuery set. (Almost all of jQuery's functions that can be getters or setters are like that; the exception is text which is different from the others.)
Finally, this line:
this.enabled = true;
...is almost certainly a no-op, since the button cannot be clicked if it's not enabled, and as lshettyl points out, the property's name is disabled, not enabled. So this.disabled = false; if you're trying to enable it, or this.disabled = true; if you're trying to disable it.
By the look of your code, I assume you have a form that has either a class or an ID (or nothing). It'd be clever to use the form's submit event as opposed to click event of the submit button. This way you ensure that the form can also be submitted via the enter button (remember accessibility?). This is only an extension to T.J. Crowder's answer which has lots of good points from which you can learn/improve coding.
//Let's say your form has an ID 'topic'
$("#topic").on("submit", function() {
//Cache jQuery objects that would be resued, for better performance.
var $name = $("#name"),
$title = $("#topic_title"),
$msg = $('#message');
//One of the elements doesn't exist (exit)
//1 + 1 <= 1
if ($name.length + $title.length <= 1) {
return;
}
if ($.trim($name.val()) === "" || $.trim($title.val()) === "") {
$msg.html('you did not fill out one of the fields').css("color", "#be4343")
return;
} else if ($name.val().indexOf("Rich") !== -1) {
$msg.html("You have entered the wrong name.");
return;
} else {
//You do not need further checks such as length, val etc.
//as they have already been checked above.
var name = $name.val();
var topic_title = $title.val();
}
});
You can make comparison to know if it's empty:
if($('#name, #topic_title').length && $('#name, #topic_title').val().length){
var name = $("#name").val();
var topic_title = $("#topic_title").val();
}}
if(name=='' || name==undefined){
//do stuff here
}
});
I have a search filter that hides s as the user enters text into a form input. I need it to be dynamic, so that as the user changes their input, the filter refreshes. I accomplished this by having the filter clear on every keyup, but that causes the filter to be delayed and to flash when a word is typed quickly into the filter. You can see what I mean here:
http://cambridgefellows.com/directory-of-fellows/
Here is my jquery:
$(document).ready(function() {
$('input[name=searchFilterInput]').val('');
$('input[name=searchFilterInput]').keyup(function() {
var searchFilterVal = $('input[name=searchFilterInput]').val();
searchFilterVal = searchFilterVal.replace(/ /g, '-');
searchFilterVal = searchFilterVal.toLowerCase();
$('tr.hide').fadeIn('slow').removeClass('hide');
if(searchFilterVal == '') {
$('tr.hide').fadeIn('slow').removeClass('hide');
} else {
$('tr.fellows').each(function() {
var pattern = $(this).attr('class'); // the pattern to be matched
var match = pattern.match(searchFilterVal);//If pattern matches it returns the match
if(!match) {
$(this).fadeOut('normal').addClass('hide');
} else {
}
});
}
});
$('#searchForm').bind("keyup keypress", function(e) {
var code = e.keyCode || e.which;
if (code == 13) {
e.preventDefault();
return false;
}
});
});
I think there must be an easier way to handle this so that the filter dynamically updates as the user enter or alters their search text. Can someone more experienced than me look at this an enlighten me to the obvious thing that I'm overlooking? Thank you so much for your help.
Looks like you need a setTimeout and clearTimeout.
var timer;
$('input[name=searchFilterInput]').keyup(function() {
clearTimeout(timer);
timer = setTimeout(function() {
var searchFilterVal = $('input[name=searchFilterInput]').val();
searchFilterVal = searchFilterVal.replace(/ /g, '-');
searchFilterVal = searchFilterVal.toLowerCase();
$('tr.hide').fadeIn('slow').removeClass('hide');
if(searchFilterVal == '') {
$('tr.hide').fadeIn('slow').removeClass('hide');
} else {
$('tr.fellows').each(function() {
var pattern = $(this).attr('class'); // the pattern to be matched
var match = pattern.match(searchFilterVal);//If pattern matches it returns the match
if(!match) {
$(this).fadeOut('normal').addClass('hide');
} else {
}
});
}
}, 300);
});
That way whenever a user hits the next key, the timeout will be cleared from the previous keypress and the code will only execute for the current keypress.
Reduce the milliseconds if you feel it's not updating fast enough.
I am using the following code to insert data into mongo and am wondering how to I wipe it all from the console so my page isn't all cluttered. I guess I would also like to know how to selectively delete as well so i could select comment name entries and delete them.
live at http://tuts.meteor.com
Messages = new Meteor.Collection('messages');
if (Meteor.is_client){
////////// Helpers for in-place editing //////////
// Returns an event_map key for attaching "ok/cancel" events to
// a text input (given by selector)
var okcancel_events = function (selector) {
return 'keyup '+selector+', keydown '+selector+', focusout '+selector;
};
// Creates an event handler for interpreting "escape", "return", and "blur"
// on a text field and calling "ok" or "cancel" callbacks.
var make_okcancel_handler = function (options) {
var ok = options.ok || function () {};
var cancel = options.cancel || function () {};
return function (evt) {
if (evt.type === "keydown" && evt.which === 27) {
// escape = cancel
cancel.call(this, evt);
} else if (evt.type === "keyup" && evt.which === 13) {
// blur/return/enter = ok/submit if non-empty
var value = String(evt.target.value || "");
if (value)
ok.call(this, value, evt);
else
cancel.call(this, evt);
}
};
};//added as test
Template.entry.events = {};
/* Template.entry.events[okcancel_events('#messageBox')] = make_okcancel_handler({
ok:function(text, event){
var nameEntry = document.getElementById('name');
if(nameEntry.value != ""){
var ts = Date.now() / 1000;
Messages.insert({name: nameEntry.value, message: text, time: ts});
event.target.value = "";
}//if statment ends
}
});
*/
Template.entry.events['click #submit'] = function() {
var nameEntry = document.getElementById('name');
if(nameEntry.value != ""){
var ts = Date.now() / 1000;
Messages.insert({name: nameEntry.value, message: $('#messageBox').val(), time: ts});
}
}
Template.messages.messages = function () {
return Messages.find({}, { sort: {time: -1} });
};
}
To erase it all:
meteor reset
To delete each one by query with the os console
meteor mongo
db.collectionname.remove({query})
Or you could just do it from your chrome/safari/firebug console if your collection is exposed to the client, which you could build a UI and use:
collectionname.remove({query})
Tip:
You can use regexp to speed up and remove sets of documents matching a regular expression. e.g if I want to remove all values containing 'the' for the field name. This will work in the mongo console, server and client.
collectionname.remove({ name : { $regex: 'the', $options: 'i' }});
The i option makes the query case insensitive.
Of course collecionname is just a placeholder for whichever collection you decide to hit down.