Extracting text from a class name - javascript

I'm attempting to write a function which will scan a range of elements which contains "*-chars" as a class. Once I've found the elements I want to take that particular class (eg max-chars) and extract the part of the class before the -. I can't use a simple split as elements could contain other classes which contain a - or even -chars.
So far I've managed the following:
var getLimitType = function (el) {
var output = el.find('*[class*="-chars"]').filter(function () {
return this.className.match(/(?:^|\s)-chars/);
});
var limitType = output.val().split("-").shift();
var getVal = el.find('input').attr('maxlength');
return limitType+'_'+getVal;
};
Obviously this doesn't work as limitType is trying to perform a split on a jQuery object instead of a string, however I can't figure out what to put in the blank line, I need something which will take all the classes from that object, work out which one I am looking for and returning only that one as a text string.

Never quite found a desirable answer, however I managed to solve my issue with this work-around:
var getLimitType = function (element) {
var ml = element.find('input').attr('maxlength');
if (element.hasClass('exact-chars')) {
return 'exact_'+ml;
} else if (element.hasClass('min-chars')) {
return 'min_'+ml;
} else if (element.hasClass('max-chars')) {
return 'max_'+ml;
} else {
return 0;
}
};

Related

Javascript function parameters in Acrobat

Hopefully you all don't get pissed at me for such a seemingly simple question..
Basically, I have a PDF form that I'm scripting with javascript.
I have a bunch of check boxes that I would like to set required and/or not required based on other inputs and I'm trying to repeat code as little as possible, especially since there's a ton of inputs.
Right now, the best way I can accomplish what I'm attempting is by setting a function for each instance of inputs as follows:
function setWalkwayNotRequired() {
this.getField("sidewalkAsphalt").required = false;
this.getField("sidewalkConcrete").required = false;
this.getField("sidewalkPavers").required = false;
this.getField("sidewalkCondition").required = false;
}
I would then call this function based on the input of a certain checkbox:
if (this.getField("sidewalkNone").value == "Yes") {
setSidewalkNotRequired();
}
Then all of the above-mentioned fields would be set to not required.
I feel like there should be a way to create a single "setRequired" or "setNotRequired" function to take a parameter of the field in question.
In my mind that would look something like this:
function setRequired(a, b, c, d) {
this.getField(a).required = true;
this.getField(b).required = true;
this.getField(c).required = true;
this.getField(d).required = true;
}
I would then call on that function for all instances, for example, walkways (like that above) or driveways, etc. like so:
if (this.getField("sidewalkNone").value == "Off") {
setRequired('"sidewalkAsphalt"', '"sidewalkConcrete"', '"sidewalkPavers"', '"sidewalkCondition"');
}
Again, in my mind what would then be output based on the above code once the function is called is something like:
if (this.getField("sidewalkNone").value == "Off") {
this.getField("sidewalkAsphalt").required = true;
this.getField("sidewalkConcrete").required = true;
this.getField("sidewalkPavers").required = true;
this.getField("sidewalkCondition").required = true;
}
Doing it the way I did in the first code block would require me to create separate functions for each set of checkboxes, creating a lot of code in an already huge file. The second way would allow me to use 1 function over and over throwing the field names as parameters depending on where I'm at in the PDF.
I'm also not very clear on if it's even legal to declare the parameters as I did with the '"..."' quotes; I did that because I need the double quotes inside the this.getField().
Again, I'm sorry if this is novice, I've just been trying to play with the code for a while now and can't get it to work.
Any input would be amazing.
You could just pass in an Array of field names:
function setRequired( fieldNames, isRequired = true ) {
for( var i = 0; i < fieldNames.length; i++ ) {
var fieldName = fieldNames[i];
this.getField( fieldName ).required = isRequired;
}
}
Usage:
if( this.getField("sidewalkNone").value == "Off" ) {
setRequired( [ "sidewalkAsphalt", "sidewalkConcrete", "sidewalkPavers", "sidewalkCondition" ] );
}
If you use hierarchical naming with dot notation, you can set properties on the parent to affect all children. For example, if you name the fields "sidewalk.Asphalt", "sidewalk.Concrete", and "sidewalk.Pavers"...
this.getField("sidewalk").required = true;
... will set all the children to be required.

How to check if html if any html element contains text from some Object

I have some object with label and value. Those elements holds some data.
For now i want to loop on html elements and check, what element match this elements. Object is called ui.
Right now i want to select all elements that contains text from any of object elements.
Those elements have class .img.
Below simple javascript:
$("#project").autocomplete({
source: Items,
appendTo: ".autocomplete",
minLength: 2,
response: function (event, ui) {
if (ui.content.length == 0) {
return false;
}
var content = ui.content[0].label;
$.each($('.img'), function () {
if ($(this).is(':contains(' + content + ')')) {
return;
} else {
$(this).fadeOut(100);
}
});
}
});
This code acts as autocomplete, and i want to hide all emelents that don't match data from ui object.
This code works for me almost fine, but there is one thing that break things:
var content = ui.content[0].label;
This selects only first item from object, and i'm looking for a way, how to check all items from obejct to check if text contains data, not only from first obejct element [0].
Thanks for advice.
I create a jsfiddle for you, If I understand the problem
var matchLabelString=_.reduce(ui,function(accumulateString,current){
if(accumulateString == ""){
return current.label;
}
return accumulateString + "|"+current.label;
},"")
var regex = new RegExp("^"+matchLabelString);
$.each($('.img'), function () {
if (regex.test($(this).text())) {
return;
} else {
$(this).fadeOut(100);
}
});
https://jsfiddle.net/3o1oy5y2/
EDIT: I see your code, and I think that my code work anyway. Try it, as you can see I have used underscore library to create a string seperatad by | from array
You can add a loop in your $each callback :
$.each($('.img'), function() {
for (var i = 0; i < ui.content.length; i++) {
var content = ui.content[i].label;
...
}
});
EDIT: Change let to var

