JavaScript reselect class personally in ListView - javascript

I am creating ListView using my template:
HTML:
<div id="ItemTemplate" data-win-control="WinJS.Binding.Template">
<div class="ItemTemplate">
<div class="back"></div>
<div data-win-bind="innerText:Info.shortName" class="shortName"></div>
<div data-win-bind="innerText:value Converters.BeginValue" class="value"></div>
<div data-win-bind="innerText:value Converters.EndValue" class="valueEnd"></div>
<div data-win-bind="innerText:Info.longName"></div>
<img data-win-bind="src:Info.flag" class="flag" />
<div data-win-bind="innerText:change Converters.BeginChange" class="change"></div>
<div data-win-bind="innerText:change Converters.EndValue" class="changeEnd"></div>
<div data-win-bind="innerText:changePercent Converters.BeginChangePercent" class="changePercent"></div>
<div data-win-bind="innerText:changePercent Converters.EndValue" class="changePercentEnd"></div>
</div>
</div>
The issue is when I meet the very long name I need to adjust font-size.
So I do (for each element in list):
JavaScript:
template = document.getElementById('ItemTemplate');
// Adjust font - size
var name = item.data.Info.longName;
// Split by words
var parts = name.split(' ');
// Count words
var count = parts.filter(function(value) {
return value !== undefined;
}).length;
var longNameDiv = $(template).children("div").children("div").eq(4);
if (count > 2) {
// Display very long names correctly
$(longNameDiv).removeClass();
$(longNameDiv).addClass("veryLongName");
}
var rootDiv = document.createElement('div');
template.winControl.render(item.data, rootDiv);
return rootDiv;
CSS:
.veryLongName {
font-size: 10pt;
}
But it doesn't effect selectivly. Moreover seems like it is check conditions for the first time and then just apply the same setting for remaining items. But it needs to change font-size to smaller only in case if the name is too long. So what am I doing wrong? Thanks.

Try by using following code instead, but u must include jquery for it.
jsfiddle : http://jsfiddle.net/vH6G8/

You can do this using jquery's filter
$(".ItemTemplate > div").filter(function(){
return ($(this).text().length > 5);
}).addClass('more_than5');
$(".ItemTemplate > div").filter(function(){
return ($(this).text().length > 10);
}).removeClass('more_than5').addClass('more_than10');
DEMO

Related

How can I change the default ordered and unordered list providing various options in Jodit Editor?

