Javascript RegEx for selecting HTML [duplicate] - javascript

This question already has answers here:
How to make Regular expression into non-greedy?
(3 answers)
Closed 23 days ago.
I am trying to select all empty tags. Here's my data that I am trying to parse:
<h1><a name="_Toc1500373542"><span style='font-size:10.0pt;line-height:107%; font-family:"Arial",sans-serif;mso-fareast-font-family:Arial'>Infrastructure agenda items</span></a><span style='font-size:10.0pt;line-height:107%;font-family: "Arial",sans-serif;mso-fareast-font-family:Arial'></span></h1> <h2><a name="_Toc325437092"><span style='font-size:10.0pt;line-height:107%; font-family:"Arial",sans-serif;mso-fareast-font-family:Arial'>General</span></a><span style='font-size:10.0pt;line-height:107%;font-family:"Arial",sans-serif; mso-fareast-font-family:Arial'></span></h2> <h2><a name="_Toc983350007"><span style='font-size:10.0pt;line-height:107%; font-family:"Arial",sans-serif;mso-fareast-font-family:Arial'>BIG-IP</span></a><span style='font-size:10.0pt;line-height:107%;font-family:"Arial",sans-serif; mso-fareast-font-family:Arial'></span></h2> <h2><a name="_Toc1240516703"><span style='font-size:10.0pt;line-height:107%; font-family:"Arial",sans-serif;mso-fareast-font-family:Arial'>CSP agenda items</span></a><span style='font-size:10.0pt;line-height:107%;font-family:"Arial",sans-serif; mso-fareast-font-family:Arial'></span></h2>
So the empty tags that I am looking for is:
<span style='font-size:10.0pt;line-height:107%;font-family: "Arial",sans-serif;mso-fareast-font-family:Arial'></span>
As you can see there's nothing in the span.
My current regex looks like this but this doesn't work because it selects the first tag and covers all the data until the last .
(<span (\S+)).*(><\/span>)
Any ideas on how to select <span style='font-size:10.0pt;line-height:107%;font-family:"Arial",sans-serif; mso-fareast-font-family:Arial'></span> only?

You can use DOMParser to parse the HTML instead.
let str = `<h1><a name="_Toc1500373542"><span style='font-size:10.0pt;line-height:107%; font-family:"Arial",sans-serif;mso-fareast-font-family:Arial'>Infrastructure agenda items</span></a><span style='font-size:10.0pt;line-height:107%;font-family: "Arial",sans-serif;mso-fareast-font-family:Arial'></span></h1> <h2><a name="_Toc325437092"><span style='font-size:10.0pt;line-height:107%; font-family:"Arial",sans-serif;mso-fareast-font-family:Arial'>General</span></a><span style='font-size:10.0pt;line-height:107%;font-family:"Arial",sans-serif; mso-fareast-font-family:Arial'></span></h2> <h2><a name="_Toc983350007"><span style='font-size:10.0pt;line-height:107%; font-family:"Arial",sans-serif;mso-fareast-font-family:Arial'>BIG-IP</span></a><span style='font-size:10.0pt;line-height:107%;font-family:"Arial",sans-serif; mso-fareast-font-family:Arial'></span></h2> <h2><a name="_Toc1240516703"><span style='font-size:10.0pt;line-height:107%; font-family:"Arial",sans-serif;mso-fareast-font-family:Arial'>CSP agenda items</span></a><span style='font-size:10.0pt;line-height:107%;font-family:"Arial",sans-serif; mso-fareast-font-family:Arial'></span></h2>`;
[...new DOMParser().parseFromString(str, "text/html").body.querySelectorAll('*')]
// get all elements
.filter(el => el.childNodes.length === 0).forEach(el => console.log(el.outerHTML));
// find elements with no children

Related

How to select an element from _ngcontent block using protractor?

