YUI3 - Autocomplete with local images - yui3

I'm trying to make an input with auto-completion but since I 'm working with emoticons need to show a picture and text on the list of recommendations
<div id="demo" class="yui3-skin-sam">
<input id="ac-input" type="text">
</div>
YUI().use('autocomplete', 'autocomplete-filters', 'autocomplete-highlighters', function (Y) {
Y.one('#ac-input').plug(Y.Plugin.AutoComplete, {
resultFilters : 'phraseMatch',
resultHighlighter: 'phraseMatch',
source : ['Alabama','Alaska','Arizona']
});
});
The output should be something like
thanks !!!

Here is a great example right from the YUI3 Documentation:
http://yuilibrary.com/yui/docs/autocomplete/ac-flickr.html?mock=true
The most important part of this code is the result formatter:
resultFormatter: function (query, results) {
return Y.Array.map(results, function (result) {
return '<div class="result">' +
'<img class="photo" src="' + getImageUrl(result) + '" alt="thumbnail">' +
'<span class="title">' + result.highlighted + '</span>' +
'</div>';
});
}

Haven't done something like that with icons etc. but I would check result formatter first and if it is not "good enough" I would try extending AutoCompleteBase. Example from YUI site:
// HTML template string that will be used for each tweet result.
var tweetTemplate =
'<div class="tweet">' +
'<div class="hd">' +
'<img src="{profile_image_url}" class="photo" ' +
'alt="Profile photo for {from_user}">' +
'</div>' +
'<div class="bd">' +
'<strong class="user">{from_user}</strong>' +
'<span class="tweet-text">{highlighted}</span>' +
'</div>' +
'<div class="ft">{created_at}</div>' +
'</div>';
// Custom formatter for tweets.
function tweetFormatter(query, results) {
// Iterate over the array of tweet result objects and return an
// array of HTML strings.
return Y.Array.map(results, function (result) {
var tweet = result.raw;
// Use string substitution to fill out the tweet template and
// return an HTML string for this result.
return Y.Lang.sub(tweetTemplate, {
created_at : tweet.created_at,
from_user : tweet.from_user,
highlighted : result.highlighted,
profile_image_url: tweet.profile_image_url
});
});
}
// Instantiate AutoComplete using the custom formatter.
Y.one('#ac-input').plug(Y.Plugin.AutoComplete, {
resultFormatter: tweetFormatter,
resultHighlighter: 'phraseMatch',
resultListLocator: 'results',
resultTextLocator: 'text',
source: 'http://search.twitter.com/search.json?q={query}&callback={callback}'
});
Both will take quite a lot of reading and experimenting, but you should be able to modify it to suit your needs...

Related

Render data from DataTables to lowercase

I need to render data returned by dataTables to lowercase. I've search the net but can't find any post on the subject. Convert "ImageName" content to lowercase before displaying. My code is:
{ data: 'ImageName', "sWidth": "20%", render : function (data, type)
{ return '<img src="' + imagepath + '' +data+'" class="WayfinderSignageImage"/>'; }
},

Vue.js 2: Highlight string occurrence

Is there a convenient way to highlight all string occurrences of a string in a text or an element?
Something like the filter method from vue.js 1?
The only problem with my solution is, that the whole v-html-text is now lowercase..
I defined the highlight-method in the methods-block:
methods: {
highlight(words, query) {
if(query === '') { return words }
if(typeof(words) === 'number') {
words = '' + words + ''
}
// when removing the .toLowerCase() your search becomes case-sensitive
return words.toLowerCase().replace(query, '<span style="background: yellow;">' + query + '</span>')
}
}
In my template it looks like this:
<span v-html="highlight('This is some sort of test', 'some')"> // should now highlight 'some'
There are filters in vuejs2 as well. You just create your own method to highlight.
<div>{{ 'some-text' | highlight }}
new Vue({
// ...
filters: {
highlight: function (value) {
// logic
}
}
})

Update the notification counter in mvc 4

