Parse Markdown into HTML in JavaScript X-Editable field - javascript

I am using the jQuery X-Editable edit-in-place library on a field and the JavaScript Marked Markdown Parser library to try and convert Markdown strings into HTML.
The goal is to show HTL and when it turns into a textarea edit field, to then how the Markdown. The Markdown will be what is saved and loaded from the backend in the live app.
I have setup a JSFiddle demo for this functionality...
http://jsfiddle.net/jasondavis/bfrrzz8h/
If you view the demo and click to edit the Description text and paste in this Markdown string # Marked in browser\n\nRendered by **marked** and click save, it will then alert you the parsed markdown to HTML string. THe problem is it does not update the DOM to show that new HTML string.
Any help in this please?
Marked library - https://github.com/chjj/marked
X-Editable library - https://github.com/vitalets/x-editable/
JavaScript from my demo
$('#task-description-modal').editable({
type: 'textarea', // text|textarea|select|date|checklist
url: '/updatetask',
pk: 123,
toggle: 'click', // click|dblclick|mouseenter|manual
inputclass: 'task_description resizable',
highlight: '#F1FFE7',
mode: 'inline', // inline | popup
placement: 'top',
title: 'Enter Task Description',
validate: function(value) {
if ($.trim(value) === '') {
return 'Task Description is Required';
}
},
params: function(params) {
//Addition params in addition to the default: pk, name, value
return params;
},
success: function(response, newValue) {
if (!response.success) return response.msg;
}
});
$('#task-description-modal').on('save', function(e, params) {
// Parse Description Markdown into HTML
var markdownDescription = marked(params.newValue);
alert(markdownDescription);
$('#task-description-modal').html(markdownDescription);
//$('#task-description-modal').html('test');
});
//ajax emulation. Type "err" to see error message
$.mockjax({
url: '/updatetask',
responseTime: 400,
response: function(settings) {
if(settings.data.value == 'err') {
this.status = 500;
this.responseText = 'Validation error!';
} else {
this.responseText = '';
}
}
});

You're injecting your compiled HTML into the element you're using to get markdown input. This is simply setting yourself up for failure: have two elements, one for markdown text, and one to show the result, and switch between the two.
For instance, the following code already makes things work fine:
HTML:
<div style="margin: 50px">
<span id="task-description-modal">Task Description text</span>
<div id="processed"></div>
</div>
JS:
$('#task-description-modal').on('save', function(e, params) {
var markdownDescription = marked(params.newValue);
$('#processed').html(markdownDescription);
});
You just need to make sure to only show the element you intend to be shown depending on what the user has just done. Hidden #task-description-modal until the user clicks on #processed, at which point you hide #processed and force .focus() on #task-description-modal? Perfect.

Related

Multiple upload inputs using ng2-uploader in Angular

I'm using https://www.npmjs.com/package/ng2-uploader package for file upload in angular, everything works fine for single input. But I want more than one input with different options and urls like this
<input type="file"
ngFileSelect
[options]="options1"
(onUpload)="handleUpload($event)"
(beforeUpload)="beforeUpload($event)">
<input type="file"
ngFileSelect
[options]="options2"
(onUpload)="handleUpload($event)"
(beforeUpload)="beforeUpload($event)">
Configuration for file upload I'm trying to do is
this.options1 = {
url: 'url for first input'
fieldName: 'first input field name',
method: 'PUT'
};
this.options2 = {
url: 'url for second input'
fieldName: 'second input field name',
method: 'PUT'
};
handleUpload(data): void {
if (data && data.response) {
data = JSON.parse(data.response);
this.uploadFile = data;
//code
}
}
fileOverBase(e:any):void {
this.hasBaseDropZoneOver = e;
}
beforeUpload(uploadingFile): void {
if (uploadingFile.size > this.sizeLimit) {
uploadingFile.setAbort();
alert('File is too large');
}
}
This results in always picking up the latter options i.e 'options2' and 'options1' donot have any effect. How do I implement this?
I had similar issue.
And in my case, I had duplicates of input's ids and label's for picked the wrong one.
By the way ng2-uploader was renamed to ngx-uploader. Recently its api changed a lot, but there was versions compatible with ng2-uploader, with some bugs fixed.

Formly input field validation

