Date is not showing up properly in Liferay portlet - liferay

In my portlet I have one form where I am showing dates through following code
JSP:
<aui:input type="text" name="createdDate" size="10" value="" id="createdDate" label="" />
<div class="calendar-icon" id="imageDiv">
<span class="aui-icon aui-icon-calendar"></span>
</div>
Script in JSP
renderCalendar('#imageDiv','#<portlet:namespace/>createdDate','#calendarDiv');
function renderCalendar(imageDiv,inputDisplay,calendarDiv) {
AUI().ready('aui-calendar', function(A) {
var inputField1 = A.one(imageDiv);
var inputField2 = A.one(inputDisplay);
var calendar1 = new A.Calendar({
dates: [ new Date() ],
dateFormat: '%d/%m/%Y',
selectMultipleDates: false,
after: {
datesChange: function(event) {
var formatted = event.target.getFormattedSelectedDates();
inputField2.val(formatted);
calendar1.toggle(); // hide after a date was selected
}
}
}).render(calendarDiv);
var boundingBoxCal1 = calendar1.get('boundingBox');
boundingBoxCal1.setX(inputField1.getX());
boundingBoxCal1.setY(inputField1.getY() + 25);
calendar1.hide();
inputField1.on('click', function() { calendar1.toggle(); });
});
}
It is showing date on page but the problem is with layout Date text field and calender icon both not coming in same line.Please help me out

use <span> instead of <div>. <div> opens a new block while <span> will remain in the same line

Strange that <span> didn't fix your problem. Try floating your <div> to the left, as in,
<div class="calendar-icon" id="imageDiv" style="float: left;">

Related

Knockout two way binding not working with Sharepoint modal dialog

I'm trying two way binding (knockout observables) with sharepoint modal dialog
var ViewModel = function () {
var self = this;
self.firstName = "Irfanullah";
self.lastName = ko.observable('M.');
self.fullName = ko.computed(function () {
return self.firstName + ' ' + self.lastName();
});
};
ko.applyBindings(new ViewModel());
<button type=button onclick="openDialog2()">click me</button>
<div id="wrap" style="display:none">
<div id="d10" class="dialogHolder">
<div id="kobasic">
<h4>Editable data</h4>
<p><input type="text" data-bind="value: firstName" /></p>
<p><input type="text" data-bind="value: lastName" /></p>
<p>Full Name: <span data-bind="text: fullName"></span></p>
</div>
</div>
When i test this code on sharepoint wiki page its working good, but when i use same code on sharepoint dialog it shows values (one way binding)but two way binding/ko.observable() does not work (when i type something in lastname text box it does not update fullname)
function openDialog2() {
var e = document.getElementById('d10');
var options = {
title: "Test Knockout",
width: 700,
height: 800,
html: e.cloneNode(true)
};
mydialog = SP.UI.ModalDialog.showModalDialog(options);
}
I believe that is alll becase e.cloneNode(true) but i could not figureout alternat solution
For SharePoint dialogs I am using this approach:
(note: jQuery needed)
// create dom element
var element = document.createElement('div');
// apply my custom view
$(element).append('<!--my HTML -->');
// apply knockout bindings
ko.applyBindings(myViewModel, element);
// show sharepoint modal dialog
var options = {
allowMaximize: false,
html: element,
title: "My title",
autoSize: true,
showClose: true,
dialogReturnValueCallback: myCallback
};
SP.UI.ModalDialog.showModalDialog(options);
So in your case:
var element = document.createElement('div');
$(element).append('<div id="d10" class="dialogHolder"><div id="kobasic"><h4>Editable data</h4><p><input type="text" data-bind="value: firstName" /></p><p><input type="text" data-bind="value: lastName" /></p><p>Full Name: <span data-bind="text: fullName"></span></p></div></div>');
ko.applyBindings(new ViewModel(), element);
var options = {
allowMaximize: false,
html: element,
title: "My title",
autoSize: true,
showClose: true,
dialogReturnValueCallback: myCallback
};
SP.UI.ModalDialog.showModalDialog(options);

Computed variable is undefined after button click

Full code: https://github.com/kenpeter/test_vue_simple_audio_2
In Main.vue
I tried to assign new value to this.player.currentTrack, by following this guide.
selectTrack: function selectTrack(id) {
this.player.currentTrack = Object.assign(
{},
this.player.currentTrack,
{ currentTrack: id },
);
this.player.elapsed = Object.assign(
{},
this.player.elapsed,
{ elapsed: 0 },
);
// this.play();
},
It seems no error, until I click the button
Error: Cannot read property 'duration' of undefined
In Main.vue, currentTrack.duration
<div class="player__timer">
<div class="player__timer__elapsed" v-text="player.elapsed"></div>
<div class="player__timer__total" v-text="currentTrack.duration"></div>
</div>
<div class="slider player__progress-bar">
<input type="range" :value="player.elapsed" :max="currentTrack.duration" />
</div>
From the image, you can see that there is a value: 274, which is the value of currentTrack.duration initially. After I click the button, currentTrack becomes undefined. currentTrack is a computed value.
You used currentTrack.duration instead of player.currentTrack.duration, try this:
<div class="player__timer">
<div class="player__timer__elapsed" v-text="player.elapsed"></div>
<div class="player__timer__total" v-text="player.currentTrack.duration"></div>
</div>
<div class="slider player__progress-bar">
<input type="range" :value="player.elapsed" :max="player.currentTrack.duration" />
</div>
this is the correct way to do object.assign. My method above is wrong.
let player = {
currentTrack: 0,
other: ""
};
console.log(player);
player = Object.assign(
{},
player,
{ currentTrack: 2}
);
console.log(player);

