iMacros - How do I TAG URL with unique surrounding html? - macros

I need to extract "https://www.somesite.com/Some.Name.123" from the code below.
That code segment is repeated many times, and I need the URLs ..Some.Name.X.
There are other code segments between each of the ones I'm interested in, with very different surrounding html. I don't need the ..Some.Name.x URLs in those other segments.
The following is unique to what URLs I need: "<a class="-cx-PRIVATE-uiImageBlock__image"
<div class="clearfix pvm">
<a class="-cx-PRIVATE-uiImageBlock__image -cx-PRIVATE-uiImageBlock__largeImage lfloat"
aria-hidden="true" tabindex="-1" href="https://www.somesite.com/Some.Name.123">

I don't know how to tag that preceding HTML with iMacros, or how to do that with jQuery as the structure will a bit different each time, but you could to this.
Save the web pages with iMacros. Write a program (c, etc.) to read each of the saved files and write the URLs that follow "cx-PRIVATE-uiImageBlock__image" to a file. Add that list of URLs to an iMacro, or have iMacros read the file, and then process each URL from iMacros.

You need to use some scripting.
My answer makes use of jQuery
var listoflinks = []; //array containing your links
$('a[href*="somesite.com"]').each(function () { // for each link that contains somesite.com in href
var j = $(this).attr('href'); //put the whole href in a variable
listoflinks.push(j); // put all values in an array
});
you'll end up with an array that contains all the href values you're looking for.
If you want to see an example and/or you want to play around with the script you can go here:
http://jsfiddle.net/flish/rESjg/
Edited
Your code is still not clear enough, but hopefully this may help
<a class="sibling a" href="link">sibling a</a><br />
<div class="sibling div"><br />
<a class="child a" href="start-with-link/correct-link">Child a</a><br />
</div><br />
Above is the markup I've used. What this means is that I have considered that you have the following elements:
a // with a sibking div
div // with a child a
a // and all of them have appropriate classes
For this markup you can use the following code (jQuery, of course)
var listoflinks = []; //array containing your links
$('a[class="sibling a"]').siblings('div[class="sibling div"]').children('a[class="child a"]').each(function () {
if ((($(this).attr("href")).substring(0,15))=="start-with-link"){
var i = $(this).attr("href");
listoflinks.push(i);
}
});
View detailed example at http://jsfiddle.net/flish/HMXDk/
Be that as it may, you can add more sibling and children elements in case you have other html entities you forgot to mention
<a class="-cx-PRIVATE-uiImageBlock__image" ------------------ <div class="clearfix pvm"> <a class="-cx-PRIVATE-uiImageBlock__image -cx-PRIVATE-uiImageBlock__largeImage lfloat" aria-hidden="true" tabindex="-1" href="somesite.com/some.name.123">
For example, what means ------------------ in your code above?

Related

Fetching dynamic id and url from image with JS

I'm implementing a fancybox into my project and I'm writing a script to automatically wrap an anchor around the images with the url to the image and a "data-fancybox" attribute to let the fancybox script do its thing. However, I'm only getting the url to the very first image, since they all share the same class. There is a dynamic figure id that seems to be the one to get.
My question is - how do I use this figure id to fetch the appropriate img src?
The html is like this:
<figure id="XXXXXXX">
<div>
<img src="image.jpg" />
</div>
</figure>
... other stuff ...
<figure id="YYYYYYY">
<div>
<img src="image2.jpg" alt="">
</div>
</figure>
My code right now is as follows (which works, but only returns the first image url):
$(document).ready(function() {
var src = $("figure img").attr("src");
var a = $("<a/>").attr( { href:src , "data-fancybox":"" } );
$("figure img").wrap(a);
});
I know I can use
var id = $("figure").attr("id");
to get the id I need, but I'm pretty new to coding so I'm not sure how I implement this and use it to get the correct url. Any help is appreciated!
If your goal is to make your images clickable, then you can do smth like this:
$('figure img').each(function() {
$(this).parent().css({cursor: 'pointer'}).attr('data-fancybox', 'gallery').attr('data-src', this.src);
});
DEMO - https://jsfiddle.net/1jznsL7x/
Tip: There is no need to create anchor elements, you can add data-fancybox and data-src attributes to any element and it will work automagically.

TinyMCE - applying a style over bullets and multiple paragraphs applies the style to each bullet & para - how do I avoid?

