How to submit the ID of input field - javascript

Is it possible (and if so, how) to submit the ID of the input field in focus when clicking it?
I've made an autosave-feature in a online-tool, that saves every time an input field is blurred.
However, since the page itself is updated on every field blur, it loses focus when another field is clicked, so I would like it to submit the ID of the field, just clicked so that I can set it in focus, manually.
(off-topic) I don't use jQuery anymore when updating, since I need the page to process a lot of numbers, serverside... so in my opinion, it's most convenient that it works as described.
I've done some researching and ended up with two possibilities:
focusobject = $(':focus');
and
document.activeElement
but when doing a JS alert, it just says [object Object] and [object HTMLBodyElement] instead of "fieldEmail"
Any ideas?
UPDATE
I previously used this to update in the background:
function writeNow(datastring) {
$.ajax( {
type: 'POST',
url: 'update.php',
data: datastring,
success: function(data) {
// Do nothing
}
});
}
This updates the fields just fine on onBlur, but the page itself calculates a lot of results, based on several class methods on runtime. If I use AJAX to update the database values, I don't see how I can set the class variables and display the correct result without reloading.

When you click on an element, it's more likely that it will get focus (unless there is some wizardry that prevents the click from requesting the focus). You may simply handle the onclick event of an input group and save it.
Let imagine some input fields that all have classname txt-group-1:
Plain JS
var lastFocus = null;
if (document.activeElement.className == 'txt-group-1') {
lastFocus = document.activeElement.id; // get the field that already has focus
}
var inputs = document.getElementsByClassName('txt-group-1');
for (var i=0;i<inputs.length;i++) {
inputs[i].addEventListener('click', function(evt){
alert(this.id+' has focus!');
lastFocus = this.id;
},true);
}
jQuery
var lastFocus = null;
if (document.activeElement.className == 'txt-group-1') {
lastFocus = document.activeElement.id; // get the field that already has focus
}
$('.txt-group-1').click(function(evt){
alert(this.id+' has focus!');
lastFocus = this.id;
});
Then, lastFocus will always have the ID of the last element that had focus so you can put it back if needed.
UPDATE:
in case of a CMS that needs to save the fields:
Your best friend in that situation will be ajax. The idea is to be able to save the new value in database without having to refresh the whole page, hence stopping any action that goes after.
I suggest that you take a look at the method that saves the fields and optimize it in a way that it doesn't need to refresh the page:
$.ajax({
url: "save.php",
data: {inputFieldName:'txtEmail', inputFieldValue:'foobar#mail.com'}
})
.done(function(data) {
console.log('saved'); // after the request is complete
});
Any post-save client-side action may be specified in the .done event. It's also possible to get a response from the server-side script that execute your request.

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
</head>
<body>
<input name="testfield" type="text" id="mtTextField" onClick="alertId(this.id);">
<script type="text/javascript">
function alertId(getid)
{
alert(getid);
}
</script>
</body>
</html>
Try out this code.

Use's Harsha's snippet except hang it on the "onchange", otherwise you will create an issue with tab navigation. You will have to modify your save function slightly so it won't trigger with every character.
Also instead of updating the entire page I suggest using AJAX.

Related

HTML form input changed but then changed back to original value