Cannot use $(this) in $.getJSON in .each

Im building a custom Minecraft Server Status and hit a problem. The first version of this was successful but the code was rather long and I decided to make it better and shorter. The script is supposed to fill the elements of each .server but it doesn't work.
<div class="server_status">
<div class="container servers_info">
<h1>My Network</h1>
<div id="of the server" class="server" title="of the server" server-ip="0.0.0.0">
<div class="name"></div>
<div class="count"><i class="fa fa-spinner fa-spin"></i></div>
<div class="players">Loading player data <i class="fa fa-spinner fa-spin"></i></div>
<div class="status"></div>
</div>
<div id="of the server" class="server" title="of the server" server-ip="0.0.0.0">
<div class="name"></div>
<div class="count"><i class="fa fa-spinner fa-spin"></i></div>
<div class="players">Loading player data <i class="fa fa-spinner fa-spin"></i></div>
<div class="status"></div>
</div>
<!-- ..... more servers -->
<span class="total"><i class="fa fa-spinner fa-spin"></i></span>
</div>
$(document).ready(function ping() {
$( ".servers_info .server" ).each( function() {
var name = $(this).attr( "title" );
var ip = $(this).attr( "server-ip" );
var id = $(this).attr( "id" );
var total = 0;
var call = "Get Avatar List adress";
//Set the name:
$(".name",this).html(name);
//Gets the data:
$.getJSON("http://mcapi.ca/v2/query/info/?ip=" + ip, function (json) {
//Checks The status and applies visual effects:
if (json.status !== "false") {
$(".status",this).html("<span class=\"l-online\">" + json.ping + " ms</span>");
$(this).removeClass('blur');
} else {
$(".status",this).html("<span class=\"l-offline\">0 ms</span>");
$(this).addClass('blur');
};
});
});
//Sets Refresh rate of 10s
setTimeout(ping, 10000);
});
I narrowed down the problem to the $.getJSON part. The data is retrieved correctly but cannot be placed in its respective DIVs. The only difference with the first version of the script is that I used 4 getJSON separately for each of the servers I wanted to display. Now using .each to combine it for all 4 of them and also $(this) to use relative objects.
I suspect the problem is in th usage of $(this) in .get but I'm nnot sure and don't know how to fix it.
As you suspect, the issue is the $(this). part. Inside the $.getJSON callback this no longer refers to the DOM object that triggered the event.
To fix this you can either:
Add a .bind(this) to the callback function. No changes required inside the function itself.
$.getJSON(url, function(json) {
/* all your code here */
}.bind(this)
);
Or save the reference to this before $.getJSON and use it inside the callback.
var _this = this;
$.getJSON(url, function(json) {
/* replace all references of this to _this for example*/
$(_this).removeClass('blur');
});
Hope that helps

Kendo UI Core Listview Edit Template with Autocomplete TextBox(Kendo Autocomplete)

How to use the Kendo UI Autocomplete textbox inside the Listview Edit Template??While trying to apply the autocomplete option the text box not taking it.The requirement also includes a server side filtering option.This needs to be implemented in an ASP.NET MVC5 Web Application.
I am working on Kendo UI for Jquery and I have implemented something similar. Idea behind the implementation is that you have to add the autocomplete when you are editing the ListView.
I am sharing the "Edit Template" and "ListView JS" below.
I found the idea here http://jsfiddle.net/F4NvL/
<script type="text/x-kendo-tmpl" id="editTemplate">
<div class="product-view k-widget">
<dl>
<dt>Product Name</dt>
<dd>
<label for="PAPC">Project Code<span class="k-icon k-i-star requiredstar" data-toggle="tooltip" title="Required"></span></label>
<input type="text" required name="PAPC" validationMessage="Hotel is required" data-bind="value: ProjectCode" />
<span class="k-invalid-msg" data-for="PAPC"></span>
</dd>
</dl>
<div class="edit-buttons">
<a class="k-button k-update-button" href="\\#"><span class="k-icon k-i-check"></span></a>
<a class="k-button k-cancel-button" href="\\#"><span class="k-icon k-i-cancel"></span></a>
</div>
</div>
var listView = $("#lvPA").kendoListView({
dataSource: datasrc,
template: kendo.template($("#template").html()),
editTemplate: kendo.template($("#editTemplate").html()),
edit: function (e) {
var model = e.model;
var item = $(e.item[0]);
var projectcode = item.find('[name="PAPC"]'); //Get your element
//Add a autocomplete here
projectcode.kendoAutoComplete({
valueTemplate: '<span>#:data.ProjectCode#</span>',
template: projectTemplate,
minLength: 3,
autoWidth: true,
dataTextField: "ProjectCode",
dataSource: new kendo.data.DataSource({
type: "GET",
serverFiltering: true,
transport: {
read: ProjectAPI,
parameterMap: function (data, type) {
return { filter: $('[name="PAPC"]').val() };
}
},
}),
height: 200
});
}
}).data("kendoListView");

