onMouseOut effect fired when mouse cursor goes to child div.... I dont want to do that - onmouseout

Here is my code --
<li>
<a id="LoginTxt2" onmouseover="MouseOver(this);" onmouseout="MouseOut(this);" href="#">
<div style="background-color:#CCC;">OLD Text</div>
</a>
</li>
JS--
MouseOver = function(obj){
var id = obj.id;
document.getElementById(id).innerHTML='<div style="background-color:#DDD;">NEW Text</div>';
}
MouseOut = function(obj){
var id = obj.id;
document.getElementById(id).innerHTML="<div style="background-color:#CCC;">OLD Text</div>";
}
when my mouse goes to child div, MouseOut fierd i dont want to do that... plz help

This is the way the event works and there's no way of avoiding the MouseOut() function to be called. What you can do is check, inside the MouseOut() function, if the element you're now hovering is a child element of the outer element:
MouseOut = function(obj, event) {
// this is the original element the event handler was assigned to
var e = event.toElement || event.relatedTarget;
// check for all children levels (checking from bottom up)
while (e && e.parentNode && e.parentNode != window) {
if (e.parentNode == this|| e == this) {
if(e.preventDefault) {
e.preventDefault();
}
return false;
}
e = e.parentNode;
}
var id = obj.id;
document.getElementById(id).innerHTML="<div style="background-color:#CCC;">OLD Text</div>";
}
Note that you need to change the onmouseout declaration to onmouseout="MouseOut(this,event);".
NOTE: solution derived from https://stackoverflow.com/a/13141057/1417546

Related

How can I add a search button to this existing accordion search code?

I am using the code by Rick Sibley from the first answer on this post: Search within an accordion
Rick mentions that a search button can be added to run the script onclick, in addition to pressing enter to submit and run the search script. Can any body help me add the search 'button' functionality to this, please?
Thanks so much!
I figured it out! I feel like a genius - though I am obviously very bad at this.
Here's what I added in addition to the keyup event listener:
//Search Accordings; Highlight & Open Matching Areas ON SEARCH BUTTON CLICK
function searchBtn() {
var input, filter, i, acc, panels, txtValue, searchText, searchTitle;
input = document.getElementById("keywordSearch");
filter = input.value.toUpperCase();
acc = document.getElementsByClassName("accordion");
panels = document.getElementsByClassName("panel");
for (i = 0; i < panels.length; i++) {
for (i = 0; i < acc.length; i++) {
searchText = panels[i].textContent || panels[i].innerText;
searchTitle = acc[i].textContent || acc[i].innerText;
if (input.value !== "") {
if (searchText.toUpperCase().indexOf(filter) > -1 || searchTitle.toUpperCase().indexOf(filter) > -1) {
if (!acc[i].classList.contains("active")) {
acc[i].classList.add("active");
}
highlightIndex.apply(filter);
panels[i].style.maxHeight = panels[i].scrollHeight + "px";
panels[i].scrollIntoView({
behavior: 'smooth'
});
} else {
if (acc[i].classList.contains("active")) {
acc[i].classList.remove("active");
}
panels[i].style.maxHeight = null;
}
} else {
highlightIndex.remove();
if (acc[i].classList.contains("active")) {
acc[i].classList.remove("active");
}
panels[i].style.maxHeight = null;
}
}
}
}
With the following button added in html
<button type="submit" id="searchBtn" onclick="searchBtn();">Search</button>

update page content

