Class added behind targeted element - javascript

I have a forloop which appends a div with child elements for each item
for (i = 0; i < len; ++i) {
if (i in courseModuleList) {
s = courseModuleList[i];
if (this.modules.get(s) != undefined) {
var moduleName = (this.modules.get(s).get('Id'));
var moduleId = (this.modules.get(s).get('OptimeIndex'));
var courseDuration = (courseTemplate.get('Duration'));
var scheduleClass;
var scheduleStatus;
var startDate;
if (scheduleStatus === "Fully Scheduled") {
scheduleClass = "cpCreatedCourseStatusScheduled";
} else if (scheduleStatus === "Part Scheduled") {
scheduleClass = "cpCreatedCourseStatusPartScheduled";
} else if (scheduleStatus === "Unscheduled") {
scheduleClass = "cpCreatedCourseStatusUnscheduled";
} else {
scheduleClass = "cpCreatedCourseStatusUnscheduled";
}
if (courseDuration == 1) {
courseDuration += " day";
} else {
courseDuration += " days";
}
div.append('<div id="selectedCourse" data-id=' + moduleId + '> <a href="#" class="list-group-item cpCreatedCourseWrap clearfix">' +
'<div class="col-lg-6 col-md-12">' +
'<div id="courseName" class="cpCreatedCourseName">' + moduleName + '</div>' +
'<div class="cpCreatedCourseDuration">' + courseDuration + '</div>' +
'</div>' +
'<div class="col-lg-3 col-md-6 col-sm-6 col-xs-6 cpCreatedCourseStatusWrap">' +
'<label>Schedule Status:</label>' +
'<div class="' + scheduleClass + '">' + scheduleStatus + '</div>' +
'</div>' +
'<div class="col-lg-3 col-md-6 col-sm-6 col-xs-6 cpCreatedCourseDateWrap">' +
'<label>Start Date:</label>' +
'<div class="cpCreatedCourseDate">' + startDate + '</div>' +
'</div>' +
'</a> </div>');
}
}
}
I then added a click event on '#selectedCourse' to add a class to the selectedCourse div if the data-id equals a item in an array.
this.$el.find('#selectedCourse').removeClass('cpCreatedCourseWrapActive');
var stepType = $(e.currentTarget).data('id');
var steps = [];
var i, s, courseModuleList = (this.courseTemplate.get('ModuleIndexList')),
len = courseModuleList.length;
for (i = 0; i < len; ++i) {
if (i in courseModuleList) {
s = courseModuleList[i];
if (this.modules.get(s) != undefined) {
var optimeIndex = (this.modules.get(s).get('OptimeIndex'));
steps.push(optimeIndex);
}
}
}
_.each(steps,
function(step) {
if (stepType === step) {
$(e.currentTarget).addClass('cpCreatedCourseWrapActive');
}
});
this is my css
.cpCreatedCourseWrapActive:hover{
background-color:#ddd;
}
.cpCreatedCourseWrapActive{
background-color:#ddd !important;
}
When I click on an element it seems to add behind the element as I can see the colour around the edges. In the image below I changed the background-color to blue to make it clear
Any ideas where I have went wrong? Any help would be appreciated.

Related

I have javascript code to view a news from RSS as a vertical list. I need help to move the list of topics as horizontal one by one, in one line