Javascript css selector for nested classes

I am creating a CSS selector for homework. I have managed to extract and get single selectors - e.g. #_id, but I cannot work out how to get a result for nested ones such as : div#_id._class [NOTE: I cannot use any libraries to do this or querySelectorAll]
The pseudo-code below is an example of what I currently have:
if (regex match for class) {
for (a in match for class) {
if (a.indexOf('.') > -1) {
var split_ = a.split(".");
var dot = split_[0];
var class_ = split_[1];
array_of_elements = document.getElementsByClassName(class_);
}
}
The problem is when the selector is nested I can't extract the whole thing using a similar method. E.g. look for an id, look for a class. Can anyone point me in the right direction?
else if (is id) {
split by ("#");
for (each result) {
if (has class ('.')) {
array_elements = document.getElementById(result_ID)
.getElementsByClassName(result_CLASS_NAME));
} else {
array_elements = (document.getElementsByTagName(result));
}
}
What you mentioned is actually called a sequence of simple selectors.
div#_id._class
It consitst of three simple selectors div, #_id, ._class
What you need to do is get elements by tag name, and then check for matches on all of the remaining simple selectors. I'll give you an idea here:
function qSelector(sequence) {
var tagName = getTag(sequence) || '*'; // 'div'
var ids = getIDs(sequence); // ['_id']
var classes = getClasses(sequence); // ['_class']
var els = document.getElementsByTagName(tagName);
return [].filter.call(els, function (el) {
for (id in ids) { if (el.id != id) return false; }
for (cls in classes) { if (el.className not contains cls) return false; }
return true;
});
}
This is more versatile than your approach and can be easily generalized to work with selectors containing spaces.
I'll leave the implementation of the get… helpers to you.

How to make my css selector engine more flexible?

I created a custom css selector engine function for my custom javascript library like so,
var catchEl = function(el) { // Catching elements by identifying the first character of a string
var firstChar = el[0],
actualNode = el.substring(1, el.length),
elements,
tempElems = [];
if (!document.querySelectorAll) {
try{
if(firstChar === "#") {//So, we can look for ids
tempElems.push(document.getElementById(actualNode));
} else if(firstChar === ".") {//or classes
elements = document.getElementsByClassName(actualNode);
for(i=0;i<elements.length;i++) tempElems.push(elements[i]);
} else {//or tags
elements = document.getElementsByTagName(el);
for(i=0;i<elements.length;i++) tempElems.push(elements[i]);
}
} catch(e) {};
} else {//but before everything we must check if the best function is available
try{
elements = document.querySelectorAll(el);
for(i=0;i<elements.length;i++) tempElems.push(elements[i]);
} catch(e) {};
}
return tempElems;
}
This function returns an array of elements. However, I turned my head around and tried to make it more flexible so that it can also return the window, document or this object, but was unsuccessful. Whenever I try to push the window object into the tempElems array, the array is still empty.
So, I want to know how to make this function return an array of elements when a string is passed through it or return the respective objects(window, document or this) as desired.
Note: I don't want to work with jQuery. So, please don't post any answers regarding jQuery.

javascript - coldfusion - working with a list

This is probably easy for someone.
I am returning a list of campaignIDs (12,45,66) via JSON to a javascript variable
var campaignList = res.DATA.CAMPAIGNS
Now, given a specified campaignID passed in the URL
var campaignId ='<cfoutput>#url.campaignID#</cfoutput>'
I want to check if the returned list contains this campaignID
Any help much appreciated.
Plenty of ways to do it, but I like nice data structures, so ...
Split the list on comma, then loop over list, looking for value:
function campaignExists(campaignList,campaignId) {
aCampaignList = campaignList.split(',');
for (i=0;i<aCampaignList.length;i++) {
if (aCampaignList[i]==campaignId)
return true;
}
return false;
}
Since Array.indexOf sadly isn't cross browser, you're looking at something like:
// assume there is no match
var match_found = false;
// iterate over the campaign list looking for a match,
// set "match_found" to true if we find one
for (var i = 0; i < campaignList.length; i += 1) {
if (parseInt(campaignList[i]) === parseInt(campaignId)) {
match_found = true;
break;
}
}
If you need to do this repeatedly, wrap it in a function
Here's a bit of a "out of the box" solution. You could create a struct for your property id's that you pass into the json searilizer have the key and the value the same. Then you can test the struct for hasOwnProperty. For example:
var campaignIDs = {12 : 12, 45 : 45, 66 : 66};
campaignIDs.hasOwnProperty("12"); //true
campaignIDs.hasOwnProperty("32"); //false
This way if the list is pretty long you wont have to loop through all of the potential properties to find a match. Here's a fiddle to see it in action:
http://jsfiddle.net/bittersweetryan/NeLfk/
I don't like Billy's answer to this, variables within the function have been declared in the global scope and it is somewhat over complicated. If you have a list of ids as a string in your js just search for the id you have from user input.
var patt = new RegExp("(^|,)" + campaignId + "(,|$)");
var foundCampaign = campaignList.search(patt) != -1;

Categories