jQuery onkeyup event in textarea that does not fires when nothing change - onchange

I was thinking to a function that check the key value pressed, and accept only the most common characters, canc, enter, ... because i need it only for basic ascii character set (not ñ, č, chinese chars, ...).
Or function that after every keyup checks if value has changed.
But really jQuery doesn't have an event handler for this situation?
Oh, it should be cross-borwser.

You could try canceling keys, but then they might just paste. Or might find a way to set the value via script. The best thing to do is to validate that the value doesn't have special characters before they're sent to the server (or otherwise acted upon).

var oldval = $('textarea').val();
$('textarea').live('mouseover', function() {
if($(this).val() != oldval) {
//do your thing here
oldval = $(this).val(); //reassign oldval
}
});
This will activate on mouseover and do whatever you want it to if the new value is not the same as the old one. I haven't tested it but I think it should also cover pasting.

Related

Selenium - How to Wait?

I need to be able to wait for one of multiple things that could happen to a page after a certain action is taken. Examples of these things are: URL changes, a certain title is set, certain content on the page appears, etc.
This explains how to wait - https://github.com/facebook/php-webdriver/wiki/HowTo-Wait. However, I need to be able to wait for multiple things at the same time. I want the waiting to stop once one of the conditions occur.
Is there a way to "or" during a wait (e.g. wait for URL to change OR title contains "foo" OR "bar" appears on the page, etc.)?
In the same link you posted, look for the "Custom conditions" section, i.e.:
$driver->wait()->until(
function () use ($driver) {
$elements = $driver->findElements(WebDriverBy::cssSelector('li.foo'));
return count($elements) > 5;
},
'Error locating more than five elements'
);
Note the use of findElements in the code example. When nothing is found, an empty array will be returned. If only one of three elements must be visible, you do something like:
$driver->wait()->until(
function () use ($driver) {
$elements1 = $driver->findElements(WebDriverBy::cssSelector('li.foo1'));
$elements2 = $driver->findElements(WebDriverBy::cssSelector('li.foo2'));
$elements3 = $driver->findElements(WebDriverBy::cssSelector('li.foo3'));
return count($elements1) + count($elements2) + count($elements3) > 0;
},
'Error locating at least one of the elements'
);

Dynamically setting passwordMask in Titanium

Since Titanium doesn't allow you to manually change the hintText colour of a textfield, I have to set hintText manually. Because of this, I have to dynamically change the passwordMask setting on one of fields I'm using.
However, I'm getting weird behaviour and I can't tell if I'm doing something wrong, or if it's a bug in Titanium.
So, here's my markup:
<TextField id="password" onFocus="passwordFocusEvent" onReturn="passwordReturnEvent" onBlur="passwordBlurEvent" value="password"></TextField>
And some of my controller code:
function passwordFocusEvent(e) {
slideViewUp();
if (e.value === 'password') {
e.source.setPasswordMask(true);
e.source.value = '';
}
}
function passwordBlurEvent(e) {
if (!e.value) {
e.source.setPasswordMask(false);
e.source.value = 'password';
}
}
function passwordReturnEvent(e) {
slideViewDown();
passwordBlurEvent(e);
}
What happens is bizarre. When I focus on the password field, it remains plain text. I enter some text, then click off to another field, stays as plain text.
I click back to the password field, it's STILL plain text.
Now here's the weirdness. Up to this point, I would just assume it's not working. However, when I click off this second time, the passwordMask is set.
Major WTF.
I even tried targeting the field directly using $.password.passwordMask = true; but same thing.
Unfortunately, you cant do this. According to the docs on Ti.UI.TextField in the fine print;
Note: on iOS, passwordMask must be specified when this text field is created.
Its not all bad news though, there are a couple ways you can approach this, one option is to make the password mask yourself, by listening to the change event:
var theStoredPassword = '';
$.password.addEventListener('change', function(e) {
var newpass = e.source.value;
if(newpass.length < theStoredPassword.length) {
// Character deleted from end
theStoredPassword = theStoredPassword.substring(0, theStoredPassword.length-1);
} else {
// Character added to end
theStoredPassword += newpass.substring(newpass.length-1);
}
// Mask the text with unicode ● BLACK CIRCLE, 25CF
$.password.value = new Array(newpass.length + 1).join('●');
});
Another option, would be to have two text fields and swap them out whenever the user focuses the password field, the top one would have the custom hinttext, the bottom one would be passwordMasked. In fact thats probably way easier than what I just coded up. :-)

