How can I reset jQuery sorting? - javascript

How can I reset the sorting by using jQuery?
The ASC and DESC sorting works perfectly, but I found no way, where I can reset the sorting back to default list with button click:
Jack
Evelyn
Jackson
Mason
James
William
Here the code snippet where the sorting works for ASC and DESC:
$('#sortByNameASC').click(function (){
$('.list .col').sort(function(a,b) {
return $(a).find(".name").text() > $(b).find(".name").text() ? 1 : -1;
}).appendTo(".list");
})
$('#sortByNameDESC').click(function (){
$('.list .col').sort(function(a,b) {
return $(a).find(".name").text() < $(b).find(".name").text() ? 1 : -1;
}).appendTo(".list");
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="sortByNameASC">Sort ASC</button>
<button id="sortByNameDESC">Sort DESC</button>
<button id="resetSorting">Reset</button>
<div class="list py-2">
<div class="col">
<li class="search-filter name">Jack</li>
</div>
<div class="col">
<li class="search-filter name">Evelyn</li>
</div>
<div class="col">
<li class="search-filter name">Jackson</li>
</div>
<div class="col">
<li class="search-filter name">Mason</li>
</div>
<div class="col">
<li class="search-filter name">James</li>
</div>
<div class="col">
<li class="search-filter name">William</li>
</div>
</div>
I have try with cache the default list, but this doesn't work. Any ideas how I can achieve this

Firstly you should note that your HTML is invalid. li elements cannot be children of a div, only ul or ol. That needs to be corrected in your HTML and current sorting logic.
With regard to your goal of 'resetting' to the original order, you can loop through the elements and store their initial index in the element metadata when the page loads. Then you can use the same pattern you currently have to sort by the original index when the 'reset' button is clicked.
Try this:
let $items = $('.list .col .name');
// store original index order on load:
$items.each((i, el) => $(el).data('index', i));
// restore original order:
$('#resetSorting').on('click', () => {
$items.sort((a, b) => $(a).data('index') > $(b).data('index') ? 1 : -1).appendTo('.col');
});
$('#sortByNameASC').on('click', () => {
$items.sort((a, b) => $(a).text() > $(b).text() ? 1 : -1).appendTo(".col");
});
$('#sortByNameDESC').on('click', () => {
$items.sort((a, b) => $(a).text() < $(b).text() ? 1 : -1).appendTo(".col");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="sortByNameASC">Sort ASC</button>
<button id="sortByNameDESC">Sort DESC</button>
<button id="resetSorting">Reset</button>
<div class="list py-2">
<ul class="col">
<li class="search-filter name">Jack</li>
<li class="search-filter name">Evelyn</li>
<li class="search-filter name">Jackson</li>
<li class="search-filter name">Mason</li>
<li class="search-filter name">James</li>
<li class="search-filter name">William</li>
</ul>
</div>

Related

How to get id values from object inner class name?

I have one page create by javascript and I have these fields. How can I navigate and get the inner values just from a class object like this?
<li class="tdays" id="23 8 2021">
<div class="info">Quinta</div>
<div class="date">23</div>
<div class="ev" id="562">
<div class="ev-desc">
<p>undefined</p>
</div>
</div>
</li>
I'd like go get the div class="ev" id="562"
My code at now is
$(document).ready(function() {
var elements = document.getElementsByClassName("tdays");
$('.tdays').click(function() {
// console.log(this.id);
// console.log(this.value)
console.log(this[0]);
});
});
Firstly, note that the id attribute on the .tdays element is invalid - id cannot contain spaces.
To do what you require you can use jQuery's DOM traversal methods to find the .ev related to the clicked .tdays element and read its id. In this case you can use children() or find():
$(document).ready(function() {
$('.tdays').on('click', function() {
let evId = $(this).children('.ev').prop('id');
console.log(evId);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li class="tdays" id="23 8 2021">
<div class="info">Quinta</div>
<div class="date">23</div>
<div class="ev" id="562">
<div class="ev-desc">
<p>undefined</p>
</div>
</div>
</li>
<li class="tdays" id="02 9 2021">
<div class="info">Quinta</div>
<div class="date">02</div>
<div class="ev" id="121">
<div class="ev-desc">
<p>undefined</p>
</div>
</div>
</li>
</ul>
In case the OP considers to give the DOM Api a try and there especially querySelector and querySelectorAll ...
function handleTDaysClick(evt) {
const elmTDays = evt.currentTarget;
const evNode = elmTDays.querySelector('[id].ev');
console.log(evNode.id);
}
document
.querySelectorAll('.tdays')
.forEach(node =>
node.addEventListener('click', handleTDaysClick)
);
.as-console-wrapper {
min-height: 100%!important;
top: 0;
left: auto!important;
width: 50%!important;
}
<ul>
<li class="tdays" id="23-8-2021">
<div class="info">Quinta</div>
<div class="date">23</div>
<div class="ev" id="562">
<div class="ev-desc">
<p>undefined</p>
</div>
</div>
</li>
<li class="tdays" id="02-9-2021">
<div class="info">Quinta</div>
<div class="date">02</div>
<div class="ev" id="121">
<div class="ev-desc">
<p>undefined</p>
</div>
</div>
</li>
</ul>

Code only working in edit mode, not on live view

I am currently trying to implement a tab element on my site. I am using Elementor via Wordpress. In the edit mode everything works fine, but one the live page the selection of the different tabs doesnt work.
const tabs = document.querySelectorAll('[data-tab-target]')
const tabContents = document.querySelectorAll('[data-tab-content]')
tabs.forEach(tab => {
tab.addEventListener('click', () => {
const target = document.querySelector(tab.dataset.tabTarget)
tabContents.forEach(tabContent => {
tabContent.classList.remove('active')
})
tabs.forEach(tab => {
tab.classList.remove('active')
})
tab.classList.add('active')
target.classList.add('active')
})
})
<ul class="tabs">
<li data-tab-target="#einsteiger" class="tab"><h3>Einsteiger</h3><p id="preis">bis 2.999 €</p></li>
<li data-tab-target="#mittelklasse" class="active tab"><h3>Mittelklasse </h3><p id="preis">von 3.000 bis 4.499 €</p></li>
<li data-tab-target="#high-end" class="tab"><h3>High-End</h3><p id="preis">ab 4.500 €</p></li>
</ul>
<div class="tab-content">
<div id="einsteiger" data-tab-content >
<h1>test1</h1>
<p>test</p>
</div>
<div id="mittelklasse" data-tab-content class="active">
<h1>test2</h1>
<p></p>
</div>
<div id="high-end" data-tab-content >
<h1>test3</h1>
<p></p>
</div>
</div>

React.js modify child element on parent click

I have a following react component:
<li key={contact.id} class="option contact-item">
<div class="thumbnail">
<a><span>{contact.name.slice(0, 1)}</span></a>
</div>
<div class="text">
<div class="label">
<div class="name">{contact.name}</div>
<div class="status">{contact.status}</div>
</div>
<div class="select-container">
<div class="select">
<i class="icon-check"></i>
</div>
</div>
</div>
</li>
I need to toggle the color of <i class="icon-check"></i> when clicking the whole <li>
How can I do that?
Firstly, in react, you don't use class, you use className.
See this for full code: https://codepen.io/pen?editors=0010
Using state, you can change styles/classes/etc
_handleClick(key) {
let clicked = this.state.myList.filter(f => f.id === key)[0];
this.setState({ clicked: clicked });
}
_changeColor(key) {
if (this.state.clicked.id === key) {
return 'icon-checked';
}
else
return 'icon-check';
}
_renderList() {
return this.state.myList.map(contact => (
<li key={contact.id}
onClick={() => this._handleClick(contact.id)}
className="option contact-item">
<i className={this._changeColor(contact.id)}></i>
{contact.name}
</li>
));
}
render() {
return (
<div>
<h1>Hello</h1>
<ul>
{this._renderList()}
</ul>
</div>
);
}
You can set "changeColor" state on <li> click and your <i> can handle this state. If you change component state React will rerender your component.
<li onClick={this.changeColor()} key={contact.id} className="option contact-item">
<div className="thumbnail">
<a><span>{contact.name.slice(0, 1)}</span></a>
</div>
<div className="text">
<div className="label">
<div className="name">{contact.name}</div>
<div className="status">{contact.status}</div>
</div>
<div className="select-container">
<div className="select">
<i className="icon-check" style={if (this.state.colorChanged) {color: 'red'}}></i>
</div>
</div>
</div>
changeColor() {
this.setState({colorChanged: true});
}
I made a simple example for you, it works with a sinle list item Check this out.
If you have a list of items, you need to add a one more component for List itself with onToggleListItem method, which will handle the state change. The state of all list items should be store there. In ListItem component you call the onToggleListItem method with a contact id so you can identify which list item was changed.
handleButtonClick() {
this.props.onToggleListItem(this.props.contact.id);
}
Make use of a state and change the state on click of li
var Hello = React.createClass({
getInitialState() {
return {
colorClass: ''
}
},
toggleClass() {
if(this.state.colorClass == '') {
this.setState({colorClass: 'someColor'});
} else {
this.setState({colorClass: ''});
}
},
render(){
return (
<div>
<li onClick={this.toggleClass}>
Some text
<i className={"icon-check " + this.state.colorClass}>value</i>
</li>
</div>
);
}
})
ReactDOM.render(<Hello />, document.getElementById('app'));
.someColor {
color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react-dom.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="app"></div>

angularJS Custom directive functionality works using ng-click but not using ng-mouseOver

Requirement goes like this :- I have left navigation panel which has to be in sync with the items added in the main active view by the user and has to display in tree structure. Basic idea is to provide context aware sub-view that change based on active view.
Custom directive used to display tree structure: https://github.com/nickperkinslondon/angular-bootstrap-nav-tree/blob/master/src/abn_tree_directive.js
my HTML code: (using ng-click)
<div class="add-data-request-panel" style="min-height:1071px;"
ng-click="expandPanel()">
<ul>
<li class="icon-drd icon-drd-diactive" ng-if="panelCollapse" ></li>
<li class="icon-pie-chart icon-pie-active" ng-if="panelCollapse"></li>
<li class="icon-publish-req" ng-if="panelCollapse"></li>
<li class="icon-view-changes" ng-if="panelCollapse"></li>
</ul>
</div>
<div class="data-slider-panel" style="min-height:1071px;display" ng-if="panelExpand">
<div class="data-slider-row mtop" ng-click="collapsePanel()">
<div class="slider-row-left">
<span class="first-char" >S</span>
<span class="second-char">ection</span>
</div>
<div class="slider-row-right">
<div class="icon-drd icon-drd-diactive">
</div>
</div>
</div>
<div class="data-slider-row">
<div class="slider-row-left">
Section2
<div class="sub-slider-row-left">
<abn-tree tree-data="mainArrayObj"></abn-tree> // passing data to tree directive
</div>
</div>
<div class="slider-row-right">
<div class="icon-pie-chart icon-pie-active">
</div>
</div>
</div>
<div class="data-slider-row" ng-click="collapsePanel()">
<div class="slider-row-left">
Section3
</div>
<div class="slider-row-right">
<div class="icon-publish-req">
</div>
</div>
</div>
<div class="data-slider-row" ng-click="collapsePanel()">
<div class="slider-row-left">
Section4
</div>
<div class="slider-row-right">
<div class="icon-view-changes">
</div>
</div>
</div>
</div>
JS implementation in my controller
$scope.panelExpand = false; //setting default flag
$scope.panelCollapse = true; //setting default flag
$scope.expandPanel = function() {
$scope.panelExpand = true;
$scope.panelCollapse = false;
$scope.mainArrayObj = []; // array that holds the data passed in html to custom directive
initialJsonSeparator($scope.model.Data); // method used for iteration
};
$scope.collapsePanel = function() {
$scope.panelExpand = false;
$scope.panelCollapse = true;
};
my HTML code: (using ng-mouseover which is not working and displaying the data passed to navigation bar)
<div class="add-data-request-panel" style="min-height:1071px;" ng-mouseover="hoverIn()"
ng-mouseleave="hoverOut()">
<ul>
<li class="icon-drd icon-drd-diactive"></li>
<li class="icon-pie-chart icon-pie-active"></li>
<li class="icon-publish-req"></li>
<li class="icon-view-changes"></li>
</ul>
</div>
<div class="data-slider-panel" style="min-height:1071px;display"
ng-mouseover="hoverIn()" ng-mouseleave="hoverOut()" ng-show="hoverEdit">
<div class="data-slider-row mtop">
<div class="slider-row-left">
<span class="first-char">S</span>
<span class="second-char">ection1</span>
</div>
<div class="slider-row-right">
<div class="icon-drd icon-drd-diactive">
</div>
</div>
</div>
<div class="data-slider-row">
<div class="slider-row-left">
Section2
<div class="sub-slider-row-left">
<abn-tree tree-data="mainArrayObj"></abn-tree> // array that holds the data passed in html to custom directive
</div>
</div>
<div class="slider-row-right">
<div class="icon-pie-chart icon-pie-active">
</div>
</div>
</div>
<div class="data-slider-row">
<div class="slider-row-left">
Section3
</div>
<div class="slider-row-right">
<div class="icon-publish-req">
</div>
</div>
</div>
<div class="data-slider-row">
<div class="slider-row-left">
Section4
</div>
<div class="slider-row-right">
<div class="icon-view-changes">
</div>
</div>
</div>
</div>
js Implementation for the ng-mouseOver: (while debugging all the iteration and methods executed as expected)
$scope.hoverIn = function() {
this.hoverEdit = true;
$scope.mainArrayObj = []; // array that holds the data passed in html to custom directive
initialJsonSeparator($scope.model.Data); //method used to iterate the data
};
$scope.hoverOut = function() {
this.hoverEdit = false;
};
Any solution to this issue would be of gr8 help. If there is any other better approach other than the ng-mouseOver and ng-mouseLeave to implement hover, please do let me know.

Conditional innerhtml change

Let's say I have an HTML structure like this:
<li id="jkl">
<div class="aa">
<div class="bb">
<div class="cc">
<div class="dd">
<a ...><strong>
<!-- google_ad_section_start(weight=ignore) -->Test
<!-- google_ad_section_end --></strong></a>
</div>
</div>
</div>
<div class="ee">
<div class="ff">
<div class="gg">
<div class="excludethis">
<a...>Peter</a>
</div>
</div>
</div>
</div>
</div>
</li>
My goal is to set the content(innerhtml) of <li id="jkl"> to '' if inside of <li id="jkl"> there is any word of a list of words(In the example below, Wortliste) except when they are in <div class="excludethis">.
In other words, ignore <div class="excludethis"> in the checking process and show the html even if within <div class="excludethis"> there are one or more words of the word list.
What to change?
My current approach(that does not check for <div class="excludethis">)
Wortliste=['Test','Whatever'];
TagListe=document.selectNodes("//li[starts-with(#id,'jk')]");
for (var Durchgehen=TagListe.length-1; Durchgehen>=0; Durchgehen--)
{
if (IstVorhanden(TagListe[Durchgehen].innerHTML, Wortliste))
{
TagListe[Durchgehen].innerHTML = '';
}
}
with
function IstVorhanden(TagListeElement, Wortliste)
{
for(var Durchgehen = Wortliste.length - 1; Durchgehen>=0; Durchgehen--)
{
if(TagListeElement.indexOf(Wortliste[Durchgehen]) != -1)
return true;
}
return false;
}
Only has to work in opera as it's an userscript.

Categories