I have below structure for my angular app.
<div _ngcontent-c8 class=“page-body”>
<div _ngcontent-c8 class=“cell-list”>
<a _ngcontent-c8="" class="cell cell-row ng-star-inserted"
queryparamshandling="preserve" ng-reflect-query- params-
handling="preserve" ng-reflect-router-link=“/path” href=“/link”
</a>
<a _ngcontent-c8="" class="cell cell-row ng-star-inserted"
queryparamshandling="preserve" ng-reflect-query- params-
handling="preserve" ng-reflect-router-link=“/path” href=“/link”
</a>
<a _ngcontent-c8="" class="cell cell-row ng-star-inserted"
queryparamshandling="preserve" ng-reflect-query- params-
handling="preserve" ng-reflect-router-link=“/path” href=“/link”
</a>
</div>
How would I select specific a tag from this structure? In the previous version of angular with ng-repeat directive, I could use "(element.all(by.repeater))".However it does not work for the above code.
I tried using element.all(by.css)), but that does not work either.
Do you guys have any suggestions?
Try following code:
getByAttribute(searchText: string): ElementFinder {
let container = element(by.css('.page-body .cell-list'));
return container.all(by.tagName('a')).filter(function(el) {
return el.getAttribute('href').then(function(value) {
return value.trim() === searchText;
});
}).first();
}
This code lists all a elements and filters them by it's href value. This is an example for showing you how to filter values.