I'm trying to use the theme_advanced_styles command within TinyMCE to add classes to selections of text within the TinyMCE editor. The problem is that if the paragraph contains bullets, then the style is applied throughout them (as well as to each individual paragraph).
What I want is just for the entire selection I made to have the style class added to the start of it. Ie if my style class is 'expandCollapse' I want:
<p class="expandCollapse">some content... some content... some content... some content... som content... some content... some content...
<ul>
<li>asdsadsadsadsasda</li>
<li>asdsadsa</li>
<li>sada</li>
</ul>
asome content... some content... some content... some content... some content... some content... some content... some content... </p>
But what I get is:
<p class="expandCollapse">some content... some content... some content... some content... some content... some content... some content...
<ul>
<li class="expandCollapse">asdsadsadsadsasda</li>
<li class="expandCollapse">asdsadsa</li>
<li class="expandCollapse">sada</li>
</ul>
</p>
<p class="expandCollapse">asome content... some content... some content... some content... some content... some content... some content... some content... </p>
Any ideas anyone?!
So I had to answer my own question as I needed an answer very quickly. It appears the behaviour I was experiencing is intentional? and certainly not something that has been removed in the very latest versions of TinyMCE (both 3.x and 4.x after testing).
With this in mind I ended up having to make a plugin to do what I wanted.
I borrowed a huge amount of code by Peter Wilson, from a post he made here: http://www.tinymce.com/forum/viewtopic.php?id=20319 So thanks very much for this Peter!
I ended up slightly changing the rules from my original question in that my solution adds an outer wrapping div around all the content I want to select. This method also allowed me to reliably then grab the required areas of html with jQuery in my front-end site.
My version of Peter's code is just very slightly modified from the original in order to add a class to the DIV, rename it, use a different button etc.
The plugin works perfectly and allows for a div to be created wrapping any amount of content within TinyMCE. The divs inserted have the class name I need also applied to it.
Add 'customDiv' to your plugin AND button bar for it to appear.
(function() {
tinymce.create("tinymce.plugins.Div", {
init : function(editor, url) {
editor.addCommand("mceWrapDiv", function() {
var ed = this, s = ed.selection, dom = ed.dom, sb, eb, n, div, bm, r, i;
// Get start/end block
sb = dom.getParent(s.getStart(), dom.isBlock);
eb = dom.getParent(s.getEnd(), dom.isBlock);
// If the document is empty then there can't be anything to wrap.
if (!sb && !eb) {
return;
}
// If empty paragraph node then do not use bookmark
if (sb != eb || sb.childNodes.length > 1 || (sb.childNodes.length == 1 && sb.firstChild.nodeName != 'BR'))
bm = s.getBookmark();
// Move selected block elements into a new DIV - positioned before the first block
tinymce.each(s.getSelectedBlocks(s.getStart(), s.getEnd()), function(e) {
// If this is the first node then we need to create the DIV along with the following dummy paragraph.
if (!div) {
div = dom.create('div',{'class' : 'expandCollapse'});
e.parentNode.insertBefore(div, e);
// Insert an empty dummy paragraph to prevent people getting stuck in a nested block. The dummy has a '-'
// in it to prevent it being removed as an empty paragraph.
var dummy = dom.create('p');
e.parentNode.insertBefore(dummy, e);
//dummy.innerHTML = '-';
}
// Move this node to the new DIV
if (div!=null)
div.appendChild(dom.remove(e));
});
if (!bm) {
// Move caret inside empty block element
if (!tinymce.isIE) {
r = ed.getDoc().createRange();
r.setStart(sb, 0);
r.setEnd(sb, 0);
s.setRng(r);
} else {
s.select(sb);
s.collapse(1);
}
} else
s.moveToBookmark(bm);
});
editor.addButton("customDiv", {
//title: "<div>",
image: url + '/customdiv.gif',
cmd: "mceWrapDiv",
title : 'Wrap content in expand/collapse element'
});
}
});
tinymce.PluginManager.add("customDiv", tinymce.plugins.Div);
})();

Unbind view model from view in knockout

