how can mootools 1.11 determine if a div contains any checked check boxes?
tried all kinds of variations using $ $$ $E $ES getElements and css selectors, its just not returning true if this div contains no tick boxes
var ticked = $(sId).getElements('[checked=checked]');
if($chk(ticked)){alert('yo');}else{unticked = true;}
"checked" is a dynamically assigned DOM property (which is a boolean), and accessing the attribute only returns the value that was there when the page loaded (or the value you placed when using setAttribute).
Also, as MooTools 1.11 does not have complex selectors (attributes can not be filtered directly within $$) and the filterByAttribute function only accepts direct string comparison, this is your only (and best!) option:
$(sId).getElements('input').filter(function(input) {
return /radio|checkbox/.test(input.getAttribute('type')) && input.checked;
})
note: I added radio just for completeness, the filter loop would have to be run anyways to verify the checked status.
If you want to simplify the process and be able to reuse the code (the MooTools way), you can also mix-in the checked filter into Elements like this:
Element.extend({
getCheckedInputs: function() {
return this.getElements('input').filter(function(input) {
return /radio|checkbox/.test(input.getAttribute('type')) && input.checked;
});
}
});
and then your selection call is reduced to:
$(sID).getCheckedInputs();
From The Documentation:
$(sId).getElements("input:checked");
for 1.1
console.log( $('id').getProperty('checked') );
Related
I have multiple elements on a page that are triggering a load of select2 to the element. I'm trying to conditionally check if the element has a certain class, and if so add the tag option; otherwise do not. I thought something like this would work, but it's not:
$('.element_to_add_select_two_on').select2({
tags:function(element) {
return (element.className === 'classname_i_am_targeting');
},
});
What am I missing here? I'm subjecting myself to the following buffoonery to get this to target and load:
$('.element_to_add_select_two_on').each((index,element) => {
let showTags = false;
if ($(element).attr('class').split(' ').includes('classname_i_am_targeting')) {
showTags = true;
}
$(element).select2({
tags:showTags,
});
});
There are a few problems with your first attempt. First, you are defining tags as a function when what you want is the result of the function, since tags needs to be defined as a boolean true or false. The other is that inside your .select2() call, you do not have access to the calling element $('.element_to_add_select_two_on') in the way that you think. It isn't an event that you are listening on, it's a function call that wants an object passed with its configuration.
You conveyed that your second method works, but it can be simplified with the jQuery hasClass() function:
$('.element_to_add_select_two_on').each((index, element) => {
$(element).select2({
tags: $(element).hasClass('classname_i_am_targeting'),
});
});
There is a much simpler way to do all of this, however, and it is much more flexible and already built into select2 via the way of data-* attributes (note, you need jQuery > 1.x). You can simply add data-tags="true" to any of your select elements with which you want tags enabled. These will override any configuration options used when initializing select2 as well as any defaults:
<select data-tags="true">
...
</select>
I have this problem:
I want to compare variable to ngModel input.
I'm doing that with directive:
Html:
<input type='text' ng-model='firstPerson.name' same-as-person='secondPerson.name'>
JS:
app.directive('sameAsPerson'), function() {
return {
require: 'ngModel',
restrict: 'A',
link: function ($scope, $element, $attrs, ctrl) {
var validate = function (firstValue) {
var secondValue = $attrs.sameAsPerson;
ctrl.$setValidity('sameAsPerson', firstValue == secondValue);
return firstValue ;} ;
ctrl.$parsers.unshift(validate);
ctrl.$formatters.unshift(validate);
$attrs.$observe('sameAsPerson', function(secondValue) {
return validate (ctrl.$viewValue);})}} ;}) ;
SameAsPerson is a costume directive that requires ngModel, restrict 'A' and set validity on the input based on the comparison between the values.
It works fine - if the firstPerson.name not equals to secondPerson.name the input border is red.
But!
In case there is not secondPerson on the scope I don't want the attribute same-as-person to be rendered to the html.
I tried to use the ng-attr but it doesn't seem to work.
In the current scenario if secondPerson doesn't exist the value of secondPerson.name in the directive is empty string.
Notice that in case secondPerson exist but the name is "" I still want to show red input.
In addition to that I compare many attributes of those two persons, not just the name, this is why I want to it be with directive and not with ngIf, ngStyle is also not the solution for me because there is more changes than just on the input itself.
Thank you very much for you help!
Only for style you can use ng-class directive.
<input ng-model="'firstPerson.name" ng-class="{ 'error':'secondPerson.name!='firstPerson.name' && secondPersonNameExist()"></input>
$scope.secondPersonNameExist = function () {
return angular.isDefined($scope.secondPerson.name);
}
Check this fiddle
Note that the class that you see is the previous so when the validation is clean you see error and on the next change you see the error absent. This is due to ng-change function is not picking up the new class status of input.
I need to create a form using the Polymer Paper-Input elements, and I need a way to know when all required content has been filled out.
I looked for a built in element, but didn't see one. So I wanted to create a polymer form element that would wrap all of the input tags. The resulting element would have an Invalid attribute which lets you know if any of the input tags are invalid.
The use of the tag would look like this:
<test-form id="testform">
<paper-input label="test" required error="This field is required"></paper-input>
</test-form>
Invalid: {{ $.testform.invalid }}
However, it appears that by the time in the elements lifecycle that I can loop over all the elements inside of the content tag, that anything added to the observe object is ignored.
Here is the code I was working on below:
<polymer-element name="test-form" attributes="invalid">
<template>
<content id="content">
</content>
</template>
<script>
Polymer('test-form', {
domReady: function () {
this.observe = {};
for (var i = 0; i < this.children.length; i++) {
this.observe["this.children[" + i + "].invalid"] = "valChanged";
}
},
invalid: false,
valChanged: function (oldValue, newValue) {
// TODO: If newValue is true set invalid to true
// If newValue is false, loop over all elements to see if all are now valid and invalid can be set to false.
alert("VALUE CHANGED" + oldValue + newValue);
}
});
</script>
Is there a better way to handle this or does anyone know how to make changes to what polymer is observing at this point in the lifecycle?
As far as checking the form's validity, you could simply check each form element's invalid property:
validate: function() {
var invalid = false;
Array.prototype.forEach.call(this.children, function(child) {
if (child.invalid === true) {
invalid = true;
}
});
this.invalid = invalid;
}
Then you could add an input event listener and run this method each time a form element's input changes.
Here's a working jsbin.
If I understand your question, your high level goal is form validation?
As has been detailed in polycasts and other places, I have used iron-form which has some very powerful validate() functionality, including what you mention above and much more.
It does sometimes require some odd usages of hidden <input> fields to get all of the work done, but this is easy to learn in the polycasts, such as polycast 55 and 56
If you stumbled upon this question in 2017, you would definitely now want to use more primitive tech, after you've seen what this has to offer.
A quick question about using context with Jquery selectors:
I'm trying to grab the text from a div element that has id="time". Can a HTML snippet be used as context in the following:
// An AJAX request here returns a HTML snippet "response":
var myTime = $("#time", response).text();
The reason I'm doing this is that I want the time variable from within the html held in response, but don't want the overhead of loading all of the html into the DOM first. (it's a large amount of html).
From the comments what I understand is the response is <span id="time">blah blah</span> which means the element time is the root variable itself, that is why the child lookup is not working.
var response = '<span id="time">blah blah</span>';
var myTime = $(response).text(); // Or $(response).filter("#time").text();
alert(myTime)
Demo: Fiddle
This method uses filter() rather than find(), the difference being:
filter() – search through the passed element set
find() – search through all the child elements only.
Did you try it?
$("#time", "<div><span id=time></span></div>")[0].id //returns 'time'
From the jQuery source code:
// HANDLE: $(expr, context)
// (which is just equivalent to: $(context).find(expr)
} else {
return this.constructor( context ).find( selector );
}
so valid selectors should work in the context parameter. Personally, I prefer using find to begin with because it keeps all the selectors in the same order instead of $("second > third", "first");
Is there the equivalent of the jQuery livequery plugin for jQuery 1.7+ ?
I'm trying to dynamically bind events, reading the events a DOM element should bind on based on data-* elements.
Test 1
Test 2
.. etc ..
I want to bind all elements with class .js-test but only on the events listed in their data-events attribute.
jQuery.on/live/bind/delegate all require the events to be passed in as params.
This is find for DOM elements that exist on the page when document.ready, however as I update the DOM (AJAX, JS, etc.) I want any new elements with class .js-test to have its events bound as well.
The livequery plugin (which is old, from jQuery 1.3 times) seems to allow this, as it simple requires a selector and a function to run against anything that matches the selector.
As of jQuery 1.7 the on method, supercedes the live method. While it doesn't have an easy method of passing in or matching selectors like you describe, it is possible to accomplish this by passing in the dynamic value of data-events in place of the event type, as long as the data-event value matches that event.
However, since the argument passed into the on method's event parameter -- the first parameter -- is taken from each data-events attribute, from each element in the set of matched elements, we must loop through the collection of matched elements so that we access each elements' individual data-events attribute value separately:
$('.js-test').each(function() {
$(this).on( $(this).attr("data-events"), function() {
// event pulled from data-events attribute
alert("hello - this event was triggered by the " + $(this).attr("data-events") + " action.");
});
});
I want all events to be mapped to the same function, but have different events trigger the function call for different DOM elements.
Since you want to map all of the events to a single function, this solution meets your specific requirements, and solves your problem.
However, should your requirements change and you find you need to map a collection of function events to match each event type, this should get you started:
var eventFnArray = [];
eventFnArray["click"] = function() {
alert("click event fired - do xyz here");
// do xyz
};
eventFnArray["mouseover"] = function() {
alert("mouseover fired - do abc here");
// do abc
};
$('.js-test').each( (function(fn) {
return function() {
$(this).on( $(this).attr("data-events"), function() {
alert("hello - this is the " + $(this).attr("data-events") + " event");
// delegate to the correct event handler based on the event type
fn[ $(this).attr("data-events") ]();
});
}
})(eventFnArray)); // pass function array into closure
UPDATE:
This has been tested and does indeed work for new elements added to the div#container. The problem was in the way the on method functions. The delegating nature of on only works if the parent element is included in the selector, and only if a selector is passed into the second parameter, which filters the target elements by data-events attribute:
HTML:
<div id="container">
Test 1
Test 2
</div>
JavaScript:
$(document).ready(function() {
$('.js-test').each(function() {
var _that = this;
alert($(_that).attr("data-events"));
$(this).parent().on(
$(_that).attr("data-events"),
'.js-test[data-events="'+ $(_that).attr("data-events") +'"]',
function() {
// event pulled from data-events attribute
alert("hello - this event was triggered by the " + $(_that).attr("data-events") + " action.");
}
);
}
);
});
Additionally, use the following jQuery to add an item to the container to test it:
$('#container')
.append("<a href='#' class='js-test' data-events='mouseover'>Test 3</a>");
Try it out:
Here is a jsfiddle that demonstrates the tested and working functionality.