Kendo Autocomplete Displays Two Suggestion Lists - asp.net-mvc

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.

Related

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;
}

ITMS-9000 "element "img" not allowed here; expected..."

Trying to get an ePub file to pass through Apple's ePub checker but get two errors multiple times.
(1) element "img" not allowed here; expected the element...
This is the coding on the page:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link href="../Styles/Style.css" type="text/css" rel="stylesheet"/>
<title></title>
</head>
<body>
<h2>Tokyo</h2>
<p>Japan is made up of five main islands: Hokkaido, Honshu, Shikoku, Kyushu, and Okinawa. Over three-quarters of the 127 million people in Japan live on Honshu, the largest and most developed island. Tokyo, the capital, lies on its eastern shore.</p>
<img alt="Tokyo Metropolis" src="../Images/Tokyo-Metropolis.jpg"/>
<p>Tokyo Metropolis, one of Japan’s 47 prefectures, is comprised of two areas: the <a class="hook" id="Special-Wards-23">23 special wards</a>, which together make up what most consider to be Tokyo, and the rest—the cities and towns that lie to the west. It is best thought of as a constellation of cities that have, over the course of time, merged into one vast urban sprawl which is home to over 13 million people.</p>
I have the alt tag inserted correctly and it displays correct in iBooks.
CSS for img is as follows:
img
{
display: block;
margin-left: auto;
margin-right: auto;
margin-top: 15px;
margin-bottom: 15px;
padding: 1px;
border: 1px solid #021a40;
background-color: #FFFFFF;
}
I've looked around at numerous forums but am none the wiser as to why I'm getting this error.
(2) Same error but in relation to tags ("element "ul" not allowed here; expected end-tag or element "li"...")
Html here...
<ul>
<li><b>Introduction</b></li>
<ul>
<li>Tokyo</li>
<li>A Brief History</li>
<ul>
<li>The Emergence of Japan</li>
[Html cut short as it is a table of contents and long].
I think this is because I have nested lists, but this works perfectly in iBooks so I don't know why it is causing an error at validation.
I'd be very grateful for some help!
The second one is clear: lists can only contain list items. That's how it is.
You say "this works perfectly in iBooks" but that's not true. It doesn't work perfectly. It's just that the app's error handling routines happen to handle this in such a way that the result looks roughly like what you expected. This will not be the same on other machines, other versions of the app etc. Avoid such errors.
The first error message is more subtle.
What version of HTML does the file identify itself as?
If it's XHTML 1.x or HTML 4.x strict, then plain text and inline elements are officially not allowed at the body level. Don't ask me why, I don't know.
If the file version is HTML 4.01 Transitional or HTML5 (or the XHTML equivalents) then images as children of the body are fine.
If anybody can tell me why this difference exists, I'd be delighted!
As for a solution, if you can't change the HTML version to HTML5 or XHTML5, then simply putting everything in the body in one big div will do the trick. Just put <div> right after the <body> and </div> just before the </body>.

paper-button with type="submit" within form doesn't submit?

I am trying to use paper-button with type attribute set to submit (as one would do with button element) to submit the enclosing form, but for some reason it is unable to submit the form. Is this a bug or feature?
How to make paper-button submit the form?
PS: I am in dart land (not js).
As noticed by Gunter, you can create a custom element which extends some of native element with your desired semantics.
I encountered with your issue too and I've created simple element which gives ability to submit to paper-button
<polymer-element name="paper-button-submit" extends="button" noscript>
<template>
<style>
:host {
border: 0;
background: transparent;
padding: 0;
font-size: inherit;
}
</style>
<paper-button>
<content></content>
</paper-button>
</template>
</polymer-element>
Then you can write this
<button type="submit" is="paper-button-submit">Add</button>
And will get a button with paper-like look
You can achieve the form submit by placing a native button inside the paper-button element:
<paper-button>
<button>Sign Up</button>
</paper-button>
Then use this following CSS to hide the native button while ensuring it's hitzone fills the entire paper-button element:
<style shim-shadowdom>
paper-button {
padding:0;
}
paper-button::shadow .button-content {
padding:0;
}
paper-button button {
padding:1em;
background-color: transparent;
border-color: transparent;
}
paper-button button::-moz-focus-inner {
border: 0;
}
</style>
There was already a discussion about using Polymer elements containing form elements within a form in the Polymer Google group and as far as I remember I answered a similar question here on SO (I will do some research afterwards).
1) You can extend an input element
<polymer-element name="my-element" extends="input">
...
</polymer-element>
and use it like
<input is="my-element">
2) You can do the form processing in custom code
(read the values from the form elements and create an AJAX call to send the data to the server)
3) Create a custom form element (extends the 2nd)
which does the form processing and AJAX call
The 1st option is not applicable to core-elments/paper-elements because the don't extend an <input> (or any other form element) but embed it.
This applies to form input elements and also to the form submit button.
Some more or less related topics
Polymer Google Group - polymer element as form input element
Getting HTML5 to work in Form with multiple polymer-dart components
Seth Ladd's Blog - Forms, HTTP servers, and Polymer with Dart
Dart Polymer form field not showing validate errors
How do you get HTML5 inputs to validate if they are inside Polymer Web Components?
What you can do if only the submit button is a Polymer element, is to invoke the click() method on an invisible (non-Polymer) submit button in the click handler of the <paper-button>
for more details see
- Polymer: manually submitting a form
There is no need to create a custom element. According to the docs the following apporach is recommended:
<paper-button raised onclick="submitForm()">Submit</paper-button>
function submitForm() {
document.getElementById('form').submit();
}
so you would just bind the onclick event to a function that manually submits your form.
UPDATE
Although the previous example from iron-form uses onclick event it is recommended to use on-tap over on-click:
Tip: Use on-tap rather than on-click for an event that fires
consistently across both touch (mobile) and click (desktop) devices.
It is also a good idea to use Polymers own DOM API:
function submitForm(e) {
Polymer.dom(e).localTarget.parentElement.submit();
}

Struts errors/messages with div, not span

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.

Resources