I have javascript code to view a news from RSS as a vertical list.
(function ($) {
$.fn.FeedEk = function (opt) {
var def = $.extend({
MaxCount: 5,
ShowDesc: true,
ShowPubDate: true,
DescCharacterLimit: 0,
TitleLinkTarget: "_blank",
DateFormat: "",
DateFormatLang:"en"
}, opt);
var id = $(this).attr("id"), i, s = "", dt;
$("#" + id).empty();
if (def.FeedUrl == undefined) return;
$("#" + id).append('<img src="loader.gif" />');
var YQLstr = 'SELECT channel.item FROM feednormalizer WHERE output="rss_2.0" AND url ="' + def.FeedUrl + '" LIMIT ' + def.MaxCount;
$.ajax({
url: "https://query.yahooapis.com/v1/public/yql?q=" + encodeURIComponent(YQLstr) + "&format=json&diagnostics=false&callback=?",
dataType: "json",
success: function (data) {
$("#" + id).empty();
if (!(data.query.results.rss instanceof Array)) {
data.query.results.rss = [data.query.results.rss];
}
$.each(data.query.results.rss, function (e, itm) {
s += '<li><div class="itemTitle"><a href="' + itm.channel.item.link + '" target="' + def.TitleLinkTarget + '" >' + itm.channel.item.title + '</a></div>';
if (def.ShowPubDate){
dt = new Date(itm.channel.item.pubDate);
s += '<div class="itemDate">';
if ($.trim(def.DateFormat).length > 0) {
try {
moment.lang(def.DateFormatLang);
s += moment(dt).format(def.DateFormat);
}
catch (e){s += dt.toLocaleDateString();}
}
else {
s += dt.toLocaleDateString();
}
s += '</div>';
}
if (def.ShowDesc) {
s += '<div class="itemContent">';
if (def.DescCharacterLimit > 0 && itm.channel.item.description.length > def.DescCharacterLimit) {
s += itm.channel.item.description.substring(0, def.DescCharacterLimit) + '...';
}
else {
s += itm.channel.item.description;
}
s += '</div>';
}
});
$("#" + id).append('<ul class="feedEkList">' + s + '</ul>');
}
});
};
})(jQuery);
I need help to move the list of topics as horizontal one by one, in one line. by used javascript code. this code display just 5 topics, which I need it, but I have problem to how can I movement it as horizontal.

how to fix this symbol ' is being displayed as &#39 in angular 2 application