I am having an issue with validation messages appearing in an application. Here is the application demo:
https://jsfiddle.net/MrPolywhirl/yxrh3ujp/
I have tried adding validation configuration. This is straight out of the docs.
app.run(function(formlyValidationMessages) {
formlyValidationMessages.messages.required = 'to.label + " is required"';
formlyValidationMessages.messages.max = '"The max value allowed is " + to.max';
formlyValidationMessages.messages.min = '"The min value allowed is " + to.min';
formlyValidationMessages.addTemplateOptionValueMessage('pattern', 'patternValidationMessage', '', '', 'Invalid Input');
});
I have set min/max values on my field. The field does get validated correctly, but the message still does not appear.
Neither the pattern/patternValidationMessage nor the validation (config) function are working for the field. They do nothing and even with a valid pattern, the field still shows that it is invalid (highlighted red).
{
key: 'cooldown',
type: 'input',
templateOptions: {
type: 'number',
label: 'Cooldown (in seconds)',
min : 0,
max : 600,
required: true,
//pattern: /^[0-9]+$/,
//patternValidationMessage: '"Needs to match " + options.templateOptions.pattern'
},
defaultValue: 30,
//validation: {
// messages: {
// required: function ($viewValue, $modelValue, scope) {
// return scope.to.label + ' is required';
// }
// }
//},
}
Can I get some pointers as to why the message will not appear?
Carefully look at the way how formcontrol condition should be setup in error template( specially in ng-if part).
<script type="text/ng-template" id="error-messages.html">
<formly-transclude></formly-transclude>
<div ng-messages="fc.$error" ng-if="options.formControl.$invalid && options.formControl.$touched" class="error-messages">
<div ng-message="{{ ::name }}" ng-repeat="(name, message) in ::options.validation.messages" class="message">{{ message(fc.$viewValue, fc.$modelValue, this)}}</div>
</div>
</script>
Also the way you have written setWrapper method in app config looks messy, so I have removed the code to a separate template and pointed the template here.
Take a look at updated jsfiddle .

Shorthand property name are not supported by current Javascript version in PHPStorm

I have used Jquery getScript and generate html form by Javascript however I got
Shorthand property name are not supported by current Javascript version in PHPStorm but my function work as well.
Concern: Before I used PHP to generate html form within another PHP framework but I think I should not used Server script to do that I should use JS to do that but I don't know how is it going on and is it support all browser or not so please give me some idea of this technique because I not yet understand much more about suing DOM and its performance.
Security Concern: if I used Javascript to generate Html form as below script it will less security or bad performance or not?
Another hand if I keep this code inside of HTMl I will never got this errors types.
$(document).ready(function () {
returnTill('returnTill');
});
function returnTill(returnTill) {
var chief_opt = '';
var teller_opt = '';
$.ajax({
url:'/teller/return_till_data',
method:'get',
dataType:'json',
timeout:4000,
async: false,
success:function (data, status) {
$.each(data, function(ins, vals){
if(ins === 'chief') {
cheifs = data.chief;
for(var key in cheifs){
chief_opt += '<option value="'+vals[key].id+'"> '+vals[key].username+' / '+vals[key].account_no+' </option>';
}
}if(ins === 'teller') { /* Tellers*/
tellers = data.teller;
for(var key in tellers){
teller_opt = '<option value="'+vals[key].id+'"> '+vals[key].username+' / '+vals[key].account_no+' </option>';
}
loadModale({
idSelector: returnTill,
title: 'Return Till',
labels: ['From','To','Amount','Description'],
loadType:'returnTill',
forms: {
input: {
selection: {
from:{chief_opt,class:'form-control', name:'retn_chief', id:'retn_chief'},
to:{teller_opt, class:'form-control', name:'retn_teller', id:'retn_teller'},
},
Amount :{type: 'text', name: 'retn_amount', class: 'form-control', Id: 'retn_amount', placeholder: '', style: '', value:''},
token:{ type: 'hidden', name: '_token', class: 'form-control', Id: 'token', placeholder: '', style: '', value: '{{csrf_token()}}'},
},
textarea : {
description:{class:'form-control', name:'tran_descr', rows:10, id:'tran_descr'}
}
},script: [
'/theme/js/jquery.validate.min.js',
'/theme/js/bootstrap-datepicker/js/bootstrap-datepicker.js',
]
});
}
});
},error: errorCallback,
});
}
Errors:
I perform the following steps in Webstorm to solve the same problem, so it may also work in PHPStorm:
Go to Settings by pressing ALT + CNTRL + S
Click on "Languages and Frameworks"
Click on 'Javascript'
In the "Javascript language version" drop-down, select 'ECMAScript 6'.
Click 'OK'
Now re-open any *.js files you may have previously had open, and notice that the errors are no longer there.
Hope that helps someone.
You can fix it this way:
from:{chief_opt: chief_opt}
So, if you change your code to this:
from:{chief_opt: chief_opt, class:'form-control', name:'retn_chief', id:'retn_chief'},
to:{teller_opt: teller_opt, class:'form-control', name:'retn_teller', id:'retn_teller'},
You shouldn't get anymore the PHPStorm error.
Hope it helped or at least cleared a little bit. ;)
PHP STORM SOLUTION
The error is attributed to the version of your Javascript Setting in PHPSTORM
STEPS
Go to settings(preference on macbook)settings/preference and click
Expand the Languages and Frameworks by clicking it
click language & frameworks
Click Javascript and change the Javascript language version to the current or ECMAScript6 recommended.select ecmascript

