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"
}),
Related
This is the relevant code of my page :
HTML :
<button class="ajout-col"><i class="fas fa-columns"> Ajouter une colonne</i></button>
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th></th>
<th>
<button class="btn"><i class="fas fa-trash remove-col"></i></button>
<button class="btn"><i class="fas fa-text-height text-col"></i></button>
<button class="btn"><i class="fas fa-sort-numeric-down nbr-col"></i></button>
<input type="text" class="form-control">
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<button class="btn"><i class="fas fa-trash remove-row"></i></button>
</td>
<td>
<input type="text" class="form-control">
</td>
</tr>
</tbody>
</table>
</div>
<button class="ajout-lig"><i class="fas fa-list-ul"> Ajouter une ligne</i></button>
Javascript :
$('body').on('click', '.remove-row', function() {
$(this).parents('tr').remove();
});
(Any button of the grid refreshes my page, I just put the remove-row one because it's the shortest code only for clarity purpose)
(Issue is located on the second tab, just fill info on the first tab to be able to access the second tab)
Any time I press a button from the grid, it refreshes my page
I searched on google and it appears I have to add "return false" or "e.preventDefault();" to fix the issue, and I tried, but it only fixes partially the issue
If I add any of those at the end of each .on('click'), it fixes the issue for Adding a column or a row
But deleting a row or a column is going to work 1 or 2 times, and then my page is going to refresh again... same for the other buttons (text and number buttons)
Thanks in advance for any help ! :)
// Code goes here
$(document).ready(function() {
// add row
$('body').on('click', '.ajout-lig', function() {
var tr = $(this).parents('.table-content').find('.table tbody tr:last');
if (tr.length > 0) {
var clone = tr.clone();
clone.find(':text').val('');
tr.after(clone);
} else {
var cols = $(this).closest('.table-content').find('th').length,
tr0 = $('<tr/>');
tr0.html('<td><button class="btn"><i class="fa fa-trash remove-row"></i></button></td><td> <input type="text" class="form-control"> </td>');
for (var i = 2; i < cols; i++) {
tr0.append('<td> static element </td>')
}
$(this).closest('.table-content').find('.table tbody').append(tr0);
}
});
// delete row
$('body').on('click', '.remove-row', function() {
$(this).parents('tr').remove();
});
// add column
$('body').on('click', '.ajout-col', function() {
$(this).parent().find('.table thead tr').append('<th><button class="btn"><i class="fas fa-trash remove-col"></i></button> <button class="btn"><i class="fas fa-text-height text-col"></i></button> <button class="btn"><i class="fas fa-sort-numeric-down nbr-col"></i></button> <input type="text" class="form-control pull-left" value=""></th>');
$(this).parent().find('.table tbody tr').append('<td><input type="text" class="form-control"></td>');
});
// change column type to text
$('body').on('click', '.text-col', function(event) {
let ndx = $(this).parent().index() + 1;
let inputsCol = $('.table tbody tr td:nth-child(' + ndx + ') input');
inputsCol.attr("type", "text");
});
// change column type to number
$('body').on('click', '.nbr-col', function(event) {
var filter = /^[0-9]*$/g;
var cond = false;
var min = prompt('Valeur minimum :');
while (cond == false) {
if (min.match(filter)) {
cond = true;
} else {
var min = prompt('Valeur minimum incorrect, réessayez :');
}
}
var cond = false;
var max = prompt('Valeur maximum :');
while (cond == false) {
if (max.match(filter)) {
cond = true;
} else {
var max = prompt('Valeur maximum incorrect, réessayez :');
}
}
let ndx = $(this).parent().index() + 1;
let inputsCol = $('.table tbody tr td:nth-child(' + ndx + ') input');
inputsCol.attr("type", "number").prop("min", min).prop("max", max);
//console.log("inputs modified, example:", inputsCol2[0])
});
// remove column
$('body').on('click', '.remove-col', function(event) {
// Get index of parent TD among its siblings (add one for nth-child)
var ndx = $(this).parent().index() + 1;
// Find all TD elements with the same index
$('th', event.delegateTarget).remove(':nth-child(' + ndx + ')');
$('td', event.delegateTarget).remove(':nth-child(' + ndx + ')');
});
});
$(document).ready(function(){
$('#btn_login_details').click(function(){
var error_date = '';
var error_titre = '';
var error_entreprise = '';
var error_conseiller = '';
var filter = /^([0-2][0-9]|(3)[0-1])(\/)(((0)[0-9])|((1)[0-2]))(\/)\d{4}$/;
if($.trim($('#titre').val()).length == 0)
{
error_titre = 'Titre requis !';
$('#error_titre').text(error_titre);
$('#titre').addClass('has-error');
}
else
{
error_titre = '';
$('#error_titre').text(error_titre);
$('#titre').removeClass('has-error');
}
if($.trim($('#entreprise').val()).length == 0)
{
error_entreprise = 'Nom de l\'entreprise requis !';
$('#error_entreprise').text(error_entreprise);
$('#entreprise').addClass('has-error');
}
else
{
error_entreprise = '';
$('#error_entreprise').text(error_entreprise);
$('#entreprise').removeClass('has-error');
}
if($.trim($('#conseiller').val()).length == 0)
{
error_conseiller = 'Nom du conseiller requis !';
$('#error_conseiller').text(error_conseiller);
$('#conseiller').addClass('has-error');
}
else
{
error_conseiller = '';
$('#error_conseiller').text(error_conseiller);
$('#conseiller').removeClass('has-error');
}
if($.trim($('#date').val()).length == 0)
{
error_date = 'Date requise !';
$('#error_date').text(error_date);
$('#date').addClass('has-error');
}
else
{
if (!filter.test($('#date').val()))
{
error_date = 'Date invalide';
$('#error_date').text(error_date);
$('#date').addClass('has-error');
}
else
{
error_date = '';
$('#error_date').text(error_date);
$('#date').removeClass('has-error');
}
}
if((error_titre != '') || (error_conseiller != '') || (error_entreprise != '') || (error_date != ''))
{
return false;
}
else
{
$('#list_login_details').removeClass('active active_tab1');
$('#list_login_details').removeAttr('href data-toggle');
$('#login_details').removeClass('active');
$('#list_login_details').addClass('inactive_tab1');
$('#list_personal_details').removeClass('inactive_tab1');
$('#list_personal_details').addClass('active_tab1 active');
$('#list_personal_details').attr('href', '#personal_details');
$('#list_personal_details').attr('data-toggle', 'tab');
$('#personal_details').addClass('active in');
}
});
$('#previous_btn_personal_details').click(function(){
$('#list_personal_details').removeClass('active active_tab1');
$('#list_personal_details').removeAttr('href data-toggle');
$('#personal_details').removeClass('active in');
$('#list_personal_details').addClass('inactive_tab1');
$('#list_login_details').removeClass('inactive_tab1');
$('#list_login_details').addClass('active_tab1 active');
$('#list_login_details').attr('href', '#login_details');
$('#list_login_details').attr('data-toggle', 'tab');
$('#login_details').addClass('active in');
});
$('#btn_gen_grille').click(function() {
// Générer la grille
// Ici
});
$('#btn_personal_details').click(function(){
$('#list_personal_details').removeClass('active active_tab1');
$('#list_personal_details').removeAttr('href data-toggle');
$('#personal_details').removeClass('active');
$('#list_personal_details').addClass('inactive_tab1');
$('#list_contact_details').removeClass('inactive_tab1');
$('#list_contact_details').addClass('active_tab1 active');
$('#list_contact_details').attr('href', '#contact_details');
$('#list_contact_details').attr('data-toggle', 'tab');
$('#contact_details').addClass('active in');
});
$('#previous_btn_contact_details').click(function(){
$('#list_contact_details').removeClass('active active_tab1');
$('#list_contact_details').removeAttr('href data-toggle');
$('#contact_details').removeClass('active in');
$('#list_contact_details').addClass('inactive_tab1');
$('#list_personal_details').removeClass('inactive_tab1');
$('#list_personal_details').addClass('active_tab1 active');
$('#list_personal_details').attr('href', '#personal_details');
$('#list_personal_details').attr('data-toggle', 'tab');
$('#personal_details').addClass('active in');
});
$('#btn_contact_details').click(function(){
var error_address = '';
var error_mobile_no = '';
var mobile_validation = /^\d{10}$/;
if($.trim($('#address').val()).length == 0)
{
error_address = 'Address is required';
$('#error_address').text(error_address);
$('#address').addClass('has-error');
}
else
{
error_address = '';
$('#error_address').text(error_address);
$('#address').removeClass('has-error');
}
if($.trim($('#mobile_no').val()).length == 0)
{
error_mobile_no = 'Mobile Number is required';
$('#error_mobile_no').text(error_mobile_no);
$('#mobile_no').addClass('has-error');
}
else
{
if (!mobile_validation.test($('#mobile_no').val()))
{
error_mobile_no = 'Invalid Mobile Number';
$('#error_mobile_no').text(error_mobile_no);
$('#mobile_no').addClass('has-error');
}
else
{
error_mobile_no = '';
$('#error_mobile_no').text(error_mobile_no);
$('#mobile_no').removeClass('has-error');
}
}
if(error_address != '' || error_mobile_no != '')
{
return false;
}
else
{
$('#btn_contact_details').attr("disabled", "disabled");
$(document).css('cursor', 'prgress');
$("#register_form").submit();
}
});
});
/* Style the header with a grey background and some padding */
* {box-sizing: border-box;}
body {
margin: 0;
font-family: Arial, Helvetica, sans-serif;
}
.header {
overflow: hidden;
background-color: #f1f1f1;
padding: 20px 10px;
}
.header a {
float: left;
color: black;
text-align: center;
padding: 12px;
text-decoration: none;
font-size: 18px;
line-height: 25px;
border-radius: 4px;
}
.header a.logo {
font-size: 25px;
font-weight: bold;
}
.header a:hover {
background-color: #ddd;
color: black;
}
.header a.active {
background-color: dodgerblue;
color: white;
}
.header-right {
float: right;
}
#media screen and (max-width: 500px) {
.header a {
float: none;
display: block;
text-align: left;
}
.header-right {
float: none;
}
}
.contenuaccueil {
text-align: center;
position : absolute;
width : 100%;
color : black;
top:50%;
left:50%;
transform:translate(-50%,-50%);
}
.background
{
margin-top : 10%;
margin-bottom : 10%;
position:relative;
text-align: center;
}
.img
{
background-repeat: repeat-x;
width: 100%;
height: auto;
text-align: center;
}
footer {
text-align : center;
padding-top: 10px;
padding-bottom: 0px;
bottom:0;
width:100%;
color : #A5A5A5;
font-family : "Lato", sans-serif;
font-size : 15px;
font-weight : 400;
text-transform : uppercase;
text-decoration : none;
letter-spacing : 3px;
}
.box
{
width:800px;
margin:0 auto;
}
.active_tab1
{
background-color:#fff;
color:#333;
font-weight: 600;
}
.inactive_tab1
{
background-color: #f5f5f5;
color: #333;
cursor: not-allowed;
}
.has-error
{
border-color:#cc0000;
background-color:#ffff99;
}
/* Styles go here */
.table-content {
padding: 20px;
}
.form-control {
width: 90px;
}
/* Style buttons */
.ajout-lig,.ajout-col {
background-color: DodgerBlue; /* Blue background */
border: none; /* Remove borders */
color: white; /* White text */
padding: 12px 16px; /* Some padding */
font-size: 16px; /* Set a font size */
cursor: pointer; /* Mouse pointer on hover */
border-radius: 5px;
}
/* Darker background on mouse-over */
.ajout-lig:hover,.ajout-col:hover {
background-color: RoyalBlue;
}
<html>
<head>
<title>Innovatech</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="css/custom.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://kit.fontawesome.com/38b99a3f0e.js" crossorigin="anonymous"></script>
</head>
<body>
<!-- Titre + Menu -->
<div class="header">
Innovatech
<div class="header-right">
Accueil
<a class="active" href="ajout.php">Nouveau</a>
Modifier
Mode d'emploi
</div>
</div>
<!-- Contenu du site web -->
<div class="contenu">
<br />
<div class="container box">
<br />
<h2 align="center">Ajout d'un nouvel audit</h2><br />
<?php echo $message; ?>
<form method="post" id="register_form">
<ul class="nav nav-tabs">
<li class="nav-item">
<a class="nav-link active_tab1" style="border:1px solid #ccc" id="list_login_details">Informations à propos de l'entreprise</a>
</li>
<li class="nav-item">
<a class="nav-link inactive_tab1" id="list_personal_details" style="border:1px solid #ccc">Grille d'audit</a>
</li>
<li class="nav-item">
<a class="nav-link inactive_tab1" id="list_contact_details" style="border:1px solid #ccc">Génération des graphiques</a>
</li>
</ul>
<div class="tab-content" style="margin-top:16px;">
<div class="tab-pane active" id="login_details">
<div class="panel panel-default">
<div class="panel-heading">Informations à propos de l'entreprise</div>
<div class="panel-body">
<div class="form-group">
<label>Titre de l'audit</label>
<input type="text" name="titre" id="titre" class="form-control" />
<span id="error_titre" class="text-danger"></span>
</div>
<div class="form-group">
<label>Nom de l'entreprise</label>
<input type="text" name="entreprise" id="entreprise" class="form-control" />
<span id="error_entreprise" class="text-danger"></span>
</div>
<div class="form-group">
<label>Nom du conseiller</label>
<input type="text" name="conseiller" id="conseiller" class="form-control" />
<span id="error_conseiller" class="text-danger"></span>
</div>
<div class="form-group">
<label>Date de l'interview (jj/mm/aaaa)</label>
<input type="text" name="date" id="date" class="form-control" />
<span id="error_date" class="text-danger"></span>
</div>
<br />
<div align="center">
<button type="button" name="btn_login_details" id="btn_login_details" class="btn btn-info btn-lg">Suivant</button>
</div>
<br />
</div>
</div>
</div>
<div class="tab-pane fade" id="personal_details">
<div class="panel panel-default">
<div class="panel-heading">Grille d'audit</div>
<div class="panel-body">
<div class="table-content">
<button class="ajout-col"><i class="fas fa-columns"> Ajouter une colonne</i></button>
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th></th>
<th>
<button class="btn"><i class="fas fa-trash remove-col"></i></button>
<button class="btn"><i class="fas fa-text-height text-col"></i></button>
<button class="btn"><i class="fas fa-sort-numeric-down nbr-col"></i></button>
<input type="text" class="form-control">
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<button class="btn"><i class="fas fa-trash remove-row"></i></button>
</td>
<td>
<input type="text" class="form-control">
</td>
</tr>
</tbody>
</table>
</div>
<button class="ajout-lig"><i class="fas fa-list-ul"> Ajouter une ligne</i></button>
</div>
<br />
<div align="center">
<button type="button" name="previous_btn_personal_details" id="previous_btn_personal_details" class="btn btn-default btn-lg">Précédent</button>
<button type="button" name="btn_personal_details" id="btn_personal_details" class="btn btn-info btn-lg">Suivant</button>
</div>
<br />
</div>
</div>
</div>
<!--A MODIFIER - PARTIE SUR LES GRAPHIQUES-->
<div class="tab-pane fade" id="contact_details">
<div class="panel panel-default">
<div class="panel-heading">Fill Contact Details</div>
<div class="panel-body">
<div class="form-group">
<label>Enter Address</label>
<textarea name="address" id="address" class="form-control"></textarea>
<span id="error_address" class="text-danger"></span>
</div>
<div class="form-group">
<label>Enter Mobile No.</label>
<input type="text" name="mobile_no" id="mobile_no" class="form-control" />
<span id="error_mobile_no" class="text-danger"></span>
</div>
<br />
<div align="center">
<button type="button" name="previous_btn_contact_details" id="previous_btn_contact_details" class="btn btn-default btn-lg">Précédent</button>
<button type="button" name="btn_contact_details" id="btn_contact_details" class="btn btn-success btn-lg">Enregistrer</button>
</div>
<br />
</div>
</div>
</div>
</div>
</form>
</div>
</div>
<!-- Le pied de page -->
<footer>
<p>
Innovatech <?php echo date("Y");?> - All rights reserved
</p>
</footer>
<script src="jss/ajout.js"></script>
<script src="jss/gengrille.js"></script>
</body>
</html>
This happens because a button with no type attribute acts as type="submit" and also try to submit the form data to server and refresh the page finally. Please try to set the type to the buttons like type="button" for no page refreshes.
<button class="ajout-col" type="button">
<i class="fas fa-columns"> Ajouter une colonne</i>
</button>
Replace <button class="ajout-lig"><i class="fas fa-list-ul"> Ajouter une ligne</i></button>
to
<button class="ajout-lig" type="button"><i class="fas fa-list-ul"> Ajouter une ligne</i></button>
I think this problem is due to, these buttons are actually submitting the form. if we doesn't specify the button type, it will take as a submit type button
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>
I have here a blade page on laravel 5.4 that allows users to input survey responses. The system should show a screensaver after being idle for a certain time ie. idle is 5mins. but the screensaver should disappear when somebody interact with the page. but the codes did not function. I've check the console but it has no error in google chrome. (newbie in javascript)
#php
use App\Bus;
use App\Bgcroute;
use App\Surveyquestion;
use App\User;
use Controller\UserController;
#endphp
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>BGC Bus Survey Page</title>
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Cookie">
<link rel="stylesheet" href="assets/css/user.css">
<link rel="stylesheet" href="assets/css/Pretty-Footer.css">
<link rel="stylesheet" href="assets/css/Pretty-Header.css">
<link rel="stylesheet" href="assets/css/Hero-Technology.css">
<link rel="stylesheet" href="js-screensaver/screensaver.css">
<script src="js-screensaver/screensaver.js"></script>
<script src="sweetalert2.all.js"></script>
<script src="sweetalert2.min.js"></script>
<link rel="stylesheet" href="sweetalert2.min.js">
<style type="text/css">
.navbar {
margin-bottom: 0;
border-radius: 0;
background-color: #00FFFF;
color: #FFF;
padding: 1 0;
font-size: 1.2em;
border: 0;
}
.navbar-brand {
float: left;
min-height: 55px;
padding: 0 15px;
}
.img-logo{
width: 75px;
height: 60px;
}
.navbar-inverse .navbar-nav .active a, .navbar-inverse .navbar-nav .active a:focus, .navbar-inverse .navbar-nav .active a:hover {
color: #fff;
background-color: #53DFF0;
}
.navbar-inverse .nav-bar-nav li a {
color: #D5D5D5;
}
.avatar{
border-radius: 100%;
max-width: 100px;
clip: rect(10px,60px,50px,10px);
}
.startScreenSaver({
timeout: 5000,
width: 30,
height: 30,
exitTimeout: 1000,
});
</style>
<body>
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#myNavbar">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#"><img class="img-logo" src="img/logo.png"></a>
</div>
<div class="collapse navbar-collapse" id="myNavbar">
<ul class="nav navbar-nav navbar-right">
<form action="{{route('logout')}}" method="post">
{!!csrf_field()!!}
#if(!empty(Auth::user()->image))
<img src="{{ Auth::user()->image }}" class="avatar" alt="" width="60" height="60">
#else
<img src={{ url('uploads/avatar.png') }} class="avatar" alt="" width="60" height="60">
#endif
<b>Your Driver of the Day, {{ Auth::user()->name }}</b>
<button class="btn btn-danger">Log out</button>
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal">
Route/Bus Details
</button>
</form>
</ul>
</div>
</div>
</nav>
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Select Your Desire Route</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form action="{{ route('surveysubmit') }}" >
<div class="form-group">
<h4>Select Bus</h4>
<select onchange="$('#busid').val(this.value);" class="form-control" >
#php
$display=''; $initbusid = '';
$buses = Bus::where(['archive'=>1])->orderBy('id')->get(['id','busplate']);
foreach($buses as $bus){
if(empty($initbusid)){$initbusid=$bus->id;}
$display .= '<option value='.$bus->id.'>'.$bus->busplate.'</option>';
}
echo $display;
#endphp
</select>
</div>
<div class="form-group">
<h4>Select Route</h4>
<select onchange="$('#routeid').val(this.value);" class="form-control" >
#php
$display2=''; $initrouteid = '';
$bgcroutes = Bgcroute::where(['routeloc'=>1,'archive'=>1])->orderBy('id')->get(['id','bgcbusroute']);
foreach($bgcroutes as $bgcroute){
if(empty($initrouteid)){$initrouteid=$bgcroute->id;}
$display2 .= '<option value='.$bgcroute->id.'>'.$bgcroute->bgcbusroute.'</option>';
}
echo $display2;
#endphp
</select>
</div>
<button type="button" class="btn btn-danger" data-dismiss="modal">Start Survey</button>
</form>
</div>
</div>
</div>
</div>
#php
$questions = Surveyquestion::where('status',1)->get(['squestions','id'])->first();
#endphp
<section class="testimonials"></section>
<div class="jumbotron visible-xs-block visible-sm-block visible-md-block visible-lg-block hero-technology">
<h2 class="bg-success hero-title">{{ $questions->squestions }}</h2>
<p class="visible-xs-block visible-sm-block visible-md-block visible-lg-block visible-xs-inline visible-sm-inline visible-md-inline visible-lg-inline visible-xs-inline-block visible-sm-inline-block visible-md-inline-block visible-lg-inline-block hidden-xs hidden-sm hidden-md hidden-lg hero-subtitle">Nullam id dolor id nibh ultricies vehicula ut id elit. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
<p class="text-primary bg-warning">Help Us Serve You Better</p>
<p></p>
<p class="text-center bg-primary">Rate us. Choose a smiley that Corresponds to your riding experience</p>
<div>
<input type="hidden" name="driverid" id="driverid" value="{{ Auth::user()->id }}"/>
<input type="hidden" name="busid" id="busid" value="{{ $initbusid }}"/>
<input type="hidden" name="routeid" id="routeid" value="{{ $initrouteid }}"/>
<input type="hidden" name="questionid" id="questionid" value="{{ $questions->id }}"/>
<input type="hidden" name="responseid" id="responseid"/>
<table class="table">
<thead>
<tr>
<th class="info visible-xs-block visible-sm-block visible-md-block visible-lg-block visible-xs-inline visible-sm-inline visible-md-inline visible-lg-inline visible-xs-inline-block">
<img class="img-rounded" src="assets/img/person-clipart-silhouette-blue-14518-blue-man-design.png" height="100">
<img src="assets/img/inlove.gif" height="70" id="loveid">
<img src="assets/img/like.gif" height="90" id="likeid">
<img src="assets/img/facepalm.gif" height="70" id="faceid">
<img src="assets/img/cry.gif" height="70" id="cryid">
</th>
<th
class="danger visible-xs-block visible-sm-block visible-md-block visible-lg-block visible-xs-inline visible-sm-inline visible-md-inline visible-lg-inline visible-xs-inline-block">
<img class="img-rounded" src="assets/img/pink-female-symbol-190136.png" width="40" height="100">
<img src="assets/img/inlove.gif" height="70" id="loveid2">
<img src="assets/img/like.gif" height="90" id="likeid2">
<img src="assets/img/facepalm.gif" height="70" id="faceid2">
<img src="assets/img/cry.gif" height="70" id="cryid2">
</th>
</tr>
</thead>
<tbody>
<tr></tr>
<tr></tr>
</tbody>
<caption> </caption>
</table>
</div>
<p>For Comments/Feedback Email us at bgc#bgc.com</p>
</div>
<div class="container">
<div class="table-responsive">
<table class="table">
<thead>
<tr></tr>
</thead>
<tbody>
<tr></tr>
<tr></tr>
</tbody>
</table>
</div>
</div>
<script src="assets/js/jquery.min.js"></script>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script type="text/javascript">
$(document).ready(function(e){
});
function surveyvote(){
driverid = $('#driverid').val();
busid = $('#busid').val();
routeid = $('#routeid').val();
questionid = $('#questionid').val();
responseid = $('#responseid').val();
$.ajax({
"type":"get",
"url": "{{ route('surveyvoting') }}",
"data": '&driverid='+driverid+'&busid='+busid+'&routeid='+routeid+'&questionid='+questionid+'&responseid='+responseid,
"success":function(result){
// Do something you want!
swal({
title: 'Thank You!',
//text: 'I will close in 3 seconds.',
timer: 1000,
onOpen: () => {
swal.showLoading()
}
}).then((result) => {
if (
// Read more about handling dismissals
result.dismiss === swal.DismissReason.timer
) {
console.log('I was closed by the timer')
}
})
}
});
}
</script>
<script type="text/javascript">
var screenSaver = {};
function startScreenSaver(options) {
//* attach event listeners to exit screensaver
attachScreenSaverEventListeners();
if(!screenSaver.initiated) {
//* set screensaver options
screenSaver.options = {
timeout: options.timeout || 5000, //* default timer to start screensaver is 10 minutes
width: options.width || 25, //* default width is 25rem
height: options.height || 25, //* default height is 25rem
exitTimeout: options.exitTimeout || null, //* default timer to exit screensaver is disabled
}
//* create elements
var overlay = document.createElement("div");
overlay.setAttribute('class', 'screensaver-overlay');
document.body.appendChild(overlay);
var createBadge = document.createElement("div");
createBadge.setAttribute('id', 'saver-badge');
document.body.appendChild(createBadge);
createBadge.style.width = screenSaver.options.width + 'rem';
createBadge.style.height = screenSaver.options.height + 'rem';
}
document.getElementsByTagName("body")[0].classList.remove('screensaver');
screenSaver.initiated = true;
screenSaver.setTimeoutValue = screenSaver.options.timeout;
screenSaver.setTimeoutExit = screenSaver.options.timeoutExit;
screenSaver.setTimeout = null; //* clear timeout
screenSaver.inProgress = false;
screenSaver.timerStarted = false;
clearTimeout(screenSaver.setTimeout);
screenSaver.setTimeout = setTimeout(function() {
document.getElementsByTagName("body")[0].classList.add('screensaver');
screenSaver.inProgress = true;
var saverBadge = document.getElementById("saver-badge");
clearInterval(screenSaver.setInterval); //* clear badge display interval
screenSaver.setInterval = null;
//* get dimensions in em
var windowHeight = window.outerHeight / parseFloat(window.getComputedStyle(document.getElementsByTagName("body")[0], null).getPropertyValue('font-size'));
var windowWidth = window.outerWidth / parseFloat(window.getComputedStyle(document.getElementsByTagName("body")[0], null).getPropertyValue('font-size'));
screenSaver.setInterval = setInterval(function() {
if (screenSaver.inProgress === true) {
saverBadge.classList.remove('visible');
setTimeout(function() {
saverBadge.offsetWidth = saverBadge.offsetWidth;
saverBadge.classList.add('visible');
},1);
var saverTopValue = Math.floor(Math.random() * windowHeight) - screenSaver.options.width;
var saverLeftValue = Math.floor(Math.random() * windowWidth) - screenSaver.options.height;
if (saverTopValue <= 0) { //* make sure the badge doesn't go off the screen
saverTopValue = saverTopValue + 15;
}
if (saverLeftValue <= 0) {
saverLeftValue = saverLeftValue + 15;
}
saverBadge.style.top = saverTopValue + 'rem';
saverBadge.style.left = saverLeftValue + 'rem';
if(screenSaver.timerStarted === false && screenSaver.options.exitTimeout != null) {
startScreenSaverTimer();
}
}
}, 6000);
}, screenSaver.setTimeoutValue);
}
function startScreenSaverTimer() {
screenSaver.timerStarted = true;
setTimeout(function() {
stopScreenSaver();
}, screenSaver.setTimeoutExit);
}
function stopScreenSaver() {
startScreenSaver();
clearInterval(screenSaver.setInterval);
document.getElementsByTagName("body")[0].classList.remove('screensaver');
screenSaver.timerStarted = false;
}
function attachScreenSaverEventListeners() {
var events = ['touchstart', 'mousedown', 'mousemove', 'touchmove', 'keypress', 'scroll'];
var resetScreenSaver = function(e) {
if (screenSaver.inProgress) {
e.stopPropagation();
e.preventDefault();
}
clearTimeout(screenSaver.setTimeout);
clearInterval(screenSaver.setInterval);
document.getElementsByTagName("body")[0].classList.remove('screensaver');
startScreenSaver();
}
var checkClick = function(e) {
if (screenSaver.inProgress) {
startScreenSaver();
}
}
var bindEvents = function(eventName) {
document.addEventListener(eventName, screenSaver.initialize);
//* bind click as fallback for touchstart and mousedown
document.addEventListener('click', checkClick);
}
var unbindEvents = function(eventName) {
document.removeEventListener(eventName, screenSaver.initialize);
}
}
</script>
</body>
</html>
Here is the related files that I think that is related on the script or the javascript
css file screensaver.css
body.screensaver #saver-badge {
opacity: 0;
display: block;
position: absolute;
filter: "progid:DXImageTransform.Microsoft.Dropshadow(OffX=12, OffY=12,Color='#444')";
filter: url(#drop-shadow);
-webkit-filter: drop-shadow(12px 12px 20px rgba(0,0,0,0.5));
filter: drop-shadow(12px 12px 20px rgba(0,0,0,0.5));
background: url(../img/vwd.png) center;
background-size: contain;
z-index: 1001;
}
body.screensaver #saver-badge.visible {
-webkit-animation: fadeBadge 6s;
-moz-animation: fadeBadge 6s;
-o-animation: fadeBadge 6s;
animation: fadeBadge 6s;
opacity: 1;
}
body.screensaver .screensaver-overlay {
background: #000;
opacity: .5;
position: fixed;
top: 0;
bottom: 0;
right: 0;
left: 0;
z-index: 1000;
}
#saver-badge {
display: none;
}
#-webkit-keyframes fadeBadge {
0% {
opacity: 0;
}
20% {
opacity: 1;
}
80% {
opacity: 1;
}
100% {
opacity: 0;
}
}
#-moz-keyframes fadeBadge {
0% {
opacity: 0;
}
20% {
opacity: 1;
}
80% {
opacity: 1;
}
100% {
opacity: 0;
}
}
#-o-keyframes fadeBadge {
0% {
opacity: 0;
}
20% {
opacity: 1;
}
80% {
opacity: 1;
}
100% {
opacity: 0;
}
}
#keyframes fadeBadge {
0% {
opacity: 0;
}
20% {
opacity: 1;
}
80% {
opacity: 1;
}
100% {
opacity: 0;
}
}
js file
screensaver.js
var screenSaver = {};
function startScreenSaver(options) {
//* attach event listeners to exit screensaver
attachScreenSaverEventListeners();
if(!screenSaver.initiated) {
//* set screensaver options
screenSaver.options = {
timeout: options.timeout || 60000, //* default timer to start screensaver is 10 minutes
width: options.width || 25, //* default width is 25rem
height: options.height || 25, //* default height is 25rem
exitTimeout: options.exitTimeout || null, //* default timer to exit screensaver is disabled
}
//* create elements
var overlay = document.createElement("div");
overlay.setAttribute('class', 'screensaver-overlay');
document.body.appendChild(overlay);
var createBadge = document.createElement("div");
createBadge.setAttribute('id', 'saver-badge');
document.body.appendChild(createBadge);
createBadge.style.width = screenSaver.options.width + 'rem';
createBadge.style.height = screenSaver.options.height + 'rem';
}
document.getElementsByTagName("body")[0].classList.remove('screensaver');
screenSaver.initiated = true;
screenSaver.setTimeoutValue = screenSaver.options.timeout;
screenSaver.setTimeoutExit = screenSaver.options.timeoutExit;
screenSaver.setTimeout = null; //* clear timeout
screenSaver.inProgress = false;
screenSaver.timerStarted = false;
clearTimeout(screenSaver.setTimeout);
screenSaver.setTimeout = setTimeout(function() {
document.getElementsByTagName("body")[0].classList.add('screensaver');
screenSaver.inProgress = true;
var saverBadge = document.getElementById("saver-badge");
clearInterval(screenSaver.setInterval); //* clear badge display interval
screenSaver.setInterval = null;
//* get dimensions in em
var windowHeight = window.outerHeight / parseFloat(window.getComputedStyle(document.getElementsByTagName("body")[0], null).getPropertyValue('font-size'));
var windowWidth = window.outerWidth / parseFloat(window.getComputedStyle(document.getElementsByTagName("body")[0], null).getPropertyValue('font-size'));
screenSaver.setInterval = setInterval(function() {
if (screenSaver.inProgress === true) {
saverBadge.classList.remove('visible');
setTimeout(function() {
saverBadge.offsetWidth = saverBadge.offsetWidth;
saverBadge.classList.add('visible');
},1);
var saverTopValue = Math.floor(Math.random() * windowHeight) - screenSaver.options.width;
var saverLeftValue = Math.floor(Math.random() * windowWidth) - screenSaver.options.height;
if (saverTopValue <= 0) { //* make sure the badge doesn't go off the screen
saverTopValue = saverTopValue + 15;
}
if (saverLeftValue <= 0) {
saverLeftValue = saverLeftValue + 15;
}
saverBadge.style.top = saverTopValue + 'rem';
saverBadge.style.left = saverLeftValue + 'rem';
if(screenSaver.timerStarted === false && screenSaver.options.exitTimeout != null) {
startScreenSaverTimer();
}
}
}, 6000);
}, screenSaver.setTimeoutValue);
}
function startScreenSaverTimer() {
screenSaver.timerStarted = true;
setTimeout(function() {
stopScreenSaver();
}, screenSaver.setTimeoutExit);
}
function stopScreenSaver() {
startScreenSaver();
clearInterval(screenSaver.setInterval);
document.getElementsByTagName("body")[0].classList.remove('screensaver');
screenSaver.timerStarted = false;
}
function attachScreenSaverEventListeners() {
var events = ['touchstart', 'mousedown', 'mousemove', 'touchmove', 'keypress', 'scroll'];
var resetScreenSaver = function(e) {
if (screenSaver.inProgress) {
e.stopPropagation();
e.preventDefault();
}
clearTimeout(screenSaver.setTimeout);
clearInterval(screenSaver.setInterval);
document.getElementsByTagName("body")[0].classList.remove('screensaver');
startScreenSaver();
}
var checkClick = function(e) {
if (screenSaver.inProgress) {
startScreenSaver();
}
}
var bindEvents = function(eventName) {
document.addEventListener(eventName, screenSaver.initialize);
//* bind click as fallback for touchstart and mousedown
document.addEventListener('click', checkClick);
}
var unbindEvents = function(eventName) {
document.removeEventListener(eventName, screenSaver.initialize);
}
for (var i=0;i<events.length;i++) {
bindEvents(events[i]);
}
}
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.
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">