i have an angular application which is making api call when i click on a name displayed in grid table. the names are getting displayed wrong as wherever i have ' is displayed as &#39. i fixed it by using
. but the jql query formed behind the scenes is still having name as "christopher O&#39 Hara" due to which the query breaks and proper page is not getting displayed. any ideas for how to solve this. img of jql query
html -
<div class="panel">
<div class="panel-heading">
{{gridTitle}}
</div>
<div class="gadget-body">
<kendo-grid #grid [kendoGridBinding]="gridData" >
<kendo-grid-column *ngFor="let column of columns" [field]="getColumnTitle(column)" [title]="getColumnTitle(column)" [width]="getColumnWidth(column)">
<template kendoGridHeaderTemplate let-column="column">
<span [title]="column.title" >{{column.title}}</span>
</template>
<template kendoGridCellTemplate let-dataItem let-rowIndex="rowIndex">
<span *ngIf="column !== 'Percentage'">
<span style="color:#3b73af;cursor:pointer">
<span [class.twoDimGrid]="column === header">
<span (click)="rowItemClick(dataItem, column)">
<!-- {{dataItem[column] }}changed to decode the html content from database -->
<span [innerHTML]="dataItem[column]"></span>
</span>
</span>
</span>
</span>
<progressbar *ngIf="column === 'Percentage'" [max]="100" [value]="dataItem[column]">
<span style="color:white; white-space:nowrap;">{{dataItem[column]}}% </span>
</progressbar>
</template>
<template kendoGridFooterTemplate let-column let-columnIndex="columnIndex">
<span style="color:#3b73af;cursor:pointer">
<span [class.twoDimGrid]="column.field === header">
<span (click)="footerClick( column)" >
{{total[column.field]}}
</span>
</span>
</span>
</template>
</kendo-grid-column>
</kendo-grid>
</div>
</div>
component.ts
ngOnInit() {
this.columns = [];
this.gridTitle = this.twoDimensionalGridInfo.Name; console.log(this.gridTitle);
this.baseJql = this.twoDimensionalGridInfo.jql; console.log( this.baseJql);
this.type = this.twoDimensionalGridInfo.type; console.log(this.type);
this.summary = this.twoDimensionalGridInfo.summary; console.log(this.summary);
if (this.summary) {
this.fields = this.summary.split('|');
this.y = this.fields[0]; console.log(this.fields[0]); console.log(this.y);
this.x = this.fields[1]; console.log(this.x); console.log(this.fields[1]);
}
let dataItem = this.gridData[0];
if (dataItem) {
var keys = Object.keys(dataItem); console.log(keys);
this.header = keys[0]
}
for (let field in dataItem) {
this.columns.push(field); console.log(field);
}
console.log(dataItem);
this.total = this.gridData.reduce((sums, obj) => Object.keys(obj).reduce((s, k) => {
k === this.header || k === 'Percentage' || (s[k] = (s[k] || 0) + +obj[k]);
return s;
}, sums), {});
this.total[this.header] = "Total";
this.total["Percentage"] = "";
}
public rowItemClick(dataItem, column) {
this.orderClause = this.baseJql.slice(this.baseJql.indexOf('ORDER'));
if (!this.orderClause.startsWith("ORDER"))
this.orderClause = '';
if (column === 'Count') {
if (dataItem[this.header] == 'No assignee' || dataItem[this.header] === 'None') {
this.customJql = this.baseJql + ' AND "' + this.x + '" is EMPTY';
}
else {
this.custombaseJql = this.baseJql;
if (this.orderClause)
this.custombaseJql = this.baseJql.slice(0, this.baseJql.indexOf("ORDER"));
this.customJql = this.custombaseJql + ' AND "' + this.x + '" = "' + dataItem[this.header] + '" ' + this.orderClause;
}
}
else if (dataItem[this.header] == 'No assignee' || dataItem[this.header] === 'None') {
this.custombaseJql = this.baseJql;
if (this.orderClause)
this.custombaseJql = this.baseJql.slice(0, this.baseJql.indexOf("ORDER"));
this.customJql = this.custombaseJql + ' AND "' + this.x + '" is EMPTY' + ' AND "' + this.y + '" = "' + column + '" ' + this.orderClause;
}
else {
this.custombaseJql = this.baseJql;
if (this.orderClause)
this.custombaseJql = this.baseJql.slice(0, this.baseJql.indexOf("ORDER"));
if (this.x == this.y) {
this.customJql = this.custombaseJql + ' AND "' + this.x + '"= "' + dataItem[this.header] + '"' + this.orderClause;
}
else
this.customJql = this.custombaseJql + ' AND "' + this.x + '"= "' + dataItem[this.header] + '"' + ' AND "' + this.y + '" = "' + column + '" ' + this.orderClause;
}
this.userService.search(this.customJql);
}
Create custom pipe unescape:
import { Pipe, PipeTransform } from '#angular/core';
#Pipe({
name: 'unescape'
})
export class UnescapePipe implements PipeTransform {
transform(value: any, args?: any): any {
const doc = new DOMParser().parseFromString(value, 'text/html');
return doc.documentElement.textContent;
}
}
Use it in the next way:
<div class="panel-heading">
{{gridTitle | unescape}}
</div>

Define a scope in directive and use it in a view

