Dynamically replacing DIV's inner text in GWT - gwt

I'm looking for the possibilities that GWT, SmartGWT, offers in terms of dynamically changing the inner HTML text of an element.
Let go though an example :
I have some lorem ipsum text in a DIV element as it follows :
<div id="text">
Lorem <span style="background-color:red">ipsum </span>
dolor sit amet, consectetur adipiscing elit.
Duis convallis iaculis
<span style="background-color:red">ipsum </span>
magna sagittis vel. Lorem
<span style="background-color:red">ipsum </span> dolor sit amet.
</div>
Desired functionality :
I want the user to be allowed to decide at runtime what text is "marked" (red colored). This impact in two things :
Being able to remove an span element, thus replacing
<span style="background-color:red">ipsum </span>
by
ipsum
Being able to add an span element (by doing the opposite)
Once the user has selected the text he wants to "mark", I use something like
RootPanel.get("text").getElement().
setInnerHTML("html content with some new spans tags");
to update the HTML code with the new selection (to achieve that I have some GWT classed that keeps track of the marked text).
This seems to be a little brutal for me because I'm in a situation that I often update the inner HTML code.
Is there any way using GWT (working closely with the DOM) or SmartGWT, to achieve that in a less violent way ?

To access the DOM of your page you can call Document.get(), which has a convenience method for finding an element by it's id Document.get().getElementById("test");
Of course, you should keep a reference to this element so as not to have to search through the DOM everytime you want to access it, because this is brutal.
private Element testDiv = Document.get().getElementById("test");
...
testDiv.setInnerHTML("Some html");
...
testDiv.setInnerHTML("Some other html");
But once you have a reference to this element, calling setInnerHTML is the most efficient way to do what you want. I'm not sure why you think this is brutal. This is probably even more efficient than when you call a method on a widget to change it's content, like setText(" ...") on a TextBox for example, because these methods usually check the value passed as parameter for security.
Security could also be a concern for you, depending on what the user can do. But usually if a user can modify the HTML in your page that's a concern. You might want to look at GWT's SafeHTML feature.
If you're looking for RichText components, you can look at GWT's RichTextArea for example. But this type of component is usually not well supported by all browsers and will take more resources than what you're doing already so I don't recommend it.

Related

Conditional processing within a Sightly/HTL component dependent upon position within a page

