Javascript to sort elements - sorting

I've need to sort some items on the page where the CMS I use doesn't provide for this. I can add some tags dynamically, but I need help here with some Javascript that would put the items in the correct order.
Further at the top of the HTML page I've got an 'event selector', e.g.:
<div class="w-embed">
<div event-selector="weddings"></div>
</div>
This would determine which set of the sorting numbers to use. Each item includes some code with a sort number from each set. w-dyn-item are the elements that need sorting.
<div class="w-dyn-list">
<div class="w-dyn-items">
<div class="w-dyn-item">
<div class="w-embed">
<div sort-event="conference" sort="09"></div>
<div sort-event="exhibition" sort="110"></div>
<div sort-event="wedding" sort="2"></div>
</div>
<div>
Content A
</div>
</div>
<div class="w-dyn-item">
<div class="w-embed">
<div sort-event="conference" sort="06"></div>
<div sort-event="exhibition" sort="60"></div>
<div sort-event="wedding" sort="1"></div>
</div>
<div>
Content B
</div>
</div>
<div class="w-dyn-item">
<div class="w-embed">
<div sort-event="conference" sort="01"></div>
<div sort-event="exhibition" sort="54"></div>
<div sort-event="wedding" sort="3"></div>
</div>
<div>
Content C
</div>
</div>
</div>
</div>
The logic would be: Sort w-dyn-item elements by using the 'sort-event' numbers that correspond to the 'event-selector' (from smallest to largest number).
The site's using jQuery if that's any help.
I've put it into a Fiddle here: https://jsfiddle.net/j2rqze8p
Many thanks for any help.

Here is how you can actually sort the elements with jQuery.
var sortPropertyName = $('.w-embed [event-selector]').attr('event-selector');
var sortAttrValues = {
'weddings': 'wedding',
'exhibitions': 'exhibition',
'conferences': 'conference'
};
var sortAttributeValue = sortAttrValues[sortPropertyName];
if(!sortAttributeValue) {
throw new Error('Unable to sort. Sort attribute value not found.')
}
var attrSelector = '[sort-event="' + sortAttributeValue + '"]';
var $container = $('.w-dyn-items');
var $items = $container.children('.w-dyn-item');
$items.sort(function (item1, item2) {
var item1Value = $(item1).find(attrSelector).attr('sort');
var item2Value = $(item2).find(attrSelector).attr('sort');
return parseInt(item1Value) - parseInt(item2Value);
});
$items.detach().appendTo($container);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="w-dyn-list">
<div class="w-embed">
<div event-selector="weddings"></div>
</div>
<div class="w-dyn-items">
<div class="w-dyn-item">
<div class="w-embed">
<div sort-event="conference" sort="09"></div>
<div sort-event="exhibition" sort="110"></div>
<div sort-event="wedding" sort="2"></div>
</div>
<div>
Content A
</div>
</div>
<div class="w-dyn-item">
<div class="w-embed">
<div sort-event="conference" sort="06"></div>
<div sort-event="exhibition" sort="60"></div>
<div sort-event="wedding" sort="1"></div>
</div>
<div>
Content B
</div>
</div>
<div class="w-dyn-item">
<div class="w-embed">
<div sort-event="conference" sort="01"></div>
<div sort-event="exhibition" sort="54"></div>
<div sort-event="wedding" sort="3"></div>
</div>
<div>
Content C
</div>
</div>
</div>
</div>
There are two moments.
First, as I noticed the value of event-selector is plural whereas sort-event are singular.
I solved this by having a hash to match one to another.
The another thing is that you might need to run this script on 'event-selector' change if you want the sort to by dynamic. But it's basically a matter of a different discussion.

Related

xpath: How to combine multiple conditions on different axes

