-1

I have a user input with id userName and I am trying to get the user input text using $("#userName").val() after user has finished inputting the text in the textbox and then storing it in a variable (a directory path), however, I'm getting undefined for $("#userName").val(). I'm thinking that the undefined is occurring cause the text field is not ready at runtime, so I'm trying to set up a callback function to use in my directory path but i'm still getting undefined when I do console.log("This is the field name: " + getUserName()); Below is my callback function:

function getUserName(){ $("#userName").keyup(function(){ console.log(this.value); return this.value; }); } 

I am trying to use this in my directory variable here (the variable filePath is outside the function getUserName()):

var filePath = "/my/path/to/the/file/" + getUserName() + ".txt"; 

However, when I do this I am still getting undefined. Am I doing something wrong here?

Update:

name.html: <div class="subArea" id="pvDiv"> <p id="nameP">Name: <input id="userName" class="userInput" type="text" placeholder="Enter Name"> </p> </div> 
6
  • provide the html of your input Commented Feb 9, 2018 at 23:26
  • What you have provided is not a "callback" function. You have a function that registers an event handler on an element when that function is called (and yes, it will get re-bound for every time the function is called). Commented Feb 9, 2018 at 23:28
  • 2
    The getUserName() function doesn't actually return anything. It attaches an event handler for the keyup event to the element with the id userName and then exits, returning undefined by default. The function that handles the keyup event return this.value to, well, the event handling routine. If you wanted to get the user name in the getUserName() function, return $('#userName').val(); would work better. Commented Feb 9, 2018 at 23:29
  • On a secondary note - you cannot return values from event handlers, so return this.value is meaningless in this context Commented Feb 9, 2018 at 23:29
  • 1
    Your two easiest options are to have getUserName() return $("#userName").val() or if you want to update the file path on each keystroke, simply put filePath = "my/path/" + this.value + ".txt" inside your keyup handler. Make sure you define filePath outside of the event handler so that it updates and is visible wherever you need it. Commented Feb 9, 2018 at 23:32

4 Answers 4

2

Your code doesn't make sense for a lot of reasons, most of which can be found in the comments under your question. In short:

  • you're setting the keyup event listener inside the function, so unless the function is called the keyup event handler won't work, because the event listener won't have been set.

  • you overlook the fact that the execution of an event handler is an asynchronous operation and doesn't return anything.

  • even if the above were possible, you still don't have a return statement in getUserName.

Try using one of the following events and construct the path inside the event handler:

  • the blur event, which fires when the input loses focus.
  • the change event, which fires when a change in the value of the input occurs.

Code:

$("#userName").on("change", function() { var filePath = "/my/path/to/the/file/" + this.value + ".txt"; console.log("The new path is '" + filepath + "'."); }); 
Sign up to request clarification or add additional context in comments.

5 Comments

.on("change") would be more appropriate, so this does not get triggered each time the user focuses and blurs the field (via tab or clicks)
I'd leave that to the OP to decide @mhodges. But thanks for the comment; I made sure to include your suggestion in the answer.
The event handler callback is not an asynchronous operation, it just run in its own scope. All event handlers are fired synchronously and in order of binding
I didn't say the callback is an asynchronous operation @ecarrizo. I said its execution is, since the callback isn't executed immediately when passed as an argument, but after the event has fired.
I misslead, since there's a difference of time between the user pressing the button and the code creating the handler, the code execution is asynchronously between them (do not coincide in time). I Missread and tought you were meaning something else.
1

The problem with getting the value of the input using the $("#userName").val() directly probably is due that the DOM Is not ready yet when you execute that code or you are not waiting to certain event to happen, Take a look at

call a function after complete page load

and the Keyup Event handler on the input is not properly implemented since it will return nothing in your function.

Then depending on how you want to handle the user input is the solution that you need to implement, Something like this should work.

var filePath; function updateFilePath() { filePath = 'myPath/' + this.value + '.txt'; console.log('The file path has changed to: %s', filePath); } // When the dom Is ready to be used, you execute your code. $(function() { // Add an event handler when userName input value change $('#userName').on('change', updateFilePath); }) 

As said in comments you can use other events like 'keyup', 'blur' or whatever fit your needs better, but probably 'change' is the best option for your intention.

4 Comments

On my page there is no button, it's just a text field with autocomplete. Once the user types the first few letters there will be an autocomplete for their name and they just click the name it suggests. Is there another way I can do this without a button?
@kkmoslehpour Well yes, I have modified the example to match your HTML code that was missing.
Thanks a lot for your help! Really cleared things out for me :)
Glad to help :)
1
  • You can bind a custom event, i.e: refreshAutoComplete to your target element.
  • Trigger that event when the user enters information into your input text.
  • Pass the entered data throughout the trigger executions
 $('#autocompleteResult').trigger('refreshAutoComplete', [{userData: this.value}]); 
  • Get that data and execute your logic
 var filePath = "/my/path/to/the/file/" + data.userData + ".txt"; $(this).html(filePath); 

This approach separates the responsibilities:

  1. User input event.
  2. Manipulation of the entered user data.

Now your logic for filePath is separated and can be re-used from other parts of your JS application.

$(document).on('input', '#userName', function() { $('#autocompleteResult').trigger('refreshAutoComplete', [{userData: this.value}]); }); $(document).on('refreshAutoComplete', '#autocompleteResult', function(e, data) { var filePath = "/my/path/to/the/file/" + data.userData + ".txt"; $(this).html(filePath); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="subArea" id="pvDiv"> <p id="nameP">Name: <input id="userName" class="userInput" type="text" placeholder="Enter Name"> </p> <p id='autocompleteResult'> </p> </div>

Comments

0

The function you created is just binding the keyup event to the text box. That function getUsername gets invoked when you are typing in it.

To get its value you could use, $("#userName").val() So you can set filepath using

var filePath = "/my/path/to/the/file/" + $("#userName").val() + ".txt"; 

If you need to do it only when the userName field exists, you can do the following:

if( $("#userName").length > 0) filePath = "/my/path/to/the/file/" + $("#userName").val() + ".txt"; 

Hope this helps.

2 Comments

It would be better if you do not fetch the element twice on the example with the validation. store it in a variable and use it as the element reference.
I agree. Will make sure I provide optimized example code in the future.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.