I need to pass a checkbox value from my .html page to a separate .js file.
the .js file doesn't share a window, I cant use jQuery, and it's not MVC so no tempdata or controllers etc.
Any ideas?
Thanks
if(checkboxid == true){
function myfunction(){
//do stuff
}
}
and in a separate file + window..
<input type="checkbox" id="checkboxid" name="checkboxid" checked>
<input type="hidden" id="checkboxid" name="checkboxid" value="false">
I'm not fully sure what you mean, but would this be a solution:
if (document.getElementById("checkboxid").checked) {
...
}
In the end I found two solutions,
one was to use localstorage,
var value = document.getElementById("value");
localStorage.setItem('key', value);
And the way I actually ended up doing it was to piggy-back it on a Web-API going from the same form.
Related
I'm using Angular 1.5.9
I have a big form, which I scattered through different Bootstrap Accordion.
When there is an error in the form, I want to be able to change the class of my accordions to show in which accordions the error is located.
To check for errors in a whole form, I can check
myFormName.$error
And to check errors for an element, I can simply do
myFormName.myInputName.$error
But I don't know if there is a way to do this for multiple element at once, without having to check each element individually.
My first thought was to change the name of my inputs like so:
<input name="accordion1.fieldName">
But this didn't give me the expected result: I don't have myFormName.accordion1.$error, actually, I don't even have myFormName.accordion1.fieldName, since my data is actually stored in myFormName['accordion1.fieldName'] which is pretty much useless.
Has anyone found an answer to this problem? I think I'll have to check each field, which is kinda ugly, and a mess to maintain whenever we add / remove fields...
Maybe there is a directive out there that could do that for me, but as a non-native English speaker, I can't find which key words to use for my search in this situation.
One approach is to nest with the ng-form directive:
<form name=form1>
<div ng-form=set1>
<input name=input1 />
<input name=input2 />
</div>
</form>
{{form1.set1.$error}}
You could name the fields with a prefix such as 'accordion1_' then add a controller function that will filter your fields.
ctrl.fieldGroup = function(form, fieldPrefix) {
var fieldGroup = {};
angular.forEach(form, function(value, key) {
if (key.indexOf(prefix) === 0) {
fieldGroup[key] = value;
}
});
return fieldGroup;
}
Then ctrl.fieldGroup('accordion1') will return an object with the appriopriate fields on it. You could extend the function further to add an aggregate $error property to the resulting fieldGroup object.
My question is more about what would be the best practice in this scenario:
I have a form that has to allow a user to input n number of ideas, each idea in an independent text field. Ideally there would be a couple of buttons next to the last text input to allow the user to create a new text input or to erase the latest one.
I know DOM manipulation is not the way to go with Angular but due to requirements, I have to do something that requires creating elements dynamically. Is there a best practice, service or directive in Angular that could allow me to do this or I should just inject the elements with jQuery?
The only thing you need is proper use of ng-repeat. No DOM manipulation with jQuery is necessary. Nor would it be good practice. Behold, the power of ng-repeat.
Working plunker here.
Something like this?
<div ng-repeat="idea in ideas">
<input ng-model="idea">
</div>
<button ng-click="AddNew()">Add New Idea</button>
<button ng-click="DeleteLast()">Delete Last Idea</button>
In controller:
$scope.AddNew = function() {
$scope.ideas.push("");
}
$scope.DeleteLast= function() {
$scope.ideas.splice($scope.ideas.length-1, 1);
}
I have an app that requires HTML to be pieced together from different APIs. Rather than getting into specifics there, let me just say that we have tried getting away from that many times but in the end the best answer always end up being what we currently have. Hopefully that changes someday but for now it's working great.
Currently, the HTML is parsed together as a string server-side using NodeJS and sent across the wire as complete HTML to be rendered. I'm in the process of adopting AngularJS, and while I'm loving it I am stuck on this issue-- how can I use Angular templating to insert invalid HTML at times?
The server will return three JSON fields: leadingHTML, trailingHTML, and copy. The copy field is always valid HTML, but leadingHTML and trailingHTML can sometimes return invalid HTML. When all three are added together, valid HTML results.
Let me illustrate:
leadingHTML='<figure>';
copy = '<img src="img1.jpg"/><img src="im2.jpg"/><figcaption>I love AngularJS</figcaption>';
trailingHTML='</figure>';
As you can see, if you add those together you will get the valid HTML that is required to be displayed. It's pretty easy to make the fields trustworthy HTML in Angular:
for (i in data.results){
data.results[i].copy=$sce.trustAsHtml(data.results[i].copy);
data.results[i].leadingHTML =$sce.trustAsHtml(data.results[i].leadingHTML );
data.results[i].trailingHTML =$sce.trustAsHtml(data.results[i].trailingHTML );
}
And then render the copy in my view:
<div ng-repeat='i in data.result'>
<p ng-bind-html='i.copy'></p>
</div>
But I need a way that does what this looks like it would do, but the leadingHTML and trailingHTML scope variables get render as strings:
<div ng-repeat='i in data.result'>
{{ i.leadingHTML }}
<p ng-bind-html='i.copy'></p>
{{ i.trailingHTML }}
</div>
Is the best answer here to build the template via javascript? Would that even work?
Are you able to pre-process your data so that you do have valid HTML?
var item;
for (i in data.results){
item = data.results[i];
item.content = $sce.trustAsHtml(item.leadingHTML + item.copy + item.trailingHTML);
}
Then you can just bind to the combined content in the view:
<div ng-repeat='i in data.results'>
<div ng-bind-html='i.content'></div>
</div>
Edit:
Yes, this will allow you to embed expressions in your HTML content.
In fact, you will need to be careful that you aren't opening yourself up to security exploits in the trusted HTML content (see the example at the bottom of the page for the $sce service).
Using $sce.trustAsHtml in this way is roughly equivalent to loading a directive's templateUrl from your site, so the security considerations around that are probably the same. See the "How does it work?" and
"Impact on loading templates".
I been struggling to reset form once form is submitted. Someone posted this Here which I want to make it work but no success. Here is my My Code Example.
$scope.form.$setPristine(); is not setting Pristine: {{user_form.$pristine}} to true. See example above.
$setPristine() was introduced in the 1.1.x branch of angularjs. You need to use that version rather than 1.0.7 in order for it to work.
See http://plnkr.co/edit/815Bml?p=preview
Had a similar problem, where I had to set the form back to pristine, but also to untouched, since $invalid and $error were both used to show error messages. Only using setPristine() was not enough to clear the error messages.
I solved it by using setPristine() and setUntouched().
(See Angular's documentation: https://docs.angularjs.org/api/ng/type/ngModel.NgModelController)
So, in my controller, I used:
$scope.form.setPristine();
$scope.form.setUntouched();
These two functions reset the complete form to $pristine and back to $untouched, so that all error messages were cleared.
Just for those who want to get $setPristine without having to upgrade to v1.1.x, here is the function I used to simulate the $setPristine function. I was reluctant to use the v1.1.5 because one of the AngularUI components I used is no compatible.
var setPristine = function(form) {
if (form.$setPristine) {//only supported from v1.1.x
form.$setPristine();
} else {
/*
*Underscore looping form properties, you can use for loop too like:
*for(var i in form){
* var input = form[i]; ...
*/
_.each(form, function (input) {
if (input.$dirty) {
input.$dirty = false;
}
});
}
};
Note that it ONLY makes $dirty fields clean and help changing the 'show error' condition like $scope.myForm.myField.$dirty && $scope.myForm.myField.$invalid.
Other parts of the form object (like the css classes) still need to consider, but this solve my problem: hide error messages.
There is another way to pristine form that is by sending form into the controller. For example:-
In view:-
<form name="myForm" ng-submit="addUser(myForm)" novalidate>
<input type="text" ng-mode="user.name"/>
<span style="color:red" ng-show="myForm.name.$dirty && myForm.name.$invalid">
<span ng-show="myForm.name.$error.required">Name is required.</span>
</span>
<button ng-disabled="myForm.$invalid">Add User</button>
</form>
In Controller:-
$scope.addUser = function(myForm) {
myForm.$setPristine();
};
DavidLn's answer has worked well for me in the past. But it doesn't capture all of setPristine's functionality, which tripped me up this time. Here is a fuller shim:
var form_set_pristine = function(form){
// 2013-12-20 DF TODO: remove this function on Angular 1.1.x+ upgrade
// function is included natively
if(form.$setPristine){
form.$setPristine();
} else {
form.$pristine = true;
form.$dirty = false;
angular.forEach(form, function (input, key) {
if (input.$pristine)
input.$pristine = true;
if (input.$dirty) {
input.$dirty = false;
}
});
}
};
I solved the same problem of having to reset a form at its pristine state in Angular version 1.0.7 (no $setPristine method)
In my use case, the form, after being filled and submitted must disappear until it is again necessary for filling another record. So I made the show/hide effect by using ng-switch instead of ng-show. As I suspected, with ng-switch, the form DOM sub-tree is completely removed and later recreated. So the pristine state is automatically restored.
I like it because it is simple and clean but it may not be a fit for anybody's use case.
it may also imply some performance issues for big forms (?) In my situation I did not face this problem yet.
Does anyone have any idea why this code seems not to work?
What am I doing wrong?
JQuery 1.5.1 is used.
JS code:
$('#search_filters #discipline a').click(function(){
var checkbox = $(this).next(':checkbox');
if (checkbox.attr('checked')) {
checkbox.attr("checked", true);
} else {
checkbox.attr("checked", false);
}
$(this).children('img').toggleClass("active");
return false;
});
HTML:
<li>
<a href="#">
<img class="inactive" alt="Football" src="/images/disciplines/e9bc7681813110c/thumb.png">
</a>
<input type="checkbox" name="search_discipline[7]" value="1" class="search_discipline">
</li>
I just ran into this myself. It seems in jQuery 1.5.1 and 1.5.2 setting the checked attribute is a bit buggy. I had better luck with $(':checkbox').val(boolean) (which is even a bit easier).
Update: after some digging, it seems the webkit inspector doesn't actually show the checked attribute in the DOM, but jQuery reads/writes it properly. Very odd. Serves me right for using the nightly webkit builds for dev.
The value of a "checked" attribute should be "checked":
if (checkbox.is(':checked'))
{
checkbox.attr("checked", "checked");
} else {
checkbox.removeAttr("checked");
}
Just two helpful ideas to check the change for attributes:
Write the plain HTML first, without Javascript. Did it work? If so, then write it with JS
If you had modified an html tag recall the attribute itself, so you can check that your code had been executed well. E. g. alert($({your target object}).attr({the attribute which added}));
That's what I do in the most cases.
Some pointers:
$('#search_filters #discipline a') will be selecting all a elements that descend from #discipline that descend from #search_filters. Is this what you indend?
Are you remembering that .next() returns a sibling.
What happens if you remove the href='#'?
Does your click event even fire?