Struts errors/messages with div, not span - struts2

We add Struts errors and messages using ActionSupport.addActionError(...) and addActionMessage(...) and then output the results using <actionerror class="x"/> and <actionmessage class="x"/>.
When these tags output the messages they output in the form: <ul><li><span class="x">msg</span></li></ul>
As you can see you can specify the css class (in this example 'x') to apply formatting. Problem is that we want to apply the margin-top and margin-bottom css properties and you can't use these properties (I gather) with <span> elements - only with <div> elements.
So is there anyway you can get these Struts tags to output error/message using a <div> instead of a <span>?
Thanks.
Update:
As per the answer/workaround below, I just enclosed the struts tag within a div:
<div class="error-status">
<s:actionerror cssClass="error"/>
<s:actionmessage cssClass="status" />
</div>
The error-status CSS class set the properties on the LI:
.error-status LI { MARGIN-TOP: 5px; MARGIN-BOTTOM: 5px; display: block; }
.error { COLOR: red }
.status { color: #0066CC }

You can apply margin to spans if you also apply display:block.
But the optimal solution is to apply margin to the li elements.

Related

Angular Material: Change font-size of <mat-list-item>

I am using Angular Material. I have a form with various fields and list items. I have changed the size of mat-form-field inputs using below
mat-form-field.mat-form-field {
font-size: 14px;
}
However since list are not a part of mat-form-field they are still their default 16px. How can I change the size of the <mat-list-item>?
<mat-list-item *ngFor="let file of files">{{file.name}}<mat-list-item>
Try the following CSS definition:
:host /deep/ .mat-list-item-content {
font-size: 18px;
}
I was actually doing this yesterday for my mat-list-items. h6 turned out to be an appropriate size for me.
<mat-list-item *ngFor="let file of files">
<span style="font-size:12px">
{{file.name}}
</span>
<mat-list-item>
or
<mat-list-item *ngFor="let file of files">
<h6>
{{file.name}}
</h6>
<mat-list-item>
You can add the styling directly to the markup. If you use class to reference CSS file, sometimes it won't work.
<mat-list-item style="font-size: 14px; height: 25px" >Test</mat-list-item>

Neovis.js not rendering completely in Salesforce Lightning Web Component

I've spent about a week or so on this, and there's very little documentation online so I figured I'd come on here to see if anyone could potentially help out. So the top level summary is that I'm trying to use an external library (neovis.js) to visualize a neo4j graph database in a Salesforce Lightning web component. I've already explored d3.js (which is compatible with Salesforces locker service) and a few other visualization libraries, but neovis.js would be the most viable option for my use case. I've made some slight modifications shown in the code below to avoid using Document.getElementById in the neovis.js library to select the element and append the canvas to the page.
However, once the canvas is drawn to the page, none of the canvas elements (nodes and edges) are shown on the screen. Here's the weird part though, I can still hover over where the nodes should be on the canvas, and the popup which displays specific information for each node appears on screen with the correct information for each node. I am not super familiar with how the canvas element works, but it seems to me as if some css property is not being applied because of Salesforce's locker service, which causes to elements to be rendered invisibly.
I've gone through a good chunk of the neovis.js library (which is just a library built on top of vis.js), and I've looked for places where perhaps styles aren't being applied to the canvas element; however up to now I've had no luck.
Here's the code I've used so far:
index.html
<template>
<lightning-card title="Neovis" icon-name="custom:custom19">
<div class="slds-m-around_medium">
<div id="neovisContainerViz" class="neoVizClass" lwc:dom="manual" style="height: 700px; width: 400px;">
</div>
</div>
</lightning-card>
</template>
index.js
drawNeovis() {
const config = {
container_id: "",
server_url: "bolt://neo4j.het.io:7687", //This is a publicly available neo4j database that I'm using for testing purposes.
server_user: "",
server_password: "",
labels: {
},
relationships: {
},
initial_cypher: "MATCH (node:Disease {name: 'lung cancer'}) RETURN node"
}
const parent = this.template.querySelector('div.neoVizClass');
const container = document.createElement('DIV');
container.className = 'neoViz';
parent.appendChild(container);
const viz = new NeoVis.default(config);
viz._container = container; //This is a property inside of the NeoVis library. This property is normally set by using the document.getElementById method, however I've replaced it with my predefined container to get around the Salesforce Locker Service.
viz.render();
}
Here is exactly what is rendered onto the Salesforce App page:
<div class="slds-card__body">
<slot>
<div class="slds-m-around_medium">
<div id="neovisContainerViz-67" class="neoVizClass" style="height: 700px; width: 400px;">
<div class="neovis">
<div class="vis-network" tabindex="900" style="position: relative; overflow: hidden; touch-action: pan-y; user-select: none; -webkit-user-drag: none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); width: 100%; height: 100%;">
<canvas width="200" height="200" style="position: relative; touch-action: none; user-select: none; -webkit-user-drag: none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); width: 100%; height: 100%;">
</canvas>
<div class="vis-tooltip" style="left: 5px; top: 5px; visibility: hidden;">
<strong>
license:
</strong>
CC BY 3.0
<br>
<strong>identifier:</strong>
DOID:1324
<br>
<strong>name:</strong>
lung cancer
<br>
<strong>source:</strong>
Disease Ontology
<br>
<strong>url:</strong>
http://purl.obolibrary.org/obo/DOID_1324
<br>
</div>
</div>
</div>
</div>
</div>
</slot>
</div>
The canvas and the tooltip are appended to the DOM, AND the tooltip dynamically updates when I hover over where the canvas elements should be displayed. However none of the nodes or edges are visible on the screen.
All in all, I am not very familiar with how the canvas element actually functions, and am hoping that someone can give me some tips on how to trouble shoot this issue and get the elements on the canvas to display.
Thank you all!
I was able to finally figure this out incase anyone else is running into similar issues. I wouldn't say this is the preferred answer, but it works (for now). Basically I injected an iframe into Salesforce, and inside of the iframe I injected the neovis.js library and generated the graph, works perfectly now.

Difficulty creating very small select statements for Angular Material web app for phone

I have been having trouble creating a web app for a phone using Angular and Material Design components. In order for my web app to work well on a phone, it needs to have small buttons and small select statements. Unfortunately, it looks like the framework is adding a style statement for the select element. That style statement is specifying the width of the element and the width it is specifying is way too big. How can I specify small select statements?
Below are the key parts of the two input files: app.component.html and app.component.css. There is a third section that shows the code that is generated by Angular2 as I see it in Chrome's developer tools. The key part of that code is the style statement (style="width: 139.325px;"). If I change the width using the develop tools then I can get the button size I want. I just don't know how to get the size i want using the CSS file.
---- Resulting Ang2 Code -----
<md-select _ngcontent-c0="" placeholder="Number of players" role="listbox" ng-reflect-model="4" ng-reflect-placeholder="Number of players" class="ng-untouched ng-pristine ng-valid mat-select" tabindex="0" aria-label="Number of players" aria-required="false" aria-disabled="false" aria-invalid="false" aria-owns="md-option-0 md-option-1 md-option-2 md-option-3 md-option-4 md-option-5 md-option-6 md-option-7 md-option-8"><div cdk-overlay-origin="" class="mat-select-trigger"><span class="mat-select-placeholder mat-floating-placeholder" style="width: 139.325px;">Number of players </span><!--bindings={
"ng-reflect-ng-if": "[object Object]"
}--><span class="mat-select-value"><span class="mat-select-value-text">4</span> </span><span class="mat-select-arrow"></span> <span class="mat-select-underline"></span></div><!--bindings={
"ng-reflect-origin": "[object Object]",
"ng-reflect-positions": "[object Object],[object Object",
"ng-reflect-offset-x": 0,
"ng-reflect-offset-y": 0,
"ng-reflect-min-width": "152.3249969482422",
"ng-reflect-backdrop-class": "cdk-overlay-transparent-backdr",
"ng-reflect-has-backdrop": "",
"ng-reflect-open": false
}--></md-select>
---- My attempt to override the css for the select statement in app.component.css -----
md-select{
font-size: 10px;
padding: 1px;
min-width: 12px;
}
md-option{
font-size: 10px;
padding: 1px;
min-width: 12px;
}
---- My app.component.html ---------
<md-select placeholder="Number of players" [(ngModel)]="numPlayers" (ngModelChange)="onChangeNumPlayers()" >
<md-option *ngFor="let mynum of numberOfPlayersList" [value]="mynum.value">{{ mynum.name }}</md-option>
</md-select>
My friend Sergiu from Romania helped me out with this. The framework creates elements that encapsulate the md-select and md-option elements. You cannot set the styles for elements outside of md-select and md-option using app.component.css. In order to control those elements you need to add them to the base styles.css file. These classes were sufficient to shrink the select statement for me.
.mat-select,
.mat-select-trigger,
.mat-select-placeholder,
.cdk-overlay-pane,
.mat-select-panel,
.mat-select-content
{
min-width: 40px !important;
width: 40px !important;
}
.mat-option {
padding: 0 2px!important;
}

Kendo Autocomplete Displays Two Suggestion Lists

My Kendo autocomplete control retrieves a Json list successfully. Unfortunately, it calls the MVC controller method twice and creates two suggestion lists. The duplicate list is displayed directly behind the first. When a value is selected from the first suggestion list, the list disappears, but the duplicate list remains visible. I am using a wrapper for the autocomplete control as shown below. I've confirmed that the control is not being referenced in any of the page scripts. The control is located in a partial view that is added to a cshtml view one time (#{ Html.RenderPartial("_AddLineItem"); }).
#(Html.Kendo().AutoComplete()
.Name("CategorySearch")
.DataTextField("CategoryName")
.Filter("contains")
.DataSource(source =>
{
source.Read(read =>
{
read.Action("PopulateCategories", "Default");
})
.ServerFiltering(false);
})
)
Generated HTML shows the suggestion list twice, but the associated input control only exists once. The following tags are in the generated HTML twice (these are tags for the suggestion list and they also contain li tags and closing div tags, removed from the pasted HTML below):
<div class="k-animation-container" style="left: 431.13px; top: 405.69px; width: 511px; height: 206px; overflow: hidden; padding-right: 2px; padding-bottom: 4px; padding-left: 2px; margin-left: -2px; display: none; position: absolute; z-index: 10002;">
Does anyone have an idea of what is happening here?
Per the comment that I added, the answer is to avoid putting a Kendo autocomplete control inside a JQuery UI dialog control. The dialog forces the autocomplete control to be rendered twice in the browser. I've confirmed this in both Internet Explorer and Firefox. It is reasonable to assume that the same behavior will occur in other browsers as well.