How to work with dynamically loaded elements in YUI

I'm currently trying to integrate spring mvc app using YUI3. I was able to call Spring Controller with static href in jsp through YUI, but script is not getting invoked when trying to invoke dynamically generated href.
<script src="http://yui.yahooapis.com/3.14.1/build/yui/yui-min.js"></script>
<script>
YUI().use('io-form', 'json','datatable','node','tabview',function(Y) {
Y.all('#nav a').on('click', function (ev) {
ev.preventDefault();
//main.load(ev.target.get('href'), '#content');
var href = ev.target.get('href');
var url = href.substring(0,href.indexOf('#'));
var idw = href.substring(href.indexOf('#')+1,href.length);
Y.io(url, {
method: 'GET',
on: {
complete: function(id, response) {
answer = Y.JSON.parse(response.responseText);
Y.log(answer);
var main = Y.one('#'+idw);
var node = main.all('li');
if(node.size()===0){
Y.Object.each(answer, function(item, index){
main.append("<li id='"+item+"' class='api-list-item class'><a href='/YUI-2-Spring/getContactDetails/"+item+".html#"+item+"'>"+item+"</a></li>");
});
}
}
}
});
});
//To call controller on clickin of dynamic links
Y.all('#api-Types a').on('click', function (ev) {
ev.preventDefault();
//main.load(ev.target.get('href'), '#content');
var href = ev.target.get('href');
var neturl = href.substring(0,href.indexOf('#'));
var studId= href.substring(href.indexOf('#')+1,href.length);
Y.io(neturl, {
method: 'GET',
on: {
complete: function(id, response) {
answer = Y.JSON.parse(response.responseText);
Y.log(answer);
var main = Y.one('#api-everything');
var node = main.all('li');
if(node.size()===0){
Y.Object.each(answer, function(item, index){
main.append("<li id='"+item+"' class='module-class'><a href='/YUI-2-Spring/getPersonalDetails/"+item+"/"+contId+"'</a>"+item+"</li>");
});
}
}
}
});
});
});
</script>
The first script I'm using for calling controller on tabview selection .Based on that I'm creating a list of String with href inside <ul id="api-Types" class="apis modules"></ul> field. In the next script, I'm trying to invoke the generated links, but script is not getting executed.
<div class="yui3-u-1-4">
<div id="docs-sidebar" class="sidebar apidocs">
<div id="api-list">
<h2 class="off-left">APIs</h2>
<div id="api-tabview" class="yui3-tabview-content">
<ul id="nav" class="tabs">
<li class="yui3-tab yui3-widget yui3-tab-selected">Elements</li>
<li class="yui3-tab yui3-widget">Contact Details</li>
<li class="yui3-tab yui3-widget">All</li>
</ul>
<div id="yui3-tabview-panel">
<ul id="api-elements" class="apis classes">
<input type="search" id="api-filter" placeholder="Type to filter APIs">
</ul>
<ul id="api-Types" class="apis modules">
<input type="search" id="api-filter" placeholder="Type to filter APIs"></ul>
<ul id="api-everything" class="apis search">
<input type="search" id="api-filter" placeholder="Type to filter APIs">
<li class="message">
Begin typing in the search box above to see results.
</li>
</ul>
</div>
</div>
</div>
This is the dynamic list that got generated got from viewsource:
<ul id="api-Types" class="apis modules yui3-tab-panel yui3-tab-panel-selected" role="tabpanel" aria-labelledby="yui_3_14_1_1_1389513296688_62">
<input type="search" id="api-filter" placeholder="Type to filter APIs"><li class="api-list-item class">ABC</li><li id="BCD" class="api-list-item class">BCD</li><li id="CDE" class="api-list-item class">CDE</li><li id="DEF" class="api-list-item class">DEF</li><li id="EFG" class="api-list-item class">EFG</li><li id="FGH" class="api-list-item class">FGH</li></ul>
When I'm clicking on the links, instead of invoking the script, my controller is getting invoked through Dispatcher servlet.
Any help will be appreciated.
To bind events on dynamically added element on DOM you should use 'delegate' to bind event instead of 'on'. It will work.

Resources