I am using angular-treeview directive. Here , It is taking some time to load the tree, so I want to show a spinner for that time. So, I want to define a variable in directive and that will be used in the view so that I can show a spinner.
**angular-treeview.js**
(function ( angular ) {
'use strict';
angular.module( 'angularTreeview', [] ).directive( 'treeModel', ['$compile', function( $compile) {
return {
restrict: 'A',
link: function ( scope, element, attrs ) {
//tree id
var treeId = attrs.treeId;
//tree model
var treeModel = attrs.treeModel;
//node id
var nodeId = attrs.nodeId || 'id';
//node label
var nodeLabel = attrs.nodeLabel || 'label';
//node class
var nodeClass = attrs.nodeClass || 'type';
//children
var nodeChildren = attrs.nodeChildren || 'children';
//search by label
var searchQuery = attrs.searchQuery || '';
//function for highlighting search text
var searchHighlightFunction = attrs.searchHighlightFunction ||
function (content, text) {
return content
};
//css class to be added for highlighting
var searchHighlightClassName = attrs.searchHighlightClassName || '';
//filter to be used with search query
var searchFilter = attrs.searchFilter || '';
//tree template
var template =
'<ul>' +
'<li data-ng-repeat="node in ' + treeModel + '| ' + searchFilter + ':' + searchQuery + '" data-ng-init="node.collapsed=true">' +
'<i class="collapsed {{node.' + nodeClass + '}}" data-ng-show="node.' + nodeChildren + '.length && node.collapsed" data-ng-click="' + treeId + '.selectNodeHead(node)"></i>' +
'<i class="expanded {{node.' + nodeClass + '}}" data-ng-show="node.' + nodeChildren + '.length && !node.collapsed" data-ng-click="' + treeId + '.selectNodeHead(node)"></i>' +
'<i class="normal {{node.' + nodeClass + '}}" data-ng-hide="node.' + nodeChildren + '.length"></i> ' +
'<span data-ng-class="node.selected" data-ng-click="' + treeId + '.selectNodeLabel(node)" ' +
'ng-bind-html="' + searchHighlightFunction + '(node.' + nodeLabel + ', ' + searchQuery + ', \'' + searchHighlightClassName + '\', true)"></span>' +
'<div data-ng-hide="node.collapsed" data-tree-id="' + treeId + '" data-tree-model="node.' + nodeChildren +
'" data-node-id=' + nodeId + ' data-node-label=' + nodeLabel + ' data-node-children="' + nodeChildren + '"' +
' data-node-class="' + nodeClass + '" data-search-query="' + searchQuery + '" data-search-highlight-function="' + searchHighlightFunction + '"' +
' data-search-highlight-class-name="' + searchHighlightClassName + '" data-search-filter="' + searchFilter + '"></div>' +
'</li>' +
'</ul>';
//check tree id, tree model
if( treeId && treeModel ) {
/*
* to expand or collapse nodes on search text changes
*/
scope.$watch(searchQuery, function (newVal, oldVal) {
var node = scope.node;
if (newVal) {
if (newVal.length > 0) {
if (node) {
if ((node[nodeChildren] && node[nodeChildren].length)
|| (node[nodeChildren] && node[nodeChildren].length)) {
node.collapsed = false;
}
}
}
} else {
if (node && ((node[nodeChildren] && node[nodeChildren].length)
|| (node[nodeChildren] && node[nodeChildren].length))) {
node.collapsed = (scope[treeId].expandedNodes.indexOf(node[nodeLabel]) < 0);
}
}
});
//root node
if( attrs.angularTreeview ) {
//create tree object if not exists
scope[treeId] = scope[treeId] || {};
//this is where we are storing nodes by user to distinguish between
// those expanded by user from those done for showing search results
scope[treeId].expandedNodes = [];
scope.$watch(treeModel, function(newVal, oldVal) {
if (newVal) {
scope[treeId].expandedNodes = [];
}
});
//if node head clicks,
scope[treeId].selectNodeHead = scope[treeId].selectNodeHead || function( selectedNode ){
var expandedNodesIndex;
//Collapse or Expand
selectedNode.collapsed = !selectedNode.collapsed;
expandedNodesIndex = scope[treeId].expandedNodes.indexOf(selectedNode[nodeLabel]);
if (expandedNodesIndex > -1) {
if (selectedNode.collapsed) {
scope[treeId].expandedNodes.splice(expandedNodesIndex, 1);
}
} else {
if (!selectedNode.collapsed) {
scope[treeId].expandedNodes.push(selectedNode[nodeLabel]);
}
}
};
//if node label clicks,
scope[treeId].selectNodeLabel = scope[treeId].selectNodeLabel || function( selectedNode ){
//remove highlight from previous node
if( scope[treeId].currentNode && scope[treeId].currentNode.selected ) {
scope[treeId].currentNode.selected = undefined;
}
//set highlight to selected node
selectedNode.selected = 'selected';
//set currentNode
scope[treeId].currentNode = selectedNode;
};
}
//Rendering template.
element.html('').append( $compile( template )( scope ) );
}
}
};
}]);
})( angular );
My html is -
<div data-angular-treeview="true" data-tree-id="Treevalue"
data-tree-model="suggestionList" data-node-id="id" data-node-class="type" data-node-label="name"
data-node-children="childrens" data-search-query="suggestionListSearchText" data-search-highlight-function="highlightHTML"
data-search-highlight-class-name="searchText" data-search-filter="NameFilter">
</div>
So, How to define a variable in this directive and use it in the scope ?
Looking through the code, it may be as simple as adding HTML inside the div with data-tree-view on it. That HTML will be wiped as part of the tree view directive, so anything you add in there (like a spinner) will be displayed until the directive finishes.
Edit:
Add an image inside the tree view div. This HTML will be cleared, so it will only show while it's loading.
<div data-angular-treeview="true" data-tree-id="Treevalue"
data-tree-model="suggestionList" data-node-id="id" data-node-class="type" data-node-label="name"
data-node-children="childrens" data-search-query="suggestionListSearchText" data-search-highlight-function="highlightHTML"
data-search-highlight-class-name="searchText" data-search-filter="NameFilter">
<img src="spinner.gif">
</div>