How do I style elements in Dart Web UI templates?

Say I have a custom component with
<head>
<link rel="stylesheet" src="...">
</head>
<body>
<element name="elem">
<template>
<ul class="foo">
...
where the referenced style sheet has an entry
ul .foo {
list-style-type: none;
}
The problem is that I can't get the style to apply to the ul. Nothing I tried works unless I put style attribute on the ul element itself. I have tried putting under with scoped attribute and that doesn't work either. It does a weird thing where the class of the ul becomes "elem_foo".
Thanks for the question! Here's how I do it:
In my main HTML:
<div is="x-click-counter">
In my custom element:
<element name="x-click-counter" constructor="CounterComponent" extends="div">
<template>
<button class="button1" on-click="increment()">Click me</button><br />
<span>(click count: {{count}})</span>
<style scoped>
div[is=x-click-counter] span {
color: red;
}
</style>
</template>
<script type="application/dart" src="xclickcounter.dart"></script>
</element>
There are two things going on here.
1) I use the form of <div is="x-foo"> instead of <x-foo>. I like how the first form is more backwards compatible, and it's more explicit with how I will find the element.
2) I put a <style scoped> inside my <template> tag.
Web UI will see the scope style tag, and generate a CSS file for you. It looks like this:
/* Auto-generated from components style tags. */
/* DO NOT EDIT. */
/* ====================================================
Component x-click-counter stylesheet
==================================================== */
div[is=x-click-counter] span {
color: #f00;
}
Web UI also adds a link to this generated CSS file to your main HTML file.

Resources