Blinking Caret Not Showing up in Input Text Field - actionscript-3

I want one of my input text boxes to be the stage focus as well as have the blinking caret without the user needing to click inside the text field. I've been searching around frantically for an answer to this question, and everyone's answer boils down to this code: (the instance name of the text field being "input")
stage.focus = input;
input.setSelection(0, input.text.length);
But for some reason this code isn't working for me. Anyone have any idea why?
Update
For some reason this works:
stage.addEventListener(MouseEvent.CLICK,update);
function update(e:MouseEvent){
stage.focus = input;
}
And this does as well but the caret doesn't blink:
var counter:int=0;
stage.addEventListener(Event.ENTER_FRAME,update);
function update(e:Event){
counter++;
if(counter>30){
stage.focus = input;
}
}
This still doesn't satisfy my question though, why do you need a mouse click of some type in order to make my desired action work properly?

1.. How about if you set focus to happen inside a mouseClick function?
2.. Try this
stage.focus = input;
input.text = " "; //with a space (for blank but not empty);
input.setSelection(0, input.text.length);
3.. Bail out scenario then this utility might help or at least you'll learn something from its code Link here

Related

AS3 set focus on specific component

I have a form with several component: datagrid, textArea, text input...
For each component FocusIn Event is available.
var objTarget:String;
protected function memo_focusInHandler(event:FocusEvent):void
{
objTarget=event.currentTarget.id;
}
With memo_focusInHandler, I know which has focus.
My goal is to backup last focus objet, and re open Windows with focus on this object.
I try to do this:
objTarget.setfocus();
But it doesn't work. Could you help to found the best way to reach my goal.
String is not a display object, thus it can't be in focus. The representation of string on the stage is a TextField.
In as3 you can set focus to the desired target by using stage method:
stage.focus = myTarget;
Please see the corresponding documentation section: https://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/Stage.html#focus
There is no need (that you've shown) to work with the string id reference. It would much simpler (and slightly more efficient) to work directly with the object reference.
var objTarget:Object; // Object instead of type :String
protected function memo_focusInHandler(event:FocusEvent):void {
objTarget = event.currentTarget; //instead of the currentTarget's id property, assign the current target itself
}
Then, when you want to reset focus, you can do:
if(objTarget is TextInput || objTarget is TextArea){ //make sure it's a text input or text area first - optional but recommended if you don't like errors
objTarget.selectRange(objTarget.text.length, objTarget.text.length); //set cursor to the end
objTarget.setFocus(); //focus the text input/area
}
I found a solution:
this[objTarget].selectRange(this[objTarget].text.length, this[objTarget].text.length);
this[objTarget].setFocus();

The best method to create typewriter effect?

Hey everyone so I am creating a game that focuses on character to character interactivity. So when you interact with a character a chat box opens and the characters start talking to one another. I have the text setup like an old school typewriter effect one letter at a time. As of now I create it by typing each letter on separate frames and have them play through. When it gets to then end of the sentence in order for the user to go on to the next sentence I have a button that they tap Here is the code:
private function nextConvo(e:MouseEvent):void
{
nNext += 1;
trace(nNext);
if (nNext == 1)
{
conversation.gotoAndPlay(1);
}else
if (nNext == 2)
{
conversation.gotoAndPlay(117);
}
}
As you can see i set it up to play the next frame with the new conversation so on and so on. I have a lot more text to do I realized it will be really time consuming and wonder if there is a easier way.
A method to where it types the string in the text box and I can still use my button so when the user wants to see the next conversation they can press the next button.
I saw a video here of someone showing the code way of doing it but Not sure how I would implement the button without having to add a lot of new mouse listeners and timers. Code Method
Please any help would be appreciated.
Omg, yes, you will go nuts if you show one character per frame :)
The idea is to have a function to handle this for you that you have ONCE somewhere (for example, on your main timeline). Then you can call it from everywhere and just pass the text, textfield to type into and a button.
private var _myText:String;
private var _myTextField:TextField;
private var _myButton:Button;
private var _currentCharacterPosition:int;
public function typeText(text:String, myTextField:TextField myButton:Button):void
{
_myText = text;
_myTextField = myTextField;
_myButton = myButton;
_myButton.visible = false;
_currentCharacterPosition = 1;
typeNextCharacter();
}
private function typeNextCharacter():void
{
_myTextField.text = _myText.substr(0, _currentCharacterPosition);
if (_currentCharacterPosition == _myText.length)
{
// all text is typed out, show your button
myButton.visible = true;
}
else
{
// type next character. 0.2 is the delay between letters (200 ms)
_currentCharacterPosition++;
setTimeout(typeNextCharacter, 0.2);
}
}
Assuming you have the textfield and button in the same place (same frame), you could then do this in that frame:
_root.typeText("This is my text to type out", myTextField, myButton);

ActionScript 3 Selecting a MovieClip

My situation is this:
I've got several (2+) MovieClips on the stage.
Each one contains an input-textbox in addition to the background.
When I click the first MovieClip, it gets selected and a light blue shadow is displayed to indicate it like so: http://puu.sh/aueAw/3575e83aca.png
If I click the second one, it looks like this: http://puu.sh/aueEj/826e1c9cb9.png
However, when the second MovieClip's textbox is clicked, the first MovieClip becomes selected! This doesn't make any sense to me.
What could be causing this? Everything works as it should as long as I don't take these nested textboxes into account.
Thanks in advance for your helpful answers!
Best regards,
Olin K.
EDIT: Here's the code that I use to add event listeners to the MovieClips.
public function updateVisualDocument()
{
if (!uniDocument.isEmpty())
{
//Update the Visual Document if the current Document contains any pages
visualDocument.uniPage.gotoAndStop(uniDocument.getCurrentPage().getLayout());
visualDocument.uniPage.pageNumber.text = uniDocument.getPageIndex();
//Update Thumbnails
for each (var someThumb in thumbnailArray)
{
someThumb.deselect();
}
thumbnailArray[uniDocument.getPageIndex() - 1].select();
for (var i:int = 0; i < visualDocument.uniPage.panelContainer.numChildren; i++)
{
var somePanelMC = visualDocument.uniPage.panelContainer.getChildAt(i);
if (!uniDocument.getCurrentPage().hasPanels())
{
uniDocument.getCurrentPage().addPanel(somePanelMC);
}
somePanelMC.addEventListener(MouseEvent.CLICK, panelClicked);
uniDocument.getCurrentPage().getPanel(i).setPanelMC(somePanelMC);
function panelClicked(e:Event)
{
//Panel gets selected
var panelIndex:int = int(e.target.name.substring(5));
uniDocument.getCurrentPage().deselectAllPanels();
uniDocument.getCurrentPage().getPanel(panelIndex).select();
}
}
uniDocument.getCurrentPage().panelsAreFull();
uniDocument.getCurrentPage().selectFirst();
}
}
EDIT: I tried changing the textbox to the dynamic text (from the input text) type and the problem is still exactly the same. I click the textbox, it selects the first MovieClip. I think it may have to do with using the same instance name, but since it's nested, why should it matter?
Looks like I figured it out on my own. Partially. I worked off what LDMS said in his comment "did you accidentally give them the same instance name?"
Well, no, I didn't. BUT- the textboxes all had the same instance name. This is irrelevant, but it got me focused on the textboxes names, and I realized that since I had mouseChildren set to false, the textboxes were the ones firing off the event listener.
So I changed up a bit of my code to look like this:
function panelClicked(e:Event)
{
//Panel gets selected
if (!e.target.name == "myText")
{
var panelIndex:int = int(e.target.name.substring(5));
uniDocument.getCurrentPage().deselectAllPanels();
uniDocument.getCurrentPage().getPanel(panelIndex).select();
}
}
And now it works! It's a simple workaround, since doing myText.mouseEnabled = false; was not an option because it needed to be clicked.
Hope this helps someone in the future! Cheers!

