jquery send action on focus and view lines of text - ajax

ie. we have page with many lines of text
<div class="textline" id=line1>text line or line with image no reason</div>
<div class="textline" id=line2>text line or line with image no reason</div>
<div class="textline" id=line500>text line or line with image no reason</div>
How to get last really visible lineID on the screen of visitor(not on whole page) and send this ID to server with jquery?
1) first time send - when page get focused more then 5 seconds (really viewed), need to send last visible lineID from the screen of visitor.
2) when page scrolled down need to send last visible line (think with some little timeout)
Is it possible with jquery? Any examples?

Grab the last element from a list of .textline elements.
Example:
$(".textline").last();
Or, if you want to select the last element visible on the screen in the viewport, you'll have to do something a lot more complex, like this:
$(".textline").each(function() {
var offset = $(this).offset().top - $(window).scrollTop();
if(offset <= window.innerHeight - $(this).height){
// it's the last visible line, do something with it.
// you can put a call to your server containing the
// line's current text with something like this:
// var curText = $(this).val();
}
}

this selects last .textline:
$('.textline').last().text()

Related

SAPUI5 Panels - Controlling position of content

I have a number of Panels which, when expanded, show the corresponding questions for that particular 'Category'
The issue I have is, say for example I answer the questions for the 1st panel, the content will scroll down, eventually hiding the panel... fair enough.
However, when I click on the Next Category (Production Area), I need to the page to scroll back up to the first question in the Category, or maybe even just display the selected category at the top of the page.
Is this possible?
Currently, the user has to continually scroll back if when they select the next Category.
You can achieve it using scrollToElement()
var oPage = sap.ui.getCore().byId("pageId"); // you page ID
var oList = sap.ui.getCore().byId("ListId"); // element ID to which it has to scroll
if (oPage && oList) oPage.scrollToElement(oList, 1000);
Execute the above code inside the panel event expand.
you can try to use this control instead which suits your needs
https://sapui5.hana.ondemand.com/#/entity/sap.uxap.ObjectPageLayout
After trying everything, this is what worked for me.
onExpand: function (oEvent) {
if (oEvent.getParameters().expand) {
var focusID = oEvent.getParameter("id");
var elmnt = sap.ui.getCore().byId(focusID);
elmnt.getDomRef().scrollIntoView(true);

Extra row atop Kendo Treelist

We have a Kendo TreeList that works fine. Data shows, everything shows in the hierarchy correctly. The problem is, we need to group each two columns into another "superset" group.
The column headings (the names above are not real) are too long if not grouped as shown, and they lose useful context.
I tried adding an HTML table above the TreeList, but that doesn't look right. And it doesn't work if the user resizes the columns. Also the toolbar (for Excel export) is in the way, so it doesn't even look like it's part of the TreeList.
I also looked at wrapping the text in the columns, but from what I've seen, that's really iffy too.
It seems like an extra row as shown above (with the ability to merge some columns, like with an HTML table) is the best way to go. Despite scouring the web, I couldn't find a way to do this. Is this even possible with a Kendo TreeList?
This has been solved. Not by me, but by another developer on our team who's insanely good at JavaScript.
The trick is to edit the TreeList's HTML and CSS through JavaScript. You can bind to any event, but we do it on page load:
<script>
$(document).ready(function () {
// anything in here will get executed when the page is loaded
addTopRowToTreeList();
});
function addTopRowToTreeList() {
// grab the thead section
// your HTML may be different
var foo = $('#MyTreeList').children('div.k-grid-header').children('div.k-grid-header-wrap');
var tableChild = foo.children('table');
var headChild = tableChild.children('thead');
var bottomRow = headChild.children('tr');
var topRow = $('<tr>').attr('role', 'row');
// bottom cell should draw a border on the left
bottomRow.children('th').eq(0).addClass('k-first');
// add blank cell
var myNewCell = $('<th>').addClass('k-header').attr('colspan', '1')
var headerString = '';
var headerText = $('<span>').addClass('k-link').text(headerString);
myNewCell.append(headerText);
topRow.append(myNewCell);
// ... add remaining cells, like above
headChild.prepend(topRow);
}
</script>
That's all there is to it!

How can I stamp text on generated PDF pages?

From your help I have managed to get a very nice PDF generation tool built. It builds a PDF based off of a 5 page template. On the 3rd and 5th page there is a possibility of needing additional pages added and moving the next pages down. The 5th page is landscape even. Everything works perfect except one little additional functionality that I am looking for.
The template that I have built has form fields on the fifth page. Therefore, I use the following code to fill the field:
var pdfReader = new PdfReader(existingFileStream);
var stamper = new PdfStamper(pdfReader, newFileStream);
var form = stamper.AcroFields;
form.SetField("fkClientName", clientName);
The field gets filled just fine, but not on the additional pages. Which is weird because I do call this line:
PdfImportedPage templatePage = stamper.GetImportedPage(pdfReader, 5);
I feel like it should see that there is form fields on that fifth page. However, I read that stamper.GetImportedPage does not retrieve form fields. I don't really care if it's a form field or text. I just need the client name at the top of each generated additional page. Here is what my columntext code looks like that builds the additional pages:
while (true)
{
ct.SetSimpleColumn(-75, 75, PageSize.A4.Height + 25, PageSize.A4.Width - 200);
if (!ColumnText.HasMoreText(ct.Go()))
break;
pageNum++;
stamper.InsertPage(pageNum, new Rectangle(792f, 612f));
stamper.GetOverContent(pageNum).AddTemplate(templatePage, 0, -1f, 1f, 0, 0, PageSize.A4.Width);
ct.Canvas = stamper.GetOverContent(pageNum);
}
If you had company stationery with some kind of background and you wanted to create a document that has flowing text (a column that can flow over to the next page) that also has a repeating header, then I would prefer using PdfWriter.
I'd use PdfWriter to add the content (without using ColumnText, just use the page size and the margins to define the column) and I would add the background and the header using page events. See for instance the Stationery example from my book.
I'd create a subclass for PdfPageEventHelper and I'd load the page you want to see repeated into a PdfImportedPage instance named page:
PdfReader reader = new PdfReader(STATIONERY);
page = writer.getImportedPage(reader, 1);
You may also want to initialize a Phrase with the name of your customer:
header = new Phrase(customerName);
Then you override the onEndPage() method like this:
public void onEndPage(PdfWriter writer, Document document) {
writer.getDirectContentUnder().addTemplate(page, 0, 0);
ColumnText.showTextAligned(writer.getDirectContent(),
Element.ALIGN_RIGHT, header, 36, 806, 0);
}
Now you don't have to worry about ColumnText and new pages. Every time a new page is created, the background and the header will be added automatically.
However, you are using PdfStamper because your original document isn't company stationery: it's a 5 page document. If this document doesn't contain any interactive elements (you've created it using iTextSharp, so you know if it's a flat document or not), I'd still try the PdfWriter approach and change the page instance in the event whenever a new page is needed.
If you want to keep on using PdfStamper, you'll have to add the header in a different way. For instance using a different ColumnText instance, or, if it's a single line, using ColumnText.showTextAligned(). If you don't know the coordinates for the header, you can retrieve the position of the field using the getFieldPositions() method.

jQuery UI Multiselect Widget With Images (Eric Hynds Version)

The excellent dropdown jQuery UI Multiselect widget that supports styling via jQuery UI Themeroller still doesn't have support for including images within the drop down rows.
I didn't see any answers to this problem within Stackoverflow yet it seems to be asked regularly in various areas of the internet, so I am giving the answer to this question below..
(ALSO See my FIDDLE Example to see this in action,)
The following is based on an initial idea by 'pdlove' for introducing the use of images within this excellent UI Multiselect for jQuery.
Adding Image support for line items in check box text area is achieved by setting out the selector option rows html like this:
<option value="somevalue" image="yourimage.jpg" class="multSelktrImg">
normal visible text
</option>
I would also add a class control to your style sheet css file to set the image size being rendered in the option line items of the drop down, along with a couple of position settings for the image, label and span text.
In this example I use the class name 'multSelktrImg', so within the css file it would look something like this:
.multSelktrImg span{position: relative;top: 10px;vertical-align: middle;
display: inline-flex;}
.multSelktrImg input {vertical-align: -2px;}
.multSelktrImg img {position: relative;height: 30px;margin: 2px 6px;top: -10px;}
Now for the change in the src/jquery.multiselect.js file
Search for the following matching code around line 130 (depending on what version id of the script you are using):
// build items
el.find('option').each(function( i ){
var $this = $(this),
parent = this.parentNode,
title = this.innerHTML,
description = this.title,
....
ADD the following line above "title = this.innerHTML,":
image = this.getAttribute("image");
so that it looks like this:
// build items
el.find('option').each(function( i ){
var $this = $(this),
parent = this.parentNode,
image = this.getAttribute("image");
title = this.innerHTML,
description = this.title,
Now Search for the following matching code around line 180:
// add the title and close everything off
html += ' /><span>' + title + '</span></label></li>';
....
Replace the code line with the following to allow for rendering of your images:
// add the title and close everything off
html += ' /><span>';
if (image != null) {
html += '<img src="'+image+'" class="multSelktrImg">';
}
html += title + '</span></label></li>';
save the new version of the script src/jquery.multiselect.js file and now the images will appear in the multiselect drop down. Use the 'multSelktrImg' class value to control the size of the image displayed by altering the pixel size for the class in your css file.
In the FIDDLE version, I have altered the minimized version of the jQuery script, and created an initialisation of the Select object.

wysihtml5-bootstrap cursor changing on submit

I am working with the wysihtml5-bootstrap gem for Ruby and am using it as a live text editor along with Pusher. When I edit text inside one of the text boxes, it updates in the other open views of that save object. However, when my update function is called to save the content that is currently in the box and then update other open views of the text, the cursor moves to the beginning and almost renders the service unusable unless the user clicks after the last word to bring the cursor back to the ending position.
Using the wysihtml5 .html() function to update the view of the text, is it possible to save the cursor position and then have the cursor move to that location after the .html() function runs? I would love to have it so that the cursor does not move or is placed back at the last position after the .html() function runs.
var channel = pusher.subscribe("update");
channel.bind("edit<%= #guide.id%>", function(data) {
// alert('Attempting to set value: ' + data.message);
var wysihtml5Editor = $('#some-textarea').data("wysihtml5").editor;
// console.log(wysihtml5Editor);
$(wysihtml5Editor.composer.element).html(data.message);
console.log("New text is: " + $('#some-textarea').val());
});
Above is the code which listens for a specific event that is triggered with Pusher.

Resources