Customise Kendo dropdownlist message to replace "no data found" - javascript

In our .NET Core 3 web app, we're using Kendo with our razor views.
We're using an Html.Kendo().DropDownListFor control which, when it has no data to display, shows the text:
"NO DATA FOUND"
We want to replace this string with a custom message. We know we can replace the string in kendo.all.min.js, but we're aware this would get overwritten once we update Kendo.
How can we specify the text string programatically, within the DropDownListFor control itself?

You can setup and assign a template to use and customize the no data message. I have also added the span with a style to remove the upper case text-transform that Kendo adds. Like so:
<!-- Template -->
<script id="noDataTemplate" type="text/x-kendo-template">
<span style="text-transform: none;">
<strong>My Custom No Data Message here</strong>
</span>
</script>
<!-- DropDownList initialization -->
#(Html.Kendo().DropDownList()
.Name("customers")
.DataTextField("ContactName")
.DataValueField("CustomerID")
.NoDataTemplateId("noDataTemplate") // Reference to the template.
.DataSource(source =>
{
source.Read(read =>
{
read.Action("Template_GetCustomers", "ComboBox");
});
})
)
More information here: https://docs.telerik.com/aspnet-core/html-helpers/editors/dropdownlist/templates#no-data-templates

I suggest you to create a JS file for your project and overwrite any message you want, so you can update kendo without any problem.
Now, to anwser your question, in case of DropDownList you can change the value of the following property like this:
kendo.ui.DropDownList.prototype.options.messages.noData = 'Sorry, no data here';
You can do that with any other widget.

Related

How can I get an HTML tag’s value to send an HTML.Action()

I have these lines of code:
<span
class="close-modal"
onclick="#Html.Action("SaveNotes", "CallCenter", new { activityId = item.callIdKey, noteText = "test1" })">
×
</span>
Notes: <br />
<textarea name="paragraph_text" rows="5" style="width:90%">
#item.NoteText
</textarea>
I would like to replace test1 from the noteText route variable and instead change it to whatever the value in the <textarea> tag is.
Is there an elegant way of doing this without writing a giant block of jQuery code?
#Html.Action() renders a partial view as an HTML string during page processing (on the server side). It doesn't exist any more in the markup, once the page is sent to the browser. You can't do what you are trying to do this way. At the very least, I'm sure you don't want to render a partial view inside the onclick event of your <span> tag.
Why not instead use an HTML helper for the <textarea> tag? Then you can get whatever value the user typed into it on the server code. You'll want to make the form post itself back to the server on the close-modal element:
<span class="close-modal" onclick="$('form').submit()">×</span>
<form method="post" action="#Url.Action("SaveNotes", "CallCenter", new { activityId=item.callIdKey }">
Notes: <br />
#Html.TextArea("noteText", item.NoteText, new { rows="5", style="width:90%" })
</form>
This assumes you have jQuery already (a common assumption with ASP.NET). You may not need the <form> tags if you already have a form on your page.
A #gunr2171 notes in the comments, the only way to dynamically update a link once it's been rendered to the browser is via some form of client-side scripting, typically JavaScript. In your case, I'd recommend doing something like this:
<span
class="close-modal"
data-href-template="#Url.Action("SaveNotes", "CallCenter", new {activityId = item.callIdKey, noteText="{note}"})"
>
×
</span>
Note: As #HBlackorby notes in his answer, you shouldn't be using #Html.Action() here; I assume you meant #Url.Action().
This way, your JavaScript has a template (data-href-template) that it can work against with a clearly defined token ({note}) to replace, instead of needing to parse the URL in order to identify where the previously replaced text is. Otherwise, you potentially end up in a scenario where you type e.g. CallCenter into your <textarea /> and it's now an ambiguous reference that you can't just blindly replace. Or, worse, you type 'a' and it's really ambiguous.
If you are already using jQuery on your site, the actual replacement might be done using something along the lines of:
$(document).ready(function () {
$('span.close-modal').click(function() {
var noteInput = $('textarea[name="paragraph_text"]');
var encodedNote = encodeURI(noteInput.text());
var template = $(this).data("href-template");
var targetUrl = template.replace("{note}", encodedNote);
window.location.href = targetUrl;
});
});
You can also do this without jQuery, obviously—and should if you're not already depending on it. The point is to illustrate that this doesn't necessarily need to be a "giant block of jQuery code". In fact, this could be done in just a few lines—and probably should be. I deliberately broke it out into multiple steps and variables for the sake of readability.