I have a morris chart that compares different students statistics. I also have a modal in which I can add a new student and the graph should update with new student statistics. After adding, the graph is getting updated but only when I refresh the whole page. How would I update the page without refreshing?
component.ts
ngOnInit() {
this.getData();
}
getData() {
this.http.get('url')
.subscribe(data => {
const graphData = data.stathistory;
const graphDataArr = [];
let currentChar = 'a';
for (const graphdata in graphData) {
const curDate = graphdata.replace(/(\d{4})(\d{2})(\d{2})/g, '$1-$2-$3');
const graphdataObj = { 'y': curDate };
for (const element in graphData[graphdata]) {
graphdataObj[currentChar] = Number(graphData[graphdata][element].rank);
currentChar = this.nextChar(currentChar);
}
graphDataArr.push(graphdataObj)
currentChar = 'a';
}
const yKeysArr = [];
for (let i = 0; i < data.domains.length; i++) {
yKeysArr.push(currentChar);
currentChar = this.nextChar(currentChar);
}
this.generateChart(graphDataArr, data.names, yKeysArr);
});
}
generateChart(graphRanks = [], names = [], yKeys = []) {
this.graphData = graphRanks;
this.graphOptions = {
xkey: 'y',
ykeys: yKeys,
labels: names,
resize: true,
parseTime: false,
pointSize: 0,
};
}
addStudent(name) {
this.http.post('url', {
name: name,
})
.subscribe(response => {
this.getData();
}
);
}
html
<div *ngIf = 'graphData' mk-morris-js [options]="graphOptions" [data]="graphData" type="Line" style="height: 500px; width: 100%;">
**code for modal dialog**
<button type="button" class="btn btn-primary" (click)="addStudent(name)">
Please let me know if more info is needed.
This looks fine. I would suggest you to add console.log(graphRanks); just before this.graphData = graphRanks; to ensure that the new data is loaded when expected. By the way your button calls the function addDomain(name) while in your script the function name is addStudent(name).
I would recommend that you make your graphData an observable and use the async pipe in your html. Something like this:
graphData$ = this.http.get('url').pipe(
map(x => // do stuff with x here)
)
Then, in your html you can make:
[graphData]="graphData$ | async"
Here is a good post by Todd Motto on the ng-if piece:
https://toddmotto.com/angular-ngif-async-pipe
EDIT:
If you don't want to make your graphData an observable - you could probably use a switchMap in you addStudent function.
addStudent(name) {
this.http.post('url', {
name: name,
})
.pipe(
switchMap(x => this.getData())
}
);
}
I finally got it working. I tried to clear the morris chart and generate the chart with new data. So, whenever there is a data change, it would clear the graph and redraw the graph with new data.
Clearing the chart
document.getElementById('idofthegraph').innerHTML = '';
This would draw the chart again
this.generateChart(graphDataArr, data.names, yKeysArr);

Chrome Extension - Background Script notified whenever another page updates

