I'd like to find and replace specific text strings within an element across multiple URLS.
The element:
<div class="text-row"><p></p></div>
Within the p tags the text strings would be:
1."Endo" change to "Endodontist"
2."MCD" change to "Lead Dentist"
How would I accomplish that using Google Tag Manager?
Using Javascript you can look for the elements that match by class/id and just edit them.
if(document.getElementsByClassName('text-row')){
var elems = document.getElementsByClassName('text-row');
for(var k = 0;k < elems.length;k++){
var text = elems[k].innerText;
if(text.indexOf('Endo') != -1){
text.replace('Endo','Endodontist');
elems[k].innerText = text;
}
}
}
In my ASP.Net MVC appication I have a loop which i'd like to display different Properties values in HTML using the HTML.DisplayFor method. But it will not accept a string value to direct to the Model parameter.
Normal mode:
<img src="#Html.DisplayFor(model => model.Image_1)" />
My loop:
#for (int i = 1; i < 11; i++)
{
string currentImage = "Model.Image_" + i;
if ((#Html.DisplayFor(model => "Model.Image_" + i ).ToString()) != "")
{
<div>
<img src="#Html.DisplayFor(model => currentImage)" />
</div>
}
}
My results in the img src are just currentImage.
I'd like it to be Model.Image_" + i.
How would I do that?
If you have a better way of doing this that would be appreciated as well.
Should my images have their own Model -class, you think?
You can get the value of a property dynamically using reflection like this.
#for (int i = 1; i < 11; i++)
{
string imagePropName= "Image_" + i;
string imageSrc = Model.GetType().GetProperty(imagePropName).GetValue(Model) as string;
if (!string.IsNullOrEmpty(imageSrc))
{
<div>
<img src="#Url.Content(imageSrc)" />
</div>
}
}
Another alternative would be to write <img src="#Url.Content(Model.Image_1), <img src="#Url.Content(Model.Image_2) /> 10 times. I mean if you have created 10 properties, might as well be consistent with the implementation.
But as stephen said, just get a List of ImagePaths and loop through them in your View. If the requirement changes to displaying 20 images, you'd have to add 10 more properties.
Basically what i need to do is looping all the posts and add css to article class like "cb-no-1" and the second one "cb-no-2" and the third one "cb-no-3" and repait it again until there's no post.
#foreach (var post in Model.Posts)
{
//First iteration
<article class= "cb-no-1">
</article>
//Second iteration
<article class= "cb-no-2">
</article>
//Third iteration
<article class= "cb-no-3">
</article>
//Fourth iteration
<article class= "cb-no-1">
</article>
//and so on.
}
How to achive it. Thanks in advance.
Use a variable and increment that in the loop and use this variable name to build the class name. When the variable reaches 3 (or your limit), reset it to initial value.
#{
var counter = 0;
}
#foreach (var post in Model.Posts)
{
if (counter >= 3)
{
counter = 0;
}
<article class= "cb-no-#(++counter)">#post.Title</article>
}
use a variable like as i inside the loop which is inited from 1 and increases in each loop and when it reachs the 4, reset it to 1
then use it for class name
Shyju, the first responder, has the right idea, but there are two modifications you need to make to his answer.
First, his code gives you a variable from 0 to 2. you asked for 1 to 3,. so the initialization needs to be "var counter = 1" and the "if" test needs to be just greater than 3, not greater than or equal to 3. Or you could change the 3 to a 4, such as: if (counter >= 4).
The second item left off of that code snippet is something to increment the counter. I'm not sure which dialect or language you are writing in but something like:
Counter+=1
or
counter = counter + 1
Modified, that code snippet would look like:
var counter = 1;
#foreach (var post in Model.Posts)
{
if (counter >= 4)
{
counter = 0;
}
<article class= "cb-no-#(++counter)">#post.Title</article>
counter += 1
}
Again, I do not know which language you are writing in so check my syntax carefully.
I'm working on my WordPress website with Visual Composer.
I need to include a pageable container but it would be great if it can be like a slideshow.
This is my pageable container
Thanks in advance,
Regards :)
Based upon the current version of WP Bakery Page Builder the below works for me:
To build it I created a row with 3 columns, with the pageable container in the middle column and the left and right arrow images in the columns on either side.
Both arrow images and the pageable container were given IDs. In my example the IDs of the arrows were #arrow_prev and #arrow_next respectively. You can give your pageable container any unique ID.
(function ($) {
$(document).ready(function(){
$( '#arrow_prev' ).click( function( e ) {
var pageable_container = $(this).closest(".vc_row").find(".vc_tta-panels-container");
move_pageable_container(pageable_container,'prev');
});
$( '#arrow_next' ).click( function( e ) {
var pageable_container = $(this).closest(".vc_row").find(".vc_tta-panels-container");
move_pageable_container(pageable_container,'next');
});
function move_pageable_container(pageable_container,direction){
// Make a list of the panel IDs
var panel_ids = $(pageable_container.find(".vc_tta-panel"))
.map(function() { return this.id; }) // convert to set of IDs
.get();
// Find position of the active panel in list
var current_active_pos = panel_ids.indexOf($(pageable_container).find(".vc_tta-panel.vc_active").attr('id'));
var new_pos = 0;
switch(direction) {
case 'prev':
if (current_active_pos > 0){
new_pos = current_active_pos-1;
}else{
new_pos = panel_ids.length-1;
}
break;
case 'next':
if (current_active_pos < panel_ids.length-1){
new_pos = current_active_pos+1;
}else{
new_pos = 0;
}
break;
}
// Clear active panels
$(pageable_container.find(".vc_tta-panel")).each(function(i,a) {
$(this).removeClass("vc_active");
});
var new_active_panel = $(pageable_container).find('#'+ panel_ids[new_pos]);
$(new_active_panel).addClass("vc_animating");
$(new_active_panel).addClass("vc_active");
setTimeout(
function(){
$(new_active_panel).removeClass("vc_animating");
}, 350);
}
}
);
})(jQuery);
If you want a pseudo fading-in effect then you can use this additional CSS in your style sheet:
#id_of_pageable_container .vc_tta-panel.vc_animating {
opacity: 0!important;
}
Where #id_of_pageable_container is the ID that you gave your pageable container
A simpler solution with vanilla js only:
The idea is to find the target page button and press it programmatically, so that there is no need to mimic the plugin's animations as in Chaz's solution.
Add js (via Raw JS widget / other means):
function prevSlide () {
const slides = document.getElementsByClassName('vc_pagination-item');
for (let i = 0; i < slides.length; i++) {
if (slides[i].className.includes('vc_active')) {
if (i - 1 < 0) return;
slides[i - 1].firstChild.click();
return;
}
}
}
function nextSlide () {
const slides = document.getElementsByClassName('vc_pagination-item');
for (let i = 0; i < slides.length; i++) {
if (slides[i].className.includes('vc_active')) {
if (i + 1 >= slides.length) return;
slides[i + 1].firstChild.click();
return;
}
}
}
Add button widgets and set href to call js:
For left arrow button,
javascript:prevSlide();
For right arrow button,
javascript:nextSlide();
Hope this helps.
I prefer to use the Post Grid widget for that. Keep in mind that the pageable container is not totally responsive, it doesn't react to swipe touching, but the Post Grid does.
Post Grid is really powerful, although it also has its caveouts. You can create your content with posts and pages, or a custom post type and then filter what you want to show in your slider from the widget options.
In "advanced mode" you can use the Grid Builder to create your own template and control the output.
The only problems that I've found with this method is to set a variable height in sliders and that sometimes it is slow loading content and is not possible to do a lazyload.
I have a dojo datagrid which is poulated dynamically. I want to add tooltip to table headers of this datagrid. How can i do that?My datagrid simply has the structure of table and table headers. the fields get populated dynamically.
Thanks,
Sreenivas
Easiest Way
The easiest way, (Without overriding the template) would be to add a domNode to your layout header definition. So for example, when you are setting the "name" for your column in the layout, you can have something like ...
var layout = [
{
cells: [
{
name:"<i id="sometooltip" class='icon-large icon-edit'></i> Col",
field: "_item",
formatter: lang.hitch( this, this.formatter )
}
]
}];
What you then want to do is in your formatter, you want to check to see if "sometooltip" has be initialized as a tooltip, and do your connect.. You can use any tooltip.. not just dijit.Tooltip.
There are a few words of caution though. Because the formatter will run every time there is a redraw on your grid, you might want to think up better ways of creating your tooltip. For instance, you might want to add it to onGridRowHeaderHover, or you might want to just use CSS3 and use [title] attribute to create a CSS3 header.
Also. You can't just create the tooltip once, because the header is constantly rebuilt every redraw/change of data.
The Correct Way
The correct way would be to override the Grid template for the header, and include your tooltip in there. You would then extend the header equivalent of onStyleRow (which I can't remember), but basically the method that places the headers, and create your tooltip then.
I would definitely use the second option by overriding the template. Because otherwise you will find the grid glitchy.
For a pre-AMD Dojo version this is the monkey patch that we included in our globally scoped javascript resource. My other answer was after we switched to an AMD Dojo version.
// HeaderBuilder.generateHtml
// If showTooltips is true, the header contents will be used as the tooltip text.
var old_HeaderBuilder_generateHtml = dojox.grid._HeaderBuilder.prototype.generateHtml;
dojox.grid._HeaderBuilder.prototype.generateHtml = function(inGetValue, inValue){
var html = this.getTableArray(), cells = this.view.structure.cells;
dojox.grid.util.fire(this.view, "onBeforeRow", [-1, cells]);
for(var j=0, row; (row=cells[j]); j++){
if(row.hidden){
continue;
}
html.push(!row.invisible ? '<tr>' : '<tr class="dojoxGridInvisible">');
for(var i=0, cell, markup; (cell=row[i]); i++){
cell.customClasses = [];
cell.customStyles = [];
if(this.view.simpleStructure){
if(cell.headerClasses){
if(cell.headerClasses.indexOf('dojoDndItem') == -1){
cell.headerClasses += ' dojoDndItem';
}
}else{
cell.headerClasses = 'dojoDndItem';
}
if(cell.attrs){
if(cell.attrs.indexOf("dndType='gridColumn_") == -1){
cell.attrs += " dndType='gridColumn_" + this.grid.id + "'";
}
}else{
cell.attrs = "dndType='gridColumn_" + this.grid.id + "'";
}
}
markup = this.generateCellMarkup(cell, cell.headerStyles, cell.headerClasses, true);
// content
markup[5] = (inValue != undefined ? inValue : inGetValue(cell));
// set the tooltip for this header to the same name as the header itself
try {
markup[5] = markup[5].replace("class","title='"+cell.name+"' class");
} catch(e) {
console.debug(e);
}
// styles
markup[3] = cell.customStyles.join(';');
// classes
markup[1] = cell.customClasses.join(' '); //(cell.customClasses ? ' ' + cell.customClasses : '');
html.push(markup.join(''));
}
html.push('</tr>');
}
html.push('</table>');
return html.join('');
};
I had a similar requirement. I wanted each DataGrid column header to use the name given to the column as the tooltip since our DataGrids weren't always showing the full column name due to the columns' widths sometimes being squeezed. I added a monkey patch (below) that is done with an AMD Dojo version:
require(
[
"dojo/dom",
"dojox/grid/DataGrid",
"dijit/_Widget",
"dijit/form/FilteringSelect",
"dijit/form/MultiSelect",
"dijit/layout/ContentPane",
"dijit/layout/TabContainer",
"dojox/grid/_Grid",
"dijit/MenuItem",
"dijit/MenuSeparator",
"dojox/grid/_Builder",
"dojox/grid/cells/_base",
"dojox/grid/util",
"dojo/parser",
"dojo/_base/array",
"dojo/_base/lang",
"dojo/ready",
"dojo/query",
"dijit/registry",
],
function(dom, dojox_grid_DataGrid, dijit__Widget, dijit_form_FilteringSelect,
dijit_form_MultiSelect, dijit_layout_ContentPane, dijit_layout_TabContainer,
dojox_grid__Grid, MenuItem, MenuSeparator, dojox_grid__Builder,
dojox_grid_cells__Base, dojox_grid_util,
parser, array, dojoLang, ready, dojoQuery, registry) {
var old_HeaderBuilder_generateHtml = dojox_grid__Builder._HeaderBuilder.prototype.generateHtml;
dojox_grid__Builder._HeaderBuilder.prototype.generateHtml = function(inGetValue, inValue){
var html = this.getTableArray(), cells = this.view.structure.cells;
dojox_grid_util.fire(this.view, "onBeforeRow", [-1, cells]);
for(var j=0, row; (row=cells[j]); j++){
if(row.hidden){
continue;
}
html.push(!row.invisible ? '<tr>' : '<tr class="dojoxGridInvisible">');
for(var i=0, cell, markup; (cell=row[i]); i++){
cell.customClasses = [];
cell.customStyles = [];
if(this.view.simpleStructure){
if(cell.headerClasses){
if(cell.headerClasses.indexOf('dojoDndItem') == -1){
cell.headerClasses += ' dojoDndItem';
}
}else{
cell.headerClasses = 'dojoDndItem';
}
if(cell.attrs){
if(cell.attrs.indexOf("dndType='gridColumn_") == -1){
cell.attrs += " dndType='gridColumn_" + this.grid.id + "'";
}
}else{
cell.attrs = "dndType='gridColumn_" + this.grid.id + "'";
}
}
markup = this.generateCellMarkup(cell, cell.headerStyles, cell.headerClasses, true);
// content
markup[5] = (inValue != undefined ? inValue : inGetValue(cell));
// set the tooltip for this header to the same name as the header itself
markup[5] = markup[5].replace("class","title='"+cell.name+"' class");
// styles
markup[3] = cell.customStyles.join(';');
// classes
markup[1] = cell.customClasses.join(' '); //(cell.customClasses ? ' ' + cell.customClasses : '');
html.push(markup.join(''));
}
html.push('</tr>');
}
html.push('</table>');
return html.join('');
};
}
);
Note that if there's any chance that any markup may be added to the cell.name then you'll need to add a condition that will somehow extract just the text from it to be the tooltip, or somehow generate a tooltip that won't throw a rendering error, or avoid setting a tooltip altogether for that column.