I'm using bootstrap to make a website and then I surfed the net for a WYSIWYG editor that's compatible with Bootstrap and I found one here that I really like. So I tried to incorporate it into my modal window but it doesn't quite work as it's supposed to.
When I press the Activity Description tab, it looks like this:
It's like it ignores the boundaries of the Modal completely.
I don't quite understand this behaviour. The styling:
#editor {
max-height: 250px;
height: 150px;
background-color: white;
border-collapse: separate;
border: 1px solid rgb(204, 204, 204);
padding: 4px;
/*box-sizing: content-box; */
-webkit-box-shadow: rgba(0, 0, 0, 0.0745098) 0px 1px 1px 0px inset;
box-shadow: rgba(0, 0, 0, 0.0745098) 0px 1px 1px 0px inset;
border-top-right-radius: 3px; border-bottom-right-radius: 3px;
border-bottom-left-radius: 3px; border-top-left-radius: 3px;
overflow: scroll;
outline: none;
}
div[data-role="editor-toolbar"] {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.dropdown-menu a {
cursor: pointer;
}
The Javascript:
/* http://github.com/mindmup/bootstrap-wysiwyg */
/*global jQuery, $, FileReader*/
/*jslint browser:true*/
(function ($) {
'use strict';
var readFileIntoDataUrl = function (fileInfo) {
var loader = $.Deferred(),
fReader = new FileReader();
fReader.onload = function (e) {
loader.resolve(e.target.result);
};
fReader.onerror = loader.reject;
fReader.onprogress = loader.notify;
fReader.readAsDataURL(fileInfo);
return loader.promise();
};
$.fn.cleanHtml = function () {
var html = $(this).html();
return html && html.replace(/(<br>|\s|<div><br><\/div>| )*$/, '');
};
$.fn.wysiwyg = function (userOptions) {
var editor = this,
selectedRange,
options,
toolbarBtnSelector,
updateToolbar = function () {
if (options.activeToolbarClass) {
$(options.toolbarSelector).find(toolbarBtnSelector).each(function () {
var command = $(this).data(options.commandRole);
if (document.queryCommandState(command)) {
$(this).addClass(options.activeToolbarClass);
} else {
$(this).removeClass(options.activeToolbarClass);
}
});
}
},
execCommand = function (commandWithArgs, valueArg) {
var commandArr = commandWithArgs.split(' '),
command = commandArr.shift(),
args = commandArr.join(' ') + (valueArg || '');
document.execCommand(command, 0, args);
updateToolbar();
},
bindHotkeys = function (hotKeys) {
$.each(hotKeys, function (hotkey, command) {
editor.keydown(hotkey, function (e) {
if (editor.attr('contenteditable') && editor.is(':visible')) {
e.preventDefault();
e.stopPropagation();
execCommand(command);
}
}).keyup(hotkey, function (e) {
if (editor.attr('contenteditable') && editor.is(':visible')) {
e.preventDefault();
e.stopPropagation();
}
});
});
},
getCurrentRange = function () {
var sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
return sel.getRangeAt(0);
}
},
saveSelection = function () {
selectedRange = getCurrentRange();
},
restoreSelection = function () {
var selection = window.getSelection();
if (selectedRange) {
try {
selection.removeAllRanges();
} catch (ex) {
document.body.createTextRange().select();
document.selection.empty();
}
selection.addRange(selectedRange);
}
},
insertFiles = function (files) {
editor.focus();
$.each(files, function (idx, fileInfo) {
if (/^image\//.test(fileInfo.type)) {
$.when(readFileIntoDataUrl(fileInfo)).done(function (dataUrl) {
execCommand('insertimage', dataUrl);
}).fail(function (e) {
options.fileUploadError("file-reader", e);
});
} else {
options.fileUploadError("unsupported-file-type", fileInfo.type);
}
});
},
markSelection = function (input, color) {
restoreSelection();
if (document.queryCommandSupported('hiliteColor')) {
document.execCommand('hiliteColor', 0, color || 'transparent');
}
saveSelection();
input.data(options.selectionMarker, color);
},
bindToolbar = function (toolbar, options) {
toolbar.find(toolbarBtnSelector).click(function () {
restoreSelection();
editor.focus();
execCommand($(this).data(options.commandRole));
saveSelection();
});
toolbar.find('[data-toggle=dropdown]').click(restoreSelection);
toolbar.find('input[type=text][data-' + options.commandRole + ']').on('webkitspeechchange change', function () {
var newValue = this.value; /* ugly but prevents fake double-calls due to selection restoration */
this.value = '';
restoreSelection();
if (newValue) {
editor.focus();
execCommand($(this).data(options.commandRole), newValue);
}
saveSelection();
}).on('focus', function () {
var input = $(this);
if (!input.data(options.selectionMarker)) {
markSelection(input, options.selectionColor);
input.focus();
}
}).on('blur', function () {
var input = $(this);
if (input.data(options.selectionMarker)) {
markSelection(input, false);
}
});
toolbar.find('input[type=file][data-' + options.commandRole + ']').change(function () {
restoreSelection();
if (this.type === 'file' && this.files && this.files.length > 0) {
insertFiles(this.files);
}
saveSelection();
this.value = '';
});
},
initFileDrops = function () {
editor.on('dragenter dragover', false)
.on('drop', function (e) {
var dataTransfer = e.originalEvent.dataTransfer;
e.stopPropagation();
e.preventDefault();
if (dataTransfer && dataTransfer.files && dataTransfer.files.length > 0) {
insertFiles(dataTransfer.files);
}
});
};
options = $.extend({}, $.fn.wysiwyg.defaults, userOptions);
toolbarBtnSelector = 'a[data-' + options.commandRole + '],button[data-' + options.commandRole + '],input[type=button][data-' + options.commandRole + ']';
bindHotkeys(options.hotKeys);
if (options.dragAndDropImages) {
initFileDrops();
}
bindToolbar($(options.toolbarSelector), options);
editor.attr('contenteditable', true)
.on('mouseup keyup mouseout', function () {
saveSelection();
updateToolbar();
});
$(window).bind('touchend', function (e) {
var isInside = (editor.is(e.target) || editor.has(e.target).length > 0),
currentRange = getCurrentRange(),
clear = currentRange && (currentRange.startContainer === currentRange.endContainer && currentRange.startOffset === currentRange.endOffset);
if (!clear || isInside) {
saveSelection();
updateToolbar();
}
});
return this;
};
$.fn.wysiwyg.defaults = {
hotKeys: {
'ctrl+b meta+b': 'bold',
'ctrl+i meta+i': 'italic',
'ctrl+u meta+u': 'underline',
'ctrl+z meta+z': 'undo',
'ctrl+y meta+y meta+shift+z': 'redo',
'ctrl+l meta+l': 'justifyleft',
'ctrl+r meta+r': 'justifyright',
'ctrl+e meta+e': 'justifycenter',
'ctrl+j meta+j': 'justifyfull',
'shift+tab': 'outdent',
'tab': 'indent'
},
toolbarSelector: '[data-role=editor-toolbar]',
commandRole: 'edit',
activeToolbarClass: 'btn-info',
selectionMarker: 'edit-focus-marker',
selectionColor: 'darkgrey',
dragAndDropImages: true,
fileUploadError: function (reason, detail) { console.log("File upload error", reason, detail); }
};
}(window.jQuery));
The HTML:
<div class="form-group">
<!-- WYSIWYG Editor Start -->
<div class="form-control">
<div class="btn-toolbar" data-role="editor-toolbar" data-target="#editor">
<div class="btn-group">
<a class="btn dropdown-toggle" data-toggle="dropdown" title data-original-title="Font">
<span class="fa fa-font">A</span>
<b class="caret"></b>
</a>
<ul class="dropdown-menu" id="font-dropdown">
<li>
<a data-edit="fontName Serif" style="font-family:'Serif'">Serif</a>
</li>
<!-- other fonts...omitted to short the amount of text to read -->
</ul>
</div>
<div class="btn-group">
<a class="btn dropdown-toggle" data-toggle="dropdown"
title="" data-original-title="Font Size">
<span class="fa fa-text-height"></span> <b class="caret"></b></a>
<ul class="dropdown-menu">
<li>
<a data-edit="fontSize 5"><font size="5">Huge</font></a>
</li>
<li>
<a data-edit="fontSize 3"><font size="3">Normal</font></a>
</li>
<li>
<a data-edit="fontSize 1"><font size="1">Small</font></a>
</li>
</ul>
</div>
<div class="btn-group">
<a class="btn" data-edit="bold" title="" data-original-title="Bold (Ctrl/Cmd+B)"><span class="fa fa-bold"></span></a>
<a class="btn" data-edit="italic" title="" data-original-title="Italic (Ctrl/Cmd+I)"><span class="fa fa-italic"></span></a>
<a class="btn" data-edit="strikethrough" title="" data-original-title="Strikethrough"><span class="fa fa-strikethrough"></span></a>
<a class="btn" data-edit="underline" title="" data-original-title="Underline (Ctrl/Cmd+U)"><span class="fa fa-underline"></span></a>
</div>
<div class="btn-group">
<a class="btn" data-edit="insertunorderedlist" title="" data-original-title="Bullet list"><span class="fa fa-list"></span></a>
<a class="btn" data-edit="insertorderedlist" title="" data-original-title="Number list"><span class="fa fa-list-ol"></span></a>
<!-- TODO: Find an Indent Left Icon -->
<a class="btn" data-edit="outdent" title="" data-original-title="Reduce indent (Shift+Tab)"><span class="fa fa-arrow-left"></span></a>
<a class="btn" data-edit="indent" title="" data-original-title="Indent (Tab)"><span class="fa fa-indent"></span></a>
</div>
<div class="btn-group">
<a class="btn btn-info" data-edit="justifyleft" title="" data-original-title="Align Left (Ctrl/Cmd+L)"><span class="fa fa-align-left"></span></a>
<a class="btn" data-edit="justifycenter" title="" data-original-title="Center (Ctrl/Cmd+E)"><span class="fa fa-align-center"></span></a>
<a class="btn" data-edit="justifyright" title="" data-original-title="Align Right (Ctrl/Cmd+R)"><span class="fa fa-align-right"></span></a>
<a class="btn" data-edit="justifyfull" title="" data-original-title="Justify (Ctrl/Cmd+J)"><span class="fa fa-align-justify"></span></a>
</div>
<div class="btn-group">
<a class="btn dropdown-toggle" data-toggle="dropdown" title="" data-original-title="Hyperlink"><span class="fa fa-link"></span></a>
<div class="dropdown-menu input-append">
<input class="span2" placeholder="URL" type="text" data-edit="createLink">
<button class="btn" type="button">Add</button>
</div>
<a class="btn" data-edit="unlink" title="" data-original-title="Remove Hyperlink"><span class="fa fa-cut"></span></a>
</div>
<div class="btn-group">
<a class="btn" title="" id="pictureBtn" data-original-title="Insert picture (or just drag & drop)"><span class="fa fa-picture-o"></span></a>
<input type="file" data-role="magic-overlay" data-target="#pictureBtn" data-edit="insertImage" style="opacity: 0; position: absolute; top: 0px; left: 0px; width: 37px; height: 30px;">
</div>
<div class="btn-group">
<a class="btn" data-edit="undo" title="" data-original-title="Undo (Ctrl/Cmd+Z)"><span class="fa fa-undo"></span></a>
<a class="btn" data-edit="redo" title="" data-original-title="Redo (Ctrl/Cmd+Y)"><span class="fa fa-repeat"></span></a>
</div>
</div>
<div id="editor" contenteditable="true"></div>
</div>
<!-- WYSIWYG Editor End -->
</div>
EDIT
I fixed the overflow problem where it appears on the wrong tab. It appears that the HTML had an "active" class on both the Activity Abstract and Description tabs.
Okay I fixed it myself. I switched out this element:
<div class="form-control">
For this:
<div class="form-group">
Related
I am trying to step away from jsTree as this is not as much as configurable as having my own custom code. I am making use of Bootstrap to have a somewhat similar functionality as jsTree. I am also stepping away from jQuery (for now), because of debugging reasons.
//Event delegation
function BindEvent(parent, eventType, ele, func) {
var element = document.querySelector(parent);
element.addEventListener(eventType, function(event) {
var possibleTargets = element.querySelectorAll(ele);
var target = event.target;
for (var i = 0, l = possibleTargets.length; i < l; i++) {
var el = target;
var p = possibleTargets[i];
while (el && el !== element) {
if (el === p) {
return func.call(p, event);
}
el = el.parentNode;
}
}
});
}
//Add content after referenced element
function insertAfter(referenceNode, newNode) {
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
//Custom function
function LoadSubOptions(ele) {
ele = ele.parentElement.parentElement;
let newEle = document.createElement("div");
newEle.classList.add("row", "flex");
//Generated HTML Content (currently hard coded):
newEle.innerHTML = "<div class='col-xs-1'><div class='tree-border'></div></div><div class='col-xs-11'><div class='row'><div class='col-xs-12'><button class='btn btn-default btn-block btn-lg'>Test</button></div></div></div>";
insertAfter(ele, newEle);
}
//Bind method(s) on button click(s)
BindEvent("#tree-replacement", "click", "button", function(e) {
LoadSubOptions(this);
});
#tree-replacement button {
margin-top: 5px;
}
.tree-border {
border-left: 1px dashed #000;
height: 100%;
margin-left: 15px;
}
.flex {
display: flex;
}
/*Probably not wise to use this method on Bootstrap's grid system: */
#tree-replacement .row.flex>[class*='col-'] {
display: flex;
flex-direction: column;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet" />
<div class="container">
<div id="tree-replacement">
<div class="row">
<div class="col-xs-12">
<button class="btn btn-default btn-block btn-lg">
Option 1
</button>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<button class="btn btn-default btn-block btn-lg">
Option 2
</button>
</div>
</div>
<!--The generated html as example: -->
<!--<div class="row">
<div class="col-xs-1">
<div class="tree-border">
</div>
</div>
<div class="col-xs-11">
<div class="row">
<div class="col-xs-12">
<button class="btn btn-default btn-block btn-lg">
Option 2
</button>
</div>
</div>
</div>
</div>-->
</div>
</div>
JSFiddle
I added a border in a .column-*-1 to allow for some spacing for the border:
The spacing however, I find a bit too much. How could I address this problem? I would like to refrain from styling Bootstrap's grid system (meaning I preferably would not want to touch any styling behind .col-* and .row classes etc.) because this might break the responsiveness or anything else related to Bootstrap.
Edit:
I also noticed that when adding a lot of buttons by just clicking them, the layout of tree will start failing as well. (I am aware this is a different question, so if I need to post another question regarding this problem, please do let me know) Is there a way I could address this so that the element works correctly?
Add this little CSS
#tree-replacement .row.flex > .col-xs-11:nth-child(2):before {
content: ' ';
position: absolute;
left: calc(-100% / 11 + 30px);
top: 2em;
border-top: 1px dashed #000000;
width: calc(100% / 5 - 15px);
}
//Event delegation
function BindEvent(parent, eventType, ele, func) {
var element = document.querySelector(parent);
element.addEventListener(eventType, function(event) {
var possibleTargets = element.querySelectorAll(ele);
var target = event.target;
for (var i = 0, l = possibleTargets.length; i < l; i++) {
var el = target;
var p = possibleTargets[i];
while (el && el !== element) {
if (el === p) {
return func.call(p, event);
}
el = el.parentNode;
}
}
});
}
//Add content after referenced element
function insertAfter(referenceNode, newNode) {
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
//Custom function
function LoadSubOptions(ele) {
ele = ele.parentElement.parentElement;
let newEle = document.createElement("div");
newEle.classList.add("row", "flex");
//Generated HTML Content (currently hard coded):
newEle.innerHTML = "<div class='col-xs-1'><div class='tree-border'></div></div><div class='col-xs-11'><div class='row'><div class='col-xs-12'><button class='btn btn-default btn-block btn-lg'>Test</button></div></div></div>";
insertAfter(ele, newEle);
}
//Bind method(s) on button click(s)
BindEvent("#tree-replacement", "click", "button", function(e) {
LoadSubOptions(this);
});
#tree-replacement button {
margin-top: 5px;
}
.tree-border {
border-left: 1px dashed #000;
height: 100%;
margin-left: 15px;
}
.flex {
display: flex;
}
/*Probably not wise to use this method on Bootstrap's grid system: */
#tree-replacement .row.flex>[class*='col-'] {
display: flex;
flex-direction: column;
}
#tree-replacement .row.flex > .col-xs-11:nth-child(2):before {
content: ' ';
position: absolute;
left: calc(-100% / 11 + 30px);
top: 2em;
border-top: 1px dashed #000000;
width: calc(100% / 5 - 15px);
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet" />
<div class="container">
<div id="tree-replacement">
<div class="row">
<div class="col-xs-12">
<button class="btn btn-default btn-block btn-lg">
Option 1
</button>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<button class="btn btn-default btn-block btn-lg">
Option 2
</button>
</div>
</div>
<!--The generated html as example: -->
<!--<div class="row">
<div class="col-xs-1">
<div class="tree-border">
</div>
</div>
<div class="col-xs-11">
<div class="row">
<div class="col-xs-12">
<button class="btn btn-default btn-block btn-lg">
Option 2
</button>
</div>
</div>
</div>
</div>-->
</div>
</div>
Here I have used absolute positioning and increased height by 5px which kind of makes it touches the next div element.
Here is the Fiddle Link
and the Code Snippet:
//Event delegation
function BindEvent(parent, eventType, ele, func) {
var element = document.querySelector(parent);
element.addEventListener(eventType, function(event) {
var possibleTargets = element.querySelectorAll(ele);
var target = event.target;
for (var i = 0, l = possibleTargets.length; i < l; i++) {
var el = target;
var p = possibleTargets[i];
while (el && el !== element) {
if (el === p) {
return func.call(p, event);
}
el = el.parentNode;
}
}
});
}
//Add content after referenced element
function insertAfter(referenceNode, newNode) {
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
//Custom function
function LoadSubOptions(ele) {
ele = ele.parentElement.parentElement;
let newEle = document.createElement("div");
newEle.classList.add("row", "flex");
//Generated HTML Content (currently hard coded):
newEle.innerHTML = "<div class='col-xs-1'><div class='tree-border'></div></div><div class='col-xs-11'><div class='row'><div class='col-xs-12'><button class='btn btn-default btn-block btn-lg'>Test</button></div></div></div>";
insertAfter(ele, newEle);
}
//Bind method(s) on button click(s)
BindEvent("#tree-replacement", "click", "button", function(e) {
LoadSubOptions(this);
});
#tree-replacement button {
margin-top: 5px;
}
.tree-border {
border-left: 1px dashed #000;
height: calc(100% + 5px);
margin-left: 20px;
position: absolute;
}
.flex {
position: relative;
display: flex;
}
.col-xs-11 .col-xs-12 {
padding-left: 0;
}
/*Probably not wise to use this method on Bootstrap's grid system: */
#tree-replacement .row.flex>[class*='col-'] {
display: flex;
flex-direction: column;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
<div id="tree-replacement">
<div class="row">
<div class="col-xs-12">
<button class="btn btn-default btn-block btn-lg">
Option 1
</button>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<button class="btn btn-default btn-block btn-lg">
Option 2
</button>
</div>
</div>
<!--<div class="row">
<div class="col-xs-1">
<div class="tree-border">
</div>
</div>
<div class="col-xs-11">
<div class="row">
<div class="col-xs-12">
<button class="btn btn-default btn-block btn-lg">
Option 2
</button>
</div>
</div>
</div>
</div>-->
</div>
</div>
So basically, I have an image upload page where users can upload images.I use laravel for the backend.It hasn't been working since and the server kept returning errors.So I chnaged the post request to GET and I found out that instead of the script sendind something like http://localhost:8000/upload?title='whatever'&body='theimageselected.jpg'
Of course,the title and body values are variables.They will be different according to what the user wants to uploaad..
It sends this:
http://localhost:8000/upload?[object%20Object]&_=1558376643031
Why?
Here is my code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="shortcut icon" type="image/x-icon" href="https://static.codepen.io/assets/favicon/favicon-aec34940fbc1a6e787974dcd360f2c6b63348d4b1f4e06c77743096d55480f33.ico" />
<link rel="mask-icon" type="" href="https://static.codepen.io/assets/favicon/logo-pin-8f3771b1072e3c38bd662872f6b673a722f4b3ca2421637d5596661b4e2132cc.svg" color="#111" />
<title>CodePen - Image Upload With Live Preview using FormData</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
<style>
.container {
padding-top: 3%;
}
.hide-element {
display: none;
}
.glyphicon-remove-circle {
float: right;
font-size: 2em;
cursor: pointer;
}
/*
* http://www.abeautifulsite.net/whipping-file-inputs-into-shape-with-bootstrap-3/
*/
.btn-file {
position: relative;
overflow: hidden;
/*box-shadow: 10px 10px 5px #888888;*/
}
.btn-file input[type=file] {
position: absolute;
top: 0;
right: 0;
min-width: 100%;
min-height: 100%;
font-size: 100px;
text-align: right;
filter: alpha(opacity=0);
opacity: 0;
outline: none;
background: white;
cursor: inherit;
display: block;
}
.alert,
.well {
box-shadow: 10px 10px 5px;
-moz-box-shadow: 10px 10px 5px;
-webkit-box-shadow: 10px 10px 5px;
}
#uploadDataInfo p {
margin-left: 2%;
margin-top: 3%;
font-size: 1.2em;
}
.media-left #edit {
z-index: 1000;
cursor: pointer;
}
.thumbnail #edit {
position: absolute;
display: inline;
z-index: 1000;
top: 1px;
right: 15px;
cursor: pointer;
}
.thumbnail #delete {
position: absolute;
display: inline;
z-index: 1000;
margin-top: 4%;
top: 20px;
right: 15px;
cursor: pointer;
}
.caption input[type="text"] {
/*width: 80%;*/
}
.thumbnail .fa-check-circle {
color: #006dcc;
*color: #0044cc;
}
.thumbnail .fa-times-circle {
color: #E74C3C;
}
.modal-header .close {
float: right !important;
margin-right: -30px !important;
margin-top: -25px !important;
background-color: white !important;
border-radius: 15px !important;
width: 30px !important;
height: 30px !important;
opacity: 1 !important;
}
.modal-header {
padding: 0px;
min-height: 0px;
}
.modal-dialog {
top: 50px;
}
.media-left img {
cursor: pointer;
}
.label-tags {
font-size: 16px;
padding: 1%;
color: black;
background-color: white;
border: 1px solid blue;
border-radius: 4px;
margin: 3px;
}
.label-tags i {
cursor: pointer;
}
</style>
<script>
window.console = window.console || function(t) {};
</script>
<script>
if (document.location.search.match(/type=embed/gi)) {
window.parent.postMessage("resize", "*");
}
</script>
</head>
<body translate="no">
<div id="individualImagePreview" class="modal fade" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><i class="fa fa-times"></i></button>
</div>
<div class="modal-body">
<img src="" alt="default image" class="img-responsive" id="individualPreview" />
</div>
<div class="modal-footer" id="displayTags">
<div class="pull-left">
</div>
</div>
</div>
</div>
</div>
<div id="progressModal" class="modal fade" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
</div>
<div class="modal-body">
<div id="ajaxLoad">
<div class="progress">
<div class="progress-bar progress-bar-striped active" role="progressbar" aria-valuemax="100" id="progressIndicator" style="">
<span class="sr-only">45% Complete</span>
</div>
</div>
<i class="fa fa-cog fa-spin fa-4x"></i> </div>
</div>
<div class="modal-footer hide-element">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<div class="container">
<div class="alert hide-element" role="alert" id="errorMessaage"></div>
<div class="alert hide-element" role="alert" id="file-error-message">
<span class='glyphicon glyphicon-remove-circle'></span>
<p></p>
</div>
<form class="well" id="imagesUploadForm">
<label for="file">Select files to upload</label>
<br />
<span class="btn btn-primary btn-file">
Browse <input type="file" multiple="multiple" accept="image/*" id="uploadImages" /></span>
<p class="help-block">
Only jpg,jpeg,png file with maximum size of 2 MB is allowed.
</p>
<button type="button" data-toggle="modal" data-target="#myModal" class="btn btn-lg btn-primary disabled" value="Preview" name="imagesUpload" id="imagesUpload">Preview</button>
</form>
<div id="uploadDataInfo" class="alert hide-element">
<a href="#" class="close" data-dismiss="alert" aria-label="close">
<i class="fa fa-times"></i>
</a>
<p class="" id="toManyFilesUploaded"></p>
<p class="" id="filesCount"></p>
<p class="" id="filesSupported"></p>
<p class="" id="filesUnsupported"></p>
</div>
<div class="hide-element" id="previewImages">
<div class="media">
<div class="media-left">
<img class="media-object thumbnail" src="img/200x200.gif" alt="" id="0" title="" data-toggle="modal" data-target="#individualImagePreview" />
</div>
<div class="media-body">
<p><label for="description">Description: </label><input type="text" class="form-control" value="" name="description" /></p>
<p><label for="caption">Caption: </label><input type="text" class="form-control" value="" name="caption" /></p>
<p><label for="tags">Tags:max of 3 tags.comma seperated </label><input type="text" class="form-control" value="" name="tags" /></p>
<a role="button" class="btn btn-primary hide-element" id="undo0">Undo</a>
<a role="button" class="btn btn-danger pull-right" id="delete0">Delete</a>
</div>
</div>
<div class="media">
<div class="media-left">
<img class="media-object thumbnail" src="img/200x200.gif" alt="" id="1" title="" data-toggle="modal" data-target="#individualImagePreview" />
</div>
<div class="media-body">
<p><label for="description">Description: </label><input type="text" class="form-control" value="" name="description" /></p>
<p><label for="caption">Caption: </label><input type="text" class="form-control" value="" name="caption" /></p>
<p><label for="tags">Tags: </label><input type="text" class="form-control" value="" name="tags" /></p>
<a role="button" class="btn btn-primary hide-element" id="undo1">Undo</a>
<a role="button" class="btn btn-danger pull-right" id="delete1">Delete</a>
</div>
</div>
<div class="media">
<div class="media-left">
<img class="media-object thumbnail" src="img/200x200.gif" alt="" id="2" title="" data-toggle="modal" data-target="#individualImagePreview" />
</div>
<div class="media-body">
<p><label for="description">Description: </label><input type="text" class="form-control" value="" name="description" /></p>
<p><label for="caption">Caption: </label><input type="text" class="form-control" value="" name="caption" /></p>
<p><label for="tags">Tags: </label><input type="text" class="form-control" value="" name="tags" /></p>
<a role="button" class="btn btn-primary hide-element" id="undo2">Undo</a>
<a role="button" class="btn btn-danger pull-right" id="delete2">Delete</a>
</div>
</div>
<div class="media">
<div class="media-left">
<img class="media-object thumbnail" src="img/200x200.gif" alt="" id="3" data-toggle="modal" data-target="#individualImagePreview" />
</div>
<div class="media-body">
<p><label for="description">Description: </label>
<input type="text" class="form-control" name="description" value="" /></p>
<p><label for="caption">Caption: </label>
<input type="text" class="form-control" name="caption" value="" /></p>
<p><label for="tags">Tags: </label>
<input type="text" class="form-control" name="tags" value="" /></p>
<a role="button" class="btn btn-primary hide-element" id="undo3">Undo</a>
<a role="button" class="btn btn-danger pull-right" id="delete3">Delete</a>
</div>
</div>
<button class="btn btn-primary pull-left" id="sendImagesToServer" data-toggle="modal" data-target="#progressModal" data-keyboard="false" data-backdrop="static">Update & Preview</button>
</div>
<br /><br />
<div id="myModal" class="modal fade" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><i class="fa fa-times"></i></button>
</div>
<div class="modal-body">
<div id="myCarousel" class="carousel slide">
<div class="carousel-inner" role="listbox" id="previewItems">
</div>
<a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="right carousel-control" href="#myCarousel" role="button" data-slide="next">
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
</div>
<div class="modal-footer hide-element">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
<script src="https://static.codepen.io/assets/common/stopExecutionOnTimeout-de7e2ef6bfefd24b79a3f68b414b87b8db5b08439cac3f1012092b2290c719cd.js"></script>
<script id="rendered-js">
$(document).ready(function () {
$('[data-toggle="tooltip"]').tooltip({
html: true });
$('.media').addClass('hide-element');
$('#imagesUploadForm').submit(function (evt) {
evt.preventDefault();
});
$('#edit').click(function () {
console.log('click detected inside circl-o of edit');
$('#edit').toggleClass('fa-circle-o').toggleClass('fa-check-circle');
if ($('#edit').hasClass('fa-check-circle')) {
$('#captionForImage').toggleClass('hide-element');
} else {
$('#captionForImage').toggleClass('hide-element');
}
});
$('#delete').click(function () {
console.log('click detected inside circl-o of delete');
$('#delete').toggleClass('fa-circle-o').toggleClass('fa-times-circle');
});
//namespace variable to determine whether to continue or not
var proceed = true;
//Ensure that FILE API is supported by the browser to proceed
if (proceed) {
var input = "";
var formData = new FormData();
$('input[type=file]').on("change", function (e) {
var counter = 0;
var modalPreviewItems = "";
input = this.files;
$($(this)[0].files).each(function (i, file) {
formData.append("file[]", file);
});
$('#previewImages').removeClass('hide-element');
$('#imagesUpload').removeClass('disabled');
var successUpload = 0;
var failedUpload = 0;
var extraFiles = 2;
var size = input.length;
$(input).each(function () {
var reader = new FileReader();
var uploadImage = this;
console.log(this);
reader.readAsArrayBuffer(this);
reader.onload = function (e) {
var magicNumbers = validateImage.magicNumbersForExtension(e);
var fileSize = validateImage.isUploadedFileSizeValid(uploadImage);
var extension = validateImage.uploadFileExtension(uploadImage);
var isValidImage = validateImage.validateExtensionToMagicNumbers(magicNumbers);
var thumbnail = validateImage.generateThumbnail(uploadImage);
if (fileSize && isValidImage) {
$('#' + counter).parents('.media').removeClass('hide-element');
$('#' + counter).attr('src', thumbnail).height('200');
$('#uploadDataInfo').removeClass('hide-element').addClass('alert-success');
successUpload++;
modalPreviewItems += carouselInsideModal.createItemsForSlider(thumbnail, counter);
} else {
$('#uploadDataInfo').removeClass('hide-element alert-success').addClass('alert-warning');
failedUpload++;
}
counter++;
if (counter === size) {
$('#myCarousel').append(carouselInsideModal.createIndicators(successUpload, "myCarousel"));
$('#previewItems').append(modalPreviewItems);
$('#previewItems .item').first().addClass('active');
$('#carouselIndicators > li').first().addClass('active');
$('#myCarousel').carousel({
interval: 2000,
cycle: true });
if (size > 4) {
$('#toManyFilesUploaded').html("Only files displayed below will be uploaded");
extraFiles = size - 4;
}
$('#filesCount').html(successUpload + " files are ready to upload");
if (failedUpload !== 0 || extraFiles !== 0) {
failedUpload === 0 ? "" : failedUpload;
extraFiles === 0 ? "" : extraFiles;
$('#filesUnsupported').html(failedUpload + extraFiles + " files were not selected for upload");
}
}
};
});
});
$(document).on('click', '.glyphicon-remove-circle', function () {
$('#file-error-message').addClass('hide-element');
});
$("body").on("click", ".media-object", function () {
var image = $(this).attr('src');
$("#individualPreview").attr('src', image);
var tags = [];
var displayTagsWithFormat = "";
$(this).parents('.media').find('input[type="text"]').each(function () {
if ($(this).attr('name') === 'tags') {
tags = $(this).val().split(",");
$.each(tags, function (index) {
displayTagsWithFormat += "<span class = 'label-tags label'>#" + tags[index] + " <i class='fa fa-times'></i></span>";
});
$("#displayTags").html("<div class='pull-left'>" + displayTagsWithFormat + "</div>");
//console.log(tags);
}
});
});
var toBeDeleted = [];
var eachImageValues = [];
$('.media').each(function (index) {
var imagePresent = "";
$("body").on("click", "#delete" + index, function () {
imagePresent = $("#" + index).attr('src');
$("#undo" + index).removeClass('hide-element');
$("#" + index).attr('src', './img/200x200.gif');
$("#delete" + index).addClass('hide-element');
toBeDeleted.push(index);
//console.log(toBeDeleted);
$("#delete" + index).parent().find('input[type="text"]').each(function () {
var attribute = $(this).attr('name');
var attributeValue = $(this).val();
eachImageValues[attribute + index] = attributeValue;
//console.log(eachImageValues);
});
//console.log(toBeDeleted.length);
if (toBeDeleted.length === 4) {
$('#sendImagesToServer').prop('disabled', true).html('No Files to Upload');
} else {
$('#sendImagesToServer').prop('disabled', false).html('Update & Preview');
}
$("#delete" + index).parent().find('input[type="text"]').prop('disabled', true).addClass('disabled');
});
$("body").on("click", "#undo" + index, function () {
$("#" + index).attr('src', imagePresent);
$("#undo" + index).addClass('hide-element');
$("#delete" + index).removeClass('hide-element');
var indexToDelete = toBeDeleted.indexOf(index);
if (indexToDelete > -1) {
toBeDeleted.splice(indexToDelete, 1);
// console.log(toBeDeleted);
$("#delete" + index).parent().find('input[type="text"]').prop('disabled', false).removeClass('disabled');
}
if (toBeDeleted.length === 4) {
$('#sendImagesToServer').prop('disabled', true).html('No Files to Upload');
} else {
$('#sendImagesToServer').prop('disabled', false).html('Update & Preview');
}
});
});
$('body').on("click", "#sendImagesToServer", function () {
var counter = 0;
var imageData = "";
var consolidatedData = [];
$('.media').each(function () {
var description = "";
var caption = "";
var tags = "";
$('.media').find('input[type="text"]').each(function (index) {
if ((index === 0 || index <= 11) && counter <= 11) {
counter++;
var attributeName = "";
var attributeValue = "";
attributeName = $(this).attr('name');
attributeValue = $(this).val();
switch (attributeName) {
case "title":
title = attributeName;
// console.log(description);
break;
case "caption":
body = attributeName;
// console.log(caption);
break;
case "tags":
tags =attributeName;
// console.log(tags);
break;
default:
break;}
if (counter % 3 === 0) {
imageData = new imageInformation(description, caption, tags);
consolidatedData.push(imageData);
//JSON.stringify(consolidatedData);
//console.log(toBeDeleted);
}
}
});
});
imageData = new deleteList(toBeDeleted);
consolidatedData.push(imageData);
var sendData = JSON.stringify(consolidatedData);
formData.append("important", sendData);
$.ajax({
type: 'GET',
url: '/upload',
xhr: function () {
var customXhr = $.ajaxSettings.xhr();
if (customXhr.upload) {
customXhr.upload.addEventListener('progress', progressHandlingFunction, false); // For handling the progress of the upload
}
return customXhr;
},
data: {title:"test",body:"body"},
dataType: 'json',
cache: false,
contentType: false,
processData: false,
success: function (data) {
$('#ajaxLoad').addClass('hide-element');
$('#successResponse').html(data.message);
console.log(data.message + " inside success function");
},
error: function (data) {
$('#successResponse').html(data.responseJSON.message).addClass('label label-danger').css({
'font-size': '18px' });
console.log(data.responseJSON.message + " inside error function");
} });
function progressHandlingFunction(e) {
if (e.lengthComputable) {
$('#progressIndicator').css({
'width': e.loaded });
}
};
//
//console.log(JSON.stringify(consolidatedData));
});
function imageInformation(description, caption, tags) {
this.description = description;
this.title = caption;
this.tags = tags;
this.type = "image";
};
function deleteList(toBeDeleted) {
this.toBeDeleted = toBeDeleted;
};
var validateImage = {
magicNumbersForExtension: function (event) {
var headerArray = new Uint8Array(event.target.result).subarray(0, 4);
var magicNumber = "";
for (var counter = 0; counter < headerArray.length; counter++) {if (window.CP.shouldStopExecution(0)) break;
magicNumber += headerArray[counter].toString(16);
}window.CP.exitedLoop(0);
return magicNumber;
},
isUploadedFileSizeValid: function (fileUploaded) {
var fileSize = fileUploaded.size;
var maximumSize = 2097125;
var isValid = "";
if (fileSize <= maximumSize) {
isValid = true;
} else {
isValid = false;
}
return isValid;
},
uploadFileExtension: function (fileUploaded) {
var fileExtension = "";
var imageType = "";
imageType = fileUploaded.type.toLowerCase();
fileExtension = imageType.substr(imageType.lastIndexOf('/') + 1);
return fileExtension;
},
validateExtensionToMagicNumbers: function (magicNumbers) {
var properExtension = "";
if (magicNumbers.toLowerCase() === "ffd8ffe0" || magicNumbers.toLowerCase() === "ffd8ffe1" ||
magicNumbers.toLowerCase() === "ffd8ffe8" ||
magicNumbers.toLocaleLowerCase() === "89504e47") {
properExtension = true;
} else {
properExtension = false;
}
return properExtension;
},
generateThumbnail: function (uploadImage) {
if (window.URL)
imageSrc = window.URL.createObjectURL(uploadImage);else
imageSrc = window.webkitURL.createObjectURL(uploadImage);
return imageSrc;
} };
var carouselInsideModal = {
createIndicators: function (carouselLength, dataTarget) {
var carouselIndicators = '<ol class = "carousel-indicators" id="carouselIndicators">';
for (var counter = 0; counter < carouselLength; counter++) {if (window.CP.shouldStopExecution(1)) break;
carouselIndicators += '<li data-target = "#' + dataTarget + '"data-slide-to="' + counter + '"></li>';
}window.CP.exitedLoop(1);
carouselIndicators += "</ol>";
return carouselIndicators;
},
createItemsForSlider: function (imgSrc, counter) {
var item = '<div class = "item">' + '<img src="' + imgSrc + '" id="preview' + counter + '" /></div>';
return item;
} };
}
});
//# sourceURL=pen.js
</script>
<script>
$('.laravel-like').on('click', function(){
if($(this).hasClass('disabled'))
return false;
var item_id = $(this).data('item-id');
var vote = $(this).data('vote');
$.ajax({
method: "post",
url: "/",
data: {item_id: item_id, vote: vote},
dataType: "json"
})
.done(function(msg){
if(msg.flag == 1){
if(msg.vote == 1){
$('#'+item_id+'-like').removeClass('outline');
$('#'+item_id+'-dislike').addClass('outline');
}
else if(msg.vote == -1){
$('#'+item_id+'-dislike').removeClass('outline');
$('#'+item_id+'-like').addClass('outline');
}
else if(msg.vote == 0){
$('#'+item_id+'-like').addClass('outline');
$('#'+item_id+'-dislike').addClass('outline');
}
$('#'+item_id+'-total-like').text(msg.totalLike == null ? 0 : msg.totalLike);
$('#'+item_id+'-total-dislike').text(msg.totalDislike == null ? 0 : msg.totalDislike);
}
})
.fail(function(msg){
alert(msg);
});
});
$(document).on('click', '.reply-button', function(){
if($(this).hasClass("disabled"))
return false;
var toggle = $(this).data('toggle');
$("#"+toggle).fadeToggle('normal');
});
$(document).on('submit', '.laravelComment-form', function(){
var thisForm = $(this);
var parent = $(this).data('parent');
var item_id = $(this).data('item');
var comment = $('textarea#'+parent+'-textarea').val();
$.ajax({
method: "get",
url: "/laravellikecomment/comment/add",
data: {parent: parent, comment: comment, item_id: item_id},
dataType: "json"
})
.done(function(msg){
$(thisForm).toggle('normal');
var newComment = '<div class="comment" id="comment-'+msg.id+'" style="display: initial;"><a class="avatar"><img src="'+msg.userPic+'"></a><div class="content"><a class="author">'+msg.userName+'</a><div class="metadata"><span class="date">Today at 5:42PM</span></div><div class="text">'+msg.comment+'</div><div class="actions"><a class="reply reply-button" data-toggle="'+msg.id+'-reply-form">Reply</a></div><form class="ui laravelComment-form form" id="'+msg.id+'-reply-form" data-parent="'+msg.id+'" data-item="'+item_id+'" style="display: none;"><div class="field"><textarea id="'+msg.id+'-textarea" rows="2"></textarea></div><input type="submit" class="ui basic small submit button" value="Reply"></form></div><div class="ui threaded comments" id="'+item_id+'-comment-'+msg.id+'"></div></div>';
$('#'+item_id+'-comment-'+parent).prepend(newComment);
$('textarea#'+parent+'-textarea').val('');
})
.fail(function(msg){
alert(msg);
});
return false;
});
$(document).on('click', '#showComment', function(){
var show = $(this).data("show-comment");
$('.show-'+$(this).data("item-id")+'-'+show).fadeIn('normal');
$(this).data("show-comment", show+1);
$(this).text("Show more");
});
$(document).on('click', '#write-comment', function(){
$($(this).data("form")).show();
});
</script>
</body>
</html>
you can try
data: JSON.stringify({
title: "Test",
body: "test"
}),
I have created a drag and drop area which generates list elements on drop, which works vertically but I'd want horizontal support. I simply want an element to "move" to the side when another element is hoverd above it.
I have tried making an invisible grid to determine where a box is but this doesn't work when sorting the elements
<div id="jvformbuilder_menu">
<div id="jvformbuilder-element-menu">
<div class="formField drag-drop input">
<p>
<i class="fas fa-fw fa-pencil-alt"></i>
Field
<i class="fas fa-fw fa-grip-lines"></i>
</p>
</div>
<div class="formField drag-drop form-button">
<p>
<i class="far fa-fw fa-dot-circle"></i>
Button
<i class="fas fa-fw fa-grip-lines"></i>
</p>
</div>
<div class="formField drag-drop slider">
<p>
<i class="fas fa-fw fa-sliders-h"></i>
Slider
<i class="fas fa-fw fa-grip-lines"></i>
</p>
</div>
<div class="formField drag-drop list">
<p>
<i class="fas fa-fw fa-list-ul"></i>
List
<i class="fas fa-fw fa-grip-lines"></i>
</p>
</div>
</div>
</div>
<div id="contentWrap">
<ul id="outer-dropzone" class="jvformbuilder_results dropzone">
<li class="builder-elements-wrap empty-insert"></li>
</ul>
</div>
JS File:
function drag() {
$(".drag-drop").draggable({
helper: "clone",
revert: "invalid",
connectToSortable: '.dropzone',
revertDuration: 300,
start: function (e) {
$(e.target).css({ opacity: 0.5 });
},
stop: function (e) { // need to put it back on stop
$(e.target).css({ opacity: 1 });
},
});
if($('.dropzone').length == 1){
$('.dropzone').append(
$('<p class="noDropText">').text("You haven't added any elements yet, add some!")
)
}
$('.builder-elements-wrap').sortable({
placeholder: "ph",
opacity: 0.5,
});
$(".dropzone").sortable({
placeholder: "ph",
opacity: 0.5,
stop: function( event, ui ) {
if($('.noDropText').length){
$('.noDropText').remove();
}
var id = ui.item.attr("class");
if (id == "formField drag-drop input ui-draggable ui-draggable-handle ui-draggable-dragging") {
var myElement = $('<li class="builder-elements-wrap item">').append(
$('<div class="builder-elements" id="input-element">').append(
$('<input class="builder-input" type="text" name="data[builderField]" placeholder ="Write something..." />'),
$('<div class="dragHandle"><i class="fas fa-arrows-alt">')
)
);
$(ui.item).replaceWith(myElement);
$(myElement).children('.builder-elements').animate({ width: '98.5%' })
}
else if (id == "formField drag-drop form-button ui-draggable ui-draggable-handle ui-draggable-dragging") {
var myElement = $('<li class="builder-elements" id="button-element">').append(
$('<input class="builderButton" type="submit" value="Submit">'),
$('<div class="dragHandle"><i class="fas fa-arrows-alt">')
);
$(ui.item).replaceWith(myElement);
$('.builder-elements').animate({ width: '99.5%' });
}
else if (id == "formField drag-drop slider ui-draggable ui-draggable-handle ui-draggable-dragging") {
var myElement = $('<li class="builder-elements" id="slider-element">').append(
$('<input type="range" min="1" max="100" value="50" class="builderSlider" id="range"><p>Value: <span id="sliderValue"></span></p>'),
$('<div class="dragHandle"><i class="fas fa-arrows-alt">')
);
$(ui.item).replaceWith(myElement);
$('.builder-elements').animate({ width: '99.5%' });
// JS for formbuilder's slider element.
var slider = document.getElementById("range");
var output = document.getElementById("sliderValue");
output.innerHTML = slider.value;
slider.oninput = function () {
output.innerHTML = this.value;
}
}
else if (id == "formField drag-drop list ui-draggable ui-draggable-handle ui-draggable-dragging") {
var myElement = $('<li class="builder-elements" id="list-element">').append(
$('<ul class="builderList">').append(
$('<li class="builderListItem">').text("item 1"),
$('<li class="builderListItem">').text("item 2"),
$('<li class="builderListItem">').text("item 3")
),
$('<div class="dragHandle"><i class="fas fa-arrows-alt">')
);
$(ui.item).replaceWith(myElement);
$('.builder-elements').animate({ width: '99.5%' });
}
$(".dropzone").droppable({
activeClass: "dropActive",
hoverClass: "dropHover",
over: function(event, ui) {
$('.noDropText').css('display', 'none');
},
out: function () {
if ($('.dropzone').find('.builder-elements').length === 0) {
$('.noDropText').css('display', 'block');
}
}
});
}
Right now the code works in veritcally but as I don't really have any idea how to do this. Desired result would be like this https://codepen.io/devpriya/pen/zGdrzP but it's built in Node and with Angular. Im currently working on a Wordpress plugin that creates forms so I don't have those two avalible for my current stack.
I think you may be trying to make it more complex than it needs to be. Consider the following code.
$(function() {
function makeDrag(o) {
o.draggable({
handle: ".fa-grip-lines",
helper: "clone",
revert: "invalid",
connectToSortable: '.dropzone',
revertDuration: 300,
opacity: 0.5
});
}
function addField(t) {
var li = $("<li>", {
class: "builder-elements-wrap item"
}).appendTo(t);
var el = $("<input>", {
class: "builder-input",
type: "text",
name: "data[builderField]",
placeholder: "Write something..."
}).appendTo(li);
var h = $("<i>", {
class: "handle fas fa-fw fa-grip-lines"
}).appendTo(li);
}
function addButton(t) {
var li = $("<li>", {
class: "builder-elements-wrap item"
}).appendTo(t);
var el = $("<input>", {
class: "builder-button",
type: "submit",
value: "Submit"
}).appendTo(li);
var h = $("<i>", {
class: "handle fas fa-fw fa-grip-lines"
}).appendTo(li);
}
function addSlide(t) {
var li = $("<li>", {
class: "builder-elements-wrap item"
}).appendTo(t);
var el = $("<input>", {
class: "builder-slider",
type: "range",
value: 50,
min: 0,
max: 100
}).appendTo(li);
var v = $("<label>", {
class: ".builder-slider-label"
}).html("Value:").appendTo(li);
$("<span>", {
class: "builder-slider-value"
}).html(50).appendTo(v);
var h = $("<i>", {
class: "handle fas fa-fw fa-grip-lines"
}).appendTo(li);
}
function addList(t) {
var li = $("<li>", {
class: "builder-elements-wrap item"
}).appendTo(t);
var el = $("<ol>", {
class: "builder-list",
}).appendTo(li);
$("<li>", {
class: "builder-list-item"
}).html("Item 1").appendTo(el);
$("<li>", {
class: "builder-list-item"
}).html("Item 2").appendTo(el);
$("<li>", {
class: "builder-list-item"
}).html("Item 3").appendTo(el);
var h = $("<i>", {
class: "handle fas fa-fw fa-grip-lines"
}).appendTo(li);
}
makeDrag($(".drag-drop"));
if ($('.dropzone').length == 1) {
$('.dropzone li:eq(0)').append(
$('<p class="noDropText">').text("You haven't added any elements yet, add some!")
);
}
$(".dropzone").sortable({
handle: ".handle",
placeholder: ".builder-placeholder",
opacity: 0.75,
receive: function(e, ui) {
if ($('.dropzone .empty-insert').length == 1) {
$('.dropzone').html("");
}
switch (true) {
case ui.helper.hasClass("input"):
console.log("Input Dropped");
addField($(this));
break;
case ui.helper.hasClass("form-button"):
console.log("Button Dropped");
addButton($(this));
break;
case ui.helper.hasClass("slider"):
console.log("Slider Dropped");
addSlide($(this));
break;
case ui.helper.hasClass("list"):
console.log("List Dropped");
addList($(this));
break;
}
ui.helper.remove();
},
over: function(event, ui) {
if ($('.noDropText').length) {
$('.noDropText').data("content", $('.noDropText').html()).html(" ");
}
},
out: function() {
if ($('.dropzone').find('.builder-elements').length === 0) {
$('.noDropText').html($('.noDropText').data("content"));
}
}
});
});
#jvformbuilder_menu {
display: block;
width: 100%;
}
#jvformbuilder-element-menu .drag-drop {
display: inline-block;
padding: .4em;
background: #ccc;
border-radius: 3px;
width: 20%;
}
#jvformbuilder-element-menu .drag-drop .fa-grip-lines {
float: right;
cursor: grab;
}
#outer-dropzone {
padding: 5px;
list-style: none;
border: 1px solid #ccc;
border-radius: 3px;
}
#outer-dropzone .item {
display: inline;
background: #999;
padding: .4em;
border-radius: 3px;
margin-right: 3px;
}
.builder-placeholder {
width: 100px;
}
.builder-slider {
display: inline-block;
}
.builder-slider-label {
font-size: .65em;
padding: 0 1px;
}
.builder-list {
padding-left: 1em
}
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css" integrity="sha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf" crossorigin="anonymous">
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div id="jvformbuilder_menu">
<div id="jvformbuilder-element-menu">
<div class="formField drag-drop input">
<i class="fas fa-fw fa-pencil-alt"></i> Field
<i class="fas fa-fw fa-grip-lines"></i>
</div>
<div class="formField drag-drop form-button">
<i class="far fa-fw fa-dot-circle"></i> Button
<i class="fas fa-fw fa-grip-lines"></i>
</div>
<div class="formField drag-drop slider">
<i class="fas fa-fw fa-sliders-h"></i> Slider
<i class="fas fa-fw fa-grip-lines"></i>
</div>
<div class="formField drag-drop list">
<i class="fas fa-fw fa-list-ul"></i> List
<i class="fas fa-fw fa-grip-lines"></i>
</div>
</div>
</div>
<div id="contentWrap">
<ul id="outer-dropzone" class="jvformbuilder_results dropzone">
<li class="builder-elements-wrap empty-insert"></li>
</ul>
</div>
When you drag an item into the list, it converts it into an HTML element. li elements use box bounding just like most elements. So the block at 100% by default. If you change the display or float them, you can have them sit side by side.
Hope that helps.
In the first function, an item is marked read or unread by clicking the .activity__button. The next function is to change the status of all of the items to read.
Why isn't the function iterating over each item and button?
var button = $(".activity__button");
var item = $(".activity__item");
When I press the button to change the status to read, nothing happens. Additionally, how do you handle a second click of the button to change all back to unread?
$(".activity__button").on("click", function(e) {
e.stopPropagation();
e.preventDefault();
var icon = $(this).find("svg");
var status = $(this).attr("data-status");
if (status === "read") {
$(this)
.removeClass("activity__button--read")
.attr("data-status", "unread");
icon.attr("data-icon", "envelope");
$(this)
.closest(".activity__item")
.removeClass("activity__item--read")
.attr("data-status", "unread");
} else {
$(this)
.addClass("activity__button--read")
.attr("data-status", "read");
icon.attr("data-icon", "envelope-open");
$(this)
.closest(".activity__item")
.addClass("activity__item--read")
.attr("data-status", "read");
}
});
$(".section").on("click", ".mark", function(e) {
e.stopPropagation();
e.preventDefault();
var button = $(".activity__button");
var item = $(".activity__item");
var icon = button.find("svg");
var status = button.attr("data-status");
if (status === "unread") {
button.addClass("activity__button--read").attr("data-status", "read");
icon.attr("data-icon", "envelope-open");
item.addClass("activity__item--read").attr("data-status", "read");
}
});
.activity__item {
position: relative;
height: 100px;
width: 300px;
border: 1px solid whitesmoke;
margin-top: -1px;
}
.activity__button {
cursor: pointer;
padding: 1rem;
font-size: 21px;
}
.activity__button svg {
color: #f8971d;
}
.activity__button.activity__button--read svg {
color: #47a877;
}
.activity__item--read {
background: #fafafa !important;
}
button {
padding: 12px;
margin: 1rem;
}
<script src="https://pro.fontawesome.com/releases/v5.8.1/js/all.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class "section">
<button class="mark">Mark as Read</button>
<div>
<div class="activity__item">
<div class="activity__button" data-status="unread"><i class="fas fa-envelope"></i>
</div>
</div>
<div class="activity__item">
<div class="activity__button" data-status="unread"><i class="fas fa-envelope"></i>
</div>
</div>
<div class="activity__item activity__item--read">
<div class="activity__button activity__button--read" data-status="read">
<i class="fas fa-envelope-open"></i>
</div>
</div>
<div class="activity__item">
<div class="activity__button" data-status="unread">
<i class="fas fa-envelope"></i>
</div>
</div>
</div>
</div>
Working example (with other classes)
var open = 'fas fa-envelope-open';
var close = 'fas fa-envelope';
$(".activity__button").off().on('click', function() {
var status = $(this).data('status');
if( status == 'unread' ) {
$(this).data('status', 'read').empty().html('<i class="' + open + '"></i>').addClass('activity__button--read');
$(this).parent().addClass('activity__item--read');
} else {
$(this).data('status', 'unread').empty().html('<i class="' + close + '"></i>').removeClass('activity__button--read');
$(this).parent().removeClass('activity__item--read');
}
});
$('.mark').off().on('click', function() {
$(".activity__button").each( function() {
$(this).data('status', 'read').empty().html('<i class="' + open + '"></i>').addClass('activity__button--read');
$(this).parent().addClass('activity__item--read');
});
});
See here:
https://jsfiddle.net/8yk9a7rn/
I am able to insert values at cursor pointer but unable to assign the textarea value to ng-model.
app.directive('myText', ['$rootScope', function($rootScope) {
return {
link: function(scope, element, attrs) {
$rootScope.$on('add', function(e, val) {
var domElement = element[0];
if (document.selection) {
domElement.focus();
var sel = document.selection.createRange();
sel.text = val;
domElement.focus();
} else if (domElement.selectionStart || domElement.selectionStart === 0) {
var startPos = domElement.selectionStart;
var endPos = domElement.selectionEnd;
var scrollTop = domElement.scrollTop;
domElement.value = domElement.value.substring(0, startPos) + val + domElement.value.substring(endPos, domElement.value.length);
domElement.focus();
domElement.selectionStart = startPos + val.length;
domElement.selectionEnd = startPos + val.length;
domElement.scrollTop = scrollTop;
} else {
domElement.value += val;
domElement.focus();
}
});
}
}
}]);
$scope.insertValue = function(value, type) {
$rootScope.$broadcast('add', value);
//$scope.model.userApprovalMessage = $scope.model.userApprovalMessage + " " + value;
$scope.model.userApprovalMsgLength = 300 - parseFloat($scope.model.userApprovalMessage.length);
};
<div class="btn-group" style="float: left; margin-left: 5px;">
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" ng-class="model.webPageSkin3">Insert Tag</button>
<ul class="action-dropdown dropdown-menu ">
<li ng-click="insertValue('$Name')"><a>$Name</a></li>
<li ng-click="insertValue('$Groupz')"><a>$Groupz</a></li>
</ul>
</div> <br>
<br>
<div class="row">
<textarea class="compose-msg-area form-control compose-textarea" style="border: 1px solid #ddd; white-space: pre-wrap; margin-left: 20px;" ng-model="model.userApprovalMessage" placeholder="Text Message" maxlength="300" ng-change="userApprovalMessageLength(model.userApprovalMessage)"
my-text="">
</textarea>
</div>
<div class="row">
<div class="col-sm-3"><input type="text" class="form-control" numbers-only disabled style="border: 1px solid #ddd; width: 40px; background-color: #fff; padding: 5px; height: 30px; margin-top: -20px; font-weight: 600; margin-left: 5px;" ng-model="model.userApprovalMsgLength">
<label class="pull-right text-left1" for="street">text left</label>
</div>
</div>
I need to display the $scope.model.userApprovalMessage length. When I try to insert $Name at cursor pointer. I am able to add but the model value is not changing.