Simple click event

I don't know why I can't figure out this problem that is really basics !! (sometimes the brain is tired I guess).
I've got a movieclip with a guitar string.
I want the string to move everytime I click on it.
I've created a movie clip with 2 lables. the first = non movement, the second = movement.
I've placed in the second one a stop(); action. (in order to stop the loop)
I've put this code :
stringOne.addEventListener(MouseEvent.CLICK, accord1, false, 0, true);
public function accord1(e:MouseEvent):void{
var stringOne;
trace("DING");
stringOne.gotoAndStop("first");
}
It works but, of course, it only play the string movement at the first click.
Do you know how I could play the string movement EVERYTIME that I click on the string ?
Thank you very much and sorry for this easy question (little ashamed)..,
EDIT
Ah ! It seems to work with goToAndPlay !
if (stringOne.currentLabel=="premier") {
stringOne.gotoAndStop("default");
} else {
stringOne.gotoAndStop("first");
}
Just a thing, I have to click twice..
(one click = the string vibrate (label2))
(one click again = the string does nothing (going to label 1))
(one click again = the string vibrate (label 2))
Is there anyway to automatically skip the 2nd click (the one that tells the string to go back at label 1), and let do the code like : - When animation of label 2 is finished, automatically go back to label 1 ? –
Presumably, the "movement" label of the string is some sort of animation?
It seems to me what you want in your "guitar string" movieClip is, on the last frame of the timeline animation for "movement", a script that says gotoAndStop('non movement'). The click handler should gotoAndPlay('movement').
Then, when the string 'movement' animation is finished, it will reset itself, so that the next time you click it will play again.
So, your original code is fine (before the edit; but remove the "var stringOne;" since that will break the reference to stringOne). The only thing you need to add is a script in the timeline on the last frame of the movement animation ("first" label?) that says gotoAndPlay("default") (assuming default is the 'non movement' label). You may need a stop() in the timeline frame for "default".
Something like that :
stage.addEventListener( MouseEvent.CLICK, onStageClick);
protected function onStageClick(event:MouseEvent):void
{
switch( event.target )
{
case stringOne:
trace("String one stuff");
break;
case stringTwo:
trace("String 2 stuff");
break;
}
}
Or add your movieClip into a Sprite and listen click event on the Sprite and not on the MovieClips.
Thank you for the answer. I've found an other way, instead of mouse click I've used mouse down for going to frame 2 and mouse up for going to frame 1

Toggle widget visibility with single button

The following code should write the inverse of true/false as found in the textbox back into the textbox when the button is clicked - but it doesn't work correctly. It will work correctly one way, but not the other (the one that works is whichever ClickHandler was defined last). I've tried using validateNotMatches too but no joy.
If I change the code so that the label's text is updated instead of the textbox's then that works fine.
I am aware of suggested workarounds such as using two buttons, but I just want to know if I'm doing something wrong or if this looks like a bug in GAS. Thanks.
function doGet(e)
{
var app = UiApp.createApplication();
var tb = app.createTextBox().setText('true');
var button = app.createButton('button');
var label = app.createLabel().setText('-');
button.addClickHandler(app.createClientHandler()
.validateMatches(tb, 'true')
//.forTargets(label).setText('false')
.forTargets(tb).setText('false')
);
button.addClickHandler(app.createClientHandler()
.validateMatches(tb, 'false')
//.forTargets(label).setText('true')
.forTargets(tb).setText('true')
);
return app.add(app.createHorizontalPanel().add(tb).add(button).add(label));
}
It's not a bug... both events fire. The validation happens on the current state of the widget, not on the state when the event was fired, so after you flip it to "false" the second handler validates and flips it back to "true".