How to render a hyperlink in a component template in Angular 6?

I have an Angular 6 application where a component is used to display a message on the page. Some of the messages contain hyperlinks embedded in them (in HTML markup). However, when the messages are displayed on the page, they are getting displayed in plain text (hyperlinks are not rendered, but the markup is displayed to the user instead).
You can visit Stackblitz # https://stackblitz.com/edit/angular-jj5nms for a sample application that I created to explain the issue.
Expected message display:
Click here.
Actual message display:
Click <a href='http://www.google.com'>here</a>
If you want to render HTML a then you need to bind to the innerHTML property of an element, for example:
<p [innerHTML]=“message | async”></p>
Where message is your observable from the service.
Using handlebars to render message is just rendering plain text, binding to innerHTML and using the async will render your html content
You can use innerHTML
In your component:
linkHtml = "Click <a href='http://www.google.com'>here</a>"
In your template:
<div [innerHTML]="linkHtml"></div>
You can use like that:
in your .ts file :
dummyLinkText: string = "Click <a href='https://www.google.com'>here</a>";
and in your .html file:
<div [innerHTML]="dummyLinkText | translate"></div>

How to add placeholder to text-field in servicenow service portal?

I need to add placeholder to text field in catalog item under service portal on page load, I tried in catalog client script with jquery and angular/document but no success, And found that it's not supported any other alternate soln ?
Catalog Client Script:
function onLoad() {
var elm = angular.element(element.getElementsByClassName("form-control"));
//when I use angular I get this error:
js_includes_sp.jsx?v=08-28-2017_0947&lp=Mon_Aug_28_11_44_06_PDT_2017&c=2_42:63808 (g_env) [SCRIPT:EXEC] Error while running Client Script "Placeholder
Script": TypeError: Cannot read property 'element' of null.
jQuery("#sp_formfield_IO:5cdafd764f02030007b03fb28110c70b").attr("placeholder","hello world");
// if I use jquery or $jq I get below error
(g_env) [SCRIPT:EXEC] Error while running Client Script "Placeholder
Script": TypeError: jQuery is not a function
}
This is how html gets generated in servicenow:
<span ng-switch-default="true" class="ng-scope">
<!-- ngIf: !field.max_length || 256 > field.max_length -->
<input ng-model="field.stagedValue" ng-change="stagedValueChange()"
maxlength="" autocomplete="off" name="IO:5cdafd764f02030007b03fb28110c70b"
id="sp_formfield_IO:5cdafd764f02030007b03fb28110c70b" data-type="string"
placeholder="" ng-if="!field.max_length || 256 > field.max_length"
class="form-control ng-pristine ng-untouched ng-valid ng-scope ng-empty ng-
valid-maxlength" ng-model-options="{allowInvalid: true}" ng-
disabled="field.isReadonly()" aria-invalid="false"><!-- end ngIf:
!field.max_length || 256 > field.max_length --><!-- ngIf: field.max_length
>= 256 --></span>
Ahoy,
The short answer is that there is no accepted way to do this in the Service Portal. This is because DOM manipulation is strictly blocked.
However, the much-much-longer answer is that there is indeed a way to do this in Service Portal. I've written an article about it, which you can find here.
You'll need the CatItemVariables Script Include from that post, which translates catalog variables into sys_ids. Since UI Scripts don't run on the Service Portal (even global ones, last I checked), you'll also need to create a UI Script and set it as a JS Include, which you include as part of the Theme for your Service Portal.
(How to do this is detailed in the post.)
In the UI Script, you'll want to get the cat item variables using a REST request, and that Script Include.
There may also be a simpler way:
Set up the Script Include(s) mentioned in the article.
In an onLoad client script, use the Script Include to get the sys_IDs of all the variables associated with the catalog item by using GlideAjax to call the client-callable Script Include.
Use the this object as the stand-in for window, and remember that document is an element of window:
this.document.getElementsByName('IO:' + itemVars['var_name'])[0];
In the above, itemVars is the variable name that contains the resulting catalog item variable objects, and 'var_name' is the variable name.
It doesn't really do what you're looking for, but you might also consider the "placeholder text" dictionary field on the field's dictionary itself.
If you're looking to just have a placeholder populated for a Variable without the need for it to be set dynamically, you can use the Example Text field in the variable itself.
This will populate as a placeholder in the form

Html not decoded in span is it Knockout.js or Jquery mobile doing things?

I am trying to display warning message that has special character ' (') in span as text on a page that is using Jquery Mobile UI and knockout.js. Text is returned by javascript function and is encoded on .NET side. Problem is it gets interpreted as literal while same exact html in JSfiddle is interpreted like '.
Is it Knockout.js or JQuery Mobile again or am I missing something here?
I have printed out function that returns the value in Chrome Dev tools in screenshot below, and you can see html too.
The problem is that the string you want to append is an HTML entity and it won't be rendered if you append it as text
Thanks to #Origineil for providing the fiddle with knockout that proves the same thing.
<span data-bind="text: data"></span><br/> <!-- ' -->
<span data-bind="html: data"></span> <!-- ' -->
And script
var vm = {
data: ko.observable('3 Optional Activities aren't Done')
};
ko.applyBindings(vm)

Why are edit in place forms rendered together with the display version instead of being rendered on the fly?

Is there a specific reason that most everyone implements edit-in-place as a shown 'display' div and a hidden 'edit' div that are toggled on and off when somebody clicks on the associated 'edit' button like so?
<div id="title">
<div class="display">
<h1>
My Title
</h1>
</div>
<div class="edit">
<input type="text" value="My Title" />
<span class="save_edit_button"></span>
Cancel
</div>
</div>
Everywhere I look, I see edit-in-place basically handled like this. This approach certainly makes sense when you are rendering all views on the server side and delivering them to the client. However, with pure AJAX apps and frameworks like backbone.js, it seems that we could make our code much more DRY by rendering edit-in-place form elements on the fly as necessary, possibly even making a factory method that determines which form element to render. e.g.
an H1 element with class "title" is replaced by <input type="text" />
a span with class "year_founded" is replaced by <input type="number" min="1900" max="2050" />
a span with class "price" is replaced by an input with the appropriate mask to only allow prices to be input.
Is this practice of rendering all edit-in-place form elements a historical legacy leftover from when pages were rendered on the server-side?
Given the flexibility and power we have with client-side MVC frameworks like Backbone.js, is there a reason for not creating and inserting the form elements on the fly when necessary using a factory method? Something like this:
HTML
<div id="description">
Lorem ipsum dolar set amit...
</div>
<span class="edit_button"></span>
Backbone.js View
events: {
"click .edit_button": "renderEditInPlaceForm",
},
renderEditInPlaceForm: function:(e) {
var el = $(e.currentTarget).previous();
var id = el.attr('id');
var value = el.text();
var tagName = el.tagName();
var view = new editInPlaceForm({
id: id,
type: tagName,
value: value
});
$("#id").html(view.render().el)
},
Where editInPlaceForm is a factory that returns the appropriate edit-in-place form element type based on tagName. This factory view also controls all its own logic for saving an edit, canceling an edit, making requests to the server and rerendering the appropriate original element that was replaced with the .html() function?
It seems to me that if we use this approach then we could also render the <span class="edit_button"></span> buttons on the fly based on a user's editing rights like so:
<h1 id="title">
<%= document.get("title") %>
</h1>
<% if (user.allowedToEdit( document, title )) { %>
<span class="edit_glyph"></span>
<% } %>
where the allowedToEdit function on the user model accepts a model and attribute as its arguments.
It's an interesting idea. The devil is in the detail.
While your simple example is easily rendered as an editable form on the fly, things quickly get trickier when dealing with other data types.
For example - suppose my edit form requires the user to choose a value from a select list. On the display form I can simply display the user's choice, but for the edit form I am going to need those other available choices. Where do I hide them on the display? Similar issues exist for checkboxes, radio lists...
So, perhaps we should consider rendering the edit form, and then deriving our display-view from that?
After 5 Backbone apps I came to same thoughts.
When things are complicated you have forms to show relations between user data,
but in simple cases you just need input, select, checkbox over h1, div or span
Now I am searching for jQuery plugin to make simple in place editing without ajax.
jQuery but not Backbone becuase I don't want to be tight coupled with Backbone for such small thing.
Likely to wright my own jQuery + Synapse plugin http://bruth.github.com/synapse/docs/.
Synapse for binding with model and jQuery for input placing

Categories