I want to sync the notification counter on both sides at a time. The attached image will make you understand easily what i need to do on which I am stuck from quite a few days.
Image:
The Right Side of the notification bell is in Layout:
<div class="header-top">
<h2 style="width:100%">#ViewBag.Heading</h2>
<a class="info sprite" id="lnkInfo"></a>
#{
if(ViewBag.ShowNotification != null && ViewBag.ShowNotification) {
<span class="notifications-icon"><em>#ViewBag.NotificationCount</em></span>
}
}
</div>
The Left Notification Bell is in View.
Code:
<div class="head">
<span class="notifications-icon"><em>#Model.Announcement.Count</em></span>
<h3>Notifications</h3>
</div>
Jquery Ajax Call to Controller Action:
function UpdateNotification(id) {
var json = { "AnnouncementID": id };
$.ajax({
type: 'POST',
url: '#Url.Action("UpdateNotificationData", "Home")',
contentType: 'application/json; charset=utf-8',
data: '{"AnnouncementID":' + id + '}',
dataType: 'json',
cache: false,
success: function (data) {
if (data) {
updatenotificationUI(id);
}
}
})
}
function updatenotificationUI(id) {
var $notificaitonContainer = $(".notifications");
if (id != null) {
var $li = $notificaitonContainer.find("li[id=" + id + "]");
if ($li != null) {
$li.slideUp("slow", function () {
$(this).remove();
var legth = $notificaitonContainer.find("#listing li").length;
if (legth > 0)
$notificaitonContainer.find("em").html(legth);
else
$notificaitonContainer.find("em").html("");
});
}
}
else {
$notificaitonContainer.find("ul").html("");
$notificaitonContainer.find("em").html("");
}
}
Home Controller :
public ActionResult UpdateNotificationData(string AnnouncementID)
{
var announcements = new AnnouncementResponse() { Announcement = new List<Announcement>() };
if (IsUserAuthenticated)
return RedirectToAction("Index", "Account");
announcements = _contentManager.Announcement();
var item = announcements.Announcement.Where(p => p.AnnouncementID == Convert.ToInt32(AnnouncementID)).FirstOrDefault();
announcements.Announcement.Remove(item);
ViewBag.NotificationCount = announcements.Announcement.Count;
return Json(new { success = true });
}
But the Notification Bell in Layout doesnt update with the viewbag value or even when the model is assigned to it.
Please provide a solution for this.
You're only updating one of the two notifications. First you find a containing element:
var $notificaitonContainer = $(".notifications");
The HTML in the question doesn't have any elements which match this, so I can't be more specific. But just based on the naming alone it sounds like you're assuming there's only one such container.
Regardless, you then choose exactly one element to update:
var $li = $notificaitonContainer.find("li[id=" + id + "]");
(This can't be more than one element, since id values need to be unique.)
So... On your page you have two "notification" elements. You're updating one of them. The solution, then, would be to also update the other one. However you identify that elements in the HTML (jQuery has many options for identifying an element or set of elements), your updatenotificationUI function simply needs to update both.

How to form query string?

I am using the grid source code from this website:
http://gridmvc.azurewebsites.net/
but I don't understand how the query string is formed for his custom columns. On the link I have provided there is an edit column, if you hover over the link you can see the hyperlink with the query string ID. I have used this source code but there is no query string for me.
Controller code
#region PartialViews
[ChildActionOnly]
public ActionResult RenderGrid()
{
DataLayer.RepositoryClient RC = new RepositoryClient();
var People = RC.GetPeople();
return PartialView("~/Views/Client/PartialViews/P_PersonGrid.cshtml", People);
}
#endregion
I get a list of people from entity framework. Then I use a list of models in my partial view.
Partial view
#model List<Models.modelPeopleGrid>
#using GridMvc.Html
#{
ViewBag.Title = "Person records";
}
<div>
#Html.Label("Search for person")
<input type="text" onkeyup="activateSearch()" id="txtSearch" style="width:150px";/>
</div>
<div class="grid-wrap" style="float:left">
#Html.Grid(Model).Named("peopleGrid").Columns(columns =>
{
columns.Add(m => m.Firstname).Titled("Firstname").Filterable(true);
columns.Add(m => m.Surname).Titled("Surname").Filterable(true);
columns.Add(m => m.DateOfBirth).Titled("DateOfBirth").Filterable(true);
columns.Add(m => m.Address).Titled("Address").Filterable(true);
columns.Add(m => m.Borough).Titled("Borough").Filterable(true);
columns.Add(m => m.PersonID).Encoded(false).Sanitized(false).SetWidth(30).RenderValueAs(
#<b>
#Html.ActionLink("Edit person details", "EditPerson", "Index")
</b>);
columns.Add()
.Encoded(false)
.Sanitized(false)
.SetWidth(30)
.RenderValueAs(m =>
#<b>
#Html.ActionLink("Add/remove claims", "EditClaim", "Index")
</b>);
}).WithPaging(20)
</div>
<div class="rowValues" style="float:right"></div>
<script>
$(function () {
pageGrids.peopleGrid.onRowSelect(function (e) {
$(".rowValues").html(
"<h4>Full details of person:</h4>" +
"Firstname: " + e.row.Firstname + "<br />" +
"Surname: " + e.row.Surname + "<br />" +
"DateOfBirth: " + e.row.DateOfBirth + "<br />" +
"Address: " + e.row.Address + "<br />" +
"Borough: " + e.row.Borough + "<br />"
);
});
});
</script>
<script type="text/javascript">
function activateSearch() {
var value = $("#txtSearch").val();
$.ajax({
url: "Client/GetPeople",
dataType: 'html',
type: "GET",
data: { Name: value },
success: function (data) {
$('.webgrid').empty().html(data);
},
error: function () {
alert("error");
}
});
}
</script>
I don't know how to get a query string formed for this line of code:
columns.Add(m => m.PersonID).Encoded(false).Sanitized(false).SetWidth(30).RenderValueAs(
#<b>
#Html.ActionLink("Edit person details", "EditPerson", "Index")
</b>);
I tried html object attributes as the fourth parameter of actionlink but I was getting a red swiggly for some reason.
Anyone know how to answer my problem?
As seen in the example on the website you've linked to, the RenderValueAs method takes a lambda expression where the parameter represents the current model for the row.
I tried html object attributes as the fourth parameter of actionlink
but I was getting a red swiggly for some reason.
Usually Razor Intellisense and syntax highlighting in Visual Studio is very buggy. Never trust it. The fact that you are getting red squiggles in a Razor page doesn't mean that you have an error in your syntax. In most cases it means that it is the syntax highlighter that simply doesn't understand the syntax. The only reliable thing is to run your application and see if it works.
So with this in mind you may try:
columns
.Add(m => m.PersonID)
.Encoded(false)
.Sanitized(false)
.SetWidth(30)
.RenderValueAs(m =>
#<b>
#Html.ActionLink(
linkText: "Edit person details",
actionName: "EditPerson",
controllerName: "Index", // <-- Huh, Index looks like an action name, double check that
routeValues: new { id = m.PersonID },
htmlAttributes: null
)
</b>
);
Notice how I have used explicit parameter names to make the code more readable and avoid any ambiguities with the gazzillions of overloads of the ActionLink method that the designers of the framework provided us.