I'm making a Chrome Extension that gets the DOM of a closed tab and updates the popup.html. So far so good, I can do that through the background script using XMLHttpRequest.
However, I would like my popup to be updated if the closed page is updated. I was thinking of running a timer in the background script to check every 10 sends or so, but I was wondering if XMLHttpRequest has a way of knowing when its page updates? Or even if the timer would work, I couldn't get it working
I've added the relevant files below. Any help is appreciated
popup.html
<body>
<h1>Agile Board Viewer</h1>
<div class="wrapper">
<button id="mainButton">Click me</button>
<p id="testingDisplay">test</p>
</div>
</body>
popup.js
document.addEventListener('DOMContentLoaded', function () {
document.getElementById("mainButton").addEventListener('click', function () {
chrome.runtime.sendMessage({
method : 'POST',
action : 'xhttp',
url : '//My url//',
data : 'q=something'
}, function (responseText) {
document.getElementById("testingDisplay").innerHTML = responseText;
});
});
});
background.js
I've deleted some lines that are pointless (I think) to avoid clutter, just error handlers and what not, also got rid of my attempt at a timer. Basically, what it does is takes a string from the DOM and sends it to the popup. I would like that popup to update whenever the string does.
var testingString = "Testing (";
chrome.runtime.onMessage.addListener(function (request, sender, callback) {
if (request.action == "xhttp") {
`var xhttp = new XMLHttpRequest();
xhttp.onload = function () {
var testingValue = xhttp.responseText.substring(xhttp.responseText.indexOf(testingString), xhttp.responseText.indexOf(testingString) + 16);
callback(testingValue);
//callback(xhttp.responseText);
};
}
});
Sorry if the formatting is a mess, I'm not too well versed on this
Just to follow up, I've solved my issue by using a timer that checks the closed tab every couple of seconds. If the label that lists the number of items in my Testing column is different, I get my notification. Still learning XHR so I'm hoping I can improve on this again but for now, I'm happy enough. Only works for 20 seconds in my example, as I don't want an infinite timer. Will put in an off switch later
var testingString = "Testing (";
var testBuffer = "";
var i = 0;
chrome.runtime.onMessage.addListener(function (request, sender, callback) {
if (request.action == "xhttp") {
var xhttp = new XMLHttpRequest();
var method = request.method ? request.method.toUpperCase() : 'GET';
var testingValue = xhttp.responseText.substring(xhttp.responseText.indexOf(testingString), xhttp.responseText.indexOf(testingString) + 16);
function startTimer() {
window.setTimeout(function () {
if (i < 20) {
xhttp.open(method, request.url, true);
xhttp.onload = function () {
testBuffer = testingValue;
testingValue = xhttp.responseText.substring(xhttp.responseText.indexOf(testingString), xhttp.responseText.indexOf(testingString) + 16);
if (testBuffer != testingValue) {
notification = new Notification('New Item in Testing Column', {
body : "You have a new item in Testing",
});
console.log(testingValue);
}
};
xhttp.onreadystatechange = function () {
if (xhttp.readyState == 4 && xhttp.status == 200) {
callback(testingValue);
}
};
xhttp.onerror = function () {
alert("error");
callback();
};
if (method == 'POST') {
xhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
}
xhttp.send(request.data);
console.log("count");
i++;
startTimer();
}
}, 5000);
}
startTimer();
return true;
}
});

How to group project results by Taxonomy Terms

I have a ContentType Animal which has a Taxonomy field species.
look at this posthttp://orchardpros.net/tickets/10636 and (http://www.ideliverable.com/blog/ways-to-render-lists-of-things) for a good explanation.
I runed the code,but It have 2 erro.
1.var speciesField = item.Animal.Species;----gave erro: CS1061 ,"Orchard.ContentManagement.ContentItem' does not contain a definition Animal".
2.var items = speciesDictionary[speciesTerm];----gave erro:CS0136 " A local or parameter named 'items' cannot be declared in this scope because that name is used in an enclosing local.
please help!
#using Orchard.ContentManagement
#using Orchard.Taxonomies.Models
#{
var items = ((IEnumerable<ContentItem>)Model.ContentItems);
var speciesDictionary = new Dictionary<TermPart, IList<ContentItem>>();
// Collect categories and their items.
foreach (var item in items) {
var speciesField = item.Animal.Species; // Assumes that the species field is attached to the Animal type's implicit part (Animal).
var speciesTerms = (IEnumerable<TermPart>)speciesField.Terms;
foreach (var speciesTerm in speciesTerms) {
var list = speciesDictionary.ContainsKey(speciesTerm) ? speciesDictionary[speciesTerm] : default(IList<ContentItem>);
if (list == null) {
list = new List<ContentItem>();
speciesDictionary.Add(speciesTerm, list);
}
list.Add(item);
}
}
}
<ul>
#foreach (var speciesTerm in speciesDictionary.Keys) {
var items = speciesDictionary[speciesTerm];
<li>
#speciesTerm.Name
</li>
}
</ul>
Your first error indicates that you are trying to get a property of the ContentItem class which does not exist. This is actually partially correct, because it does exist on the ContentItem, but because you cast it to a ContentItem class, it loses the dynamic properties.
You can fix this by not casting to a ContentItem class, but just to dynamic:
var items = ((IEnumerable<dynamic>)Model.ContentItems);
The second error indicates that you are trying to create a variable while it already exists. This is obvious, because in the top of your .cshtml you already have items defined:
#{
// var items is defined here, you can not redefine it
// as always in C#
var items = ((IEnumerable<ContentItem>)Model.ContentItems);
}
So instead give it a different name in the bottom:
<ul>
#foreach (var speciesTerm in speciesDictionary.Keys) {
// Cannot use 'items' here again
var speciesItems = speciesDictionary[speciesTerm];
<li>
#speciesTerm.Name
</li>
}
</ul>

Sharepoint InputFormTextBox not working on updatepanel?

I have two panels in update panel. In panel1, there is button. If I click, Panel1 will be visible =false and Panel2 will be visible=true. In Panel2, I placed SharePoint:InPutFormTextBox. It not rendering HTML toolbar and showing like below image.
<SharePoint:InputFormTextBox runat="server" ID="txtSummary" ValidationGroup="CreateCase" Rows="8" Columns="80" RichText="true" RichTextMode="Compatible" AllowHyperlink="true" TextMode="MultiLine" />
http://i700.photobucket.com/albums/ww5/vsrikanth/careersummary-1.jpg
SharePoint rich text fields start out as text areas, and some javascript in the page load event replaces them with a different control if you are using a supported browser.
With an update panel, the page isn't being loaded, so that script never gets called.
Try hiding the section using css/javascript rather than the server side visible property. That generally lets you make whatever changes you need to the form without sharepoint seeing any changes.
<SharePoint:InputFormTextBox ID="tbComment" CssClass="sp-comment-textarea" runat="server" TextMode="MultiLine" RichText="True"></SharePoint:InputFormTextBox>
<%--textbox for temporay focus - trick the IE behavior on partial submit--%>
<input type="text" id="<%= tbComment.ClientID %>_hiddenFocusInput_" style="width: 0px; height: 0px; position: absolute; top: -3000px;" />
<%--tricking code that makes the 'SharePoint:InputFormTextBox' to work correctly in udate panel on partial podtback--%>
<script id="<%= tbComment.ClientID %>_InputFormTextBoxAfterScript" type="text/javascript">
(function () {
// where possible rich textbox only
if (browseris.ie5up && (browseris.win32 || browseris.win64bit) && !IsAccessibilityFeatureEnabled()) {
// find this script element
var me = document.getElementById("<%= tbComment.ClientID %>_InputFormTextBoxAfterScript");
if (me) {
// search for script block of the rich textbox initialization
var scriptElement = me.previousSibling;
while (scriptElement && (scriptElement.nodeType != 1 || scriptElement.tagName.toLowerCase() != "script")) {
scriptElement = scriptElement.previousSibling;
}
// get the content of the found script block
var innerContent = scriptElement.text;
if (typeof innerContent == 'undefined') {
innerContent = scriptElement.innerHTML
}
// get text with function call that initializes the rich textbox
var callInitString = "";
innerContent.toString().replace(/(RTE_ConvertTextAreaToRichEdit\([^\)]+\))/ig, function (p0, p1) { callInitString = p1; });
// register on page load (partial updates also)
Sys.Application.add_load(function (sender, args) {
setTimeout(function () {
// get the toolbar of the rich textbox
var toolbar = $get("<%= tbComment.ClientID %>_toolbar");
// if not found then we should run initialization
if (!toolbar) {
// move focus to the hidden input
$get("<%= tbComment.ClientID %>_hiddenFocusInput_").focus();
// reset some global variables of the SharePoint rich textbox
window.g_aToolBarButtons = null;
window.g_fRTEFirstTimeGenerateCalled = true;
window.g_oExtendedRichTextSupport = null;
parent.g_oExtendedRichTextSupport = null;
// call the initialization code
eval(callInitString);
setTimeout(function () {
// call 'onload' code of the rich textbox
eval("RTE_TextAreaWindow_OnLoad('<%= tbComment.ClientID %>');");
}, 0);
}
}, 0);
});
}
}
})();
</script>

Resources