Skip to content

Instantly share code, notes, and snippets.

@pardamike
Last active December 20, 2017 09:56
Show Gist options
  • Save pardamike/d0b2bec8b3da6576e93696f3e180dd81 to your computer and use it in GitHub Desktop.
Save pardamike/d0b2bec8b3da6576e93696f3e180dd81 to your computer and use it in GitHub Desktop.
;(function ($) {
$.fn.bootstrapFeedback = function (config) { // Add object to jQuery's functions
var bsfb = {
// Settings variables
targetElementId: 'showFeedbackForm',
getOptionsUrl: false,
sendFeedbackUrl: false,
styles: {
submitBtnClasses: 'btn btn-primary',
closeBtnClasses: 'btn btn-default'
},
modal: {
selectorId: 'feedbackModal',
title: 'Feedback Form',
subtitle: 'Comments or suggestions?',
commentTxBxId: 'feedbackModalComment',
radioGroupName: 'bsfb_rad1',
radioGroupContainer: 'feedbackModalLisWrapper',
saveBtnId: 'feedbackModalSend',
notificationAreaId: 'notificationArea'
},
useDefaulsModal: true,
// Init function, kicks everything off
init: function () {
if (!bsfb.getOptionsUrl || !bsfb.sendFeedbackUrl) {
throw new Error('Please pass in getOptionsUrl and sendFeedbackUrl')
}
// Should always run all your event attachment and server calls here
bsfb.attachEvents();
if (bsfb.useDefaulsModal) {
bsfb.injectModal(); // Inject modal if not provided
} else {
bsfb.addModalEvents(); // If modal provided, attach events
}
},
// Attach ALL events in here, easy to find and they always run with .init
attachEvents: function () {
// Click action for "Give Feedback" button
$(document).on('click', '#' + bsfb.targetElementId, function () {
bsfb.getOptions().then(function (ajaxRes) {
// Once options are loaded, build the select list
// Using fake data here, 'options' would normally be from ajaxRes
var options = [
{ text: 'This is helpful', id: 3 },
{ text: 'The weather is wrong', id: 4 },
{ text: 'The location is wrong', id: 6 },
{ text: 'This is not useful', id: 7 },
{ text: 'Something else', id: 9 },
];
bsfb.buildRadioGroup(options);
$('#' + bsfb.modal.selectorId).modal('show');
});
});
// On keydown when the textarea is focused, expand +1 row, up to 8 rows total if 'Enter' button pressed
$(document).on('keydown', '#' + bsfb.modal.commentTxBxId, function (event) {
if (event.keyCode === 13) {
var totalRows = this.getAttribute('rows');
if (totalRows < 8) {
this.setAttribute('rows', totalRows + 1);
}
}
});
// On click of save, validate then save
$(document).on('click', '#' + bsfb.modal.saveBtnId, function () {
if ($('input[name="' + bsfb.modal.radioGroupName + '"]:checked').val() > 0) {
bsfb.saveFeedback( bsfb.getFeedback($('input[name="' + bsfb.modal.radioGroupName + '"]:checked').val()) ).then(function () {
bsfb.notify(true, "Thanks for the feedback!");
});
} else {
bsfb.notify(false, "Please make sure you select a reason.");
}
});
},
// The rest of the functions for this object... "methods":
// Get options from the server
getOptions: function () {
// AJAX call to get the options
// Just going to a random API
// This is where we would use bsfb.getOptionsUrl
return $.ajax({
url: 'https://randomuser.me/api/'
});
},
// Build select list from options passed in
buildRadioGroup: function (optionsArr) {
optionsArr.forEach( function (option) {
$('#' + bsfb.modal.radioGroupContainer).append(bsfb.buildRadioButton(option));
});
},
// Builds a single radio button
buildRadioButton: function (option) {
return '\
<div class="form-check"> \
<label class="form-check-label"> \
<input class="form-check-input" type="radio" name="' + bsfb.modal.radioGroupName + '" value="' + option.id + '"> \
' + option.text + ' \
</label> \
</div>';
},
// Save feedback form, gets the data, then sends it
saveFeedback: function (data) {
console.log(data);
// Again,not actually saving anything, just hitting a random API for the AJAX call
// This is where our bsfb.sendFeedbackUrl would live
return $.ajax({
url: 'https://randomuser.me/api/'
});
},
// Make a feedback object to give to the server
getFeedback: function (selectedOptionVal) {
return {
selectedOption: selectedOptionVal,
comments: document.getElementById(bsfb.modal.commentTxBxId).value
};
},
// Clear the modal, need to remove options and reset textarea
clearModal: function () {
$('#' + bsfb.modal.radioGroupContainer).html('');
document.getElementById(bsfb.modal.commentTxBxId).value = '';
},
// Show notification, CSS class based on if success or not
notify: function (success, msg) {
$('#' + bsfb.modal.notificationAreaId).html(
$('<div />', {
class: 'alert alert-' + (success ? 'success' : 'danger'),
text: msg
})
);
$('#' + bsfb.modal.notificationAreaId).fadeIn();
setTimeout(function () {
bsfb.clearNotifications();
}, 2000)
},
// Clear notifications
clearNotifications: function () {
$('#' + bsfb.modal.notificationAreaId).fadeOut(function () {
$(this).html('');
})
},
// Insert modal into HTML
injectModal: function () {
$('body').append(bsfb.getModalHTML());
bsfb.addModalEvents();
},
// Just returns modal HTML
getModalHTML: function () {
return '<div class="modal fade" id="' + bsfb.modal.selectorId + '"> \
<div class="modal-dialog" role="document"> \
<div class="modal-content"> \
<div class="modal-header"> \
<h5 class="modal-title">' + bsfb.modal.title + '</h5> \
<button type="button" class="close" data-dismiss="modal" aria-label="Close"> \
<span aria-hidden="true">&times;</span> \
</button> \
</div> \
<div class="modal-body"> \
<div id="' + bsfb.modal.notificationAreaId + '" style="display:none;"></div> \
<div id="' + bsfb.modal.radioGroupContainer + '"></div> \
<br> \
<h5>' + bsfb.modal.subtitle + '</h5> \
<div class="form-group"> \
<textarea rows="1" class="form-control" id="' + bsfb.modal.commentTxBxId + '" placeholder="Optional"></textarea> \
</div> \
</div> \
<div class="modal-footer"> \
<button type="button" class="' + bsfb.styles.closeBtnClasses + '" data-dismiss="modal">Close</button> \
<button type="button" id="' + bsfb.modal.saveBtnId + '" class="' + bsfb.styles.submitBtnClasses + '">Send</button> \
</div> \
</div> \
</div> \
</div>';
},
// Events we need to add to the modal once it is in the DOM
addModalEvents: function () {
$('#' + bsfb.modal.selectorId).on('hidden.bs.modal', function () {
bsfb.clearModal();
});
}
};
var new_bsfb = $.extend({}, bsfb, config); // Merge bsfb and config without modifying
$.extend(bsfb, config); // default values or properties unless passed in
return new_bsfb;
};
})(jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment