Using Variables with getElementById. Trying to create chord diagrams for guitar - getelementbyid

I'm doing a little experiment that might grow into something bigger, but I've hit a snag. Something isn't working right with the variable "placement" and getElementById. I know you can use variables with getElementById, but for some reason I can't get it to work. Here's my code so far. Thanks for the help!
<script>
var chord = [3, 2, 0, 0, 3, 3];
for(i=0; i<chord.length; i++){
switch(chord[i]){
case 0:
var note = '0';
break;
case 1:
var note = '1';
break;
case 2:
var note = '2';
break;
case 3:
var note = '3';
break;
case 4:
var note = '4';
break;
case 5:
var note = '5';
break;
}
var placement = 'note' + i + note;
var placement = placement.toString();
document.getElementById(placement).innerHTML = 'o';
}
</script>
<table class="chord">
<tr style="border-top:5px solid gray;">
<td id="note00"></td><td id="note10"></td><td id="note20"></td><td id="note30"></td><td id="note40"></td><td id="note50"></td>
</tr>
<tr>
<td id="note01"></td><td id="note11"></td><td id="note21"></td><td id="note31"></td><td id="note41"></td><td id="note51"></td>
</tr>
<tr>
<td id="note02"></td><td id="note12"></td><td id="note22"></td><td id="note32"></td><td id="note42"></td><td id="note52"></td>
</tr>
<tr>
<td id="note03"></td><td id="note13"></td><td id="note23"></td><td id="note33"></td><td id="note43"></td><td id="note53"></td>
</tr>
<tr>
<td id="note04"></td><td id="note14"></td><td id="note24"></td><td id="note34"></td><td id="note44"></td><td id="note54"></td>
</tr>
</table>

http://jsfiddle.net/L59s4924/
it works.
But try to remove second "var" on "placement" variable declaration.
var placement = 'note' + i + note;
placement = placement.toString();

Related

How to represent Attributes with Anonymous Alphabets in view blade in Laravel

I have this code in Laravel-5.8:
public function index()
{
$userCompany = Auth::user()->company_id;
$departments = HrDepartment::where('company_id', $userCompany)->get();
return view('hr.departments.index')->with('departments', $departments);
}
view
#foreach($departments as $key => $department)
<tr>
<td>
{{$key+1}}
</td>
<td>
{{$department->dept_name ?? '' }}
</td>
<td>
{{isset($department->dept_code) ? $department->dept_code : 'N/A'}}
</td>
</tr>
#endforeach
I don't want the user to see the real department name ( {{$department->dept_name ?? '' }}), but to make it anonymous.
That is, it can randomize {{$department->dept_name ?? '' }} and represent each with alphabets. The first one can be A, second B, C, .... Z
How do I achieve this?
Thanks
You can use this simple function using the ID of the department
function toAlphabet($integer){
$alphabet = array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z');
$alpha_flip = array_flip($alphabet);
if($integer <= 25){
return $alphabet[$integer];
}
elseif($integer > 25){
$dividend = ($integer + 1);
$alpha = '';
$modulo;
while ($dividend > 0){
$modulo = ($dividend - 1) % 26;
$alpha = $alphabet[$modulo] . $alpha;
$dividend = floor((($dividend - $modulo) / 26));
}
return $alpha;
}
}
you can then do
toAlphabet($department->id);
//26 will give "AA"
//25 will give "Z"
//19682 will give "ACCA"

htmlagilitypack remove row attributes

How do we remove the inline height attribute from html?
<tr style="height:2px;">
</tr>
<tr style="height:2px;">
</tr>
I want only height attributes to be removed from all tr tags.
Thanks a lot in advance,
You can:
If your trs have no other styles other than height, you can simply remove strip them from their style attribute (the line I commented out)
Otherwise, you can write something like the snippet below to filter which style keys you want to remove
string html = #"<tr style='height:2px;'>
</tr>
<tr style='height:2px;'>
</tr>";
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(html);
var trs = doc.DocumentNode.SelectNodes("tr");
foreach (var tr in trs)
{
Console.WriteLine(tr.OuterHtml);
//tr.Attributes.Remove("style");
var filteredStyles = GetStyles(tr.GetAttributeValue("style"), "height");
tr.SetAttributeValue("style", string.Join(":", filteredStyles));
Console.WriteLine(tr.OuterHtml);
}
Helper function:
private static List<string> GetStyles(string style, params string[] keysToRemove)
{
List<string> styles = new List<string>();
var stylesKeyPairs = style.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
if (keysToRemove != null)
{
foreach (var styleKeyPair in stylesKeyPairs)
{
var styleKeys = styleKeyPair.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
if (!keysToRemove.Contains(styleKeys.FirstOrDefault()))
styles.Add(styleKeyPair);
}
}
else
styles.AddRange(stylesKeyPairs);
return styles;
}
Output (for both solutions, in this case):