I've recently begun as an Ops dev on an AEM project, and we have a component (a table, that has a title, some copy and a field where the author can author some HTML to represent the contents of a table, with and elements. This, for whatever reason, has to sit within a component, called ArticleContainer. The title should have an H1 tag if the table is at the top of the page, and an H2 tag if it's anywhere lower down. I've tried using data-sly-test thus:
<sly data-sly-test.topOfPage="${table.firstPosition==true}">
<h1 data-sly-test="${table.headerCopy}" class="heading fontH2 headingLinear headingThick">
<span class="tableHeadingWrapper">${table.headerCopy # context='html'}</span>
</h1>
</sly>
<sly data-sly-test="${!topOfPage}">
<h2 data-sly-test="${table.headerCopy}" class="heading fontH2 headingLinear headingThick">
<span class="tableHeadingWrapper">${table.headerCopy # context='html'}</span>
</h2>
</sly>
Now, this kind of processing has worked elsewhere where the component doesn't sit within a container, but it seems that if it's in a container it always picks up the non-topOfPage condition. I assume there might be a way to maybe do the test within the container component & pass it down into the table component? How would one go about this, or if it's not possible, is there another method by which one might achieve this?
There are two things here:
What does table.firstPosition return? You should be able to debug this in your Sling Model or POJO and probably need to adjust the logic to account for intermediary containers.
HTL/Sightly has a data-sly-element that allows you to change the HTML element based on an expression, you could make your code shorter (and easier to maintain):
<h1 data-sly-test="${table.headerCopy}" data-sly-element="${table.firstPosition ? 'h1' : 'h2'}" class="heading fontH2 headingLinear headingThick">
<span class="tableHeadingWrapper">${table.headerCopy # context='html'}</span>
</h1>

Remove autogenerated HTML in typo3

Trying to get into typo3; unfortunately the docs aren't really helpful for me. After creating a backend-layout I am trying to output multiple columns.
Right now I'm getting the following output:
<div id="c23" class="frame frame-default frame-type-text frame-layout-0">
<a id="c30"></a>
<header>
<h2 class="">Title</h2>
</header>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed …</p>
</div>
I'd like to have the output without any extra elements, like this:
<h2>Title</h2>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed …</p>
What is the correct way to get the "correct" output in typoscript?
Such HTML attributes comming from EXT:fluid_styled_content (/typo3/sysext/fluid_styled_content/Resources/Private/Layouts/Default.html).
To adapt this and all other files, you should make a copy of folders Templates, Partials, Layouts from /typo3/sysext/fluid_styled_content/Resources/Private, define them via typoscript constants as new paths:
styles.templates {
templateRootPath = [PATH/TO/YOUR/FOLDER/Templates]
partialRootPath = [PATH/TO/YOUR/FOLDER/Partials]
layoutRootPath = [PATH/TO/YOUR/FOLDER/Layouts]
}
and adpat them for your needs, especially /PATH/TO/YOUR/FOLDER/Layouts/Default.html
This is best done in a recommended own sitepackage. You could use https://sitepackagebuilder.com/new/ to start with.
If is TYPO3 7.6
Yo need to override boostrap-package Layouts/ContentElements/Default.html
because there are created that classes and from that files remove wrapper
div id="c{data.uid}" class="frame frame-type-{data.CType} frame-layout-{data.layout} {sectionClass}"
Only wrapper!
with FSC (fluid_styled_content) all your markup is in fluid-templates, which you can override.
go to your server and copy files from (webroot)/typo3/sysext/fluid_styled_content/Resources/Private/ + Layouts/ and/or Partials/ and/or Templates/.
In typoscript setup you need to define additional pathes to your variants.
Don't copy all files, but copy only those you modify.
In your case you probably need to modify the Layouts/* and Partials/header.

In Tritium, how do I transform all <p> tags to <div> tags?

I’m working in the Moovweb SDK and am optimizing my personal desktop site for mobile.
How do I transform all my <p> tags to <div> tags? I really don't want to do it manually! Search and replace?? haha
You can use the name() function to change the name of an element. For example:
$("//p") {
name("div")
}
See it in action here: http://tester.tritium.io/bd1be4f2c187aed317351688e23f01127d26343a
Cheap way: Add p{margin:0} to your CSS, this will remove the only special styling of <p> tags making them look like <div>s.
This is only a visual effect, though. For instance, you're still not allowed to put a <form> inside a <p>, even with the above CSS. If that's what you're after, a simple search and replace will do:
Replace <p> with <div>
Replace <p␣ (left angle, p, space) with <div␣ (there's a space at the end of that one too)
Replace </p> with </div>
That should do it!

Autofill input type="text" field from an external link

I have a link on one page which looks like this:
http://www.domain.com/sample-link#product_id
and on the other page (sample-link), I have this input field:
<input type="text" name="name" value="name" />
So, when I click the link from the first page, I want to open the "sample-link" page, and autofill the name field with the "product_id" text. Any ideas how can I make this?
Thanks in advance.
You'll just have to add a tiny Javascript snippet:
if (document.location.hash)
document.getElementById('testbox').value = decodeURIComponent(document.location.hash.substr(1));
For obvious reasons you'll have to adjust the id of the text box.
It gets a bit more complicated in case you'd like to pass more than one value.
The call to decodeURIComponent() is optional, but required in case you're passing characters like spaces or non-alphanumerical stuff (just to be sure).

CSS design for large form - Design Advice

I have a large form that consists of all the input (text, checkbox, radio, etc...), I have them grouped together in a fieldset tag and a legend for each feildset. Each input has a label associated with it as well. My question is what is the best approach to display the information on one screen and take advantage of the horizontal real estate the user might or might not have?
I would love it to be all CSS with minimal (if any) table layout(s) as I think tables are for tablature data and not presentation. CSS3 and HTML5 are welcome as well.
Also I would like to have the ability to add branding as this might need to look like another site instead of the original site developed for.
What would be the best approach for this? I have the idea I would use li tags to do the horizontal look but I would like to break to the next line at the end of the screen (Think no scrolling horizontal but vertical is okay)
CSS Novice looking for design pattern advice
This is an example but I think I have around 50 fields
<!DOCTYPE HTML>
<html>
<head>
<title>Large Form</title>
</head>
<body>
<form action="">
<fieldset>
<legend>***</legend>
<label for="fname">First Name</label><br />
<input type="text" name="fname" id="fname" value="" /><br /><br />
<label for="lname">Last Name</label><br />
<input type="text" name="lname" id="lname" value="" /><br /><br />
<label for="gender">Gender</label><br />
<select name="gender" id="gender">
<option value="">-- select</option>
<option value="male">Male</option>
<option value="female">Female</option>
</select>
</fieldset>
<br />
<input type="submit" value="Submit" />
</form>
</body>
</html>
The first thing that comes to mind is that you want to remove the <br/> tags from the form. If you need vertical space, use CSS padding and margins since they're easier to change and make spacing consistent.
With that out of the way, other than branding (which will influence the look and feel of the form the most) the things you want to consider the most are accessibility and ease of use. Your use of labels and unwillingness to use tables for layout are a good start for accessibility so I'm not going to mention it further.
For ease of use, you'll need to make sure that each field can be tabbed to (in an order that makes sense), has a clear, meaningful label, has no unnecessary validation rules (such as forbidding whitespace in a phone number - don't force the user to clean data that can be cleaned automatically) and those validation rules that are necessary have clear, easy to understand messages that appear, ideally, as the user is entering the data rather than waiting for the user to submit the form.
Each of your field sets should be visually grouped either by colour, with a border or some other method. Individual field set should not be broken up, but different field sets can be separate from each other as long as they are contextually different (like address versus interests, for example).
Since you're already grouping field sets, you can use them as your basic unit of page layout. Each set could be floated, for example, in order to maximimize horizontal usage regardless of the user's browser width. As long as the sets are visually distinct enough and are clearly labelled there shouldn't really be any issues with that.
If consistency is more your thing, then each field set should be separated from each other vertically. That would make sure the form is ordered and laid out the same way for every user. Again, the important thing is visual consistency and ease of use. Users are used to forms being laid out vertically so the wasted horizontal space of doing it that way shouldn't be a very big concern.
Just remember: you're making something that should be easy to use and not frustrating. The position of fields should reflect that: they should be natural, grouping like fields together and separating groups of like fields from dissimilar fields. As long as you're keeping that in mind you're probably in good shape.
And don't forget to do some quick usability tests to make sure your validations make sense and are clear.
Have a look at CSS3 grid positioning. It has a clear but powerful syntax, e.g. from the link:
body {
grid-columns: * * (0.5in * *)[2];
grid-rows: 20% *;
columns: 3;
column-gap: 0.5in;
}
Elements use gr units to choose their grid cell:
img {
position: absolute;
left: 2gr;
width: 3gr;
}
You would only have to give an id to your fieldsets then set their position and extents in your style file.
One of my favorite ways to group large forms is with the jQuery style accordion. It allows you to abstract the form into key groupings, keep the form all on one page, and eliminate the need for page scrolling; all with an intuitive user interface.
A good example of this is the Barnes & Noble checkout form process.
Check out CSS Flexbox for some liquid flexibility withing you design sets. I would also recommend picking a "style" and sticking with it. Agree with Welbog.
I guess that if you have a form with 50 fields, you surely have to split it to themed tabs. Say 3 to 5 tabs. They can be implemented by Javascript.
You may want to save input data on-the-fly, because the user may need a long time to finish the form, so there is bigger possibility that he will catch a loss of internet connection or some other factor, that will erase his half-finished form, which would probably dissapoint him and leave your site.
Also consider that user has to have a place for his eye to rest, so be sure to make enough blank room between inputs.