Flex Rich Text Editor - Limiting the number of characters - apache-flex

Is there a way to restrict the number
of characters in the Flex Rich Text Editor?
I guess there should be, since it's possible
in a textarea. So, if I could get hold
of the textarea contained in the rich
text editor, I would be able to do it

I think this would be fairly easy in actionscript, although I'm not exactly sure how one would do it in mxml. It appears that there are two children that are contained in the RichTextEditor, one of them being TextArea. According to the documentation (http://livedocs.adobe.com/flex/3/langref/mx/controls/RichTextEditor.html#propertySummary), you can access the subcontrols like so:
myRTE.toolBar2.setStyle("backgroundColor", 0xCC6633);
With myRTE being the instance of your text editor. So my guess would be something like this would work:
myRTE.textArea.maxChars = 125;
With 125 being the number a characters you would want restricted to.

i just ran into this.
setting your maxChars on the textArea will provide a limit to the text area, but that won't be representative of the number of characters the user can type.
as the user is typing, markup is added behind the scenes, and that greatly increases the char count.
for example, if i type the letter 'a' into a RichTextEditor, i get a char count of 142 and this htmlText:
<TEXTFORMAT LEADING="2"><P ALIGN="LEFT"><FONT FACE="Verdana" SIZE="10" COLOR="#0B333C" LETTERSPACING="0" KERNING="0">a</FONT></P></TEXTFORMAT>
i could not see a straightforward way to get a proper maxChar to work out of the box, so i extended RichTextEditor and gave it a maxChar. if maxChar > 0, i added a listener to "change" and did something like this in the event handler:
protected function handleTextChange(event:Event) : void
{
var htmlCount:int = htmlText.length;
// if we're within limits, ensure we reset
if (htmlCount < maxChars)
{
textArea.maxChars = 0;
this.errorString = null;
}
// otherwise, produce an error string and set the component so the user
// can't keep typing.
else
{
var textCount:int = textArea.text.length;
textArea.maxChars = textCount;
var msg:String = "Maximum character count exceeded. " +
"You are using " + htmlCount + " of " + maxChars + " characters.";
this.errorString = msg;
}
}
the idea is to apply a maxChars to the text area only when in the error state, so the user cannot type anything additional and will be prompted to erase some chars. once we leave the error state, we need to set the textArea.maxChars to zero so they can continue.

Related

JavaFX: Select a single line of text in a textarea where .getCaretPosition()

Platform: Intellij IDEA
Language: JavaFX
I would like to be able to select a line of text where the cursor lies. Similar to SQL Developer, I have a textarea that allows multiples lines of input or queries. It is nice to be able to use the textarea as a query bank while testing queries.
Using the txtOutput.getCaretPosition(), I would like to get the current integer index of the line where the cursor resides and then be able to select all of the text that is within that same line with the same keyboard shortcut as SQL Developer (Ctrl + Enter). Using the .selectForward() or .selectBackward() will not work if there are multiple lines.
Any help or suggestions as to how to limit the selection of text to one line or select text up until a specific character (e.g. ";") would be much appreciated.
public void executeEvent(KeyEvent event) {
//int cursorLine = txtInput.getCaretPosition();
if (event.isControlDown() == true && event.getCode() == KeyCode.ENTER) {
//select line of text where integer equals cursorLine
//txtInput.selectBackward();
//txtInput.selectForward();
}
}
Just search the text for the relevant delimiting character (e.g. a newline character), and select the relevant portion. The only thing you have to be careful of here is if the user selects the last line, in which case there will be subsequent newline character:
int caretPos = txtInput.getCaretPosition();
int previousNewline = txtInput.getText().lastIndexOf('\n', caretPos);
int nextNewline = txtInput.getText().indexOf('\n', caretPos);
if (nextNewline == -1) nextNewline = txtInput.getText().length();
txtInput.selectRange(previousNewLine + 1, nextNewLine);

.Net Core 3 Preview SequenceReader Length Delimited Parsing

