I am using bootstrap modals in my application.
In here we have modal options like windowClass, Keyboard, etc.
I want to know whether we can add our own custom options in here like 'preventModalClose', 'ABC', etc.
You need to modify the source code of bootstrap UI (I suppose you are using it because of the angularjs tag).
For example, go to the source file of modal.js. Go to Line 99, you will find that the option windowClass works simply by:
element.addClass(attrs.windowClass || '');
Say, you want to add a customized option like preventModalClose, just modify the function scope.close in Line 102:
scope.close = function (evt) {
if (attrs.preventModalClose) {
return;
}
// The original logic.
}
Start reading the source code of them, they are just Angular directives or even plain JavaScript.
Related
I need to display the form in read-only mode , I am creating the form based on Json using angular-formly . Checked the link http://angular-formly.com/#/example/other/read-only-form which works for text input , please suggest how to set read-only for radio , multicheckbox and checkbox
we do it via jQuery:
$(document).ready(function () {
$('input').click(function (e) {
e.preventDefault();
});
});
OR if you want to "pretend" you are using "angular" to do this, even though you are actually using jQuery, and want to type out a whole lot more code to write the exact same thing(literally, it will simply run the above code in jQuery as angular.element is an "alias" for jQuery---straight out of the angular docs: https://docs.angularjs.org/api/ng/function/angular.element), you can do:
angular.element(function() {
angular.element('input').trigger('click')(function(e) {
e.preventDefault();
};
});
This way you can look cool and spout off nonsense like "It's bad practice to run angular and jQuery together" because you have no clue what you are talking about and just read that somewhere.
This works for all input fields. If you have buttons or datepickers with buttons, etc the easiest way to do it is to set a readOnly property on the model in the form and then set it to true on page where you want it to be read only then set the ng-show on the buttons to: ng-show="!model.readOnly"
My settings are as following:
singleFileUploads: false,
// To limit the number of files uploaded with one XHR request,
// set the following option to an integer greater than 0:
limitMultiFileUploads: undefined,
maxNumberOfFiles: 1,
I am trying to allow my client to upload a personal image, after successfully uploading this image,
I would like to reset the file selection, and allow my user to upload another image instead of the first one.
Before setting the maxNumberOfFiles setting to 1, the plugin just tried to upload any new file that the user would select along with the old ones, now, it allows the user to upload a file only once per each visit to the page which contains the plugin instance.
Here is what I've tried so far:
$scope.model.resetFiles = function(){
angular.forEach(
angular.element("input[type='file']"),
function(inputElem){
// angular.element(inputElem).val(null);
angular.element(inputElem).find('.files').empty();
angular.element(inputElem).scope().clear()
});
}
For security reasons, Javascript doesn't allow you to clear the file fields in the manner you'd think. It seems as if creating a new element and replacing the old file field will do the trick though. Check out this link for some more detail, and a code example.
I've seen some people suggesting wrapping the element in a <form> tag and using jQuery's reset() function to reset the form, but if you're not using the full version of jQuery, I don't believe this is included with the jqLite that's used by default by AngularJS.
I've found a temporary solution until the plugin gets updated for better Angular support.
var filePicker = null;
$scope.options = {
done: function (e, data) {
filePicker = data;
}
};
$scope.clearFiles = function () {
filePicker.scope.clear(filePicker.files);
};
Just add the options to the directive like this:
<form file-upload="options" action="import/excelupload" method="POST" enctype="multipart/form-data">
I simply solved it using this simple form reset
document.forms["mediaUploader"].reset();
my directive on the file input was autobinding the files to a scope variable.
after calling forms.reset(); also autobinds files.length to 0 zero so works marvelously!
also check out
https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement.reset
If file field is wrapped inside form tag then use standard html form reset button type.
<button type="reset" value="Reset">Reset</button>
Also you can put ng-click directive on reset button to perform any changes in $scope.
<button type="reset" value="Reset" ng-click="formReset()">Reset</button>
$scope.resetForm = function (){
// Your business logic after form reset.
}
I would like to be able to prevent an image that has an ng-src attribute from loading until it is visible in the viewport.
Is this possible with Angular?
Previously I have used the jQuery LazyLoad Plugin , however I am trying to do this without having to have both Angular and jQuery.
In case you're still interested, i found out this repo on github :
https://github.com/afklm/ng-lazy-image
I tried it and it rocks !
Images are loaded only when appearing in viewport AND you can choose which image to load based on screen size. It means that you can load smaller images for mobile users ;)
In angularjs, lazy loading can be implemented using a directive.
Steps:
Step 1. create directive as follows:
App.directive('lazyLoad', lazyLoad)
function lazyLoad() {
return {
restrict: 'A',
link: function (scope, element, attrs) {
const observer = new IntersectionObserver(loadImg);
const img = angular.element(element)[0];
observer.observe(img)
function loadImg(changes) {
changes.forEach(change => {
if (change.intersectionRatio > 0 && change.target.getAttribute('tempData')) {
change.target.src = change.target.getAttribute('tempData');
}
});
}
};
};
};
Step 2: use lazy-load attribute in tag and replace "ng-src" with tempData
eg. In html
<img ng-repeate="obj in objects" lazy-load tempData="obj.srcURL">
Note: we are not directly assigning src because we want to prevent image from sending request to server to load image.
Important Note: Dependence upon es-6. You may get parse error while making a build.
*Solution: npm install --save gulp-uglify-es
You need to update your gulp file after installing command.
This will install dependency and your code can make a build now.
That's all!!!
Thank you for reading!!!
I think you could just bind the source to a getter that only returns the value if the element is visible (assuming you are using a binding of some sort to trigger visibility of the img).
For example, use ng-src="{{getImgSource()}}" and in your controller:
scope.getImgSource = function(){
if(scope.showImg){
return "myImageUrl.png";
}
return "";
};
However, if that is something that you will have to use a lot, maybe you should look into creating your own directive to do that.
I have a page with 50 hidden checkboxes, and I want to be able to toggle each checkbox by clicking on a visible link. The actual checkboxes have to stay hidden...so... Is there a better way to do this, with a JS function so I don't have to include the entire onclick in each link? And I use mootools, not jQuery.
This works to activate a checkbox:
Select
But to toggle it, this works:
onclick="if (event.target.tagName != 'INPUT') document.getElementById('field_select_temp_professional_10').checked = !document.getElementById('field_select_temp_professional_10').checked"
None of what you posted is actually mootools code, you may as well not use mootools...
Markup:
Select
js in your domready:
document.getElements("a.add_app").addEvents({
click: function(e) {
if (e.target.get("tag") != 'input') {
var checkbox = document.id("field_select_p" + this.get("data-id"));
checkbox.set("checked", !checkbox.get("checked"));
}
}
});
If you have 100+ then I suggest you look at using event delegation from mootools-more and add just one event to the parent instead of creating 100 events and storing 100 functions that deal with it.
This is coding to patterns, and it involves changing your markup to make things work. You can also make the change based upon walking the DOM in relation to the clicked item, e.g. this.getParent().getElement("input[type=checkbox]"), or something can mean you don't need to store a relative id in the element itself.
To add javascript, you can use:
drupal_add_js
And similar for css:
drupal_add_css
But what if I just want to add html at the end of my page. I.e. Add a div with some text in it at the end of the page?
A lot of suggestions here work if you want your alteration to be theme-based, but if you want this to come from a module, using a block region, page template or page prepocess won't cut it, because you're tying the alteration to the theme.
From a modular standpoint, the following options are best:
hook_footer() -- http://api.drupal.org/api/function/hook_footer/6 :: my_module_footer() should return a string of HTML, which can even be javascript. E.g.
function my_module_footer(){
return "<script type='text/javascript'>//your script</script>"
}
You can use drupal $_GET['q'] to get the page URL and have that return be conditional for the page URL.
Otherwise, I sometimes use $GLOBALS["_add_my_footer"] as a boolean, and set it at various points in the module, then in hook_footer(), see if it is true.
drupal_add_js -- api.drupal.org/api/drupal/includes--common.inc/function/drupal_add_js/6 :: You can use this to add javascript to the footer by setting the $scope parameter to "footer" -- e.g.
function my_module_init(){
$script = "your script "; // notice no <script> tags
drupal_add_js($script, 'inline', 'footer');
// you can also use this function to grab a .js file
}
Note that I put that drupal_add_js into hook_init() -- I did that because if you don't, the script could get lost when using Drupal's aggressive caching feature.
Unfortunately, there is no $scope parameter for drupal_add_css
As hook_footer did not survive Drupal 6, here's the equivalent function and how to implement it in Drupal 7:
/**
* Implements hook_page_alter().
*/
function example_page_alter(&$page) {
if (variable_get('dev_query', 0)) {
$page['page_bottom']['devel']= array(
'#type' => 'markup',
'#markup' => '<div style="clear:both;">' . devel_query_table() . '</div>',
);
}
}
(From http://preprocess.me/drupal-hookfooter-in-drupal-7)
You can add the following to your theme's template.php file:
function phptemplate_preprocess_page(&$vars) {
$vars['closure'] .= 'Add markup here';
}
Drupal has a hook you can implement and add in whatever code you'd like to the footer of the page - hook_footer. See http://api.drupal.org/api/function/hook_footer/6
You could write a block to do it and put the block in the closure.
...or, probably not as recommended as the other answers, but more direct, you can add the html straight to the page.tpl.php file.
There have already beed made some good suggestions:
Using a block
Editing templates
Using preprocess function.
The easiest thing would be to add a block that you create, where you can put your custom markup. You could even create a special template for it, so you don't get your usual drupal block markup, but only what you write in the block content.
That should cover your needs:
You have 100% control over where the markup is generated (You can define the region in your them)
You have 100% control over what markup is generated
Now if you don't want to use blocks, because you don't want the site admins to know about the block, the 2nd best thing would be:
Add a checkbox to your theme settings.
In your preprocess page hook, set a boolean variable if the checkbox is checked or not.
In your page template, you check for the variable, if it's TRUE you write your markup where you want it.
This will basically do the same thing as above, only you have the setting in your theme, instead of adding a block. It will require more work.
You can do pretty much the same in a custom module, but it wont make much sense to do this in a module, since it's purely presentation and you are dependent on your theme anyways.
here is a little trick that works in drupal 6 and 7
$script = '//--><!]]></script><strong>this is bold html code</strong><script type="text/javascript"><!--//--><![CDATA[//><!--';
drupal_add_js($script, 'inline', 'footer');
since it is apparent you don't want to modify the template files or use any of the other methods suggested above, this should work to add html to the page just like it does for js and css
I dont' recommend using block , as its overkill for just adding some elements on the footer.
Here is the hook that you can use to add the content before </body> tag for Drupal 7 .
function hook_page_build(&$page) {
$page['page_bottom']['YOUR_MODULE'] = array(
'#markup' => '<div> I want to get inserted at the bootom of the page </div>',
);
}