Avoiding onChange on ComboBox when chaning selection dynamically

I have a combobox for which I have a validation that a change in selection should be reverted back on meeting a condition.
I have detected the condition but when I change the value and displayedValue of combobox, the onChange associated with the combobox gets fired. Following is the code I am using to change the selection:
dijit.byId('scheduleName').set('value',val,false);
dijit.byId('scheduleName').set('displayedValue',displayVal,false);
I have also tried to set the onChange to blank before firing above code and then re attaching the onChange code as below:
dojo.connect(dijit.byId('scheduleName'),'onChange','');
dijit.byId('scheduleName').set('value',scheduleNameVal,false);
dijit.byId('scheduleName').set('displayedValue',trim(String(scheduleNameName)),false);
dojo.connect(dijit.byId('scheduleName'),'onChange', "hideGrid");
hideGrid is a javascript function. I am using Dojo 1.8
Set only value, not displayedValue
myComboBox.set("value", value, false);
then only watch callback is fired, not dojo/on or onChange.
Check this jsFiddle out to see differencies: http://jsfiddle.net/phusick/d7ymY/
Note: If you need to trim() displayedValue consider a custom setter or dojo/aspect::before.
You should use dojo.disconnect instead of
dojo.connect(dijit.byId('scheduleName'),'onChange','');
Example:
var hndl, sched = dijit.byId('scheduleName');
var fnWireOnChange = function(){
hndl = dojo.connect(sched,'onChange', 'hideGrid');
};
dojo.disconnect(hndl);
sched.set('value',scheduleNameVal,false);
sched.set('displayedValue',trim(String(scheduleNameName)),false);
fnWireOnChange();
As a side note, connect/disconnect has been deprecated in favor of dojo/on
https://dojotoolkit.org/reference-guide/1.8/dojo/on.html#dojo-on

Clearing input textbox using FuncUnit

I am writing FuncUnit for my application. I am browsing the application in Google Chrome. I have a textbox which is initially hidden. I need to make it visible and then clear the text already present in that textbox. I have the following code which makes the box visible but fails to clear the text in it.
S('#search').visible().clearText();
Can anyone tell what is wrong here?
Try to clear the textbox by typing - Ctrl+A and Delete.
var input = S('input.my-input');
input.type('[ctrl]a[ctrl-up][delete]', function() {
// Continue in test case after the text has been removed
});
Your statement is not accurate. visible() does not turn things visible. It is a wait function which waits for the source element to become visible before proceeding to the next action.
koalix's key sequence works. With the type() command you might need to first click into the text input before clearing it.
Try:
S('#search').visible().click().type('[ctrl]a[ctrl-up][delete]');
You could also try empty quotes <" ">
var input = S('input.my-input');
input.type('', function() {
// remove existing text
});
I don't know if you're still waiting for an answer.
I think you're not using visible() in the correct way.
In FuncUnit (see docs here), among other things, you can distinguish between "actions" and "waits". visible() is a wait, and should be used to wait for an element to become visible, like this:
S('#el').visible( function() {
// do something when element with id="el" becomes visible
});

Flexigrid - how to turn off row selection

Is it possible to turn off the row selection feature on Flexigrid?
It's somewhat annoying when you haven't implemented anything that makes use of the selection.
Unfortunately Mr Flibble's accepted answer does not stop all selection capability, it merely restricts it to one row.
To disable it completely, add a new property to the $.extend block (around line 20)
// apply default properties
p = $.extend({
<SNIP>
onSubmit: false, // using a custom populate function
disableSelect: true
Then in the .click section of the row (around line 754) add a check for the property
$(this)
.click(
function (e)
{
var obj = (e.target || e.srcElement); if (obj.href || obj.type) return true;
if (p.disableSelect) return true;
$(this).toggleClass('trSelected');
if (p.singleSelect) $(this).siblings().removeClass('trSelected');
}
)
Turns out you need to change the singleSelect property to true.
singleSelect: true
I know this thread is a bit old but I came upon it looking for the same thing. The singleSelect didn't work for me as I didn't want to be able to select any row. I found that I could remove any row selection with a single line of code:
$('.grid tr').unbind('click');
This a course removes all bindings on the table row so if you needed the binding you won't have it unless you rebind later but I needed to remove any and all row selection on my table. I didn't need to touch the flexigrid code to do so which I liked a bit more than previous answers.