I want to implement an X button inside a textfield (x on right side of textfield) to clear entered texts. I have seen many extjs application that has this feature. How do I go about doing that? Any suggestion or comments would be really appreciated...
THanks
it looks something like this...
You have to use a Ext.form.field.Trigger. Here is a example for that
Ext.define('Ext.ux.CustomTrigger', {
extend: 'Ext.form.field.Trigger',
alias: 'widget.customtrigger',
initComponent: function () {
var me = this;
me.triggerCls = 'x-form-clear-trigger'; // native ExtJS class & icon
me.callParent(arguments);
},
// override onTriggerClick
onTriggerClick: function() {
this.setRawValue('');
}
});
Ext.create('Ext.form.FormPanel', {
title: 'Form with TriggerField',
bodyPadding: 5,
width: 350,
renderTo: Ext.getBody(),
items:[{
xtype: 'customtrigger',
fieldLabel: 'Sample Trigger',
emptyText: 'click the trigger'
}]
});
For ease of testing, here is a JSFiddle
This is what works for me with the CSS:
CSS
.x-form-clear {
background-image: url('../../resources/themes/images/default/form/clear-trigger.gif');
background-position: 0 0;
width: 17px;
height: 22px;
border-bottom: 1px solid #b5b8c8;
cursor: pointer;
cursor: hand;
overflow: hidden;
}
.x-form-clear-over {
background-position: -17px 0;
border-bottom-color: #7eadd9;
}
.x-form-clear-click {
background-position: -68px 0;
border-bottom-color: #737b8c;
}
Class
Ext.define('Ext.ux.form.field.Clear', {
extend: 'Ext.form.field.Trigger',
alias: 'widget.clearfield',
triggerBaseCls: 'x-form-clear',
onTriggerClick: function() {
this.setValue();
}
});
Usage
Ext.create('Ext.container.Container', {
renderTo: Ext.getBody(),
items: [
Ext.create('Ext.ux.form.field.Clear', {
fieldLabel: 'Clear Field',
cls: 'clear-trigger'
})
]
})
Or use this 'clearbutton' plugin: http://www.eekboom.de/ClearButton.html
I like it because it's just a plugin, one line, instead of requiring a custom subclass.
Also, it can be used on all kinds of fields, not just on a textfield.
You can use the Ext.form.field.Text with triggers in Extjs 5.0 and later, no need to define a new type.
var textfield = Ext.create('Ext.form.field.Text', {
triggers: {
clear: {
cls: 'x-form-clear-trigger',
handler: function () {
this.setValue('');
}
}
}
});
The scope of the trigger's handler is the Ext.form.field.Text component.
You can have multiple triggers, and can also use MVVM model. For example:
var textfield = Ext.create('Ext.form.field.Text', {
triggers: {
clear: {
cls: 'x-form-clear-trigger',
handler: function () {
this.setValue('');
}
},
search: {
cls: 'x-form-search-trigger',
handler: 'onSearch'
}
}
});
The search trigger uses a handler function, i.e. onSearch, that is defined in the controller of the component that has the Ext.form.field.Text object.
In ExtJS 6+, you can also just add the following 2 configs on your Ext.form.field.Text and show/hide the trigger with the built-in change listener
triggers: {
clearText: {
cls: 'clear-text-trigger-icon',
handler: function() {
this.setValue('');
}
}
},
listeners: {
change: function(textField) {
if (textField.getValue()) {
textField.setHideTrigger(false);
} else {
textField.setHideTrigger(true);
}
}
}
Related
Position: sticky doesn't support by the most mobile browsers. But position: fixed is not that thing I need (because of fixed block overlaps content in the bottom of document).
I guess for jquery it will be easy to set static position for fixed block if we get bottom of document onscroll.
But for Vue2 I haven't any idea how to do the same. Give some advice please. Or maybe better solution exists.
As I mentioned in the comments, I'd recommend using a polyfill if at all possible. They will have put a lot of effort into getting it right. However, here is a simple take on how you might do it in Vue.
I have the application handle scroll events by putting the scrollY value into a data item. My sticky-top component calculates what its fixed top position would be, and if it's > 0, it uses it. The widget is position: relative.
new Vue({
el: '#app',
data: {
scrollY: null
},
mounted() {
window.addEventListener('scroll', (event) => {
this.scrollY = Math.round(window.scrollY);
});
},
components: {
stickyTop: {
template: '<div class="a-box" :style="myStyle"></div>',
props: ['top', 'scrollY'],
data() {
return {
myStyle: {},
originalTop: 0
}
},
mounted() {
this.originalTop = this.$el.getBoundingClientRect().top;
},
watch: {
scrollY(newValue) {
const rect = this.$el.getBoundingClientRect();
const newTop = this.scrollY + +this.top - this.originalTop;
if (newTop > 0) {
this.$set(this.myStyle, 'top', `${newTop}px`);
} else {
this.$delete(this.myStyle, 'top');
}
}
}
}
}
});
#app {
height: 1200px;
}
.spacer {
height: 80px;
}
.a-box {
display: inline-block;
height: 5rem;
width: 5rem;
border: 2px solid blue;
position: relative;
}
<script src="//unpkg.com/vue#latest/dist/vue.js"></script>
<div id="app">
<div class="spacer"></div>
<div class="a-box"></div>
<sticky-top top="20" :scroll-y="scrollY"></sticky-top>
<div class="a-box"></div>
</div>
This seem to work for me
...
<header
ref="header"
class="header-container"
:class="{ 'header-container--sticky': isHeaderSticky }"
>
...
...
data() {
return{
scrollY: null,
headerTop: 0,
isHeaderSticky: false,
}
},
mounted() {
window.addEventListener('load', () => {
window.addEventListener('scroll', () => {
this.scrollY = Math.round(window.scrollY);
});
this.headerTop = this.$refs.header.getBoundingClientRect().top;
});
},
watch: {
scrollY(newValue) {
if (newValue > this.headerTop) {
this.isHeaderSticky = true;
} else {
this.isHeaderSticky = false;
}
}
}
...
...
.header-container {
&--sticky {
position: sticky;
top: 0;
z-index: 9999;
}
}
...
I have the following jQuery dialog. How can I change the button size of the two buttons? So they won't be underneath each other, but next to each other.
Here is my code
function ApplyJQueryUI() {
$("#<%= callForwardingAlwaysOption.ClientID %>").buttonset();
$("#callForwardingAlwaysDialog").dialog({
resizable: false,
modal: true,
autoOpen: false,
show: "fade",
closeOnEscape: false,
hide: "fade",
buttons: {
"> Ok": function () {
$("#<%= callForwardingAlwaysButton.ClientID %>").click();
},
"> Annuleren": function () {
$("#<%= callForwardingAlwaysOption.ClientID %>_0").attr("checked", "checked");
$("#<%= callForwardingAlwaysOption.ClientID %>").buttonset("refresh");
$(this).dialog("close");
}
}
});
$('#callForwardingAlwaysDialog').keypress(function(e) {
if (e.keyCode == $.ui.keyCode.ENTER) {
$("#<%= callForwardingAlwaysButton.ClientID %>").click();
}
});
$("#callForwardingAlwaysDialog").parent().appendTo($("#<%= callForwardingAlwaysUpdatePanel.ClientID %>:first"));
if (isPostBack){
$(dialogInstance).dialog("close");
}
}
You can do this with a little bit of CSS, all you need to do is reduce the font size:
#dialog .ui-button-text {
font-size: 10px; /* Or whatever smaller value works for you. */
}
You can also drop the padding:
#dialog .ui-button-text {
font-size: 10px;
padding: 1px 1px 1px 1px; /* Or whatever makes it small enough. */
}
I had some problem when I used recursive partials. I tried to create comments which every one can comment again, like this:
comment (depth 0)
comment (depth 1)
comment (depth 2)
I want to add some special classes for different depth of comments
{{#messages}}
{>message}
{{/messages}}
<!-- {{>message}} -->
<div class="{{getClasses()}}"">{{text}}</div>
{{incrDepth()}}
{{#comments}}
{{>message}}
{{/comments}}
{{decrDepth()}}
<!-- {{/message}} -->
This is additional function which I use
{
data: {
incrDepth: function () {
this.depth++;
},
decrDepth: function () {
this.depth--;
},
getClasses: function () {
return 'depth' + this.depth;
}
}
}
So, before every comments I increase depth and after comments I decrease it. But unfortunately all my invokes of getClasses() return 'depth0' and I can't understand why.
It helps if you think of templates as being read-only - rather than 'executing' the template from top to bottom, Ractive constructs a virtual DOM from the template, and updates nodes within it whenever they need to change. For that reason, there's no guarantee about when a given function will be called.
So you should avoid functions with 'side-effects' - they should be for retrieving data, never setting it.
But a recursive structure is definitely possible - you need to use inline components. A component is a nested Ractive instance that manages its own data, and it's easy to set a depth property to 'whatever the parent depth is, plus one' - try running the code snippet below to see it in action.
Ractive.components.comment = Ractive.extend({
template: '#comment',
data: { depth: 0 } // default
});
var ractive = new Ractive({
el: 'main',
template: '#template',
data: {
comments: [
{
author: 'alice',
content: 'FIRST!'
},
{
author: 'bob',
content: 'first!!1!',
children: [
{
author: 'bob',
content: 'argh alice beat me',
children: [
{
author: 'alice',
content: 'haha'
},
{
author: 'charles',
content: 'you snooze you lose'
}
]
}
]
},
{
author: 'larry_34xj',
content: 'Thank you for this article, it is very interesting. Please visit my blog at http://pills4u.com'
},
{
author: 'dawn',
content: 'This article is terrible. I don\'t know where to begin',
children: [
{
author: 'bob',
content: 'do you have nothing better to do than write snarky comments on blog posts?',
children: [
{
author: 'dawn',
content: 'Do you have nothing better to do than write "first"? loser',
children: [
{
author: 'bob',
content: 'touché'
},
{
author: 'alice',
content: 'haha pwned'
}
]
}
]
}
]
}
]
}
});
body { font-family: 'Helvetica Neue', arial, sans-serif; font-weight: 200; color: #353535; } h1 { font-weight: 200; } p { margin: 0.5em 0; }
.comment {
padding: 0.5em;
border-top: 1px solid #eee;
}
.comment .comment {
padding-left: 2em;
}
.depth-1 {
color: #555;
}
.depth-2 {
color: #999;
}
<script src="http://cdn.ractivejs.org/latest/ractive.js"></script>
<main></main>
<script id='template' type='text/ractive'>
<h1><a href='http://ifyoulikeitsomuchwhydontyougolivethere.com/' target='_blank'>spEak You're bRanes</a></h1>
{{#each comments}}
<comment comment='{{this}}'/>
{{/each}}
</script>
<script id='comment' type='text/ractive'>
<article class='comment depth-{{depth}}'>
<p><strong>{{comment.author}}</strong> wrote:</p>
<p>{{comment.content}}</p>
{{#each comment.children}}
<comment comment='{{this}}' depth='{{depth + 1}}'/>
{{/each}}
</article>
</script>
I have this CSS class:
.relationshipsTree
{
display: inline;
font-size: 10pt;
text-decoration: none;
/*cursor: hand;*/
overflow: hidden;
overflow-x: hidden;
overflow-y: hidden;
filter: none;
font-weight: bold;
color: green;
background-color: transparent;
}
And I want to use it on the parent nodes of this Kendo Tree View:
<div id="relationshipsTree"></div>
How do I go about doing this?
EDIT -
This is the .js file I'm using to create the tree. I added:
$('#relationshipsTree').parent().addClass('relationshipsTree');
Based on an answer here, however, it is still not working.
Whole file:
function CreateRelationshipsTree()
{
var primaryContactId = 671;
var personOrCompany = 'C';
var rootMemberId = 0;
var data = new kendo.data.HierarchicalDataSource({
transport: {
read: {
url: "../api/relationships?primaryContactId=" + primaryContactId + "&personOrCompany=" + personOrCompany + "&rootMemberId=" + rootMemberId,
contentType: "application/json"
}
},
schema: {
model: {
hasChildren: "hasChildren",
children: "Items"
}
}
});
$("#relationshipsTree").kendoTreeView({
dataSource: data,
loadOnDemand: true,
dataUrlField: "LinksTo",
dataTextField: ["Name", "Name"],
select: treeviewSelect
});
function treeviewSelect(e) {
var node = this.dataItem(e.node);
window.open(node.NotificationLink, "_self");
}
$('#relationshipsTree').parent().addClass('relationshipsTree');
}
function RefreshProjectTree() {
var treeView = $("#relationshipsTree").data("kendoTreeView");
treeView.dataSource.read();
}
Updated
I found that I have misunderstood your question. I think you want to select the DOM parent element while you want to select the parent node in the tree view. This is my updated answer.
Midify your handler a bit:
function treeviewSelect(e) {
$('#relationshipsTree div').removeClass('relationshipsTree');
$(e.node).parents('li').first().children('div').addClass('relationshipsTree');
var node = this.dataItem(e.node);
window.open(node.NotificationLink, "_self");
}
A demo updated here
YOu can use jquery to target the parent of an element.
$('#youselector').parent().css({
display:'inline',
font-size:'10pt',
text-decoration:'none',
overflow:'hidden',
overflow-x:'hidden',
overflow-y:'hidden',
filter:'none',
font-weight:'bold',
color:'green',
background-color:'transparent',
});
How can I integrate ASP.NET MVC unobtrusive validation and Twitter Bootstrap? I want to have all those validation messages and styles appropriately.
A nice way of handling this if you're using Bootstrap 2 is...
Add this to your _Layout.cshtml:
<script type="text/javascript">
jQuery.validator.setDefaults({
highlight: function (element, errorClass, validClass) {
if (element.type === 'radio') {
this.findByName(element.name).addClass(errorClass).removeClass(validClass);
} else {
$(element).addClass(errorClass).removeClass(validClass);
$(element).closest('.control-group').removeClass('success').addClass('error');
}
},
unhighlight: function (element, errorClass, validClass) {
if (element.type === 'radio') {
this.findByName(element.name).removeClass(errorClass).addClass(validClass);
} else {
$(element).removeClass(errorClass).addClass(validClass);
$(element).closest('.control-group').removeClass('error').addClass('success');
}
}
});
$(function () {
$("span.field-validation-valid, span.field-validation-error").addClass('help-inline');
$("div.control-group").has("span.field-validation-error").addClass('error');
$("div.validation-summary-errors").has("li:visible").addClass("alert alert-block alert-error");
});
</script>
These are the posts where I found the code pieces above:
Integrating Bootstrap Error styling with MVC’s Unobtrusive Error Validation
Twitter Bootstrap validation styles with ASP.NET MVC
MVC Twitter Bootstrap unobtrusive error handling
UPDATE
Right now I needed to do the same when using Bootstrap 3. Here's the modifications necessary since the class names changed:
<script type="text/javascript">
jQuery.validator.setDefaults({
highlight: function (element, errorClass, validClass)
{
if (element.type === 'radio')
{
this.findByName(element.name).addClass(errorClass).removeClass(validClass);
} else
{
$(element).addClass(errorClass).removeClass(validClass);
$(element).closest('.form-group').removeClass('has-success').addClass('has-error');
}
},
unhighlight: function (element, errorClass, validClass)
{
if (element.type === 'radio')
{
this.findByName(element.name).removeClass(errorClass).addClass(validClass);
} else
{
$(element).removeClass(errorClass).addClass(validClass);
$(element).closest('.form-group').removeClass('has-error').addClass('has-success');
}
}
});
$(function () {
$("span.field-validation-valid, span.field-validation-error").addClass('help-block');
$("div.form-group").has("span.field-validation-error").addClass('has-error');
$("div.validation-summary-errors").has("li:visible").addClass("alert alert-block alert-danger");
});
</script>
Copy the css of the validators in your css file and change the color accordinlgly.
Something like this should do
.field-validation-error {
color: #b94a48;
display: inline-block;
*display: inline;
padding-left: 5px;
vertical-align: middle;
*zoom: 1;
}
.field-validation-valid {
display: none;
}
.input-validation-error {
/*
border: 1px solid #ff0000;
background-color: #ffeeee;
*/
color: #b94a48;
border-color: #b94a48;
}
.input-validation-error:focus {
border-color: #953b39;
-webkit-box-shadow: 0 0 6px #d59392;
-moz-box-shadow: 0 0 6px #d59392;
box-shadow: 0 0 6px #d59392;
}
.validation-summary-errors {
/*font-weight: bold;*/
color: #b94a48;
}
.validation-summary-valid {
display: none;
}
I suggest to include Bootstrapper in less format and do the same thing as Iridio suggested but in .less.
That way you could have something like:
.validation-summary-errors
{
.alert();
.alert-error();
}
.field-validation-error
{
.label();
.label-important();
}
so when bootstrapper will change you'll pick up the changes automatically.
Regular styles that handle visibility from MVC default Site.css will stay in place and handle visibility.
Why not just use css !important and call it a day:
/* Styles for validation helpers
-----------------------------------------------------------*/
.field-validation-error {
color: #f00 !important;
}
.field-validation-valid {
display: none;
}
.input-validation-error {
border: 1px solid #f00 !important;
background-color: #fee !important;
}
.validation-summary-errors {
font-weight: bold;
color: #f00;
}
.validation-summary-valid {
display: none;
}
On Bootstrap 3 you have to add:
.validation-summary-errors
{
.alert();
.alert-danger();
}
.field-validation-error
{
.label();
.label-danger();
}
you'll see something like that:
For the ValidationSummary, you can use the overload that allows you to specify htmlAttributes. This allows you to set it to use the Twitter Bootstrap alert css styles.
#Html.ValidationSummary(string.Empty, new { #class = "alert alert-danger" })
A similar overload exists for the ValidationMessage and ValidationMessageFor helper methods.
You can integrate MVC3 validation with Bootstrap framework by adding the following javascript to your page (View)
<script>
$(document).ready(function () {
/* Bootstrap Fix */
$.validator.setDefaults({
highlight: function (element) {
$(element).closest("div.control-group").addClass("error");
},
unhighlight: function (element) {
$(element).closest("div.control-group").removeClass("error");
}
});
var current_div;
$(".editor-label, .editor-field").each(function () {
var $this = $(this);
if ($this.hasClass("editor-label")) {
current_div = $('<div class="control-group"></div>').insertBefore(this);
}
current_div.append(this);
});
$(".editor-label").each(function () {
$(this).contents().unwrap();
});
$(".editor-field").each(function () {
$(this).addClass("controls");
$(this).removeClass("editor-field");
});
$("label").each(function () {
$(this).addClass("control-label");
});
$("span.field-validation-valid, span.field-validation-error").each(function () {
$(this).addClass("help-inline");
});
$("form").each(function () {
$(this).addClass("form-horizontal");
$(this).find("div.control-group").each(function () {
if ($(this).find("span.field-validation-error").length > 0) {
$(this).addClass("error");
}
});
});
});
</script>
Besides, on the Views (for example "Create.cshtml") make sure that the fields in the form are formatted as the following...
<div class="editor-label">
#Html.LabelFor(Function(model) model.Name)
</div>
<div class="editor-field">
#Html.EditorFor(Function(model) model.Name)
#Html.ValidationMessageFor(Function(model) model.Name)
</div>
For those using Bootstrap 3, the css classes have changed and the solutions above need modifications to work with Bootstrap 3. I have used the following with success with MVC 4 and Bootstrap 3. See this SO thread for more:
$(function () {
// any validation summary items should be encapsulated by a class alert and alert-danger
$('.validation-summary-errors').each(function () {
$(this).addClass('alert');
$(this).addClass('alert-danger');
});
// update validation fields on submission of form
$('form').submit(function () {
if ($(this).valid()) {
$(this).find('div.control-group').each(function () {
if ($(this).find('span.field-validation-error').length == 0) {
$(this).removeClass('has-error');
$(this).addClass('has-success');
}
});
}
else {
$(this).find('div.control-group').each(function () {
if ($(this).find('span.field-validation-error').length > 0) {
$(this).removeClass('has-success');
$(this).addClass('has-error');
}
});
$('.validation-summary-errors').each(function () {
if ($(this).hasClass('alert-danger') == false) {
$(this).addClass('alert');
$(this).addClass('alert-danger');
}
});
}
});
// check each form-group for errors on ready
$('form').each(function () {
$(this).find('div.form-group').each(function () {
if ($(this).find('span.field-validation-error').length > 0) {
$(this).addClass('has-error');
}
});
});
});
var page = function () {
//Update the validator
$.validator.setDefaults({
highlight: function (element) {
$(element).closest(".form-group").addClass("has-error");
$(element).closest(".form-group").removeClass("has-success");
},
unhighlight: function (element) {
$(element).closest(".form-group").removeClass("has-error");
$(element).closest(".form-group").addClass("has-success");
}
});
}();
You can add a few classes to your Site.css file:
/* styles for validation helpers */
.field-validation-error {
color: #b94a48;
}
.field-validation-valid {
display: none;
}
input.input-validation-error {
border: 1px solid #b94a48;
}
select.input-validation-error {
border: 1px solid #b94a48;
}
input[type="checkbox"].input-validation-error {
border: 0 none;
}
.validation-summary-errors {
color: #b94a48;
}
.validation-summary-valid {
display: none;
}
FYI: http://weblogs.asp.net/jdanforth/form-validation-formatting-in-asp-net-mvc-5-and-bootstrap-3
This will convert ValidationSummary() to a boostrap alert. You can include a little script to remove unnecessary classes and give a highlight to fields with problems.
#if (ViewData.ModelState.Any(x => x.Value.Errors.Any())) {
<div class="alert alert-danger">
×
<h4>Validation Errors</h4>
#Html.ValidationSummary()
</div>
}
<script>
$(".validation-summary-errors").removeClass("validation-summary-errors");
$(".input-validation-error").removeClass("input-validation-error").parent().addClass("has-error");
</script>
See more information at http://chadkuehn.com/convert-razor-validation-summary-into-bootstrap-alert/
This is a neat solution that gives you more control over how the ValidationSummary renders errors to the view. The Unordered List it produced did not look right inside the alert. Therefore, I simply looped through the errors and rendered them how I wanted - using paragraphs in this case. For example:
#if (ViewData.ModelState.Any(x => x.Value.Errors.Any()))
{
<div class="alert alert-danger" role="alert">
<a class="close" data-dismiss="alert">×</a>
#foreach (var modelError in Html.ViewData.ModelState.SelectMany(keyValuePair => keyValuePair.Value.Errors))
{
<p>#modelError.ErrorMessage</p>
}
</div>
}
Which results in a neat Validation Summary Alert:
The following worked for me:
$(function () {
// any validation summary items should be encapsulated by a class alert and alert-danger
$('.validation-summary-errors').each(function () {
$(this).addClass('alert');
$(this).addClass('alert-danger');
});
// update validation fields on submission of form
$('form').submit(function () {
if ($(this).valid()) {
$(this).find('div.control-group').each(function () {
if ($(this).find('span.field-validation-error').length == 0) {
$(this).removeClass('has-error');
$(this).addClass('has-success');
}
});
}
else {
$(this).find('div.control-group').each(function () {
if ($(this).find('span.field-validation-error').length > 0) {
$(this).removeClass('has-success');
$(this).addClass('has-error');
}
});
$('.validation-summary-errors').each(function () {
if ($(this).hasClass('alert-danger') == false) {
$(this).addClass('alert');
$(this).addClass('alert-danger');
}
});
}
});
// check each form-group for errors on ready
$('form').each(function () {
$(this).find('div.form-group').each(function () {
if ($(this).find('span.field-validation-error').length > 0) {
$(this).addClass('has-error');
}
});
});
});
var page = function () {
//Update the validator
$.validator.setDefaults({
highlight: function (element) {
$(element).closest(".form-group").addClass("has-error");
$(element).closest(".form-group").removeClass("has-success");
},
unhighlight: function (element) {
$(element).closest(".form-group").removeClass("has-error");
$(element).closest(".form-group").addClass("has-success");
}
});
}();
Taken from http://www.benripley.com/development/javascript/asp-mvc-4-validation-with-bootstrap-3.