How to make this Razor View work like the ASPX one does?

I have been struggling to get a partial View working in Razor. The View engine cannot make sense of the code below but it is simple using the ASPX View engine. Can anyone show me how to get this to work with Razor? Note that I am just writing out a calendar so the <tr> tag happens at the end of every week. The first sign of a problem is that the Razor code will not format in the VS editor and it complains that the 'while' block is missing its closing brace. I have tried all kinds of combinations, even using a delegate. (I think the cause of the problem may be the conditional TR tag because it is highlighted as an error because it is not closed.)
Razor (doesn't work)
<table class="calendarGrid">
<tr class="calendarDayNames">
<th>Monday</th>
<th>Tuesday</th>
<th>Wednesday</th>
<th>Thursday</th>
<th>Friday</th>
<th>Saturday</th>
<th>Sunday</th>
</tr>
#{
var loopDate = gridStartDate;
}
#while (loopDate <= gridEndDate)
{
if (loopDate.DayOfWeek == DayOfWeek.Monday)
{
<tr class="calendarWeek">
}
<td class="calendarDay">
<span class="calendarDayNumber">#loopDate.Day</span>
#if (Model.AllCalendarDays.ContainsKey(loopDate.Date))
{
foreach (var ev in Model.AllCalendarDays[loopDate.Date])
{
<span class="calendarEvent">#ev.Venue</span>
}
}
</td>
#{
loopDate = loopDate.AddDays(1);
#if (loopDate.DayOfWeek == DayOfWeek.Monday)
{
</tr>
}
}
}
ASPX (works)
<table class="calendarGrid">
<tr class="calendarDayNames">
<th>Monday</th>
<th>Tuesday</th>
<th>Wednesday</th>
<th>Thursday</th>
<th>Friday</th>
<th>Saturday</th>
<th>Sunday</th>
</tr>
<%
var loopDate = gridStartDate;
while (loopDate <= gridEndDate)
{
if (loopDate.DayOfWeek == DayOfWeek.Monday)
{
%>
<tr class="calendarWeek">
<%} %>
<td class="calendarDay">
<span class="calendarDayNumber">
<%: loopDate.Day %></span>
<% if (Model.AllCalendarDays.ContainsKey(loopDate.Date))
{
foreach (var ev in Model.AllCalendarDays[loopDate.Date])
{ %>
<span class="calendarEvent">
<%: ev.Venue %></span>
<% }
} %>
</td>
<% {
loopDate = loopDate.AddDays(1);
if (loopDate.DayOfWeek == DayOfWeek.Monday)
{ %>
</tr>
<% }
}
} %>
</table>
Working solution in Razor based on #jgauffin's view model suggestion and #dommer's ugly raw html solution. Combined together they're almost aesthetically acceptable. :)
View model now has iterator
public IEnumerable<Tuple<DateTime, IList<CalendarEventDto>>> GridItems()
{
var loopDate = GridStartDate;
while (loopDate <= GridEndDate)
{
yield return new Tuple<DateTime, IList<CalendarEventDto>>(loopDate.Date, AllCalendarDays[loopDate.Date]);
loopDate = loopDate.AddDays(1);
}
}
Okay, the Tuple is lazy but I will probably create another model to hold more complex information about the date and events (IsPast/greyed, etc).
The pesky View
#foreach (var item in Model.GridItems())
{
if (item.Item1.DayOfWeek == DayOfWeek.Monday)
{
#Html.Raw("<tr class=\"calendarWeek\">");
}
#Html.Raw("<td class=\"calendarDay\">");
#Html.Raw(string.Format("<span class=\"calendarDayNumber\">{0}</span>", item.Item1.Day));
foreach (var ev in item.Item2)
{
#Html.Raw(string.Format("<span class=\"calendarEvent\">{0}</span>", Server.HtmlEncode(ev.Venue)));
}
#Html.Raw("</td>");
if (item.Item1.DayOfWeek == DayOfWeek.Sunday)
{
#Html.Raw("</tr>");
}
}
Note that when I reformat the View source in VS, it gets egregiously tabbed, with the if statement having about 10 tabs to the left of it, but there are no compilation warnings and it does what I want. Not nice, or easy though. I think the Razor devs should provide some support for explicit breakout and breakin to code and markup so that when the parser cannot parse it unambiguously, we can tell it what we intended.
#Andrew Nurse's solution
Andrew 'works on the ASP.Net team building the Razor parser!'. His solution runs okay but still produces compiler warnings and is obviously confusing Visual Studio because the code cannot be reformatted without ending up in a big glob on a few lines:
<tbody>
#foreach (var calDay in Model.GridItems())
{
if (calDay.DayOfWeek == DayOfWeek.Monday)
{
#:<tr class="calendarWeek">
}
<td class="calendarDay">
<span class="calendarDayNumber">#calDay.Day</span>
#foreach (var ev in calDay.CalendarEvents)
{
<span class="calendarEvent">#ev.Venue</span>
}
</td>
if (calDay.DayOfWeek == DayOfWeek.Sunday)
{
#:</tr>
}
}
</tbody>
The primary issues here were these lines:
if (loopDate.DayOfWeek == DayOfWeek.Monday)
{
<tr class="calendarWeek">
}
...
#if (loopDate.DayOfWeek == DayOfWeek.Monday)
{
</tr>
}
The problem is that Razor uses the tags to detect the start and end of markup. So since you didn't close the "tr" tag inside the first if, it doesn't actually switch back to code, so it doesn't see the "}" as code. The solution is to use "#:", which lets you put a line of markup without regard for tags. So replacing those lines with this should work and be more concise than using Html.Raw:
if (loopDate.DayOfWeek == DayOfWeek.Monday)
{
#:<tr class="calendarWeek">
}
...
#if (loopDate.DayOfWeek == DayOfWeek.Monday)
{
#:</tr>
}
I would move all logic to the viewmodel which leaves the following code in your view:
#while (Model.MoveNext())
{
#Model.WeekHeader
<td class="calendarDay">
<span class="calendarDayNumber">#Model.DayNumber</span>
#foreach (var ev in Model.CurrentDayEvents)
{
<span class="calendarEvent">#ev.Venue</span>
}
</td>
#Model.WeekFooter
}
And the new model:
public class CalendarViewModel
{
private DateTime _currentDate;
public string WeekHeader
{
get
{
return _currentDate.DayOfWeek == DayOfWeek.Monday ? "<tr class="calendarWeek">" : "";
}
}
public string WeekFooter
{
get
{
return _currentDate.DayOfWeek == DayOfWeek.Monday ? "</tr>" : "";
}
}
public IEnumerable<DayEvent>
{
get
{
return AllCalendarDays.ContainsKey(loopDate.Date) ? AllCalendarDays[loopDate.Date] ? new List<DayEvent>();
}
}
public bool MoveNext()
{
if (_currentDate == DateTime.MinValue)
{
_currentDate = gridStartDate;
return true;
}
_currentDate = _currentDate.AddDays(1);
return _currentDate <= gridEndDate;
}
}
MAJOR EDIT: Okay, what happens if you do this?
<table class="calendarGrid">
<tr class="calendarDayNames">
<th>Monday</th>
<th>Tuesday</th>
<th>Wednesday</th>
<th>Thursday</th>
<th>Friday</th>
<th>Saturday</th>
<th>Sunday</th>
</tr>
#{
var loopDate = gridStartDate;
while (loopDate <= gridEndDate)
{
if (loopDate.DayOfWeek == DayOfWeek.Monday)
{
#Html.Raw("<tr class=\"calendarWeek\">");
}
#Html.Raw("<td class=\"calendarDay\">");
#Html.Raw("<span class=\"calendarDayNumber\">" + loopDate.Day + "</span>");
if (Model.AllCalendarDays.ContainsKey(loopDate.Date))
{
foreach (var ev in Model.AllCalendarDays[loopDate.Date])
{
#Html.Raw("<span class=\"calendarEvent\">" + ev.Venue + "</span>");
}
}
#Html.Raw("</td>");
loopDate = loopDate.AddDays(1);
if (loopDate.DayOfWeek == DayOfWeek.Monday)
{
#Html.Raw("</tr>");
}
}
}
Have you tried adding <text> tags around the contents of the blocks?
I think the Razor parse only works when it's obvious where the blocks end. It may be getting confused by the fact you have an if, a td and then some more code, all inside the block.
There's more info on this here: http://weblogs.asp.net/scottgu/archive/2010/12/15/asp-net-mvc-3-razor-s-and-lt-text-gt-syntax.aspx

