I have such HTML:
<form data-bind="submit: mySubmit>
<input type="text" ...
And I want to access the input's value upon submit:
mySubmit = function() {
var textValue = ???;
alert(textValue);
}
How can I do that ? I am OK with giving a kind of ID to the text field, but I don't want this ID to be global (for example I may have several of these forms on one page).
If you are looking at it from a Knockout perspective, then you really want to have the value of your input represented in your view model. This would mean adding a data-bind="value: myValue" to your input. Then, you would access it from the view model in your mySubmit method.
Something like: http://jsfiddle.net/rniemeyer/sAyET
I would not recommend it, but the submit method is actually passed the form element in its first argument by Knockout (it really should be passed the current data and event, but currently it is the element).
So, you could do something like: http://jsfiddle.net/rniemeyer/sAyET/1/. Ideally, your view model should not have any references to the DOM/view in it, so I would not recommend this option, unless absolutely necessary.
Related
Good evening,
I am writing an application using AngularJS and I require for the application to send data with a POST request to the nodejs server.
My data is structured like as a json object and it has data binding thanks to the AngularJS framework.
As of now, a function is dynamically trying to create possible values that the user might like inside of some input tags. An example:
<button ng-click="generateFoodAndBeverages(row)>Generate</button>
<input type="text" ng-model="row.service.day.beverage" placeholder="beverage" />
<input type="text" ng-model="row.service.day.food" placeholder="food" />
The two input values can be set by the user by typing in the value they would like (e.g. "Cola", "Hamburger"), but above the input tags is a button that can generate the input values for the user.
The function that generates the values takes them from an array and then at the end of the function returns two possible values, one for beverages and one for food.
When it has the two returning values it changes the attribute value of both inputs, setting them to the two possibilities generated by the function:
jQuery("#input1").attr("value", generateFoodAndBeverages(row)[0]);
jQuery("#input2").attr("value", generateFoodAndBeverages(row)[1]);
This is not perfect nor elegant but it's working. The function populates and dynamically changes the value attribute of those two input elements each time the user requests for automatic generation of food and beverages so the values are actually set and do exist.
Even so, even if I see them on screen as text inside the input fields, my POST request does not recognize the fact that the ng-model actually changed. The only way the ng-model registers the changes to the value attribute of the input fields is if the user types something with his keyboard, manually changing the value attribute. Another example:
<input type="text" value="generateValue()" ng-model="row.service.info" />
The one up here does not change the ng-model value at all.
<input type="text" value="User Typed Value" ng-model="row.service.info" />
This other one instead does change the ng-model value and as it changes and exists, it is passed to the $scope that can later be sent as a POST request to the server.
Any ideas as to why the "automatically and dynamically generated" value of the input field does not get registered by the ng-model while the user typed value does?
Thanks in advance!
[EDIT]
Apparently the problem comes with the ng-model not changing. I tried to debug the problem by applying an ng-change in the input. If the change is done by javascript, it is not registered with the ng-model and the ng-change function does not fire because the ng-model was not changed even tho' I can clearly see the new value set by javascript for the input tag. If I change the value of the input tag by hand the ng-change is fired and the console logs the change.
I could apply the changes directly to the ng-model if it weren't so different for each row.
Having the ng-model like this:
<input ng-model="row.serviceInfo.DayObject[dayString].food" />
<input ng-model="row.serviceInfo.DayObject[dayString].beverage" />
How would I be able to apply the changes directly to the ng-model given how dynamic the model is. As an example, I could have 1000 rows, each with their own serviceInfo object. I don't know how I could change the model for each of those rows with the dynamically generated values.
[EDIT]
The problem was indeed with ng-model not changing. The solution consisted in applying the changes to the ng-model for each element inside the dynamically generated values function. Thanks everyone for the input. I'll leave this piece of code here if anyone ever comes across the same problem! Thanks again!
let foodEl = angular.element(the row element food input);
let beverageEl = angular.element(the row element beverage input);
$scope.displayedCollection[i].serviceInfo = {
"day" : {
"food" : generatedValuesFood(el, day),
"beverage" : generatedValuesBeverage(el, day)
}
};
foodEl.val($scope.displayedCollection[i].serviceInfo.day.food);
beverageEl.val($scope.displayedCollection[i].serviceInfo.day.beverage);
I think that your problem is quite simple. As #ssougnez said, don't mixed jquery with angularjs. Angularjs use data-binding concept, don't use jquery style to change the input value instead use the ng-model directive to bind data from the model to the view on HTML controls (input, select, textarea). In your generateFoodAndBeverages function just set the ng-model value according to which row for eg:
var generateFoodAndBeverages = function () {
$scope.row.service.day.beverage = array[0];
$scope.row.service.day.food = array[1];
};
I am setting values on a form in an iframe via Javascript.
Please note that I do not have access to the page displayed in the iframe. My Javascript page is on the same server, so it has access to the form displayed.
//HTML of Forename field in form control
<input class="form-control" id="Forename" type="text" data-bind="value: dto.Forename">
Javascript setting the value:
var frameNode = document.getElementById('frm1');
var fieldNode = frameNode.contentDocument.getElementById('Forename');
fieldNode.value = FirstName; //previously defined
The values set successfully (see attached img). However, when I hit SAVE, I still get a 'values Required' message. I suspect this is because the Knockout Javascript libraries that binds the value with the view model, needs a keypress.
Even when I manually go into the form and press Enter/Tab after each value, I still get the message. It's only when I change the Forename and Surname manually to something else that the Save is successful.
Has anybody done something like this before? Thanks
In this image you can see the values are set
I believe the problem you're experiencing is actually due to a deeper issue involved in using a knockout binding. Updating the value of a UI control directly has no effect because the real underlying value is stored in a javascript view-model object. The DOM element only mirrors that value, and updates are performed using a change event hook under the hood. When you change the value manually on the UI the change event is triggered and the view-model value gets updated.
Knockout.js Docs
So to properly update the values you should try using the knockout library to update the underlying data:
var frameNode = document.getElementById('frm1');
var fieldNode = frameNode.contentDocument.getElementById('Forename');
var viewModel = ko.dataFor(fieldNode);
viewModel.dto.Forename(FirstName); //value setting works like a function
If you can't get that to work you can also try manually triggering the change event. That's far easier if you have jQuery, but can still be done without. See How can I trigger an onchange event manually?
In an HTML code , i have a form Tag :
<form id='my_form' action='url.hmtl'> ... </form>
The corresponding JS object has a property named 'action', which contains the string 'url.html':
my_form=document.getElementById('my_form');
console.log(form.action);
The above code displays: url.hmtl
But if i add a sub-object, say an input, inside the form, with id='action':
<form id='my_form' action='url.hmtl'>
<input type="hidden" id="action" />
</form>
Then form.action is now the JS object corresponding to the input.
My questions :
Is this behaviour normal ?
Should I forbid myself to use the string 'action' as id of any input ?
If there is such an input, is there any way to get the original property 'Action' of the form or is it lost for ever ?
Is this behaviour normal?
Yes, unfortunately.
Should I forbid myself to use the string 'action' as id of any input?
Yes, that one and many more.
If there is such an input, is there any way to get the original property 'Action' of the form or is it lost for ever?
The attribute is still in the DOM, and when you remove the input the action property would represent the attribute's value again. Until then, you can use the getAttribute method of the form element.
The form attribute "action" is not overwritten. See example of Florian.
The question is if you experiencing a problem when sending the form to the "action" address ?
A mistake in the URL might cause an unwanted result (triggered by your typo "url.hmtl" instead of " url.html"
To answer your questions:
The behaviour is normal but perhaps confusing because it differs if you address an element by id or get the value of an attribute.
there is no need to avoid using "action" as id as long as you are specific enough about the information you are interested in. (form attribute or input element)
the form attribute action is not lost as properly answered by Florian :-)
This is a default behaviour, and will happen everytime you do somethink like that. You can use the getAttribute() function to get the Attribute.
my_form=document.getElementById('my_form');
console.log(form.getAttribute("action");
I'm relatively new to programming, but understand the basics of HTML, CSS, and Javascript (including jQuery). Due to my greenness, I'd appreciate it if answers contained both a simple solution and a reason as to why the solution works. Thanks!
So I've got a form, with a text input and a submit button:
<form>
<input type="text">
<button type="submit">Submit</button>
</form>
When the user types data into the text field and clicks submit, how do I gain access to this data? If a user inputs their name, how do I grab that information? I don't intend to store it or write it anywhere, just to hold onto it as a variable in javascript, which I'll assign to a jQuery cookie.
So how do I access the data that the user has submitted, preferably using only Javascript (with jQuery)? Thanks for the help!
You access the data on the server side (in PHP via $_POST['username'] for example). The form sends data to your sever for any named input, so you would probably have to change the input to:
<input type=text name=username>
If you want to access it on the client side (with JavaScript), you can do that too, but you have to prevent the form from submitting:
$("form").on('submit', function (e) {
$.cookie('username', $(this).find('[name=username]').val());
//stop form from submitting
e.preventDefault();
});
say you had an html input tag such as:
<input id="textfield" type="text">
using javascript, you can store the value of that field in a variable like this:
var inputvalue = $('#textfield').val();
of course, you'll need something to run the script.
the reason this works is that the the textfield is an object. you might think of it as a tree trunk with different branches coming out. one of these "branches" is the value contained inside of it. since you know jquery, you know that $('#textfield') gets the element by a selector. the period says we're getting one of the branches, and "value" says we want the branch that tells what's in the textfield.
hope this helps.
I am working on a project where I need to recall the fields entered in a form so I can repopulate them later. When a form has a name, I can remember it and then later use some JavaScript (document.getElementsByName(...)[0]) to access it. However, if there is no name...I'm at a loss for how to get a reference to it later.
I'm using jQuery, but am open to a JavaScript solution as well. One idea is to remember the index of the form. So, if it was document.forms[3] then later I can use the index. However, when someone submits a form, how do I know the index of the form that it is? (NOTE: I am blindly adding submit handlers to all forms when a page loads to capture the activity.)
Instead of attaching events to the submit buttons, attach it to the <form> elements directly, like this:
$("form").submit(function() {
//do something with this
//this == the form element being submitted
});
Or...in your current event handlers, use .closest() to get the closest parent <form> element:
$(":submit").click(function() {
var form = $(this).closest("form");
});
If you don't want to use an index on all form (flaky because someone may add a form in anywhere), you could use its surroundings as a reference... for example.
$('#content').parent().next().find('form')