Select File. Submit. Cannot select file again

I have a form with different fields and with input type="file". I use fileupload jQuery library.
Select file
Call
$('#some_id').fileupload().fileupload(
'send',
{
files: file,
url: widget.options.saveVideoUrl,
}
).success(
//...
(first fileupload called for init)
Try again to select file. Got: No files selected, clear console, etc..
Upd.1
The problem appear in E-commerce framework Magento2 in admin area.
The described form appear in such entity like 'slide-out panel'. It means that there is div block and this block wrapped in aside block using javascript.
<button onclick="jQuery('#new').modal('openModal')" .... >
<span>New</span>
</button>
Here is demo example:
Admin URL: https://iwdagency.com/magento2/admin
Username: admin
Password: admin123
Open Products / Catalog / select any product / click on New category
You should see following panel:
On such panel I've added by php constructor fields:
<div class="admin__field field field-new_video_screenshot " data-ui-id="product-tabs-tab-google-experiment-fieldset-element-form-field-new-video-screenshot">
<label class="label admin__field-label" for="..." data-ui-id="product-tabs-tab-google-experiment-fieldset-element-file-image-label"><span>Preview Image</span></label>
<div class="admin__field-control control">
<input id="...." name="image" data-ui-id="product-tabs-tab-google-experiment-fieldset-element-file-image" value="" title="Preview Image" type="file">
</div>
</div>
Script:
define([
'jquery',
'jquery/ui',
'Magento_Ui/js/modal/modal',
'mage/translate',
'mage/backend/tree-suggest',
'mage/backend/validation'
], function ($) {
'use strict';
$.widget('mage.newDialog', {
_create: function () {
var widget = this;
var newVideoForm = $('#new');
this.element.modal({
type: 'slide',
modalClass: 'mage-new-dialog form-inline',
title: $.mage.__('Create'),
buttons: [{
text: $.mage.__('Create'),
class: 'action-primary',
click: function (e) {
var file = $('#new_screenshot').get(0).files[0];
var result = $('#new_screenshot').fileupload().fileupload(
'send',
{
files: file,
url: widget.options.saveUrl,
}
).success(
function(result, textStatus, jqXHR)
{
var data = JSON.parse(result);
data['url'] = $('#new_url').val();
data['name'] = $('#new_name').val();
data['description'] = $('#new_description').val();
$('#media_gallery_content').trigger('addItem', data);
$('#new').modal('closeModal')
}
);
}
}],
});
}
});
return $.mage.newDialog;
});
I found the problem.
In my case the problem appear after initialization fileUpload library.
When I selected input:file, the library wasn't initialized (read as infected). When I pressed the button, initialization ran and any operations with this input become unavailable.
Solution is following: clone our input before it become infected, than do our operations and at the end replace existing infected input with its healthy copy, created before.

How to print html response (tinymce) in x-editable

Using x-editable and tinymce to edit a field, however the return value is printed showing the html code (with etc.), when reloading the page it is fine.
example of what is shown when saving the field;
<p>this is a test response</p>
<p> </p>
(instead of)
this is a test response
 
Editable initializations code:
$('.editable').editable('option','validate', function (v) {
if (this.dataset.type == 'textarea') {
return {newValue: tinyMCE.activeEditor.getContent()};
}
});
This is the editable field:
<%= editable #article, :introduction, url: article_update_path(#article), type: 'textarea', onblur: 'ignore' %>
I want it to be showing the "html-output" instead of the html code.
Problem solved:
$('.editable').editable('option','display', function (value, sourceData) {
this.innerHTML = value;
});

Categories