How can I get the content inside Ace (code editor) after clicking a button? - express

I have a page with an embedded Ace code editor that will contain Java code. I want to get its contents via a POST request after a button is pressed.
I'm aware that one can do this in order to get the value:
var code = editor.getValue();
However, I'm not too sure how I would get this value from my route handler. Ideally, I'd like to have the editor script inside a separate .js file, but I can't seem to get it to be recognized by anything.
In my handlebars template for /myroute/*
<div class = "bigclass">
some divs
<div id = "containerclass">
<div id = "editor"></div>
<script src = "https://pagecdn.io/lib/ace/1.4.8/ace.js", type = "text/javascript" charset = "utf-8"></script>
<script>
var editor = ace.edit("editor");
editor.setTheme("ace/theme/github");
editor.session.setMode("ace/mode/java");
editor.session.setUseWrapMode(true);
editor.setValue("Hello");
editor.clearSelection();
</script>
</div>
some more divs
<div id = "someotherclass">
<form method = "POST" action = "">
<button style = "text-align: center" type="submit" class="btn"> Submit</button>
</form>
</div>
</div>
Route Handler for /myroute/*
app.post('/myroute/*', function(req, res) {
// Get the contents of the editor
});

You've to set an input inside your form, and fill it every time a change is done on the editor.
On clicking submit, you can have the value from the req.body
<div class = "bigclass">
some divs
<div id = "containerclass">
<div id = "editor"></div>
<script src = "https://pagecdn.io/lib/ace/1.4.8/ace.js", type = "text/javascript" charset = "utf-8"></script>
</div>
some more divs
<div id = "someotherclass">
<form method = "POST" action = "">
<textarea name="content" id="content"></textarea>
<button style = "text-align: center" type="submit" class="btn"> Submit</button>
</form>
</div>
</div>
<script>
var editor = ace.edit("editor");
editor.setTheme("ace/theme/github");
editor.session.setMode("ace/mode/java");
editor.session.setUseWrapMode(true);
editor.getSession().on("change", function () {
document.getElementById('content').val(editor.getSession().getValue());
});
editor.setValue("Hello");
editor.clearSelection();
</script>
Server:
app.post('/myroute/*', function(req, res) {
const content = req.body.content;
});

Related

How to bind change on text area to v-model value?

I have this checkbox that will generate raw HTML on textarea, then generate whatever contain in textarea to the picture on top of the form, on that textarea, I want to be able to edit the text to customize the data position on the image.
The checkbox and the pic work fine, but when I edit data on the textarea, it reverts back, and of course, the rendered HTML reverts back too. And 1 more thing, I have to open the vue extension on inspecting menu to get all DOM rendered
Pic render code
<template>
<div class="card-item container-fluid mt--7">
<div class="card-item__cover">
<img v-if="form.img" :src="background" class="imageBackground" />
<div
v-if="previewImage"
class="imageBackground"
:style="{ 'background-image': `url(${previewImage})` }"
></div>
</div>
<span v-html="htmlBaru"></span>
</div>
</template>
Textarea
<div class="form-group">
<label class="col-form-label form-control-label">HTML</label>
<textarea
ref="htmlInput"
rows="4"
class="form-control col-sm-10"
v-model="htmlBaru"
#change="pantek"
></textarea>
</div>
Checkbox
checkboxCond() {
var sendKeyData = [];
var newHtml = [];
for (var a = 0; a < this.keyData.length; a++) {
if (this.keyData[a].status) {
newHtml.push(
`<tr>
<td >` +
this.keyData[a].key_readable +
` : {` +
this.keyData[a].key +
`}</td>
</tr>`
);
sendKeyData.push(this.keyData[a].key);
}
}
this.htmlBaru = this.html + newHtml.join("\r\n") + this.footer;
this.sendKeyData = sendKeyData;
console.log(this.htmlBaru);
// return this.htmlBaru;
}
Onchange
methods: {
pantek() {
// console.log(this.htmlBaru);
this.htmlBaru = this.$refs.target.value;
// this.$emit("change", this.htmlBaru);
},
}

Model data not binding to html template in Backbone,Marionette

I am new to backbone and Marionette.
My requirement is,
I have a main grid having few rows. If i select a row from grid i need to fetch the details and display on the same page.
Binding the grid is working fine. But when i click on the row data is not binding to html template. I am unable to find out the issue.
Below is my html template for row details
<script id="selected-broker-details-tmpl" type="text/x-handlebars-template">
<div id="pnl-broker-details" class="panel panel-default">
<div class="panel-heading">
Broker Details
</div>
<div id="broker-details-container" class="panel-body">
<div class="col-md-6">
<div class="form-group">
<label for="inputbrokerName" class="col-sm-3 control-label">BrokerName</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="inputbrokerName" placeholder="Broker Name" value="{{BrokerName}}">
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="inputMnemonic" class="col-sm-3 control-label">Mnemonic</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="inputMnemonic" placeholder="Mnemonic" value="{{Mnemonic}}">
</div>
</div>
</div>
</div>
</div>
</script>
Backbone view declaration
App.Views.BrokerDetails = Backbone.View.extend({
initialize: function () {
this.listenTo(this.model, 'change', this.render);
},
el: '#details',
template: brokerTemplates.BrokerDetailsTempalte,
render: function () {
this.$el.html(this.template({}));
}
});
Model and collection declaration
var BrokderDetails = Backbone.Model.extend({
BrokerId: null,
BrokerName: null,
Mnemonic: null,
OASYSMnemonic: null
});
var BrokerDetailsCollection = Backbone.Collection.extend({
initialize: function (options) {
this.model = BrokderDetails;
this.url = '/api/BrokerSelections/SelectedBroker/';
}
,
setParam: function (str) {
this.url = '/api/BrokerSelections/SelectedBroker/' + str;
this.fetch();
},
parse: function (data) {
return data;
}
});
click event in main grid
events: {
"click .selection": "selectedBroker",
},
selectedBroker: function (e) {
var details = new BrokerDetailsCollection();
var brokerdetails = new App.Views.BrokerDetails({ model: null, collection: details });
details.setParam($(e.currentTarget).data("id"));
details.fetch();
brokerdetails.render();
},
Now there are 2 issues,
1. Click event is firing 2 times, if i select a row i main grid
2. Model data is not binding to html template. I mean html template is displayed, but with empty values in textboxes

Dropzone inside a html form with other form fields not working

I want to add a dropzone inside an existing form but it doesn't seem to work.
When I view the console I get error throw new Error("No URL provided"). When I click upload I get no preview either - all I get is a normal file input.
<link href="../dropzone.css" rel="stylesheet">
<form action="/" enctype="multipart/form-data" method="POST">
<input type="text" id ="Username" name ="Username" />
<div class="dropzone" id="my-dropzone" name="mainFileUploader">
<div class="fallback">
<input name="file" type="file" />
</div>
</div>
<div>
<button type="submit" id="submit"> upload </button>
</div>
</form>
<script src="../jquery.min.js"></script>
<script src="../dropzone.js"></script>
<script>
$("my-dropzone").dropzone({
url: "/file/upload",
paramName: "file"
});
</script>
No url provided error is because $("my-dropzone") is wrong instead it must be $('#mydropzone')
dropzone along with other form, yes this is very much possible, you have to post the data using the URL provided in the dropzone not in the form action. That means all your form data along with the files uploaded shall be posted back to the url provided for the dropzone. A simple untested solution is as below;
<link href="../dropzone.css" rel="stylesheet">
<form action="/" enctype="multipart/form-data" method="POST">
<input type="text" id ="Username" name ="Username" />
<div class="dropzone" id="my-dropzone" name="mainFileUploader">
<div id="previewDiv></div>
<div class="fallback">
<input name="file" type="file" />
</div>
</div>
<div>
<button type="submit" id="submitForm"> upload </button>
</div>
</form>
<script src="../jquery.min.js"></script>
<script src="../dropzone.js"></script>
<script>
$("#mydropzone").dropzone({
url: "/<controller>/action/" ,
autoProcessQueue: false,
uploadMultiple: true, //if you want more than a file to be uploaded
addRemoveLinks:true,
maxFiles: 10,
previewsContainer: '#previewDiv',
init: function () {
var submitButton = document.querySelector("#submitForm");
var wrapperThis = this;
submitButton.addEventListener("click", function () {
wrapperThis.processQueue();
});
this.on("addedfile", function (file) {
// Create the remove button
var removeButton = Dropzone.createElement("<button class="yourclass"> Remove File</button>");
// Listen to the click event
removeButton.addEventListener("click", function (e) {
// Make sure the button click doesn't submit the form:
e.preventDefault();
e.stopPropagation();
// Remove the file preview.
wrapperThis.removeFile(file);
});
file.previewElement.appendChild(removeButton);
});
// Also if you want to post any additional data, you can do it here
this.on('sending', function (data, xhr, formData) {
formData.append("PKId", $("#PKId").val());
});
this.on("maxfilesexceeded", function(file) {
alert('max files exceeded');
// handle max+1 file.
});
}
});
</script>
The script where you initialize dropzone can be inside $document.ready or wrap it as a function and call when you want to initialize it.
Happy coding!!

Multer can not get the upload form data in Express 4

I'm using Ajax to upload the form data. The output of multer(req.file, req.body) is always undefined/{};
My server code:
import multer from 'multer';
import post from './router/api_post';
var upload = multer({dest: 'uploads/'});
app.use('/api/post', upload.single('thumb') , post);
and the api_post router file:
import express from 'express';
var router = express.Router();
router
.post('/', (req, res, next) => {
console.log("POST POST");
var post = {};
console.log(req.body);
console.log(req.file);
});
export default router;
the output of req.body is {} and of req.fileisundefined`.
I use react on the browser side and upload data via ajax:
savePost(ev) {
ev.preventDefault();
var editor = this.refs.editorDom.getDOMNode();
var ajaxReq = new AjaxRequest();
var formData = new FormData();
formData.append('post_id', this.state.post_id);
formData.append('title', this.state.title);
formData.append('author', this.state.author);
formData.append('digest', this.state.digest);
formData.append('content', editor.innerHTML);
formData.append('content_source_url', this.state.content_source_url);
formData.append('create_time', new Date());
formData.append('thumb', this.state.thumb);
ajaxReq.send('post', '/api/post', ()=>{
if(ajaxReq.getReadyState() == 4 && ajaxReq.getStatus() == 200) {
var result = JSON.parse(ajaxReq.getResponseText());
if(result.ok == 1) {
console.log("SAVE POST SUCCESS");
}
}
}, '', formData);
}
The savePost() is callback of a button's event listener. I did upload data successfully with formidable. I just replaced the formidable with multer but can not get it.
I didn't set the content-type property. I found it in the header is
, multipart/form-data; boundary=----WebKitFormBoundary76s9Cg74EW1B94D9
The form's HTML is
<form id="edit-panel" data-reactid=".ygieokt1c0.1.0.1.0.1">
<div id="title" class="form-group" data-reactid=".ygieokt1c0.1.0.1.0.1.0">
<input type="text" class="form-control" name="title" value="" data-reactid=".ygieokt1c0.1.0.1.0.1.0.1">
</div>
<div id="author" class="form-group" data-reactid=".ygieokt1c0.1.0.1.0.1.1">
<input type="text" class="form-control" name="author" value="" data-reactid=".ygieokt1c0.1.0.1.0.1.1.1">
</div>
<div id="thumb" class="form-group" data-reactid=".ygieokt1c0.1.0.1.0.1.2">
<button class="btn btn-default" data-reactid=".ygieokt1c0.1.0.1.0.1.2.1">
<input type="file" name="thumb" accept="image/*" data-reactid=".ygieokt1c0.1.0.1.0.1.2.1.0">
<span data-reactid=".ygieokt1c0.1.0.1.0.1.2.1.1">UPLOAD</span>
</button>
</div>
<div class="form-group" data-reactid=".ygieokt1c0.1.0.1.0.1.3">
<textarea class="form-control" name="digest" rows="5" data-reactid=".ygieokt1c0.1.0.1.0.1.3.1"></textarea>
</div>
<div id="rich-text-editor" class="form-group" data-reactid=".ygieokt1c0.1.0.1.0.1.4">
<div id="editor-div" class="form-control" contenteditable="true" data-reactid=".ygieokt1c0.1.0.1.0.1.4.1"></div>
</div>
<div id="content-source-url" class="form-group" data-reactid=".ygieokt1c0.1.0.1.0.1.5">
<input type="text" class="form-control" name="content_source_url" value="" data-reactid=".ygieokt1c0.1.0.1.0.1.5.1">
</div>
<button class="btn btn-default" data-reactid=".ygieokt1c0.1.0.1.0.1.6">保存并提交</button>
</form>
I can output the thumb, it's a File{} object.
Thanks for help.
Finally I found the problem is the Content-Type.
I used this.request.setRequestHeader("Content-Type", postDataType); to set the Content-Type and set the postDataType to '', then the actual Content-Type in header is , multipart/form-data; boundary=----WebKitFormBoundary76s9Cg74EW1B94D9 as I mentioned at the first.
You can see there is a comma and a space before the multipar/form-data. I have no idea where this comma come from. But anyway, when I remove the comma and space, everything just works fine!

Use AngularJS with ASP.NET MVC 4 to detect changes

I have an existing MVC 4 application with several groups of checkboxes and I need to detect when a user has made a change, i.e. checked or unchecked a checkbox. If the user has made a change and they try to navigate away from the page I need to prompt them to save their changes. I am just learning AngularJS, but figured I could use it to detect when a checkbox state has change and also use routes in angular to detect when a user is navigating away from the page.
I have based my code on the answer here. Since the view is already being rendered by MVC I cannot use REST services and angular to populate the model and view.
HTML rendered in the view
<div id="userPermissions" class="userWrapper" ng-app="myApp.User">
<div id="actionCategories" class="section" ng-controller="UserCtrl">
<div class="actionGroupBody">
<div class="actionGroupAction">
<input type="checkbox" value="Create new users"
id="action-f9ae022b-5a53-4824-8a79-f7bbac844b11"
data-action-category="8aefed6e-b76c-453f-94eb-d81d2eb284f9"
ng-checked="isSelected('f9ae022b-5a53-4824-8a79-f7bbac844b11')"
ng-click="updateSelection($event,'f9ae022b-5a53-4824-8a79-f7bbac844b11')"/>Create new users
</div>
<div class="actionGroupAction">
<input type="checkbox" value="Edit users"
id="action-5525d5e7-e1dd-4ec3-9b1d-3be406d0338b"
data-action-category="8aefed6e-b76c-453f-94eb-d81d2eb284f9"
ng-checked="isSelected('5525d5e7-e1dd-4ec3-9b1d-3be406d0338b')"
ng-click="updateSelection($event,'5525d5e7-e1dd-4ec3-9b1d-3be406d0338b')"/>Edit users
</div>
<div class="actionGroupAction">
<input type="checkbox" value="Edit personal account"
id="action-9967c1c2-c781-432b-96df-224da760bfb6"
data-action-category="8aefed6e-b76c-453f-94eb-d81d2eb284f9"
ng-checked="isSelected('9967c1c2-c781-432b-96df-224da760bfb6')"
ng-click="updateSelection($event,'9967c1c2-c781-432b-96df-224da760bfb6')"/>Edit personal account
</div>
</div>
<div class="caption">
<label class="actionGroupCaption">Store</label> <span class="actionCategorySelectAll"><input type="checkbox" value="select all Store" id="7bace6c1-4820-46c2-b463-3dad026991f2" data-action-category="selectall"/>All</span>
</div>
<div class="actionGroupBody">
<div class="actionGroupAction">
<input type="checkbox" value="Access home page"
id="action-fba7e381-4ed8-47ce-8e85-b5133c9ba9f7"
data-action-category="7bace6c1-4820-46c2-b463-3dad026991f2"
ng-checked="isSelected('fba7e381-4ed8-47ce-8e85-b5133c9ba9f7')"
ng-click="updateSelection($event,'fba7e381-4ed8-47ce-8e85-b5133c9ba9f7')"/>Access home page
</div>
<div class="actionGroupAction">
<input type="checkbox" value="Edit settings"
id="action-2d02b77b-14a4-4136-a09f-fd51eecd2dbe"
data-action-category="7bace6c1-4820-46c2-b463-3dad026991f2"
ng-checked="isSelected('2d02b77b-14a4-4136-a09f-fd51eecd2dbe')"
ng-click="updateSelection($event,'2d02b77b-14a4-4136-a09f-fd51eecd2dbe')"/>Edit settings
</div>
<div class="actionGroupAction">
<input type="checkbox" value="Edit products"
id="action-f42f933c-a2b8-42e8-af4b-d52f90f58ddb"
data-action-category="7bace6c1-4820-46c2-b463-3dad026991f2"
ng-checked="isSelected('f42f933c-a2b8-42e8-af4b-d52f90f58ddb')"
ng-click="updateSelection($event,'f42f933c-a2b8-42e8-af4b-d52f90f58ddb')"/>Edit products
</div>
<div class="actionGroupAction">
<input type="checkbox" value="Edit orders"
id="action-92ed258b-c954-46e4-b5c9-a89fdb5c54d9"
data-action-category="7bace6c1-4820-46c2-b463-3dad026991f2"
ng-checked="isSelected('92ed258b-c954-46e4-b5c9-a89fdb5c54d9')"
ng-click="updateSelection($event,'92ed258b-c954-46e4-b5c9-a89fdb5c54d9')"/>Edit orders
</div>
</div>
</div>
</div>
here's the angular code
var app = angular.module('myApp.User', []);
app.controller('UserCtrl', function ($scope) {
$scope.entities = [{ //how to populate with checkboxes state from view? factory maybe similar to below??? // }];
$scope.selected = [];
var updateSelected = function (action, id) {
if (action == 'add' & $scope.selected.indexOf(id) == -1)
$scope.selected.push(id);
if (action == 'remove' && $scope.selected.indexOf(id) != -1)
$scope.selected.splice($scope.selected.indexOf(id), 1);
};
$scope.updateSelection = function ($event, id) {
var checkbox = $event.target;
var action = (checkbox.checked ? 'add' : 'remove');
updateSelected(action, id);
};
$scope.selectAll = function ($event) {
var checkbox = $event.target;
var action = (checkbox.checked ? 'add' : 'remove');
for (var i = 0; i < $scope.entities.length; i++) {
var entity = $scope.entities[i];
updateSelected(action, entity.id);
}
};
$scope.getSelectedClass = function (entity) {
return $scope.isSelected(entity.id) ? 'selected' : '';
};
$scope.isSelected = function (id) {
return $scope.selected.indexOf(id) >= 0;
};
$scope.isSelectedAll = function () {
return $scope.selected.length === $scope.entities.length;
};
});
app.factory('UserDataService', function () {
var service = {}
service.getData = function () {
var actions = $("input[id^=action-]");
return actions;
}
return service;
});
Whenever I click a checkbox none of the $scope functions (.updateSelection, .isSelected, etc.) fire in the controller.