How to remove an element when using gravity forms? - javascript-objects

I'm trying to remove a widget from a form so that I can have the "date picker" in gravity forms be read only. I have already disabled text input for this gravity forms field, but a calendar widget provides a loophole to change the date anyway. This date picker widget may have been created based on a plug in that is installed (the plug-in is necessary for the proper function of the form for our company's purposes).
I'm wondering if there are any problems with my code, if there is another code I can try to remove the widget, or perhaps if this is an issue with gravity forms (if anyone knows the program that well).
I tested the following code in Google Chrome's console and I was able to successfully remove a calendar widget in the date picker:
var element = document.getElementById('ui-datepicker-div');element.parentNode.removeChild(element);
And then in the HTML field, according to gravity form's instructions, I inserted the code I had written between the following code that Gravity Forms Provided:
<script>
function myCustomJs() {
return true;
}
function myCustomJs();
</script>
which produced this as the present code:
<script>
function myCustomJs() {
return true;
var element = document.getElementById('ui-datepicker-div');element.parentNode.removeChild(element);
}
function myCustomJs();
</script>
But unfortunately, when I ran the preview, nothing happened (different than when I ran it in google chrome's developer console).

If your goal is simple to disable the Gravity Forms datepicker for a specific field, I would recommend doing this with PHP.
add_filter( 'gform_field_content_123_4', function( $content ) {
$content = str_replace( 'datepicker', '', $content );
return $content;
} );
Update the 123 in the filter name to your form ID and the 4 to your Date field ID.
FYI, this is handled out-of-the-box with the Gravity Forms Read Only plugin.

Related

How to make quill editor required?

How to make the quill editor field required? The editor gets rendered into a div, but it isn't clear if there is a way to make the field/editor required when the form submits.
As you wrote, Quill works with a div and not with a form element so it can't help you with form validation.
You'll need to check manually if the editor's content is empty, prevent the user from submitting the form and show a message that this field is required.
You can copy quill contents to a hidden input element before submitting the form as shown in this example.
A custom form control is also a good way to go. You can try to workaround with Quill's event handler and getting the value of the form.
Then a custom form validator is also possible.
Check : https://blog.thoughtram.io/angular/2016/07/27/custom-form-controls-in-angular-2.html
I've been trying to work around exactly this problem too today, using Python for back-end and a hidden form-field (name='editor') to get the value from the quill container to the back-end. Ended up with not actually really a validator but working about the same:
if request.form['editor'] == '\"<p><br></p>\"':
flash("You cannot send in empty posts!")
return redirect(CURRENT PAGE)
else:
CODE EXECUTED IF EDITOR IS NOT EMPTY
Not sure what you're doing with the input on the editor or whether you're even using Python for backend but I hope this helps. "<p><br></p>" is what the console told me the standard input on empty submission was when getting the information out of the editor.
Good luck!
const yourText = '<div><br></div>';
const htmlTagsToRemove = ['<div>', '</div>', '<br>'];
function removeHtmlTags(data) {
let text = data;
htmlTagsToRemove.forEach(it => {
text = text.replace(it, '');
});
return text;
}
const newText = removeHtmlTags(yourText);
console.log(newText);

OnsenUI loads page in text, via a splitter

I have previously created a web app, and now I would like to integrate it with OnsenUI to enable my app to be used on all mobile devices as well as the web.
I am using a splitter in a toolbar which will be the header of all pages, and it will redirect the user to other pages when they click an item in it. Clicking the home item successfully redirects to the home page (index, which is already loaded correctly). However, clicking any of the other items in the splitter redirects me to the requested page, but shows the content of the file in text format instead of actually rendering the page. It looks like the following, except it's all jumbled together with no spaces:
searchForTrainer.jade:
//-ons-template(id='searchForTrainer.jade')
ons-page(ng-controller='SearchController' ng-init='showme = false; getAllTrainers();')
ons-toolbar
.left
ons-toolbar-button(ng-click='mySplitter.left.open()')
ons-icon(icon='md-menu')
.center
| Search Trainer
// ***** I cut off the rest of the file for simplicity
// ***** I should still be able to see the toolbar if the page loads correctly
Here is the content of index.jade:
doctype html
html
head
link(rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css')
link(rel='stylesheet', href='/stylesheets/style.css')
link(rel='stylesheet' type='text/css' href='/stylesheets/jquery.datetimepicker.css')
link(rel='stylesheet' type='text/css' href='/stylesheets/ratings.css')
link(rel='stylesheet' type='text/css' href='/stylesheets/searchTrainerTab.css')
link(rel='stylesheet' type='text/css' href='/onsenui/css/onsenui.css')
link(rel='stylesheet' type='text/css' href='/onsenui/css/onsen-css-components.css')
block loadfirst
script(src='https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js')
script(src="https://code.jquery.com/jquery-1.12.3.min.js"
integrity="sha256-aaODHAgvwQW1bFOGXMeX+pC4PZIPsvn2h1sArYOhgXQ=" crossorigin="anonymous")
script(src='/onsenui/js/onsenui.js')
script(src='/onsenui/js/angular-onsenui.js')
script(src='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js')
script(src='/angular/fitnessapp.js')
script(data-require='angular-credit-cards#*', data-semver='3.0.1', src='https://rawgit.com/bendrucker/angular-credit-cards/v3.0.1/release/angular-credit-cards.js')
script(async='', defer='', src='https://maps.googleapis.com/maps/api/js?key=AIzaSyDcVf7YAPNwa8gUsMCOZNQZA31s5Ojf2n8&libraries=places')
body
ons-splitter(var='mySplitter', ng-controller='RootController as splitter')
ons-splitter-side(side='left', width='220px', collapse='', swipeable='')
ons-page
ons-list
ons-list-item(ng-click="splitter.load('index.jade')", tappable='')
| Home
ons-list-item(ng-click="splitter.load('searchForTrainer.jade')", tappable='')
| Search Trainer
ons-list-item(ng-click="splitter.load('searchForEvent.jade')", tappable='')
| Search Event
ons-list-item(ng-click="splitter.load('trainerAddEvent.jade')", tappable='')
| Create Event
ons-list-item(ng-click="splitter.load('userProfile.jade')", tappable='')
| Profile
ons-list-item(ng-click="splitter.load('addPayment.jade')", tappable='')
| Payment
ons-list-item(ng-click="splitter.load('userSettings.jade')", tappable='')
| Settings
ons-list-item(ng-click="splitter.load('trainerSignup.jade')", tappable='')
| Trainer Application
ons-list-item(ng-click="href='/logout'", tappable='')
| Logout
ons-splitter-content(page='index.jade')
ons-template(id='index.jade')
ons-page(ng-controller='MapController' ng-init='getEvents()')
ons-toolbar
.left
ons-toolbar-button(ng-click='mySplitter.left.open()')
ons-icon(icon='md-menu')
.center
| Fitness App
//-.right
a(href='https://www.paypal.com/webapps/mpp/paypal-popup', title='How PayPal Works', onclick="javascript:window.open('https://www.paypal.com/webapps/mpp/paypal-popup','WIPaypal','toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=yes, width=1060, height=700'); return false;")
img(src='https://www.paypalobjects.com/webstatic/mktg/logo/bdg_now_accepting_pp_2line_w.png', border='0', alt='Now Accepting PayPal')
//- google maps stuff
ons-input#pac-input.controls(type='text', placeholder='Search Box')
div#map.col-md-12
ons-bottom-toolbar
.center
| Fitness App
block scripts
script.
// ***** I cut out javascript related to Google Maps for simplicity
here is the splitter load page function I am using in my angular file:
this.load = function(page) { console.log("The page is: " + page);
mySplitter.content.load(page)
.then(function() {
mySplitter.left.close();
});
};
Has anyone successfully built an Onsen app using Jade?
UPDATE
When I leave the code in html instead of jade, everything works correctly. When I convert it back to jade it shows up as text again.
UPDATE 2
Using Solution 1 from the selected answer, I realized and solved my problem with the guidance from the selected answer on my other post:
Answer
By the looks of it you seem to be using Jade on the server side.
To solve the problem I see a couple possible solutions.
Solution 1:
Make sure that whatever Onsen UI is receiving is pure HTML. You're free to use Jade, but as it stands Onsen does not have Jade bundled inside, so there is no way for it to support it out of the box. However as long as Onsen sees only html it should be fine.
The reason why the ons-template(id='index.jade') works initially is actually because when you serve the page you are actually serving actual html, so when onsen starts the contents of that template are actually pure html.
In searchForTrainer.jade it seems that you are giving it raw jade, which it does not know how to handle. You can handle this on the server side, making sure that the request for the searchForTrainer returns html. Returning jade.renderFile('searchForTrainer.jade') from the server instead of the jade file itself should solve the issue.
Solution 2:
As you noticed as long the contents are inside the initial page everything will be fine. So you could just put all your ons-templates inside the initial page.
If you want to retain your current file structure you can just do
include searchForTrainer.jade
while having an ons-template tag in the file itself. That way in the end the result will be a page with the template already converted into html.
Solution 3:
The final option is to give the raw jade files, but help Onsen understand Jade, so that it can use them properly. To do that you need to include jade.js and modify Onsen UI so that it uses it.
However since Onsen does not currently provide an official API for switching template engines whatever hack we use now might break in the future. It's possible that in the near future a feature like that may be implemented, but in order to do it now we need to wrap some of onsen's internal functions.
Here's a simple example to do it.
module.run(function($onsen) {
var old = $onsen.normalizePageHTML;
ons._internal.normalizePageHTML = $onsen.normalizePageHTML = function(html) {
return old(jade.render(html, {}));
};
});
And here's also a working Demo showing this solution in action.
Note: that demo actually checks for a comment // jade at the beginning just to be safe.
Which solution to choose?
Solution 1 - I think this makes most sense as it retains a clear separation of concerns. If you want to change the templating engine it should be handled only in one place. Onsen does not need to know what you're using on the server as long as it gets what it wants.
Solution 2 - Not the best way to solve the problem, but it may be the easiest to use if you just want things to work. One minus is that with it you would load all the templates at the beginning, which may not be very good.
Solution 3 - While this solution can work I would suggest avoiding it as handling jade on the frontend would result in poor performance. It's could be an option if you actually decide not to rely on the server.

Breeze/Angular: date input directive not working/strange behaviour

I'm trying to get this directive (https://github.com/eight04/angular-datetime) to work in my project. It works alright in the following plunk:
http://plnkr.co/edit/DawLbi?p=preview
But when I plug in the same code (below) into my larger scale project, it doesn't work and I have no idea why and where to search.
<input type="text" datetime="dd.MM.yyyy" ng-model="vm.firstDate" class="form-control" data-z-validate />
What happens: The input displays the formatted date correctly, but when I click on the year (or some other component) and try to change it using the number keys (enter a new year), it clears out the whole field (upon entering the first digit)! Using the up/down arrow keys works.
The problem happens only when I use the data-model on a breeze-entity. If I just put a simple js Date object on my controller and link to that one, it works.
I also tried extending my breeze entity like so:
function registerRechnungRec(metadataStore) {
metadataStore.registerEntityTypeCtor(g14EntityNames.rechnung, RechnungRec, postCtorInitializer);
function RechnungRec() {
this.datumExt = moment().toDate(); // doesn't work
}
function postCtorInitializer(rechnung) {
// this works, but not tracked by breeze then
rechnung.datumExtDate = moment(rechnung.datum).toDate();
}
// also no luck with that one:
// http://stackoverflow.com/questions/26982624/angular-and-breeze-edit-date-object
//addDateWrapperPropertyExt(RechnungRec, 'datum', 'datumExtDate');
}
A normal input with type date works just fine for entering/selecting the date. But I need to do some momentjs formatting afterwards to save the date correctly to the database then before I call entityManager.save(). Also, I don't really need the whole date picker component, a simple date input is all we need.
So how do I find out what's going wrong where?
Or is there another suggested date input directive/component, or an easier way to just have a text input field that allows me to input a date (no time) or a null date?

Angular UI datepicker popup with type-in returns one date earlier than typed in protractor

This is a bit complicated, but I've now verified it with both Angular Scenario tester and Protractor, and in the user interface.
Set up Twitter Bootstrap 3.x (I'm using the latest but had 3.0.3 before) - from the bower boostrap install
Set up Angular UI with the built-in templates (I'm using the angular-ui-bootstrap-bower library from Bower)
Set up a datepicker-popup field in Angular-UI like this:
<label for='due_date'>Due Date</label>
<input id='due_date'
class='form-control'
type='text'
datepicker-options="dateOptions"
datepicker-popup='yyyy-MM-dd'
ng-model="task.dueDate">
Add a button and a controller method to inspect the variable.
Testing:
Click on the date field, and type in a date: 2013-01-05
Hit escape or click on another field to close the popup dialog (i.e. don't click Done)
Submit the form
You'll find the date to be one day behind.
Interestingly, if you click on an actual date in the date picker, it will be correct. Including 'today'. If I remove the ui datepicker, it works fine with persisting the typed-in data. My date format is YYYY-MM-DD when I type it in.
This is maddening, as I've thought it was a bug in Angular Scenario, but once I figured out that Protractor ALSO fails, and that I could reproduce it by canceling the dialog, and even typing and submitting, I am beginning to think it has something to do with localization and timezones.
Anyone else run into this?
Here is a protractor test that fails:
it('should return one task', function () {
thePage.clearTasksButton.click();
thePage.newTaskButton.click();
thePage.taskDescription.clear();
thePage.taskDescription.sendKeys('A new task');
thePage.taskPriority.clear();
thePage.taskPriority.sendKeys('1');
thePage.dueDate.clear();
// pick today and dismiss the Angular DatePicker
thePage.todayButton.click();
thePage.createTaskButton.click();
var task = element.all(by.repeater('task in tasks').row(0).column('dueDate'));
task.then(function(elems) {
// should result in one row
expect(elems.length).toEqual(1); // this works
expect(elems[0].getText()).toEqual('2014-03-19'); // this is 2014-03-18
});
...
Thanks
Ken

Load HTML content into Aloha editor

I am using the Aloha editor on my website. I have been able to use it successfully and users can create HTML and save it to my database. However I am having problems in pre-loading HTML content into the editor so that users can edit existing HTML.
Here is the Javascript that initialises the editor:
<script type="text/javascript">
Aloha.ready(function () {
Aloha.jQuery('#richTextEditor').aloha();
Aloha.bind('aloha-smart-content-changed', function (event, editable) {
$(".hiddenTextArea").val(Aloha.getActiveEditable().getContents());
$("#btnSave").click();
});
var obj = "";
Aloha.activeEditable().setContents($(".hiddenTextArea").val(), obj);
});
</script>
I have tried to use Aloha.activeEditable().setContents() as I saw this mentioned on another site but I get an error in my browsers saying
Error: TypeError: Aloha.activeEditable is not a function
Aloha!
It's
/**
* Set the contents of this editable as a HTML string
* #param content as html
* #param return as object or html string
* #return contents of the editable
*/
Aloha.activeEditable.setContents('your html string', true);
not
Aloha.activeEditable().setContents();
Have you seen this example: http://aloha-editor.org/howto-store-data-with-aloha-editor-ajax.php
You don't need to write the content to a textarea. You could also submit it directly via AJAX or just .aloha() the textarea directly if you need the content with other values in a form (attention when using a textarea: if the html id of the textarea is "xy" then the id for the editable within Aloha Editor will be "xy-aloha")
Do you really want the send the form on each 'aloha-smart-content-changed' event? Maybe use 'aloha-editable-deactivated'? 'aloha-smart-content-changed' will not be fired when eg something is formatted bold...
Rene's answer is correct but I discovered there is a second way to pre-fill the Aloha editor with data. You can simply add text to the HTML element that you target the Aloha editor to (in my case #richTextEditor) and then call Aloha.bind() afterwards.

Resources