ExtJS 4.1 condition in tooltip

I'm trying to create a condition inside a tooltip template.
I've declared my template like this:
tooltipTpl: new Ext.XTemplate(
'<tpl for=".">',
'<dl class="eventTip">',
'<tpl if="values.getLength() == 1">',
'<dt class="icon-clock">Time</dt><dd>{[Ext.Date.format(values.start, "d-m")]} - {[Ext.Date.format(Ext.Date.add(values.end,Ext.Date.SECOND,-1), "d-m")]}</dd>',
'</tpl>',
'<tpl if="values.getLength() > 1">',
'<dt class="icon-clock">Day</dt><dd>{[Ext.Date.format(values.start, "d-m")]}</dd>',
'</tpl>',
'<dt class="icon-task">Status</dt><dd>{Name}</dd>',
'</dl>',
'</tpl>'
).compile(),
The idea behind is to be able to display 2 dates (start and end) if event is longer than 1 day, if it is one day event just display that date.
I've declared my model as so:
Ext.define('Urlopy.Model.Plan', {
extend : 'Sch.model.Event',
idProperty : 'id',
resourceIdField : 'userID',
startDateField : 'start',
endDateField : 'end',
fields : [{ name : 'id', type : 'int'},
{ name : 'userID', type : 'string'},
{ name : 'start', type : 'date', dateFormat : 'MS'},
{ name : 'end', type : 'date', dateFormat : 'MS'},
{ name : 'Name'}],
getLength : function() {
return Sch.util.Date.getDurationInDays(this.get('start'), this.get('end'));
}
});
The second line of my tooltip is displayed, but line with dates isn't. It looks like I cant call function from my model in my template.
How to fix this? Is it possible?
The answer to the question - if it is possible to run function from the object passed to the template as a data object, yes. The function will be called.
You can run the following short snippet of code inside the any browser console like FireBug
(of course you need to open the console at the page which has extjs, simple open console on the extjs documentation page) to see it.
Code snippet:
var t = new Ext.XTemplate(
'<tpl for=".">',
'\n===',
'<tpl if="values.getLength() == 1"> ONE </tpl>',
'<tpl if="values.getLength() > 1"> TWO </tpl>',
' *{name}* ',
'===',
'</tpl>'
).compile();
var a = [
{name: 'Foo', getLength: function() {return 1;} },
{name: 'Boo'}
];
var s = t.apply(a);
console.log(s);
You will see the following results:
return 1:
=== ONE *Foo* ===
=== *Boo* ===
return > 1:
=== TWO *Foo* ===
=== *Boo* ===
I don't know the context of using this template with the underlying model, you are not provided code applying the model to the template. But I'm pretty sure that to the template is going the model data but not the whole model object, that is why you can see the second line with modal's field {Name}.
To overcome it you can add to the template its own method, like:
//for the simplicity sake I've not pasted the whole template
//also you can call the *this.getLength(values.start, values.end)*
//and change this method parameters
var tooltipTpl = new Ext.XTemplate(
'<tpl for=".">',
// ...
'<tpl if="this.getLength(values) > 1">',
// ...
'</tpl>',
// ...
'</tpl>'
,{
getLength : function(data) {
//move the model method to the template
return Sch.util.Date.getDurationInDays(data.start, data.end);
}
}).compile();
You can use the model's method..
Define the model static method:
Ext.define('Urlopy.Model.Plan', {
//...
static: {
getLength: function(data) {
console.log('data', data);
console.log(data.start, data.end);
return 5; //just test function
}
}
//.....
});
Use it in the template:
'<tpl if="Urlopy.Model.Plan.getLength(values) == 1">'
So you can delete the template's method.