I'm trying to use SequenceReader<T> in .Net Core Preview 8 to parse Guacamole Protocol network traffic.
The traffic might look as follows:
5.error,14.some text here,1.0;
This is a single error instruction. There are 3 fields:
OpCode = error
Reason = some text here
Status = 0 (see Status Codes)
The fields are comma delimited (semi-colon terminated), but they also have the length prefixed on each field. I presume that's so that you could parse something like:
5.error,24.some, text, with, commas,1.0;
To produce Reason = some, text, with, commas.
Simple comma delimited parsing is simple enough to do (with or without SequenceReader). However, to utilise the length I've tried the following:
public static bool TryGetNextElement(this ref SerializationContext context, out ReadOnlySequence<byte> element)
{
element = default;
var start = context.Reader.Position;
if (!context.Reader.TryReadTo(out ReadOnlySequence<byte> lengthSlice, Utf8Bytes.Period, advancePastDelimiter: true))
return false;
if (!lengthSlice.TryGetInt(out var length))
return false;
context.Reader.Advance(length);
element = context.Reader.Sequence.Slice(start, context.Reader.Position);
return true;
}
Based on my understanding of the initial proposal, this should work, though also could be simplified I think because some of the methods in the proposal make life a bit easier than that which is available in .Net Core Preview 8.
However, the problem with this code is that the SequenceReader does not seem to Advance as I would expect. It's Position and Consumed properties remain unchanged when advancing, so the element I slice at the end is always an empty sequence.
What do I need to do in order to parse this protocol correctly?
I'm guessing that .Reader here is a property; this is important because SequenceReader<T> is a mutable struct, but every time you access .SomeProperty you are working with an isolated copy of the reader. It is fine to hide it behind a property, but you'd need to make sure you work with a local and then push back when complete, i.e.
var reader = context.Reader;
var start = reader.Position;
if (!reader.TryReadTo(out ReadOnlySequence<byte> lengthSlice,
Utf8Bytes.Period, advancePastDelimiter: true))
return false;
if (!lengthSlice.TryGetInt(out var length))
return false;
reader.Advance(length);
element = reader.Sequence.Slice(start, reader.Position);
context.Reader = reader; // update position
return true;
Note that a nice feature of this is that in the failure cases (return false), you won't have changed the state yet, because you've only been mutating your local standalone clone.
You could also consider a ref-return property for .Reader.

Is it a good practice to compare combobox.selectedvalue to a string?

I have a combo box and couple of text boxes in my web page, depending on combobox's selected value, I will set focus to specific text box. Following is my code:
if (cbo1.SelectedValue == "01")
txt1.Focus();
else
txt2.Focus();
This would work even when the combo box being just loaded and there is no selected item. My question is "is this a good practice?" since SelectedValue actually is an object. Normally I use cob1.SelectedValue.ToString(), but I got an exception when there is no selected item.
Good practice would be to declare a string constant:
private const string FIRST_FIELD_VALUE = "01";
(...)
if (cbo1.SelectedValue.Equals(FIRST_FIELD_VALUE))
txt1.Focus();
else
txt2.Focus();
Otherwise, yes. I think comparing strings with strings is good practice.
Add this condition
if( cbo1.SelectedIndex > 0)
{
if (cbo1.SelectedValue == "01")
txt1.Focus();
else
txt2.Focus();
}

I am having trouble adding elements to a referenced vector of a map