I try to extract all links based on these three conditions:
Must be part of <div data-test="cond1">
Must have a <a href="..." class="cond2">
Must not have a <img src="..." class="cond3">
The result should be "/product/1234".
<div data-test="test1">
<div>
<div data-test="cond1">
Link 1
<div class="test4">
<div class="test5">
<div class="test6">
<div class="test7">
<div class="test8">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div data-test="test2">
<div>
<div data-test="cond1">
Link 2
<div class="test4">
<div class="test5">
<div class="test6">
<div class="test7">
<div class="test8">
<img src="bild.jpg" class="cond3">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
I'm able to extract the links with the following xpath query.
//div[starts-with(#data-test,"cond")]/a[starts-with(#class,"cond")]/#href
(I know the first part is not really neccessary. But better safe than sorry.)
But I'm still struggling with excluding the links containing an descendant img tag and how to add it to the query above.
This should do what you want:
//div[#data-test="cond1" and not(.//img[#class="cond3"])]
/a[#class="cond2"]
/#href
/product/1234

Laravel Blade foreach combine

I have two separate divs, one where the images are loaded and the other where the data is displayed.
<div class="banner-slider-image">
<div class="swiper-container">
<div class="swiper-wrapper">
<!-- Slide Item -->
<div class="swiper-slide">
<div class="bg" style="background-image: url(include/assets/images/main-slider/1.jpg);">
</div>
</div>
</div>
</div>
</div>
<div class="banner-slider-content">
<div class="side-text">AVANT</div>
<div class="swiper-container banner-slider">
<div class="swiper-wrapper">
#if(count($listings) > 0)
#foreach($listings as $listing)
<!-- Slide Item -->
<div class="swiper-slide">
<div class="content-outer">
<div class="content-box">
<div class="inner">
<h5>{{$listing->first_name}} {{$listing->last_name}}</h5>
<h1><span>{{$listing->name}}</span> </h1>
<div class="text">{{$listing->property_description}}.</div>
<div class="link-box">View Listing</div>
</div>
</div>
</div>
</div>
#endforeach
#endif
</div>
</div>
</div>
So the first div will also be in a foreach loop, but I dont know how I can combine the two where they show the same related data.
Use 2 foreach loops . It is the easiest and desired solution for you. or you can define two variable and concat the contents using one forloop and then display them later like
#php
$first='';
$second='';
#endphp
#if(count($listings) > 0)
#foreach($listings as $listing)
#php
$first.='first div content';
$second.='second div content';
#endphp
#endforeach
#endif
<div class="banner-slider-image">
<div class="swiper-container">
<div class="swiper-wrapper">
{!!$first!!}
</div>
</div>
</div>
<div class="banner-slider-content">
<div class="side-text">AVANT</div>
<div class="swiper-container banner-slider">
<div class="swiper-wrapper">
{!!$second!!}
</div>
</div>
</div>
<html>
<body>
#section('sidebar')
This is the master sidebar.
#show
<div class="container">
#yield('content')
</div>
</body>
use for yield

How to get last child while parsing HTML with Goutte in Laravel

<div class="table">
<div class="table-head">
<div class="table-head-title">Ranking Equipos</div>
</div>
<div class="table-body">
<div class="table-body-row active">
<div class="col-key">Mark</div>
<div class="col-value">9233</div>
</div>
<div class="table-body-row">
<div class="col-key">Amanda</div>
<div class="col-value">7216</div>
</div>
<div class="table-body-row">
<div class="col-key">Mark</div>
<div class="col-value">6825</div>
</div>
<div class="table-body-row">
<div class="col-key">Paul</div>
<div class="col-value">6184</div>
</div>
<div class="table-body-row">
<div class="col-key">Amanda</div>
<div class="col-value">5866</div>
</div>
</div>
</div>
This is my HTML and I want to get last child of .table-body.
I tried to use JavaScript like logic and used indexing like this
$lastChild = $node->filter('.table-body .table-body-row')[4]; but it shows error. Cannot use object of type "Symfony\Component\DomCrawler\Crawler" as array
I was stuck in similar situation recently and I resolve this by using last() method. Syntax is here: $node->filter('.table-body .table-body-row')->last();

How to select text node without preceding text in XPath?

<div class="a">
<div class="a random number of div wrapers">
<div>Random1<em>Median</em>
<div class="b">
<div class="c">Edit</div>
</div>
</div>
<div>Random2<em>Median</em></div>
<div>
<em>Median</em>
</div>
<div>Random3<em>Median</em></div>
<div>Random4<em>Median</em>
<div>Random4<em>Median</em></div>
</div>
</div>
<div class="a">
<div class="a random number of div wrapers">
<div>Random1<em>Median</em></div>
<div>Random2<em>Median</em></div>
<div>
<em>Median</em>
</div>
<div>Random3<em>Median</em>
<div class="b">
<div class="c">Edit</div>
</div>
</div>
<div>Random4<em>Median</em>
</div>
</div>
In this case, how to get the two nodes contains 'Median' that doesn't have text before it using XPath?
I prefer not using the index because the node position could be random.
Maybe try:
//*[.='Median'][not(preceding-sibling::text()[normalize-space()])]

Xpath keeps selecting all objects of the given class instead of the first

This one has me stumped., I'm trying to select the first class = csb-quantity-listbox object of the below using the XPATH //select[#class='csb-quantity-listbox'][1], but instead of selecting the first quantity listbox it's selecting ALL the listboxes on the page with that class (see image below).
What am I doing wrong?
<div class="gwt-product-detail-products-container">
<div class="gwt-product-detail-products-header-column">
</div>
<div id="gwt-product-detail-widget-id-12766" class="gwt-product-detail-widget">
<div class="gwt-product-detail-widget-image-column ui-draggable" title="12766">
<div class="gwt-product-detail-widget-options-column">
</div>
<div class="gwt-product-detail-widget-price-column">
</div>
<div class="gwt-product-detail-widget-quantity-panel">
<select class="csb-quantity-listbox" name="quantity_12766"></select>
</div>
<div class="gwt-bundle-add-to-cart-btn">
</div>
</div>
</div>
<div id="gwt-product-detail-widget-id-10617" class="gwt-product-detail-widget">
<div class="gwt-product-detail-widget-image-column ui-draggable" title="10617">
<div class="gwt-product-detail-widget-options-column">
</div>
<div class="gwt-product-detail-widget-price-column">
</div>
<div class="gwt-product-detail-widget-quantity-panel">
<select class="csb-quantity-listbox" name="quantity_10617"></select>
</div>
<div class="gwt-bundle-add-to-cart-btn">
</div>
</div>
</div>
</div>
Image:
You just need to put brackets around the statement before the [1]
Like so:
(//select[#class='csb-quantity-listbox'])[1]

Resources