Fetching data in chunks

I have a carousel which I have built, which gets a list of products from my API and then each product is created as a slide in a carousel. This is all working perfectly.
When the current slide becomes active I download all of the images for that slide and populate the slide. This data also comes from the API.
What I want to do is have a speedier way to do this. At the moment I am loading these one at a time as they become "active". Ideally I want to be able to load 5 in straight away. So that the start of the array (0) is in the center of the loading array. Then when a user navigates left or right through the carousel I want to call in the next one forward or back.
So far my code is working so that when a slide is active it will have all images loaded, the code I have used for this is here:
module.carousel = (function(){
"use strict";
var exports = {};
exports.details = {};
exports.init = function (options) {
var defaultOptions = {
speed: 1500,
next: {},
back: {},
target: {}
};
if(options == null) options = {};
options = $.extend(defaultOptions, options);
exports.details.targetLength = options.target.children('li').length - 1;
exports.details.position = 0;
exports.details.products = options.target.children('li');
options.target.children('li:nth-child(' + (exports.details.position + 1) + ')').addClass('active');
exports.details.position += 1;
getMedia();
function removeActive() {
options.target.children('li.active').removeClass('active');
}
function addActive() {
options.target.children('li:nth-child(' + (exports.details.position) + ')').addClass('active');
}
function nextItem() {
if(exports.details.position >= exports.details.targetLength + 1) {
exports.details.position = 1;
} else {
exports.details.position += 1;
}
removeActive();
addActive();
getMedia();
}
function getMedia() {
var id = options.target.children('li.active').attr('data-id');
$.ajax({
url: "/beta/api/v1/watches/id/" + id + "/media",
dataType: "json",
async: false,
success: function(data) {
var mediaItems = "";
for(var x = 0, tot = data.length; x < tot; x++) {
mediaItems += "<div class='box'><img src='" + data[x] + "' class='intro-image'></div>";
}
$('#' + id + '_media').html(mediaItems);
}
});
}
function previousItem() {
if(exports.details.position === 1) {
exports.details.position = exports.details.targetLength + 1;
} else {
exports.details.position -= 1;
}
removeActive();
addActive();
getMedia();
}
$('html, body').on('swipeleft', function(event) {
event.stopPropagation();
nextItem();
});
$('html, body').on('swiperight', function(event) {
event.stopPropagation();
previousItem();
});
};
return exports;
}());
That is how my carousel works, and this is how I start it :
$(document).ready(function() {
$.getJSON("/beta/api/v1/watches", function(data) {
var productArray = [];
for(var i = 0, tot = data.length; i < tot; i++){
var productItem = "";
if(i === 0) {
productItem += "<li data-id='" + data[i].id + "' class='product active'>";
} else {
productItem += "<li data-id='" + data[i].id + "' class='product'>";
}
productItem += "<div class='product-header'><h3>"
+ data[i].name + "</h3><h3>" + data[i].case_finish
+ "</h3><h3>" + data[i].id + "</h3><h3>£" + data[i].price + "</h3></div>";
var product = data[i];
productItem += "<div id='" + data[i].id + "_media'></div>";
productItem += "</li>";
productArray.push(productItem);
}
$('#carousel').html(productArray);
$(document).on('swipeleft swiperight', function(event) {
event.stopImmediatePropagation();
});
module.carousel.init({
target: $('#carousel'),
next: $('#next'),
back: $('#back')
});
});
});