I am being able to provide option's in the menu bar but when I click on any of the option it's working absolutely fine,but if I tried to select twice it is changing at all places.
For Ex.
I want to make a ordered list such as:
1.Some Text here
a.option 1 b.option 2
c.option 3 d.option 4.
When I am trying to select some text its also converting 1 to A.
Please help.Thanks in advance
document.execCommand('insertUnorderedList',true,null);
let selectedStyle = event.target.parentNode.classList.value;
$('li').attr('id', function(i) {
return 'unorder'+(counter+1);
});
$('ol > li').css({'list-style-type':selectedStyle});
You can ignore the counter part its not required.I was trying to put id at every element and use jquery to update only that part.
let counter = 0;
document.querySelectorAll (".unorder-list-select .unorder-list-main .unorder-container ul").forEach((elem)=>{
elem.addEventListener("click",(event)=>{
counter++;
$('li').attr('id', function(i) {
return 'unorder'+(counter+1);
});
$('ul > li').css({'list-style-type':selectedStyle});
}
HTML
<div class="order-list-select" id="orderList" draggable="true">
<div>
<span class="jodit_popup_triangle"></span>
<div class="math-toolbar-top" id="orderlistHeader"></div>
<div class="order-list-main">
<div class="order-list-container"></div>
<div class="order-container">
<ol class="upper-roman">
<li><hr></li>
</ol>
<ol class="decimal">
<li><hr></li>
</ol>
</div>
</div>
</div>
</div>
Actual
1.text
2.text
Some text here
1.Txt
2.Txt
Expected
1.text
2.text
Some text here
a.Txt
b.Txt
I did it by Jquery don't know if its right approach but it has made me achieve my task.
Below is the code for my this.
document.querySelectorAll(".unorder-list-select .unorder-list-main .unorder-container ul").forEach((elem)=>{
elem.addEventListener("click",(event)=>{
counter++;
document.execCommand('insertUnorderedList',true,null);
let selectedStyle = event.target.parentNode.classList.value;
let select = window.getSelection().focusNode.parentElement.parentElement;
let ul_id = ""
$(select).attr('id', function(i) {
ul_id = "unorder"+(counter);
return ul_id;
});
if(selectedStyle == "right-arrow"){
$('#'+ul_id).css({'list-style-image':`url('icons/list-right-editor.svg')`});
}else if(selectedStyle == "open-square"){
$('#'+ul_id).css({'list-style-image':`url('icons/square-open-editor.svg')`});
}else{
$('ul').attr('type',function(){
return selectedStyle;
})
$('#'+ul_id).css({'list-style-type':selectedStyle});
}
document.querySelector(".unorder-list-select").remove();
})
});
Please change the classess accordingly to get the tag and click.

Including the current node in the find scope

Consider the following snippet as an example:
<div class="bar foo">
</div>
<div class="bar">
<div class="foo"></div>
</div>
Given var $set=$('.bar'); I need to select both nodes with foo class. What is the proper way to achieve this. Considering addBack() requires a selector and here we need to use the $set jQuery object and $set.find('.foo') does not select the first node.
use this :
var $set = $(".bar").filters(function () {
var $this = $(this);
if($this.is(".foo") || $this.find(" > .foo").length !== 0){
return true;
} else{
return false;
}
});
Here's one way of going about it:
var set = $('.bar');
var foos = [];
for (var i = 0; i < set.length; i++) {
if ($(set[i]).hasClass('foo')) {
foos.push(set[i]);
}
}
if (set.find('.foo').length !== 0) {
foos.push(set.find('.foo')[0]);
}
console.log(foos);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="bar foo"></div>
<div class="bar">
<div class="foo"></div>
</div>
The for loop checks all elements picked up with jQuery's $('.bar'), and checks if they also have the foo class. If so, it appends them to the array. The if checks if any of the elements picked up in set have any children that have the foo class, and also adds them.
This creates an array that contains both of the DIVs with the foo class, while excluding the one with just bar.
Hope this helps :)
test this :
var $newSet = $set.filter(".foo").add($set.has(".foo"));
You could use the addBack() function
var $set=$('.bar');
console.log($set.find(".foo").addBack(".foo"));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="bar foo">
</div>
<div class="bar">
<div class="foo"></div>
</div>

How to select element has class start and end with specific string using jquery?

I got several divs using classes like
.wrap-1-addon-1
.wrap-2-addon-1
.wrap-3-addon-1
I want to select all of them and use if ( $(this).hasClass() ) to check if its one of them. Currently I only do check for a single class. How can I check all of these, for example .hasClass('wrap-*-addon-1')?
Best regards.
You can combine two jquery Attribute Starts With Selector [name^=”value”] and Attribute Ends With Selector [name$=”value”] to do this work.
$('div[class^="wrap-"][class$="-addon-1"]')
$('div[class^="wrap-"][class$="-addon-1"]').css("color", "red");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrap-1-addon-1">wrap-1-addon-1</div>
<div class="wrap-2-addon-1">wrap-2-addon-1</div>
<div class="wrap-3-addon-1">wrap-3-addon-1</div>
<div class="wrap-3-addon-2">wrap-3-addon-2</div>
You can use starts with selector:
$('div[class^="wrap"]')
JsFiddle demo
You could use .is() which support multiple classes, unfortunately .hasClass() works only for one class at a time.
Example:
element.is('.wrap-1-addon-1, .wrap-2-addon-1, .wrap-2-addon-1')
It is better to add another class and select with this class. You can then test it with regex.
$el = $(".wrap");
$el.each(function() {
var test = /wrap-[1-3]-addon-1/.test($(this).attr("class"));
$(".result").html(test);
console.log(test);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrap-1-addon-1 wrap"></div>
<div class="wrap-2-addon-1 wrap"></div>
<div class="wrap-3-addon-1 wrap"></div>
<div class="result"></div>
Inspiring regex matching from this answer:
var $ele = $("div:first");
alert(matchRule($ele.attr('class'),'wrap-*-addon-1'))
function matchRule(str, rule) {
return new RegExp("^" + rule.split("*").join(".*") + "$").test(str);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="wrap-1-addon-1">
</div>
<div class="wrap-2-addon-1">
</div>
<div class="wrap-3-addon-1">
</div>
This might help you, i used regex to resolve if current element's class(es) suits the desired pattern.
I assume you have more than 3 classes to check.
This pattern is for wrap-1-addon-1 to wrap-n-addon-1, n is some digit
function hasMyClass(elm) {
var regex = /(wrap-)+(\d)+(-addon-1)/i;// this is the regex pattenr for wrap-*-addon-1
var $this = $(elm);
var myClassesStr = $this.attr('class');
if(myClassesStr) { // if this has any class
var myClasses = myClassesStr.split(' '); // split the classes
for(i=0;i<myClasses.length;i++) { // foreach class
var myClass = myClasses[i]; // take one of classes
var found = myClass.match(regex); // check if regex matches the class
if(found) {
return true;
}
}
}
return false;
}
function test() {
$('#container div').each(function(){
var $this = $(this);
$('#pTest').append('<br/>test result for ' + $this.attr('id') + ':' + hasMyClass(this));
// hasMyClass(this) is the sample usage
})
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<div id="div1" class="wrap-1-addon-1 anotherClass">div1 (wrap-1-addon-1)</div>
<div id="div2" class="wrap-2-addon-1 anotherClass anotherClass2">div2 (wrap-2-addon-1)</div>
<div id="div3" class="wrap-3-addon-1 anotherClass">div3 (wrap-3-addon-1)</div>
<div id="div4" class="anotherClass">div4 (none)</div>
</div>
<button id="testBtn" onclick="test();" type="button">TEST</button>
<p id="pTest" >...</p>

How to divide result given in html() jquery?

I'm trying to create a function where I click a button and I get content from a <div>. After, I need to divide the content. I mean, if this div has 10 children, I need to save 5 children in my var code1 and the other 5 in var code2. My problem is I'm not able to use html() function. My code looks like:
$(".pluscontrol").click(function(){
var id = $(this).attr("id");
var items=$(this).closest("table").parent().next().children('#'+id).children().length;
var middle = items / 2;
var code1="";
$(this).closest("table").parent().next().children('#'+id).html(
function(index,currentcontent){
if (index < middle )
code1 = code1 + currentcontent;
});
if ( $(".modal-body .row .sdiv").attr("id") == 1 )
$(".modal-body .row #1.sdiv").html(code1);
if ( $(".modal-body .row .sdiv").attr("id") == 2 )
$(".modal-body .row #2.sdiv").html("...");
});
As you can see, at first, I get the children lenght but I get all items.
I've checked this reference but it not helps too much
the var items is the number of items
Giving an argument to .html() makes it change the HTML of the selected elements. If you want to get the HTML, just call .html() with no argument.
To get the HTML of all the elements in a collection, use .map() to iterate, then combine them with .join().
var allChildren = $(".parent").children();
var middle = Math.floor(allChildren.length/2);
var code1 = allChildren.slice(0, middle).map(function(index, element) {
return element.innerHTML + " " + index;
}).get().join(' ');
var code2 = allChildren.slice(middle).map(function(index, element) {
return element.innerHTML + " " + (index + middle);
}).get().join(' ');
$("#out1").html(code1);
$("#out2").html(code2);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="parent">
<div class="child">Test1</div>
<div class="child">Test2</div>
<div class="child">Test3</div>
<div class="child">Test4</div>
<div class="child">Test5</div>
<div class="child">Test6</div>
<div class="child">Test7</div>
<div class="child">Test8</div>
<div class="child">Test9</div>
<div class="child">Test10</div>
</div>
First group:
<div id="out1"></div>
Second group:
<div id="out2"></div>
You can use querySelectorAll which gives u a collection of child element. It also has a length function which you can call. If you want you can chain a foreach method to it. I have broken it down for clarity.
var children = document.querySelectorAll('.parent > div');
var midPoint = Math.round(children.length / 2);
var firstHalf = Array.prototype.slice.call(children,0,midPoint);
var secondHalf = Array.prototype.slice.call(children,midPoint);
firstHalf.forEach(function(elm){
console.log(elm.innerHTML);
});
<div class="parent">
<div class="child"><p>Test1</p></div>
<div class="child"><p>Test1</p></div>
<div class="child"><p>Test1</p></div>
<div class="child"><p>Test1</p></div>
<div class="child"><p>Test1</p></div>
<div class="child"><p>Test1</p></div>
<div class="child"><p>Test1</p></div>
<div class="child"><p>Test1</p></div>
<div class="child"><p>Test1</p></div>
</div>

Get all elements with id above 4 (ID is combined by string and number )

<div id="table1"></div>
<div id="table2"></div>
<div id="table3"></div>
<div id="table4"></div>
<div id="table5"></div>
...
How to select all elements with "table" and an ID > 4.
Something like this might help you:
var test = /table(\d+)/;
$("[id^='table']").filter(function () {
return parseInt(test.exec(this.id)[1], 10) > 4;
});
It will match all elements starting with 'table' and then filter out those ending with values smaller than or equal to 4.
You can go over each element that the id starts with table [id^='table'] and check if the rest (the number) is bigger than 4
Example here http://jsfiddle.net/fLg00oxq/2/
$("[id^='table']").each(function(){
var id = $(this).attr('id').substr(5); // remove table and leave just the number
if(id > 4 ){
// Your code here
}
});
Edit, Updated
Try
v1 (for numerically ordered id's , i.e.g., table1 -> table2)
$("[id=table4] ~ [id*=table]")
v2 (unordered id's)
$("[id*=table]").not(function() {
// return elements that _don't_ match the selector ,
// `id` cast as `Number` <= 4
return this.id.match(/\d+/)[0] <= 4
})
See
Attribute Equals Selector [name="value"]
Next Siblings Selector (“prev ~ siblings”)
Attribute Contains Selector [name*="value"]
.not()
$("[id*=table]").not(function() {
// return elements that _don't_ match the selector ,
// `id` cast as `Number` <= 4
return this.id.match(/\d+/)[0] <= 4
})
.each(function() {
this.innerText = this.id
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="table10"></div>
<div id="table2"></div>
<div id="table9"></div>
<span></span>
<div id="table6"></div>
<div id="table5"></div>
<div id="table1"></div>
<div id="table7"></div>
<div id="table8"></div>
<div></div><br />
<div id="table3"></div>
<div id="table4"></div>
If your div they ordered will in example:
Edit your HTML :
<div class="table"></div>
<div class="table"></div>
<div class="table"></div>
<div class="table"></div>
<div class="table"></div>
Scripts
$(document).ready(function() {
$('.table:gt(2)').each(function() {
// Apply your functions for each div ....
});
}
This will do it:
$("div[id^=table]").slice(4);
Basically it selects all the div elements with id starting with "table". After that it removes four first matches and returns all the remaining jQuery objects.
So this has an assumption that there is <div id="table1"> ... <div id="table2"> ... <div id="table[n+1]">.
demo
var $tables = $('[id^=table]').filter(function(){
return +this.id.replace(/\D+/,'') > 4;
});
$tables.hide(); // Use example
the above will get the number out of the selector ID and compare if greater than 4. $tables will now result in a collection of elements returned by the jQuery's filter() method.
.replace(/\D+/,'') will remove all non-numeric (D+) Characters; the unary + will convert the String result to Number and > 4 does the desired.
For a micro-Plugin extension you can go for:
// Retrieve elements from mixed ID str+number
// Returns a collection of elements with ID number greather than the num argument
$.fn.idNumGreaterThan = function(num){
return this.filter(function() {
return +this.id.replace(/\D+/,'') > num;
});
};
$('[id^=table]').idNumGreaterThan(4).hide();
// Also with class selectors (element must have a mixed alphaNumeric ID)
$('.element').idNumGreaterThan(4).hide();
You can try with this code, however i think that there are better ways to do it:
for (var i = 4; i <= 100; i++) {
$('#table'+i)...
};
You Could try the contain selector like so $('div[id~=table]')
Reference http://api.jquery.com/attribute-contains-word-selector/

Categories