I'm looking for unbind functionality in knockout. Unfortunately googling and looking through questions asked here didn't give me any useful information on the topic.
I will provide an example to illustrate what kind of functionality is required.
Lets say i have a form with several inputs.
Also i have a view model binded to this form.
For some reason as a reaction on user action i need to unbind my view model from the form, i.e. since the action is done i want all my observables to stop reacting on changes of corresponding values and vise versa - any changes done to observables shouldn't affect values of inputs.
What is the best way to achieve this?
You can use ko.cleanNode to remove the bindings. You can apply this to specific DOM elements or higher level DOM containers (eg. the entire form).
See http://jsfiddle.net/KRyXR/157/ for an example.
#Mark Robinson answer is correct.
Nevertheless, using Mark answer I did the following, which you may find useful.
// get the DOM element
var element = $('div.searchRestults')[0];
//call clean node, kind of unbind
ko.cleanNode(element);
//apply the binding again
ko.applyBindings(searchResultViewModel, element);
<html>
<head>
<script type="text/javascript" src="jquery-1.11.3.js"></script>
<script type="text/javascript" src="knockout-2.2.1.js"></script>
<script type="text/javascript" src="knockout-2.2.1.debug.js"></script>
<script type="text/javascript" src="clickHandler.js"></script>
</head>
<body>
<div class="modelBody">
<div class = 'modelData'>
<span class="nameField" data-bind="text: name"></span>
<span class="idField" data-bind="text: id"></span>
<span class="lengthField" data-bind="text: length"></span>
</div>
<button type='button' class="modelData1" data-bind="click:showModelData.bind($data, 'model1')">show Model Data1</button>
<button type='button' class="modelData2" data-bind="click:showModelData.bind($data, 'model2')">show Model Data2</button>
<button type='button' class="modelData3" data-bind="click:showModelData.bind($data, 'model3')">show Model Data3</button>
</div>
</body>
</html>
#Mark Robinson gave perfect solution, I've similar problem with single dom element and updating different view models on this single dom element.
Each view model has a click event, when click happened everytime click method of each view model is getting called which resulted in unnecessary code blocks execution during click event.
I followed #Mark Robinson approach to clean the Node before apply my actual bindings, it really worked well.
Thanks Robin.
My sample code goes like this.
function viewModel(name, id, length){
var self = this;
self.name = name;
self.id = id;
self.length = length;
}
viewModel.prototype = {
showModelData: function(data){
console.log('selected model is ' + data);
if(data=='model1'){
ko.cleanNode(button1[0]);
ko.applyBindings(viewModel1, button1[0]);
console.log(viewModel1);
}
else if(data=='model2'){
ko.cleanNode(button1[0]);
ko.applyBindings(viewModel3, button1[0]);
console.log(viewModel2);
}
else if(data=='model3'){
ko.cleanNode(button1[0]);
ko.applyBindings(viewModel3, button1[0]);
console.log(viewModel3);
}
}
}
$(document).ready(function(){
button1 = $(".modelBody");
viewModel1 = new viewModel('TextField', '111', 32);
viewModel2 = new viewModel('FloatField', '222', 64);
viewModel3 = new viewModel('LongIntField', '333', 108);
ko.applyBindings(viewModel1, button1[0]);
});

Insert locallang values into TypoScript [stdWrap]

I wonder if it is possible to insert a locallang value into my typoscript wrap / stdWrap object:
I have:
singleView {
related.wrap = <div class="related">Related items: |</div>
}
What I need is something like that:
singleView {
related.wrap = <div class="related">{LLL:related_items}:|</div>
}
EDIT:
What I am looking for is an TS equivalent for $this->pi_getLL (which works fine).
In our case, we would be replacing values in our extension with
$this->cObj->stdWrap($item, $this->conf['singleView.']['related']);
locallang.xml in extensions /pi1 directory:
<languageKey index="default" type="array">
<label index="related_items">Related items: </label>
</languageKey>
singleView {
related.dataWrap = <div class="related">{LLL:EXT:myextensionkey/pi1/locallang.xml:related_items}:|</div>
}
Of course related_items must be a valid locallang key.
Edit: Do not use wrap with insertData here, because insertData is then run on the whole content, including the user input. If somebody uses {DB:be_users|0|password} inside the content you are wrapping, he can just see the password (hash) of the backend user with uid 0.
Building on the answer of pgampe here, sadly I don't have enough reputation to do it in a comment.
For easier use, do something like this:
constants:
extension.key = myextensionkey
LLL = LLL:EXT:{$extension.key}/Resources/Private/Language/locallang.xlf
and in your typoscript:
singleView {
related.dataWrap = <div class="related">{{$LLL}:related_items}:|</div>
}

Dojo events: getting it to work with dynamically added DOM elements

I have a method of a class as follows:
add_file: function(name, id, is_new){
// HTML: <div class="icon mime zip">name.zip <a>x</a></div>
var components = name.split('.');
var extension = components[components.length-1];
this.container.innerHTML += "<div id='"+id+"' class='icon mime "+extension+"'>"+name+" <a id='remove-"+id+"' href='#remove'>x</a></div>";
// Add event to a tag
dojo.connect(dojo.byId('remove-'+id), 'onclick', function(ev){
// here i am
});
},
All is working well, until I run this method more than once. The first time the event is registered correctly, and clicking the 'x' will run the "here i am" function. However, once I add more than one node (and yes, the ID is different), the event is registered to the last node, but removed from any previous ones.
In affect I have this:
<div id="field[photos]-filelist">
<div id="file1" class="icon mime jpg">file1.jpg <a id="remove-file1" href="#remove">x</a></div>
<div id="file2" class="icon mime jpg">file2.jpg <a id="remove-file2" href="#remove">x</a></div>
</div>
...and the remove link only works for the last node (remove-file2 in this case).
The problem is you are using the innerHTML +=
That is going to take the existing html, convert it to plain markup, and then completely create new nodes from the markup. In the process, all of the nodes with events get replaced with nodes that look exactly the same but are not connected to anything.
The correct way to do this is to use dojo.place(newNodeOrHTML, refNode, positionString)
var myNewHTML = "<div id='"+id+"' class='icon mime "+extension+"'>"+name+" <a id='remove-"+id+"' href='#remove'>x</a></div>"
//This won't work as is breaks all the connections between nodes and events
this.container.innerHTML += myNewHTML;
//This will work because it uses proper dom manipulation techniques
dojo.place(myNewHTML, this.container, 'last');