EDIT: Forgot to mention that my programming language is C++, and my IDE is Qt Creator.
I don't understand why I am having trouble adding elements to a referenced vector of a map (i.e. sometimes it works and sometimes it fails).
For example:
class C_html4_tags {
public:
C_html4_tags();
//.......
typedef std::vector<S_html_attr_value> TYPE_attr_values;
//.....
};
//...
C_html4_tags::C_html4_tags() {
//........
map<S_browser, TYPE_attr_values> attr_supported_attr_values_map;
S_browser dummy_browser; //a fake browser key for referencing a fully Html 4.01-compliant supported attr values list
dummy_browser.name = "Dummy";
//.....
TYPE_attr_values& attr_supported_attr_values = attr_supported_attr_values_map[dummy_browser];
//......
**attr_supported_attr_values = attr_supported_attr_values_map[dummy_browser];**
//...
**attr_supported_attr_values.clear();
attr_supported_attr_values_map.clear();**
//......
**attr_supported_attr_values = attr_supported_attr_values_map[dummy_browser];**
//...
**attr_supported_attr_values.clear();
attr_supported_attr_values_map.clear();**
}
I do the bolded lines multiple times with a bunch of different attributes, with very little difference between them, without a problem until reaching this one attribute (a_tabindex_attr), in which the IDE doesn't report anything wrong when running it normally (except "The program has unexpectedly finished." However, when debugging it, it now reports:
Signal received
The inferior stopped because it received a signal from the Operating
System.
Signal name : SIGSEGV Signal meaning : Segmentation fault
And the backtrace points to the attribute I mentioned above, on the line of code which does this:
attr_supported_attr_values.clear();
Now, after adding some debugging cout lines to the code, I learned that what's happening is, for some reason, even after doing:
attr_supported_attr_values.push_back(attr_value);
the vector object which is the returned mapped value of:
attr_supported_attr_values = attr_supported_attr_values_map[dummy_browser];
is not actually being changed when I push_back an S_html_attr_value object to the referenced vector. Now, I don't why that is, since I do pretty much the exact same thing in a bunch of other attributes' code before this one, without any problem, but for some reason now, on this one, it ain't adding the object to attr_supported_attr_values (which is a reference to the returned mapped value of 'dummy_browser'). And I know this for a fact, because I outputted the size of the internal mapped value object of the map (using an iterator for the map), and it was 0 after the call to push_back(). However, what is even more odd is, I ALSO outputted attr_supported_attr_values.size() after the call to push_back(), and that was 1! Now how could that be since they're both supposed to be the same object??
Note:
The full code of what I'm talking about is below (or at least the attribute code, minus the debugging statements...):
//a_tabindex_attr:
attr_desc = "Specifies the position of an <a> element in the\n"
"tabbing order for the current document.\n"
"The tabbing order defines the order in which\n"
"elements will receive focus when navigated by\n"
"the user via the keyboard. The tabbing order\n"
"may include elements nested within other elements.\n"
"Elements that may receive focus based on tabindex\n"
"adhere to the following rules:\n\n"
"1. Those elements that support this attribute and\n"
"assign a positive value to it are navigated first.\n"
"Navigation proceeds from the element with the\n"
"lowest tabindex value to the element with the\n"
"highest value. Values need not be sequential\n"
"nor must they begin with any particular value.\n"
"Elements that have identical tabindex values\n"
"should be navigated in the order they appear\n"
"in the character stream.\n"
"2. Those elements that do not support this\n"
"attribute or support it and assign it a value\n"
"of \"0\" are navigated next. These elements are\n"
"navigated in the order they appear in the\n"
"character stream.\n"
"3. Elements that are disabled do not participate\n"
"in the tabbing order.";
attr_supported_attr_values = attr_supported_attr_values_map[dummy_browser];
attr_value_desc = "A number you specify for the tab index/order.\n"
"It must be a value between 0 and 32767.";
attr_value_content = "<i>number</i>";
attr_value = C_html4_attributes_obj.getAttrValue(attr_value_desc, attr_value_content,
attr_value_supported_browsers,
attr_value_required, attr_value_deprecated,
attr_value_notes, attr_value_tips);
attr_value.is_relative = true;
attr_supported_attr_values.push_back(attr_value);
try {
N_init_class_members::initAttr(C_html4_attributes::attr_tabindex, a_tabindex_attr, attr_desc,
attr_supported_browsers, attr_supported_attr_values_map, attr_required,
attr_deprecated, attr_notes, attr_tips);
}
catch (const char* exc) {
string exc_str = "Error! Call to N_init_class_members::initAttr() from\n"
"constructor of C_html4_tags class. That function\n"
"reported the following exception:\n\n";
exc_str += exc;
throw (exc_str.c_str()); //re-throw exception
}
a_tabindex_attr.is_standard_attr = true;
a_tabindex_attr.is_optional_attr = true;
//cleanup from attribute operations so we can begin working on the next attribute:
C_html4_attributes_obj.clear(); //wipes the slate clean for all the supported attributes' properties except content
attr_desc.clear();
attr_supported_attr_values.clear();
attr_supported_attr_values_map.clear();
attr_value_desc.clear();
attr_value_content.clear();

How to get multiple value from one textbox?

I have created web application and textbox as a textarea. I am using javascript for validation. When I enter value in text box so it should be number not alphabet I have use textmode is multiple line.
My problem is that how I get multiple value from textbox and store in array in javascript and check each value is number or not. I am using the web form. Please help me.
You can get the value from a textarea like
var txtvalue = document.getElementById("txtareaid").value
and if are using a separator then something like
var txtvaluearray = document.getElementById("txtareaid").value.split(';')
will get you all the values in an array if the seperator is ;
Edit
As per your update you can use \n as the separator and as pointed by #Sohnee you can do the validation.
As addition to rahul:
If you want the values in the textarea seperated by line, you can use \r\n as the splitter.
This is a starter for ten.
var textValues = document.getElementById("mytextarea").value.split("\n");
for (var i = 0; i < textValues.length; i++) {
if (isNaN(textValues[i])) {
alert(textValues[i] + " is not a number.";
}
}

Resources