If statement overlay a div [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have a view with multiple projects. Some of these are running and some aren't
In the function if a deadline is passed it will output the 'days' as a zero on the view. (so this are the non-running projects) They remain visible on the view with the running projects. But ofcourse the running projects are shown with (for example) 24 days left or something.
Now what I want to do: If a project deadline has passed and the output is '0' I want to create a blurry layer over the div.
I have the following function working:
function get_all_open_designments($now) {
$this->db->where('active', 1);
$this->db->where('deleted !=', '1');
$this->db->order_by('date_to', 'DESC');
$designments = $this->db->get('designments')->result_array();
foreach ($designments as &$designment_info) {
$designment_info['image'] = self::get_image_for_designment($designment_info['designment_id']);
$designment_info['count_joined'] = self::get_users_count_joined_by_id($designment_info['designment_id']);
$designment_info['count_ideas'] = self::get_users_count_ideas_by_id($designment_info['designment_id']);
$date_to = $designment_info['date_to'];
$diff = $date_to - $now;
$days = round($diff / 86400);
$time_left = $days . ' days';
if($days <= 0){
$days = 0;
$time_left = $days . ' days';
}
$designment_info['time_left'] = $time_left;
}
return $designments;
}
Is there a way to put a code there if the 'days' are '0' put a blurry layer over it.
The code beneath is the code for the view:
<script type="text/x-mustache" id="designment_template">
<div class="designment_view item">
<ul class="box-div bg-white shadow">
{{#image}}
<li>
<img width="302" src="{{image}}"/>
</li>
{{/image}}
<li class="p15 orange ff-b" style="font-size: 21px">
{{title}}
</li>
<li class="p15 black ff-l" style="font-size: 14px">
{{small_description}}
</li>
<li class="h45 black tc ff-l f14">
<dl class="clearfix bg-lightgrey user-dash-dl tc">
<dd class="fl br-1 lh36" style="width:74px" title="Cash reward for selected idea">
<p class="f11 ff-l lh12 pt33 reward"></p>
<p class="ff-m f12">{{reward}}</p>
</dd>
<dd class="fl br-1 lh36" style="width:74px" title="Amount of days left until the deadline">
<p class="f11 ff-l lh12 pt33 timeleft"></p>
<p class="ff-m f12">{{time_left}}</p>
</dd>
<dd class="fl br-1 lh36" style="width:74px" title="Amount of joined designers">
<p class="f11 ff-l lh12 pt33 joinedpeople"></p>
<p class="ff-m f12">{{people}}</p>
</dd>
<dd class="fl lh36" style="width:74px" title="Amount of uploaded ideas">
<p class="f11 ff-l lh12 pt33 ideascount"></p>
<p class="ff-m f12">{{idea}}</p>
<!-- mous over-->
</dd>
</dl>
</li>
{{#joined}}
<a class="joined" data-id="{{id}}" data-url="<?= site_url('app/dashboard/id') ?>/{{id}}">
<li class="btn-designment clearfix h45 tc orange ff-b f14 lh45" style="cursor: pointer;">
<div class="designment-arrow"></div>
{{/joined}}
{{^joined}}
<a class="joinable" data-id="{{id}}" data-url="<?= site_url('app/dashboard/id') ?>/{{id}}">
<li class="btn-designment clearfix h45 tc orange ff-b f14 lh45" style="cursor: pointer;">
<div class="designment-join-arrow"></div>
{{/joined}}
</li>
</a>
</ul>
</div>
There would be multiple things you need to take care of.
You have to pass $days as single parameter from controller to view.
Add condition in view to check if $days are 0 or not, if
yes then add a blank div within main div.
Add appropriate styles to the main div and the blank div.
Give relative position to min div and absolute position to blank blurry div. Apply styles as you want.

More effective way to append json data with jQuery & Laravel

I am building a twitter style feed with Laravel and jQuery.
My problem is that I'm sure I built this logic up badly.
So I have an included view what shows the tweet results.
Sending the data is just a basic ajax post with some DOM manipulation that's fine too.
After the form is submitted I display the fresh tweet with and append.
But the problem is no matter how i build my logic up, i always end up with duplication.
So what I do
Send the form, and the success function appends the data to the view
success: function(data) {
if(data.status === "success") {
$('#tweet-textarea').val("");
$('#tweets-wrapper').prepend(data.content);
}
},
And returning the goes the following way. After the tweet is saved, I return it in an array what I encode to json
$data = array('status' => 'success', 'content' =>
'<div class="tweet-box">
<div class="media">
<a class="pull-left" href="#">
<img src="http://placehold.it/60x60" alt="">
</a>
<div class="media-body">
<h4 class="media-heading">
'. $this->tweet->user->metadata->full_name .'
<small>'. "#".$this->tweet->user->username .'</small>
<small>'. $this->tweet->created_at .'</small>
</h4>
'. $this->tweet->message .'
</div>
</div>
</div>');
I know not the best way, and my problem is actually in my controller I am duplicating code, because the returned result "content in array" is the same just like in my view, so if I make any modification I need to make both
So is there a more effective way to do this?
You can use jQuery jPut Plugin to append json easily
<div jput="template">
<div class="tweet-box">
<div class="media">
<a class="pull-left" href="#">
<img src="http://placehold.it/60x60" alt="">
</a>
<div class="media-body">
<h4 class="media-heading">{{}}</h4>
</div>
</div>
</div>
</div>
<div id="main">
</div>
<script>
$(document).ready(function(){
//main is the div that you want to append
$('#main').jPut({
ajax_url:'domain.com/data.json', //your json data page
name:'template' //jPut template name
});
});
</script>
And in you json page no need to send all the div
$data = array('status' => 'success', 'content' => $this->tweet->user->metadata->full_name);
If you want to remove duplication of code, you are going to have to take all that logic out of your view and just pass it a nice long string for the entire section from your controller.
I'd start with making a function which can take a full name, username, timestamp, and message and create the tweet.
public function createTweet($fullName, $username, $created_at, $message)
{
return '<div class="tweet-box">
<div class="media">
<a class="pull-left" href="#">
<img src="http://placehold.it/60x60" alt="">
</a>
<div class="media-body">
<h4 class="media-heading">
'. $full_name .'
<small>'. "#".$username .'</small>
<small>'. $created_at .'</small>
</h4>
'. $message .'
</div>
</div>
</div>';
}
Then when you are looping through your tweets, call this function each time through and keep concatenating the response in a string, then you can just pass the string to your view and echo it there.
On your function which is returning ajax, do the same...
return Respons::json(array(
'status' => 'success',
'content' => $this->createTweet($this->tweet->user->metadata->full_name, $this->tweet->user->username, $this->tweet->created_at, $this->tweet->message)
));
You could also take a lot at HTML::macro() as well if you find yourself needing this functionality across your entire app. http://laravel-recipes.com/recipes/181 for a nice and quick HTML::macro() tut.

Count specific characters within a class (and apply text truncate logics to each instance of that class)

I have HTML like
<a href="/blabla" class="matchupLink">
<span class="teams"> USA</span>
<strong> -0 </strong>
<span class="teams">Netherlands</span>
<span class="pull-right dateOrScore"><strong>15 Jul</strong> : 3:00pm CST</span>
</a>
<a href="/blabla2" class="matchupLink">
<span class="teams"> USA</span>
<strong> -0 </strong>
<span class="teams">Netherlands</span>
<span class="pull-right dateOrScore"><strong>15 Jul</strong> : 3:00pm CST</span>
</a>
<a href="/blabla3" class="matchupLink">
<span class="teams"> USA</span>
<strong> -0 </strong>
<span class="teams">Netherlands</span>
<span class="pull-right dateOrScore"><strong>15 Jul</strong> : 3:00pm CST</span>
</a>
I want to count the number of characters that's inside each "matchupLink" class, but without counting the characters inside the "dateOrScore" class.
My goal is to then cut the text and put ellipses after char 20 if char count is over 20 characters, while keeping the date (dateOrScore) element there.
I tried something like
$('.matchupLink .teams').each(function () {
console.log($(this).html())
});
But that returns every teams element individually, can't really use the ellipses logics that way.
Any ideas?
Thanks
Ps: I also tried taking all text, and excluding 'dateOrScore' (using not()) but that also failed.
Is this what you want?
var ellipses = 20;
$('.matchupLink').children().not('.dateOrScore').each(function() {
var text = $(this).text();
if(text.length > ellipses)
$(this).text(text.substr(0, ellipses) + '...');
});

If I can only use javascript, how can I filter list by date?

I have this list structure:
<ul class="pol list">
<li>
<div class="tekst">
<h2><span class="name"></span></h2>
<p class="description"></p>
<div class="commentsBar1">
<div class="commentsBarL1">
<h5>
<strong class="category">
<span style="display:none;"></span>
<span class="d">27.12.2011</span>
</strong>
</h5>
<h5><strong></strong></h5>
</div>
</div>
</div>
</li>
<li>
<div class="tekst">
<h2><span class="name"></span></h2>
<p class="description"></p>
<div class="commentsBar1">
<div class="commentsBarL1">
<h5>
<strong class="category">
<span style="display:none;"></span>
<span class="d">03.03.2012</span>
</strong>
</h5>
<h5><strong></strong></h5>
</div>
</div>
</div>
</li>
</ul>
I need js that will hide all list tags which contain a date outside of a certain range. The date range is given by user and both start and end dates are given in same way as dates in the list (dd.mm.yyyy).
<input id="Date1" name="Date1">
<input id="Date2" name="Date2">
I have this date comparison code:
var dControl = document.getElementsByClassName("d");
var d1Control = document.getElementById("Date1");
var d2Control = document.getElementById("Date2");
var arrD = dControl.value.split(".");
var dd0 = new Date(arrStartDate[2], arrStartDate[1], arrStartDate[0]);
var arrD1 = d1Control.value.split(".");
var dd1 = new Date(arrStartDate[2], arrStartDate[1], arrStartDate[0]);
var arrD2 = d2Control.value.split(".");
var dd2 = new Date(arrStartDate[2], arrStartDate[1], arrStartDate[0]);
if((dd0 <= dd2 && dd0 >= dd1)) {
return true;
}
return false;
And one more thing... The number of list elements varies from page to page so I also need to get some idea about the list size, but that I assume is easy to do with "length".
Any ideas how can I achieve this?
You will need to write javascript to build the dom based on the dates you have. I suggest using a templating framework such as mustache or handlebars to keep your code tidy.
just run through the elements with class "d" and check if they meet your date criteria if not then set that li to display "none". you will have to find the li in the DOM node tree which appears to be 8 levels higher that your date.

Categories