So this was hard to search on, read on you'll see why.
This is my goal - detect if a form field has changed so i can enable the "Save" button. Ok, so this is super easy. Here's the rub. If the user then changes the input back to the ORIGINAL value when the form loaded I want to disable the save button again.
Quick example;
Page loads - input contains the value "red"
User changes it to "blue"
script detects change from original value, enable the save button
User then decides he liked "red" so changes the input back to "red"
script sees the change is same as original value, disable the save button
I know this may be a bit anal. But my clients don't get why the form still needs saved if the input is back to the beginning value.
Of course the whole thing then needs to work with many inputs.
I assume you have some onChange callback that you've registered on the `change' event for input fields. In that callback you'd want to be able to check if the new value has gone back to the original value. (If so, you'd want to disable the save button again). What is missing is some reference to the original value.
So when do you first know what the initial value is? I'm guessing you are, at some point, populating the input field with previously saved data. At that time, you had the information about what the "original" value was.
Now you want to have a specialized onChange callback for each of the input fields, where each of these callbacks would have access to the original value.
One way you could do that is using higher order functions. A function returning a new function. How would that work?
function createOnChangeCallback(originalValue) {
// returning a function!
return function(changeEvent) {
// this is the callback that will run for one
// of the input elements. Note that the "originalValue"
// is in scope
const newValue = changeEvent.target.value;
const hasGoneBackToOriginalValue = newValue == originalValue;
if(hasGoneBackToOriginalValue) {
// disable the submit button
}
}
};
Then, when you are populating a specific field, you would do something like
// get a reference to the input element
const $myInput = $('#myInput');
// give the input field it's first value ("populate")
$myInput.val(originalValue);
// create a specialized callback with access to the original value
$myInput.click( createOnChangeCallback(originalValue) )
A little more background. The app built using the .Net and MVC technology.
The primary view page where most action is happening has a table with a page
of job request records. Each record has an "Edit" link like this.
Edit
I use jquery to catch events at the document level because the table is loaded and rendered dynamically using the DataTables.net library.
Here's how I catch the "Click" event of the ".btnJobEdit" links (there will be one for each row of the jobs table).
And also the "Change" and "Submit" events of the "#frmJobEdit", this form does not exist until the above "Edit" link is clicked.
$(document)
.on('click', '.btnEditJob', event_click_btnEditJob)
.on('change', '#frmJobEdit', function () {
// .valid() is a jQuery validation library
$(this).find(':submit').attr('disabled', !$(this).valid());
$(this).find(':reset').attr('disabled', false);
})
.on('submit', '#frmJobEdit', event_submit_frmJobEdit)
Now we have the inital page loaded.
When a user clicks the "Edit" button for a record the function event_click_btnEditJob() runs.
Heres that simple function
function event_click_btnEditJob() {
event.preventDefault();
$.get($(this).attr('href'), function (response) {
// the response will be a full html form returned as a partial view
// by the _JobEdit method of the JobController
// I then set this into a BootStrap modal dialog and show the modal
$('#modal_JobEdit .modal-body')
.html(response)
.modal('show')
});
}
When the user clicks the "Save Changes" button the function event_submit_frmJobEdit handles the submit again thru ajax call to the JobController which again returns a partial view with the form and the newly changed data ready for another edit as well as now there is a message indication the success or fail of the submit action.
This existing process is, clean, stable and simple. Introducing this requirement of toggling the "Save" button based on user edits is undesirable from the development perspective. And at this time the customer representatives to this project have agreed. "Train the users!"
Try this:
$("#your-client-form").submit(function(e){
e.preventDefault(); //prevents for reloading the page.
});
Here is a full example of doing something similar to what you want to do.
// Retrieves the initial state of the form as a JSON object
// data-field-name determines the JSON field name
const getForm = () => {
return $("#my-form");
};
const getFormState = (form) => {
let originalFormState = {};
form.children(":input").each(function() {
const fieldName = $(this).data("fieldName");
const fieldValue = $(this).val();
if (fieldName) {
originalFormState[fieldName] = fieldValue;
}
});
return originalFormState;
};
const setSubmitButtonState = (form, isChanged) => {
form.children("#submit-form").prop("disabled", isChanged);
};
const checkAndHandleFormState = (form, originalFormState) => {
const currentFormState = getFormState(form);
let isChanged = false;
for (const field of Object.keys(originalFormState)) {
if (originalFormState[field] !== currentFormState[field]) {
isChanged = true;
break;
}
}
setSubmitButtonState(form, isChanged);
};
const addListenersToFormInputFields = (form, originalFormState) => {
form.children(":input").each(function() {
if ($(this).data("fieldName")) {
$(this).change(function() {
const fieldName = $(this).data("fieldName");
const fieldValue = $(this).val();
checkAndHandleFormState(getForm(), originalFormState);
});
}
});
};
$(document).ready(function() {
const form = getForm();
addListenersToFormInputFields(form, getFormState(form));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="my-form">
<input id="name" data-field-name="name" type="text" value="John" />
<input id="age" data-field-name="age" type="text" value="12" />
<input id="submit-form" type="submit" />
</form>

Meteor App get value of textarea in form

I am writing a little Meteor app. There is a textarea in a form, which looks like this:
<form name="comments-form">
<label for="textarea">Comment:</label><br>
<textarea cols="40" rows="10" name="comment_textarea" class="comment_textarea">Write your comment here.</textarea><br>
<button class="btn btn-success js-add-comment">add comment</button>
</form>
In my client.js I have the following code for accessing the value of the textarea:
EVENT_HANDLED = false;
Template.website_item_details.events({
"click .js-add-comment": function(event) {
var comment_text = event.target.comment_textarea.value;
if(Meteor.user()) {
Comments.insert({
created_by: Meteor.user()._id,
text: comment_text,
website_id: this._id
});
}
return EVENT_HANDLED;
}
});
However, when I click the button to add the comment, I get the following console output:
TypeError: event.target.comment_textarea is undefined
["click .js-add-comment"]()
client.js:103
Template.prototype.events/eventMap2[k]</</<()
blaze.js:3697
Template._withTemplateInstanceFunc()
blaze.js:3671
Template.prototype.events/eventMap2[k]</<()
blaze.js:3696
attached_eventMaps/</</</<()
blaze.js:2557
Blaze._withCurrentView()
blaze.js:2211
attached_eventMaps/</</<()
blaze.js:2556
HandlerRec/this.delegatedHandler</<()
blaze.js:833
jQuery.event.dispatch()
jquery.js:4690
jQuery.event.add/elemData.handle()
This seems to be basic form handling, but somehow I can't get that text in the textarea into a variable in my javascript code. I've already tried a multitude of variants of accessing it:
document.getElementsByClass()[0].value
$('.comment_textarea').get(0).val() // there should only be one such text area anyway
event.target.comment_textarea.value;
But none of those work for me, I always get that error. It's almost like the textarea was not part of my html or there is a bug in Meteor, which prevents me from accessing textareas.
I also checked whether there are other things named comment_textarea with a fulltext search on all of my projects clientside files, but there isn't any other.
Am I simply blind and overlooking something? How do I get that text?
What's more is, that although I return false, the browser still reloads the page. Could it be related to the error happening before?
You are using the click event of the button and on that event, the textarea is not available. You need to change the event into submit form. First, put the id into your form, change the button into type submit and change the code into
"submit #your-form-id": function(event) {
event.preventDefault();
var comment_text = event.target.comment_textarea.value;
.....
}
After trying even more desperate ways to access that textarea, I think I know now what's wrong:
// var comment_text = event.target.comment_textarea.value;
// var comment_text = document.getElementByName('comment_textarea').value;
// var comment_text = document.getElementByTagName('textarea')[0].value;
// var comment_text = $('textarea').get(0).val();
// var comment_text = $('textarea').get(0).text();
var comment_text = $('textarea').get(0).value; // finally working!
So it seems that when I use jQuery, I can't use the .val() function as stated in my other answers to many other questions, but for some reason I have to treat it like a normal DOM object and use the attribute value instead of the function .val().
Maybe it's specific to the jQuery version in my Meteor app?
So I will test the following:
var comment_text = $('textarea.comment_textarea').get(0).value;
...
Yes, that also works.
Also it fixes the reload issue. I guess since there was an error, it didn't even get to return false and this is why the website reloaded.

Jquery: Start function after browser fills textbox

I have created a server control for a login panel.
On this panel I have a textbox for the username and a textbox for the password.
Below that there is the button for login.
I want the button to be disabled if either or both textboxes are empty.
For that I created a function that checks the length of the contents of the textboxes.
function doCheck()
{
var lngth1 = document.getElementById('pnLogin_txtUserName').value.length;
var lngth2 = document.getElementById('pnLogin_txtPassword').value.length;
if (lngth1 > 0 && lngth2 > 0)
{
$('#pnLogin_btLogin').removeAttr('disabled');
} else {
$('#pnLogin_btLogin').attr('disabled','disabled');
}
}
I run this function at the start and on every keyup event.
That works great.
The problem is when the browser starts with the page. It fills in the username and password if they are stored.
When the function is then run, it still disables the button even though there is information in the textboxes.
I tried this:
setTimeout( function()
{
doCheck();
}, 2000);
But after 2 seconds I see the button disabling while seeing my credentials filled in.
If I inspect the element in Chrome, I don't see my credentials in the html code.
So where is it stored? How can I detect this?
You will not see the values in the html as they are not actually in the DOM.
You may access their values using $("#pnLogin_txtUserName").val() and
$("#pnLogin_txtPassword").val().
I would simplify your function and use jQuery specific syntax rather than native javascript.
function doCheck() {
var lngth1 = $("#pnLogin_txtUserName").val().length;
var lngth2 = $("#pnLogin_txtPassword").val().length;
if (lngth1 > 0 && lngth2 > 0) {
$('#pnLogin_btLogin').prop('disabled', false);
} else {
$('#pnLogin_btLogin').prop('disabled', true);
}
}
I also changed your code from .attr to .prop for disabling the input. Find more information with this stackoverflow question
The problem is when the browser starts with the page. It fills in the username and password if they are stored. When the function is then run, it still disables the button even though there is information in the textboxes.
Your code is being executed the moment it is loaded and parsed by the browser. The proper jQuery method is to use whats called .ready() which will execute after jQuery detects the page has finished loading.
$(document).ready( function() {
doCheck();
});
Or more simplified to:
$(function() {
doCheck();
});
detecting change
We can detect when the values get changed by bind an event listener:
$("pnLogin_txtUserName").change(function() {
console.log( 'pnLogin_txtUserName has changed', $(this).val() );
});
If we add a class to your inputs, say .loginElements, then we do things a bit easier and detect several different events:
$(".loginElements").on( 'change keypress', function() {
doCheck();
});

Having issues calling an ID after I have appended data from an ajax call

Ok,
So I have a .on click event which is called to an ajaxed script. The script returns a set of HTML information.
Now, what I seem to be having an issue with and maybe I am just not typing the right search terms in for this so my apologies if this was answered already.
When the html is appended to the correct box, the user is then able to click a link on that box, drop down the box and see a new input box. The user should be able to type the text in and hit the enter key and it should work.
When I run an inspect element, I do see the element's ID properly inserted, but it is like javascript doesn't even recognize the new element id.
UPDATE: I am really not sure why you need code to be able to answer this question, however here it is. The code works normally unless the above happens so yes I am appending it, and yes I am SURE i am appending it, please make sure to read everything before posting a comment, thanks!
$('body').on('keypress', '.peapComment', function(event) {
if(event.which == 13) {
var peap_id = $(this).attr('rel');
var comment = $(this).val();
$.ajax({
type: "POST",
url: "index.php",
data: {
page: "postPeapComment",
peap_id: peap_id,
comment: comment,
}
}).done(function(msg) {
console.log(msg);
$('#comment_' + peap_id).append(msg);
});
console.log('Send to Peap #' + peap_id + ': ' + comment);
$('#commentbox_' + peap_id).val('');
}
});
I have tested your code, and it seems to work without problems for me. My assumption would be that the data returned from your ajax call, is failing to return the proper "Peap_ID" or not returning anything all around, as this is the only way I can reproduce what you have claimed your error is, otherwise the code you have posted looks great.

Popup using jQuery?

I'm trying to do a pretty simple thing, I believe. I need to popup a success confirmation dialog after a user clicks to add someone to his friends list. Simply there's an add link on the page with the url (mysite.com/add/friendname). I needed to make issue this request asynchronously so I used jQuery.ajax built-in function to send the request. Take a look at the following code:
$(document).ready(function() {
$('.track_links').click(function() {
if (confirm("are you sure you want to track <firstname lastname>?")) {
$.ajax({
type: "GET",
url: this.href,
success: function() {
alert("Congratulation! you're now tracking <firstname lastname>");
},
error: function() {
alert("Oops! An error occured, plz try again later!");
}
});
return false;
}
else {
return false;
}
});
});
Now, here's what I need to do in short:
1- I need to use an already designed Html form as the success or failure confirmation message, instead of just alerting!
2- I also need to replace a placeholder (###username###) on that html page with the actual user name (firstname space lastname) which is the value of another field on the document. How to manipulate this html before poping it up on the client?
p.s: My Html/Javascript skills is totally awesome ;) (well, not really)!
For the first part
You can use the
show
function to show a div in the ajax success function.
$("#divResult").show();
if divResult is the id of the div to be shown
For the second part
you can get the value of first name and last name using
$("#txtFirstname" ).val();
and
$("#txtLastname" ).val();
if your first name text box id is txtFirstname and last name text box id is txtLastName
This is how I setup an Acknowledgement dialog, which could quickly be modified to be a confirmation for an action like yours.
http://professionalaspnet.com/archive/2009/06/02/Displaying-a-Confirmation-Dialog-with-the-JQuery-UI-Dialog.aspx
For the Form, I would suggest the html() Method, which injects raw HTML you have to provide. Since you already have it, you can give it to the Method via parameters.
For the Placeholder Part, I would suggest the val() Methods, coupled with Javascript's built-in regex functions.
If your placeholder is "###firstname###", then you should try something like
var firstname = jQuery('input#firstname').val();
var lastname = jQuery('input#lastname').val();
var text = jQuery('span#ThePlaceMyPlaceholderIsAt').text();
text = text.replace(/\#\#\#firstname\#\#\#/,firstname);
text = text.replace(/\#\#\#lastname\#\#\#/,lastname);
jQuery('span#ThePlaceMyPlaceholderIsAt').text(text);

Categories

Resources