JavaScript function performed on 6 id's at a time (return after 6 calls ?)

I am wondering if there is a function I can use so that I can seperate data being called into groups of 6.
here is the long form of the code
var currentResults;
function init() {
getProducts();
}
function getProducts() {
$.ajax({
url:"php/products.php",
dataType: "json",
data: { public: true },
success:function(result){
processResults(result);
}
});
}
function processResults(results) {
currentResults = null;
if (!results && !results.products)
return;
currentResults = results.products;
for (var i = 0; i < results.products.length; i++) {
processResult(results.products[i]);
}
$(".galleryitem").click(handleThumbnailClick);
}
function processResult(result) {
var newDiv = '<div id="galleryitem' + result.id + '" class="galleryitem">';
newDiv += '<div class="imageHover" style="background: ' + result.color + '"> </div>';
newDiv += '<img class="galleryImage" src="' + encodeImagePath(result.thumbnail) + '" />';
if (result.artist)
newDiv += '<div class="imageArtist">' + result.artist + '</div>';
newDiv += '< /div>';
$('#gallery').append(newDiv);
}
i would like the function to be able to sort the images to groups of 6, something like this... (see areas at bottom with ***'s)
function processResult(result) {
var newDiv = '<div id="galleryitem' + result.id + '" class="galleryitem">';
newDiv += '<div class="imageHover" style="background: ' + result.color + '"> </div>';
newDiv += '<img class="galleryImage" src="' + encodeImagePath(result.thumbnail) + '" />';
if ***(!!first 6 called!!)***
newDiv += '<div class="imageArtist">' + result.artist + '</div>';
newDiv += '< /div>';
$('#galleryfirst').append(newDiv);
if ***(!!second 6 called!!)***
newDiv += '<div class="imageArtist">' + result.artist + '</div>';
newDiv += '< /div>';
$('#gallerysecond').append(newDiv);
}
Is doing something like this possible? Or does this whole code need an overhaul?
First, pass the index:
for (var i = 0; i < results.products.length; i++) {
processResult(results.products[i], i);
}
Then check it:
function processResult(result, index) {
var newDiv = ...
//check if the index is a multiple of 6
if(index % 6 == 0){
//do something every six results
}
HTH,
-Ted
Since you want to append the new items to different DIVs, the processResults function might be the better place to do this:
function processResults(results) {
var i = 0,
length = results.length,
first = $("#galleryfirst"),
second = $("gallerysecond");
first.append('<div class="imageArtist">' + results[0].artist + '</div>');
for (i; i < 6 && i < length; i++) {
processResult(results[i], first);
}
if (length > 6) {
second.append('<div class="imageArtist">' + results[6].artist + '</div>');
for (i = 6; i < 12 && i < length; i++) {
processResult(results[i], second);
}
}
}
function processResult(product, containerId) {
var newDiv = "...";
// build the HTML for newDiv...
$(containerId).append(newDiv);
}

Categories