I need to change active doc displayed by swagger with Jquery.
Detail:
My routes are separated into groups/version, so average api call looks like this: Api/{group}/{version}/Controller/Method
And my swagger docs are generated that way aswell. But I dont really like the way user selects active doc inside the UI. So I just added my own javascript to insert some inputs for this. What I dont know is hot to tell the swaggerUI to change to specific doc.
Here is my javascript:
(function (){
var DiscoveryUrlSelector = Backbone.View.extend({
render: function ()
{
// Nerenderuj opakovaně na reloadu
var defaultVal = this.$el.val()
if (!this.$el.find('#input_' + this.options.name).length) {
var select = $('<select id="input_' + this.options.name + '" name="' + this.options.name + '"></select>');
select
.css('margin', '0px 10px 0px 0px')
.css('border', '1px solid gray')
.css('padding', '3px')
.css('width', '100px')
.css('font-size', '0.9em');
_.each(this.options.discoveryPaths, function (path) {
var option = $('<option>' + path + '</option>');
select.append(option);
});
select.val(defaultVal);
select.change(SetVersionedGroup);
select.insertBefore('#input_username');
}
return this;
}
});
new DiscoveryUrlSelector(
{
el: $('#api_selector'),
name: 'Group',
rootUrl: swashbuckleConfig.rootUrl,
discoveryPaths: Array.from(new Set(swashbuckleConfig.discoveryPaths.map(x => x.substring(13, x.lastIndexOf("v")))))
}).render();
new DiscoveryUrlSelector(
{
el: $('#api_selector'),
name: 'Version',
rootUrl: swashbuckleConfig.rootUrl,
discoveryPaths: Array.from(new Set(swashbuckleConfig.discoveryPaths.map(x => x.substring(x.lastIndexOf("v"), x.length))))
}).render();
function SetVersionedGroup()
{
}
})();
And my Header looks like this:
Any ideas how to finish my SetVersionedGroup function?
Related
I'm just learning JS and jQuery, so I can not reduce the normal code is shown below:
var menuBtn = '#menu',
classMenuOpen = 'side_menu_open',
aboutBtn = '#about',
classAboutOpen = 'side_about_open',
dateBtn = '#date',
classDateOpen = 'side_date_open',
closeBtn = '.header__menu a, .close';
// Menu Side
$(menuBtn).on('click', function() {
$('html').toggleClass(classMenuOpen);
});
$(closeBtn).not(menuBtn).on('click', function() {
$('html').removeClass(classMenuOpen);
});
// About Side
$(aboutBtn).on('click', function() {
$('html').toggleClass(classAboutOpen);
});
$(closeBtn).not(aboutBtn).on('click', function() {
$('html').removeClass(classAboutOpen);
});
// Date Side
$(dateBtn).on('click', function() {
$('html').toggleClass(classDateOpen);
});
$(closeBtn).not(dateBtn).on('click', function() {
$('html').removeClass(classDateOpen);
});
I would like to write a loop (example below) , but knowledge is not enough. I hope someone can help, thanks in advance ;)
['menu', 'about', 'date'].forEach((selector) => {
$('.' + selector + ' .scrollbar-inner').scrollbar({
onScroll: function(y, x){
$('.' + selector + ' .scrollbar-inner').toggleClass('scroll-shadow', y.scroll >= 5);
}
});
});
maybe something like this:
// wrap in IIFE for scope containment
(function($) {
// Setup button keys
const buttons = ['menu', 'about', 'date'];
// click handler
const createClickHandler = value => {
// set loop variables
let selector = `#${value}`
, className = `side_${value}_open`;
// create event triggers
$(selector).on('click', e => $('html').toggleClass(className));
$('.header__menu a, .close').not(selector).on('click', e => $('html').removeClass(className))
};
// iterate keys and apply handler method
buttons.forEach(createClickHandler);
})(jQuery);
Here is the loop you are looking for!
In the forEach() loop you are looping through the array of strings, component holds the string element (so here 'menu', 'about', etc...). Then inside the loop's body set two variables:
selector is the selector string
classOpen is the class name of an element you have associated with the component
Then you basically write the same code using only those two variables instead of writing the code three times with set strings.
let closeBtn = '.header__menu a, .close'
['menu', 'about', 'date'].forEach(function(component) {
let selector = '#' + component;
let classOpen = '.side_' + component + '_open';
$(selector).on('click', function() {
$('html').toggleClass(classOpen);
});
$(closeBtn).not(selector).on('click', function() {
$('html').removeClass(selector);
});
});
I'm trying to create tooltips with title attribute and jQuery but can't find method to show dynamically added element.
HTML
some page
CSS
.tooltip {
…
display: none; /* I's needed for hard coded tooltips */
…
}
jQuery
$(function () {
if (window.matchMedia('(min-width: 980px)').matches) {
$('.dfn').hover(
function () {
var el = $(this);
var txtTitle = el.prop('title');
el.append('<p class="tooltip">' + txtTitle + '</p>');
//That's it. My tooltip has been created, but it has not been shown
$(el + ' .tooltip').show('fast');
el.data('title', el.prop('title'));
el.removeAttr('title');
}, function () {
$(el + ' .tooltip').hide('fast').remove();
el.prop('title', el.data('title'));
}
);
}
});
As mentioned by others, $(el + ' .tooltip').show('fast'); is probably wrong.
The el is an object, not a string to concat', one way is to use el.find('.tooltip').show().
The other way is to use the context option: $('.tooltip', el).show();
You need to have correct code to find new element:
$('.tooltip', el).show('fast');
Your current one probably endup searching for something like [object] .tooltip or similar string depending on how JavaScript decides to convert HTML element to string.
As others have mentioned el.find('.tooltip').show() and el.find('.tooltip').hide().remove(); solve the problem.
Also, in HandlerOut function, you el was not declared. Fiddle here
$(function () {
//if (window.matchMedia('(min-width: 980px)').matches) {
$('.dfn').hover(
function () {
var el = $(this);
var txtTitle = el.prop('title');
el.append('<p class="tooltip">' + txtTitle + '</p>');
//That's it. My tooltip has been created, but it has not been shown
el.find('.tooltip').show()
el.data('title', el.prop('title'));
el.removeAttr('title');
}, function () {
var el = $(this);
el.find('.tooltip').hide().remove();
el.prop('title', el.data('title'));
}
);
//}
});
I'm trying to grok Backbone a little more, and from someone who has only used Backbone views in the past, I'm now trying my hand with Models and Collections.
Right now, when I post a comment, I try to increment the comment count.
Model:
Comment = Backbone.Model.extend({
defaults: {
text: null,
count: 0
},
updateCount : function() {
console.log(this.set('count', this.get('count') + 1));
console.log(this.get('count'));
}
});
Collection:
CommentsCollection = Backbone.Collection.extend({
model: Comment,
initialize: function (models, options) {
this.on("add", options.view.appendComment);
this.on('add', options.view.resetComment);
}
});
View:
CommentsView = Backbone.View.extend({
el: $("body"),
initialize: function () {
_.bindAll(this,
'addComment',
'appendComment',
'resetComment'
);
this.comments = new CommentsCollection(null, {
model: Comment,
view: this
});
},
events: {
"click #post-comment": "addComment"
},
addComment: function (evt) {
var $target = $(evt.currentTarget);
var $container = $target.closest('#comment-wrapper');
var text = $container.find('textarea').val();
var comment = new Comment({
text: text
});
//Add a new comment model to our comment collection
this.comments.add(comment);
return this;
},
appendComment: function (model) {
$('#comments').prepend('<div> ' + model.get('text') + '</div>');
model.updateCount();
return this;
},
resetComment: function () {
$('textarea').val('');
}
});
Why is it always returning 1 (add a comment and click Post then view the console to see)?
Demo: http://jsfiddle.net/ZkBWZ/
This is happening because you're storing the count on the Comment model. Each time you hit the submit button, you create a new Comment which has the count set to the default, 0. The method updateCount then updates the count on that brand new model, so you're always seeing 1.
If you're just looking to determine how many comments have been made, I'd suggest you just look at the size of the CommentsCollection. In appendComment, you can do it this way:
appendComment: function (model) {
$('#comments').prepend('<div> ' + model.get('text') + '</div>');
// Get the number of comments
console.log(model.collection.models.length);
return this;
},
I have 2 textfields with id's source,destination. If any field value changes that corresponding model attribute will be change. I did this one using Backbone.Model and events object in Marionette.CompositeView. It's working fine.
Once any model Attribute change corresponding function will call. For this I written the following code. It's not working the problem was even one attribute changes both functions are evaluating.
model Code:
var mapModel = Backbone.Model.extend({
defaults: {
startPlace: "",
endPlace: ""
}
});
Marionette.CompositeView code:
var mapView = Marionette.CompositeView.extend({
events: {
"blur #source": "sAttributeSetting",
"blur #destination": "dAttributeSetting"
},
dAttributeSetting: function() {
this.model.set({"endPlace": document.getElementById(this.ui.destinationPlace).value});
},
sAttributeSetting: function() {
this.model.set({"startPlace": document.getElementById(this.ui.sourcePlace).value});
},
modelEvents: {
"change startPlace": "startMarkerDisplay",
"change endPlace": "endingMarkerDisplay"
},
startMarkerDisplay: function() {
alert("start");
},
endingMarkerDisplay: function() {
alert("end");
}
});
html code:
<input type="text" id="source">
<input type="text" id="destination">
creating instance for both model and view
mapModelObj = new mapModel();
var mapViewObj = new mapView({el:$('#mapDiv'), model:mapModelObj});
problems:
Initially If I enter any value in first field(source) getting 2 alert boxes("start", "end").
Initially If you enter any value in second field(destination) getting 4 alert boxes("start", "end", "start", "end")
I tried alot but I didn't understand where I am getting the problem
Can anyone help me.
Thanks
modelEvents should be connected by :. Say, event of changing startPlace should be
'change:startPlace'
If you use space you'll end with two events, not one event specific to this attribute.
Your code 'change startPlace' represents two events, one is 'change', the other is 'startPlace'. So you'll see "start","end","start","end"
My observations are the following for your solution (however I propose a second solution at the bottom):
The binding of entity event has colon syntax. It should be a hash of { "event:name": "eventHandler" } configuration. Multiple handlers can be separated by a space. A function can be supplied instead of a string handler name.
You can use advantage of the el property of the backbone view.
Instead of using document.getElementById(this.ui.sourcePlace), you can use this.$('#source'). This latest searches only in the context of el rather than searching the whole dom. This way the evaluation will be way faster... That way you should use this expression: this.$('.destination').val()
Please check my jsfiddle about your issue: http://jsfiddle.net/orbanbotond/VEcK6/
The code is the following:
var mapModel = Backbone.Model.extend({
defaults: {
startPlace: "",
endPlace: ""
}
});
var mapView = Marionette.CompositeView.extend({
events: {
"blur .source": "sAttributeSetting",
"blur .destination": "dAttributeSetting"
},
dAttributeSetting: function(){
console.log('end blured');
console.log('input value:' + this.$('.destination').val());
this.model.set({
"endPlace": this.$('.destination').val()
});
console.log('endplace set to: ' + this.model.get('endPlace'));
},
sAttributeSetting: function() {
console.log('start blured');
console.log('input value:' + this.$('.source').val());
this.model.set({
"startPlace": this.$('.source').val()
});
console.log('startPlace set to: ' + this.model.get('startPlace'));
},
modelEvents: {
"change:startPlace": "startMarkerDisplay",
"change:endPlace": "endingMarkerDisplay"
},
startMarkerDisplay: function () {
alert("start");
},
endingMarkerDisplay: function () {
alert("end");
}
});
$(document).ready(function(){
var mapModelObj = new mapModel();
var mapViewObj = new mapView({
el: $('#mapDiv'),
model: mapModelObj
});
});
My proposed second solution:
Use the stickit library which does all you are doing. You only need to define the mapping between the dom selector and the observed model attribute.
Here is the jsfiddle for it: http://jsfiddle.net/orbanbotond/fm64P/
Here is the code:
var mapModel = Backbone.Model.extend({
defaults: {
startPlace: "initialStartPlace",
endPlace: "initialEndplace"
},
});
var mapView = Marionette.CompositeView.extend({
template: "#mapDiv",
events: {
"blur .source": "sAttributeSetting",
"blur .destination": "dAttributeSetting"
},
bindings: {
'.source': {
observe: 'startPlace'
},
'.destination': {
observe: 'endPlace'
}
},
onRender: function() {
this.stickit();
console.debug("Sticked to it already");
},
});
$(document).ready(function(){
var mapModelObj = new mapModel();
var mapViewObj = new mapView({
el: $('#mapDiv'),
model: mapModelObj
});
mapViewObj.render();
mapModelObj.bind('change:startPlace', function(obj){alert("New value: " + obj.get('startPlace'));});
mapModelObj.bind('change:endPlace', function(){alert("New value: " + obj.get('endPlace'));});
});
For every code sample I used this template (I used class selectors instead of id selectors):
<div id="mapDiv">
<input type="text" class="source">
<input type="text" class="destination">
</div>
If I have more than 1 instance of the same plugin on the same page how can I separate functionality. eg. in this demo http://jsfiddle.net/3jwAK/, I have a plugin "editor" that appends a link simulating some plugin/widget button, that when clicked will append a line to the textarea.
The problem with it currently is it only targets the last textarea
Code looks like
JS
(function($) {
$.fn.editor = function(options) {
var helpers = {
rand: function() {
return Math.round(Math.random() * 20);
}
};
return this.each(function() {
$this = $(this);
var div = $("<a>", {
text: "Add Random Number",
href: "#",
click: function() {
$this.val( $this.val() + "\n" + helpers.rand() );
}
});
$this.before(div);
});
}
})(jQuery);
HTML
<textarea name="txtArea1" cols="50" rows="6" id="editor1"></textarea>
The problem is the variable $this needs to be a local copy in each run of that function. Put var in front of it.
var $this = $(this);
Updated: http://jsfiddle.net/3jwAK/1/