Greasemonkey, XPath: find all links within table row

Given:
<tr>
<td>Keyword 1</td>
<td>Keyword 2</td>
<td>Keyword 3</td>
</tr>
<tr>
<td>Keyword 4</td>
<td>Keyword 5</td>
<td>Keyword 6</td>
</tr>
I need to match each URI within the table cells. The keyword is consistent throughout the document. I can match links for the entire document with no trouble:
var links_in_document = document.evaluate(
"//a[starts-with(text(),'Keyword')]",
document,
null,
XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
null);
However, even though I have an easy way to reference the TR node, I can't seem to find the right XPath to obtain the links in the row. The snippet below seems to give me the first link in the first TD, but not the rest. Help?
var links_in_row = document.evaluate(
".//a[starts-with(text(),'Keyword')]",
row,
null,
XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
null);
(where 'row' is the context node).
Edited: perhaps I wasn't clear, I can find the links from document level just fine. I am trying to isolate the links in a single row by using the TR node as the context for the XPath.
Edit: solution, for interest. The broken markup I was working on had no id attributes, so I added some and was able to proceed. Snippet:
var exhibit_link;
for( var i = 0; i < all_exhibit_links.snapshotLength; i++ ) {
exhibit_link = all_exhibit_links.snapshotItem( i );
// The rows have no unique ID, so we need to give them one.
// This will give the XPath something to 'latch onto'.
exhibit_link.parentNode.parentNode.id = 'ex_link_row_' + i.toString();
exhibit_link.addEventListener( "click",
function( event ) {
var row_id = event.target.parentNode.parentNode.id;
// Find only those links that are within rows with the corresponding id
var row_links = document.evaluate(
"id('" + row_id + "')/td/a[starts-with(text(),'Exhibit')]",
document,
null,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
null);
// Open each link in a new tab
for( var j = 0; j < row_links.snapshotLength; j++ ) {
row_link = row_links.snapshotItem( j );
GM_openInTab( row_link.href );
}
// Suppress the original function of the link
event.stopPropagation();
event.preventDefault();
},
true );
}
a quick test in the JavaScript Shell with your html example and the following code:
var links_in_row = document.evaluate( ".//a[starts-with(text(),'Keyword')]"
, document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
var i = 0;
while( (link = links_in_row.snapshotItem(i) ) != null) {
print(link.innerHTML);i++;
}
prints out:
Keyword 1
Keyword 2
Keyword 3
which suggests it is working correctly.
Only change i made was not to start at the row level, but at the document...
Extending on what bert wrote, this works for me.
var rows = document.evaluate( "//tr"
, document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
var i = 0;
while( (row = rows.snapshotItem(i) ) != null) {
print( 'NEW ROW----');
var links = document.evaluate(".//a[starts-with(text(),'Keyword')]",
row, null,
XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
var k = 0;
while ((link = links.snapshotItem(k)) != null) {
print( link.innerHTML );
k++;
}
i++;
}
Prints out:
NEW ROW----
Keyword 1
Keyword 2
Keyword 3
NEW ROW----
Keyword 4
Keyword 5
Keyword 6
I think there's something missing outside of what was copy pasted.
bert should get the answer for this one IMHO.
Try:
descendant::*[self::a[starts-with(text(), 'Keyword')]]

prototype findElements querySelectorAll error

i'm call the "down" function but am getting an invalid argument using 1.6.1_rc2
here's the html snippet:
<TR id=000000214A class="activeRow searchResultsDisplayOver" conceptID="0000001KIU">
<TD>
<DIV class=gridRowWrapper>
<SPAN class=SynDesc>Asymmetric breasts</SPAN>
<DIV class=buttonWrapper>
<SPAN class=btnAddFav title="Add to Favorites"> </SPAN>
</DIV>
</DIV>
</TD>
</TR>
here's the code:
var description = row.down('span.SynDesc').innerHTML;
row is a dom reference to the element.
prototype is appending a # then the id of the element:
findElements: function(root) {
root = root || document;
var e = this.expression, results;
switch (this.mode) {
case 'selectorsAPI':
if (root !== document) {
var oldId = root.id, id = $(root).identify();
id = id.replace(/[\.:]/g, "\\$0");
e = "#" + id + " " + e;
}
results = $A(root.querySelectorAll(e)).map(Element.extend); <-- e = "#000000214A span.SynDesc"
root.id = oldId;
return results;
case 'xpath':
return document._getElementsByXPath(this.xpath, root);
default:
return this.matcher(root);
}
i get an "invalid argument" error?
if i put a breakpoint before the offending line and change e to be equal to "span.SynDesc" it works fine.
help. :)
I ran into this. Changing the TR's ID to start with a letter should fix the problem. It turns out that legal HTML IDs match /^[A-Za-z][A-Za-z0-9_:.-]*$/.

Resources