ExtJS4 Change TextField emptyText on the Fly - javascript

How do I change my textfield's emptyText field on the fly?
I've tried:
myTextField.emptyText = 'new empty text';
myTextField.emptyText = 'new empty text';
myTextField.applyEmptyText();
myTextField.emptyText = ['new empty text'];
myTextField.emptyText = ['new empty text'];
myTextField.applyEmptyText();
I realize that applyEmptyText() is not listed in the API docs but I thought I'd give it a shot as this worked in previous versions. I've also read that one needs to add the brackets too.
I've printed myTextField to the console and I see the emptyText property set to what I want but the field in the browser is not updating.

I love ExtJS and all that it brings to the table but nuances like this (trying to get dynamically updated emptyText to work) really slow down development. None of the other SO posts on this issue have resolved the problem for me (emptyText just wouldn't update).
After several hours "fighting with my tools" and dozens of different permuations I came up with the following simple fix - just add a myTextField.reset(); to your code block.
myTextField.emptyText = 'new empty text';
myTextField.applyEmptyText();
myTextField.reset();
Hope this saved someone else some time.

Your first attempt should work as expected. However, as you can see in the source, there are certain criteria to be met before the placeholder is set. Your best bet is to place a breakpoint in the applyEmptyText function and debug it.
applyEmptyText : function(){
var me = this,
emptyText = me.emptyText,
isEmpty;
if (me.rendered && emptyText) {
isEmpty = me.getRawValue().length < 1 && !me.hasFocus;
if (Ext.supports.Placeholder) {
me.inputEl.dom.placeholder = emptyText;
} else if (isEmpty) {
me.setRawValue(emptyText);
me.valueContainsPlaceholder = true;
}
//all browsers need this because of a styling issue with chrome + placeholders.
//the text isnt vertically aligned when empty (and using the placeholder)
if (isEmpty) {
me.inputEl.addCls(me.emptyCls);
}
me.autoSize();
}
}

Through debugging it seems like the Text.inputEl.dom.placeholder property was not being set during my event in time to update the field. Based on the reset source above, I found that just setting the Text.inputEl.dom.placeholder in my code worked.

This applyEmptyText method is definately buggy!!
Look at the code, and imagine you want to set a zero as emptyText....
Look at the if conditions:
if (me.rendered && emptyText)
when emptyText = 0 , in the condition it will be as a false interpretated..... it's then with this code impossible to set the zero as emptyText!!!!

Related

Individual custom start position in Qualtrics through Javascript

I want to use either a slider question or a draggable bar chart in Qualtrics to present to respondents how they answered in former questions. More specifically, I compute a value out of then answers with weighting, and want the slider or bar to be positioned at this value.
Notably, as each respondent has a value (stored in an embedded data field), the position will thereby be individual for each respondent. Piping only works for text fields, as far as I understood the support page.
Based on this question/answer I came to the following code for the bar graph:
Qualtrics.SurveyEngine.addOnload(function()
{
var result = "${q://Field/result}";
var qwidth = $('QID1936~1~track').offsetWidth;
var resrec = ((qwidth*result)/100);
$('QID1936').select('.bar').each(function(name, index) {
name.setStyle({ width: resrec +"px"});
});
});
Basically, I get the result for each respondent out of the embedded data, get the width of the full bar graph, compute the ratio that should be colored based on the result, and update the position of the bar graph (following the mentioned answer).
Funny enough, everything works when done in the console. Also, the embedded data is correctly loaded, qwidth as well.
Two problems arise: it seems resrec could be computed wrongly, as a console.log() spits out 0 instead of the correct value. I assumed this could be somehow as a variable is not recognized as number, but several tries with Number() or 0+var did not change how this works in Qualtrics. In the console, it works just fine.
Also, no update of the bar (or slider with similar code) happens, neither with the correct value nor with the 0 that is produced by Qualtrics.
I search for two things: either a solution to the Javascript problem as described, basically how I can update the bar or slider with embedded data. Or another solution how to directly get embedded data into one of those two question formats as a starting value for each respondent individually.
Thanks for your help or ideas!
Try this:
Qualtrics.SurveyEngine.addOnload(function()
{
var qid = this.questionId;
var result = parseFloat("${e://Field/result}");
var qwidth = $(qid+'~1~track').offsetWidth;
var resrec = ((qwidth*result)/100);
$(qid).select('.bar').each(function(name, index) {
name.style.width = resrec + "px";
});
});
Notes:
It is best not to use a hardcoded QID
In a pipe use e: to refer to an embedded variable. q: is for questions.
Use parseFloat to convert the string to a number
No need to use setStyle if you are only setting one value
One solution proposed by Qualtrics support: when you use bars and/or sliders, piped values are actually possible.
The trick is to have the value of the bar/slider shown (a thing we do not use in the whole survey elsewhere). Then, you can access over the Advanced Question Options > Add Default Choices the blue arrow for piping text behind the value. Through this, the value is individually set to either embedded data or another answer.
Note, however, to tick "Show value" before accessing the default choices, else you will only be able to drag around the bar and set it for all simultaneously.
Here is a solution using the Qualtrics Question API method setChoiceValue that does not require you to compute the ratio and update the length of the bars manually.
Below is an example code for the result of ten respondents saved in embedded data from previous questions.
Qualtrics.SurveyEngine.addOnload(function()
{
var embedded = ["${e://Field/r1}", "${e://Field/r2}",
"${e://Field/r3}", "${e://Field/r4}", "${e://Field/r5}",
"${e://Field/r6}", "${e://Field/r7}", "${e://Field/r8}",
"${e://Field/r9}", "${e://Field/r10}"];
for (var i = 0; i < 11; i++) {
var index = i + 1;
var choiceInput = embedded[i];
this.setChoiceValue(index, choiceInput);
}
});
For one respondent:
Qualtrics.SurveyEngine.addOnload(function()
{
var value = "${e://Field/r1}";
this.setChoiceValue(1, value);
});

How do you programmatically clear HTML5 date fields?

I'm looking for a way to programmatically clear HTML5 date fields with Javascript (specifically jQuery). So far I have tried two methods which I thought obvious:
$('input[type=date]').val('');
$('input[type=date]').val('0000-00-00');
But neither of them work on the latest version of Chrome for PCs at least, haven't tried them with other browsers or platforms yet. Is there an API call or something that can clear date fields in a cross-browser way? Solutions I have searched for like this require the user to clear the date field whereas I need this to be done programmatically.
$("input[type=date]").val("") works for me in chrome. It sets the input field to dd/mm/yyyy.
Maybe it's browser specific. Most browsers have only partial or no support for this input: http://caniuse.com/input-datetime
If you can't clear a date field, this could also depend on a browser bug.
I spend some time until I found out that you cannot reset the date in Firefox if the date control is disabled.
See: https://bugzilla.mozilla.org/show_bug.cgi?id=1465979
Without the bug, I am able to clear the date like that:
document.getElementById("myDate").value = "";
I needed to do it recently and i've made this little hack... Seems to do the job.
It was just with JavaScript, but the jQuery version is pretty the same...
function reset_date_native() {
var date_input = document.getElementById('date-id');
//erase the input value
date_input.value = '';
//prevent error on older browsers (aka IE8)
if (date_input.type === 'date') {
//update the input content (visually)
date_input.type = 'text';
date_input.type = 'date';
}
}
function reset_date_jquery() {
$('#date-id').val('')
.attr('type', 'text')
.attr('type', 'date');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="date-id" type="date" />
<button onclick="reset_date_native()">Trigger the reset function (native)</button>
<button onclick="reset_date_jquery()">Trigger the reset function (jQuery)</button>
document.getElementById("datePicker").valueAsDate = null;
this line of code works with my browser (chrome) , didn't tested in other browsers
You can change the date as empty
$('#invoiceDate').val(new Date())
You can restore the placeholder;
$('input[type=date]')[0].valueAsDate = '';
this line works with my browser (chrome, latest version)
$('input[type=date]')[0].value = 0;
Can you use the reset function of your form ?
You can do this with reset button :
<button type="reset" value="Reset">Reset</button>
or programmaticaly :
$("#yourFormId").reset();
or
$('input[type=date]').reset();
Use the native defaultValue property:
$('input[type=date]').each( function resetDate(){
this.value = this.defaultValue;
} );
This works as long as the form doesn't have an initial value specified, as demonstrated in this fiddle.
This solution checks if a default value exists and, if so, uses it to reset the input. Otherwise, it clears the input it by updating value and valueAsDate.
Info on valueAsDate available at: w3c.org.
var dateEl = element.find('input#myDateInput[type="date"]');
dateEl[0].value = ('undefined' !== typeof dateEl[0].defaultValue) ? dateEl[0].defaultValue : '';
if (dateEl[0].value !== '') {
dateEl[0].valueAsDate = new Date(dateEl[0].value);
} else {
dateEl[0].valueAsDate = null;
}
I had a similar issue with the value.
I wanted the onchange() function to run when I set the value to empty. Normally, this always works but for date it didn't even if the value appeared to be blanked and you blurred the input
I discovered that I had to force the onchange() function to trigger the value change too.
document.getElementById('mydate').value='';
document.getElementById('mydate').onchange();
It worked for me and now my form fades out when the value is blanked.
I do not know why that works. I tried blur() and focus() but nothing else seems to work.
Set myDate = one space.
I like simple solutions.

jquery masked input plugin to not clear field when errored

I'm looking at the http://digitalbush.com/projects/masked-input-plugin/
I'm calling it like this:
$(control).mask('999-999-9999');
And I don't want it to throw away the users input if something is wrong, e.g. they haven't finished
[407-555-____]
If you leave the field after having typed this much, it clears it. I'd like to leave it so they can finish later.
I'm new to jQuery, and I've looked through his source, but I can't find any way to do that, nor can I find any way to edit it to accomplish what I want, because the code is arcane to my eyes.
Set autoclear option to false.
$(control).mask('999-999-9999', {autoclear: false});
It looks like I should just make the whole mask optional:
mask('?999-999-9999')
That way the control thinks what the user has is "valid" and I can continue. Even though it isn't really the optional part of the mask.
You should delete statement input.val(""); in checkVal() function for a proper solution.
If you're using minified version, you should search and delete statement:
if(!a&&c+1<i)f.val(""),t(0,k);else
Try update file jquery.maskedinput.js
In function function checkVal(allow) set parameter allow on true. Its help for me.
function checkVal(allow) {
allow = true; ///add this command
//..............
}
In addition to removing the input.val("") in checkVal() you can also change the call to clearBuffer.
In the original code it is: clearBuffer(0, len); removing all user input.
if you change this to clearBuffer(lastMatch + 1, len); the user input will be displayed, followed by the mask placeholders that are still needed to complete correct input.
I have also added a user message in the .bind. This works for us, as we are using the MaskedInput for exactly one type of input. I'm checking for any input going further than position 7, because that's where the user input starts.
Here is what I did:
.bind("blur.mask", function() {
// find out at which position the checkVal took place
var pos = checkVal();
// if there was no input, ignore
if (pos <=7) {input.val(""); clearBuffer(0, len);}
// if the user started to input something, which is not complete, issue an alert
if (pos > 7 && pos < partialPosition) alert("Tell the user what he needs to do.");
if (input.val() != focusText)
input.change();
})
Adding Placeholder could solve the problem.
$(control).mask('999-999-9999');
Add an empty place holder into mask. see below
$(control).mask('999-999-9999', { placeholder: "" });
which would replace _ on the input text field by default. so there would bot be any _ left if the input length is dynamic and not fixed.
Looking for into the pluging script the unmask method.
$('#checkbox').unmask();

jQuery(formElement).val(null) : inconsistent results in different browsers

The code is here:
http://jsfiddle.net/jf7t2/1/
Please run it on the latest versions of all browsers, and see for yourself. When the button is clicked, on:
on Chrome (and Safari of course) it just doesn't select anything, instead creates some ghostly empty option
on Firefox and Opera, it works the way I expect and want it to work, de-selects all options
on Internet Explorer, it does nothing
So, which one is the expected behaviour?
If you look at the jQuery 1.5.1 source code line 1970 you'll see this:
// Treat null/undefined as ""; convert numbers to string
if ( val == null ) {
val = "";
So the expected behavior is the same as if you gave the empty string as argument.
If you continue to line 1984 you'll see this:
} else if ( jQuery.nodeName( this, "select" ) ) {
var values = jQuery.makeArray(val);
jQuery( "option", this ).each(function() {
this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
});
if ( !values.length ) {
this.selectedIndex = -1;
}
So the expected behaviour is:
if there is an option with an empty string value, choose that.
if not set selectedIndex = -1
From here on it is up to the browser to determine what to do if selectedIndex is set to -1
Looking at the msdn library it says:
The selectedIndex property returns -1
if a select object does not contain
any selected items. Setting the
selectedIndex property clears any
existing selected items.
So in ie the expected behavior seems to be that it will de-select all options
The same goes for the MDC documentation and thus firefox, where theya re very explicit about it
Returns the index of the currently
selected item. You may select an item
by assigning its index to this
property. By assigning -1 to this
property, all items will be
deselected.
It seems webkit based browsers have a different take on things.
If you google "webkit selectedIndex" you will see quite a few bug report regarding the select tag, so maybe it's just funky ;)
Come to think of it, this is a bug in jQuery since it is a library that should be able to behave the same across browsers - it should be reported ;)
which one is expected behaviour?
jQuery's val() function is documented to take a string value or an array of string values, so there is no defined behaviour.
Try val([]) to select nothing, or to restore the original value use the defaultSelected property:
$('#select option').each(function() {
this.selected= this.defaultSelected;
});
I forked your jsfiddle with one that I think can help you:
http://jsfiddle.net/marcosfromero/AYLrT/
I tested it in IE, Firefox and Chrome
jQuery("#button").click(function(event){
var select = jQuery("#select");
// Button click will try to find a "none" option (with no value)
if(select.find('option.none').length===0) {
// If it's not found, it creates the option
select.prepend('<option value="" class="none"></option>');
}
// And then it selects it
select.val('');
});
// When select value is changed...
jQuery('#select').change(function() {
var me = $(this);
// ... to something different than empty ("")...
if(me.val() !== '') {
//... it removes that option
me.find('option.none').remove();
}
});
None of those behaviors are unreasonable.
In Chrome, it makes sense because you are setting the value to nothing, so it displays nothing.
In IE, it makes sense because you are not changing to a valid value, so it changes nothing.
If you want all the browsers to behave like Firefox, just set the value to 1.

How can I ensure that changes to a form DOM are complete before POSTing?

Currently I have a race condition existing in my JavaScript code. What I am trying to do with this code is convert all check boxes which are a part of the 'checkbox' class and are not checked into text boxes with a value of zero. Currently when you post a check box that is not checked it does not appear in the $_POST data. However I need to know all the values whether true or false for these particular set of check boxes.
The code I have is here:
Code:
function checkboxConvert() {
var chkBxs = $$('.checkbox');
for (var i = 0; i < chkBxs.length; i++) {
if (chkBxs[i].checked == false) {
chkBxs[i].type = 'textbox';
chkBxs[i].value = '0';
}
}
setTimeout("document.productForm.submit();",1000);
}
Now the problem that I have been getting is that when I try to submit this form the values of the recently changed text boxes does not appear in the $_POST data. Therefore, as you can see above I have postponed the page submit for 1 sec and then I have all the data available to me. However as time goes on and my data set gets larger, 1 sec may no longer be enough. This I think is a race condition and I need to figure some way of running the code only after all the check boxes have been converted and they have their new values. I would have thought that this would be unnecessary from the start, but for some reason it's trying to run both pieces simultaneously and I can't submit until I have the proper values in place.
Any help is much appreciated!
This is definitely not the way to do web. I strongly advise you abandon your checkboxConvert function, and solve this issue on the server side
JavaScript always runs single-threaded in the browser so I don't think it can be a race condition.
I'd generally agree with others that you shouldn't do this, but your problem may be that you're changing the element to a type of "textbox" instead of "text". If you declare an input of type "textbox" in HTML markup, it will usually render as a text field anyway because that's the default. However, changing an already valid "checkbox" type input to the invalid "textbox" may not work predictably.
Try changing it to this:
function checkboxConvert() {
var chkBxs = $$('.checkbox');
for (var i = 0; i < chkBxs.length; i++) {
if (chkBxs[i].checked == false) {
chkBxs[i].type = 'text';
chkBxs[i].value = '0';
}
}
// Because JS in the browser is single-threaded, this
// cannot execute before the preceding loop completes anyway.
document.productForm.submit();
}
There's got to be a better way to do this. Try something like:
Know about all your possible values on the server side. It looks like you're using PHP; keep a simple array with the names of your checkboxes.
When you take your $_POST data, remove the names of checkboxes you've received values for from your array.
The remaining are all false.

Categories

Resources